Compare commits
No commits in common. 'main' and 'master' have entirely different histories.
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="accountSettings">
|
||||
<option name="activeRegion" value="us-east-1" />
|
||||
<option name="recentlyUsedRegions">
|
||||
<list>
|
||||
<option value="us-east-1" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="true" />
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="idempotent" />
|
||||
<module name="sentinel" />
|
||||
<module name="auth-service" />
|
||||
<module name="cache" />
|
||||
<module name="security" />
|
||||
<module name="file" />
|
||||
<module name="web" />
|
||||
<module name="music-service" />
|
||||
<module name="music-related-service" />
|
||||
<module name="songlist-service" />
|
||||
<module name="gateway" />
|
||||
<module name="feign-api" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel>
|
||||
<module name="eureka-server" target="11" />
|
||||
<module name="redis-utils-spring-boot-starter" target="1.8" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
<component name="JavacSettings">
|
||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
||||
<module name="auth-service" options="-parameters" />
|
||||
<module name="cache" options="-parameters" />
|
||||
<module name="common" options="" />
|
||||
<module name="eureka-server" options="-parameters" />
|
||||
<module name="feign-api" options="-parameters" />
|
||||
<module name="file" options="-parameters" />
|
||||
<module name="gateway" options="-parameters" />
|
||||
<module name="idempotent" options="-parameters" />
|
||||
<module name="music-related-service" options="-parameters" />
|
||||
<module name="music-service" options="-parameters" />
|
||||
<module name="security" options="-parameters" />
|
||||
<module name="sentinel" options="-parameters" />
|
||||
<module name="songlist-service" options="-parameters" />
|
||||
<module name="web" options="-parameters" />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="cloudmusic@localhost" uuid="53a721df-c00d-4041-ad61-e0640ed15c76">
|
||||
<driver-ref>mysql.8</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://localhost:3306/cloudmusic</jdbc-url>
|
||||
<vm-options>-Djava.net.preferIPv4Stack=true</vm-options>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="postgres" uuid="6c8494e7-5d7f-4128-9f4e-2785d71a708f">
|
||||
<driver-ref>postgresql</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:postgresql://8.210.250.29:5432/</jdbc-url>
|
||||
<vm-options>-Djava.net.preferIPv4Stack=true</vm-options>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="@8.210.250.29" uuid="d49b167b-b85b-472a-ae80-068cc0b8961f">
|
||||
<driver-ref>mysql.8</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://8.210.250.29:3306</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="@localhost" uuid="417deb03-8f32-42f9-bca8-0682793af9d9">
|
||||
<driver-ref>mysql.8</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/auth-service/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/auth-service/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/cache/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/cache/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/file/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/file/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/idempotent/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/idempotent/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/security/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/security/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/sentinel/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/sentinel/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/web/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/common/web/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/eureka-server/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/eureka-server/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/feign-api/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/feign-api/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/gateway/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/gateway/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/music-related-service/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/music-related-service/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/music-service/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/music-service/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/songlist-service/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/songlist-service/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="FrameworkDetectionExcludesConfiguration">
|
||||
<file type="web" url="file://$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/memorandum-auth/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/memorandum-event/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/memorandum-note/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/gateway/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/feign-api/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/common/web/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/common/oss/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/common/security/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/common/sentinel/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/common/file/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/common/cache/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/common/idempotent/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="TemplatesSettings">
|
||||
<option name="templateConfigs">
|
||||
<TemplateContext>
|
||||
<option name="generateConfig">
|
||||
<GenerateConfig>
|
||||
<option name="annotationType" value="NONE" />
|
||||
<option name="basePackage" value="generator" />
|
||||
<option name="basePath" value="src/main/java/com/flyingpig/cloudmusic/music" />
|
||||
<option name="classNameStrategy" value="camel" />
|
||||
<option name="encoding" value="UTF-8" />
|
||||
<option name="extraClassSuffix" value="" />
|
||||
<option name="ignoreFieldPrefix" value="" />
|
||||
<option name="ignoreFieldSuffix" value="" />
|
||||
<option name="ignoreTablePrefix" value="" />
|
||||
<option name="ignoreTableSuffix" value="" />
|
||||
<option name="moduleName" value="cloudmusic-music" />
|
||||
<option name="modulePath" value="$PROJECT_DIR$/cloudmusic-music" />
|
||||
<option name="moduleUIInfoList">
|
||||
<list>
|
||||
<ModuleInfoGo>
|
||||
<option name="basePath" value="src/main/java/com/flyingpig/cloudmusic/music" />
|
||||
<option name="configFileName" value="domain.ftl" />
|
||||
<option name="configName" value="domain" />
|
||||
<option name="encoding" value="UTF-8" />
|
||||
<option name="fileName" value="${domain.fileName}" />
|
||||
<option name="fileNameWithSuffix" value="${domain.fileName}.java" />
|
||||
<option name="modulePath" value="$PROJECT_DIR$/cloudmusic-music" />
|
||||
<option name="packageName" value="generator.dataobject" />
|
||||
</ModuleInfoGo>
|
||||
</list>
|
||||
</option>
|
||||
<option name="needToStringHashcodeEquals" value="true" />
|
||||
<option name="needsComment" value="true" />
|
||||
<option name="needsModel" value="true" />
|
||||
<option name="relativePackage" value="dataobject" />
|
||||
<option name="superClass" value="" />
|
||||
<option name="tableUIInfoList">
|
||||
<list>
|
||||
<TableUIInfo>
|
||||
<option name="className" value="Like" />
|
||||
<option name="tableName" value="like" />
|
||||
</TableUIInfo>
|
||||
</list>
|
||||
</option>
|
||||
<option name="templatesName" value="custom-model-swagger" />
|
||||
</GenerateConfig>
|
||||
</option>
|
||||
<option name="moduleName" value="cloudmusic-music" />
|
||||
<option name="projectPath" value="$PROJECT_DIR$" />
|
||||
<option name="templateName" value="custom-model-swagger" />
|
||||
</TemplateContext>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SonarLintProjectSettings">
|
||||
<option name="moduleMapping">
|
||||
<map>
|
||||
<entry key="file" value="oss" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
|
||||
@ -0,0 +1,308 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Apache Maven Wrapper startup batch script, version 3.2.0
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /usr/local/etc/mavenrc ] ; then
|
||||
. /usr/local/etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "$(uname)" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
|
||||
else
|
||||
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=$(java-config --jre-home)
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="$(which javac)"
|
||||
if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=$(which readlink)
|
||||
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="$(dirname "\"$javaExecutable\"")"
|
||||
javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
|
||||
else
|
||||
javaExecutable="$(readlink -f "\"$javaExecutable\"")"
|
||||
fi
|
||||
javaHome="$(dirname "\"$javaExecutable\"")"
|
||||
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=$(cd "$wdir/.." || exit 1; pwd)
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
# Remove \r in case we run on Windows within Git Bash
|
||||
# and check out the repository with auto CRLF management
|
||||
# enabled. Otherwise, we may read lines that are delimited with
|
||||
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
|
||||
# splitting rules.
|
||||
tr -s '\r\n' ' ' < "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
log() {
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
printf '%s\n' "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
|
||||
log "$MAVEN_PROJECTBASEDIR"
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if [ -r "$wrapperJarPath" ]; then
|
||||
log "Found $wrapperJarPath"
|
||||
else
|
||||
log "Couldn't find $wrapperJarPath, downloading it ..."
|
||||
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
else
|
||||
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
fi
|
||||
while IFS="=" read -r key value; do
|
||||
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
|
||||
safeValue=$(echo "$value" | tr -d '\r')
|
||||
case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
|
||||
esac
|
||||
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
log "Downloading from: $wrapperUrl"
|
||||
|
||||
if $cygwin; then
|
||||
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
log "Found wget ... using wget"
|
||||
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
else
|
||||
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
log "Found curl ... using curl"
|
||||
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||
else
|
||||
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
else
|
||||
log "Falling back to using Java to download"
|
||||
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaSource=$(cygpath --path --windows "$javaSource")
|
||||
javaClass=$(cygpath --path --windows "$javaClass")
|
||||
fi
|
||||
if [ -e "$javaSource" ]; then
|
||||
if [ ! -e "$javaClass" ]; then
|
||||
log " - Compiling MavenWrapperDownloader.java ..."
|
||||
("$JAVA_HOME/bin/javac" "$javaSource")
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
log " - Running MavenWrapperDownloader.java ..."
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
|
||||
wrapperSha256Sum=""
|
||||
while IFS="=" read -r key value; do
|
||||
case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
|
||||
esac
|
||||
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ -n "$wrapperSha256Sum" ]; then
|
||||
wrapperSha256Result=false
|
||||
if command -v sha256sum > /dev/null; then
|
||||
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
|
||||
wrapperSha256Result=true
|
||||
fi
|
||||
elif command -v shasum > /dev/null; then
|
||||
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
|
||||
wrapperSha256Result=true
|
||||
fi
|
||||
else
|
||||
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
|
||||
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
|
||||
exit 1
|
||||
fi
|
||||
if [ $wrapperSha256Result = false ]; then
|
||||
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
|
||||
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
|
||||
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
# shellcheck disable=SC2086 # safe args
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
$MAVEN_DEBUG_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||
@ -0,0 +1,205 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.2.0
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %WRAPPER_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
|
||||
SET WRAPPER_SHA_256_SUM=""
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
|
||||
)
|
||||
IF NOT %WRAPPER_SHA_256_SUM%=="" (
|
||||
powershell -Command "&{"^
|
||||
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
|
||||
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
|
||||
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
|
||||
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
|
||||
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
|
||||
" exit 1;"^
|
||||
"}"^
|
||||
"}"
|
||||
if ERRORLEVEL 1 goto error
|
||||
)
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% ^
|
||||
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||
%MAVEN_OPTS% ^
|
||||
%MAVEN_DEBUG_OPTS% ^
|
||||
-classpath %WRAPPER_JAR% ^
|
||||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||
|
||||
cmd /C exit /B %ERROR_CODE%
|
||||
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>cloud-music</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>auth-service</artifactId>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!-- springboot web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- 持久层: mysql mybatis mybatis-plus -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>8.0.33</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-autoconfigure</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.4.2</version>
|
||||
</dependency>
|
||||
<!-- springsecurity -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-security</artifactId>
|
||||
</dependency>
|
||||
<!-- fast json -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.62</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!-- nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<!-- mail -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<!-- feign调用 -->
|
||||
<dependency>
|
||||
<groupId>com.flyingpig</groupId>
|
||||
<artifactId>feign-api</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- 服务通用模块 -->
|
||||
<dependency>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common-web</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common-security</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common-file</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common-cache</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,17 @@
|
||||
package com.flyingpig.cloudmusic.auth;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
|
||||
@EnableSwagger2
|
||||
@SpringBootApplication
|
||||
@EnableAsync
|
||||
public class AuthApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AuthApplication.class, args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.flyingpig.cloudmusic.auth.config;
|
||||
|
||||
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.Config;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class RedissonConfig {
|
||||
|
||||
@Value("${spring.redis.host:localhost}")
|
||||
private String redisHost;
|
||||
|
||||
|
||||
@Value("${spring.redis.port:6379}")
|
||||
private int redisPort;
|
||||
|
||||
@Bean
|
||||
public RedissonClient redissonClient() {
|
||||
// 配置
|
||||
Config config = new Config();
|
||||
config.useSingleServer().setAddress("redis://" + redisHost + ":" + redisPort);
|
||||
// 创建RedissonClient对象
|
||||
return Redisson.create(config);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.flyingpig.cloudmusic.auth.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder(){
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
//关闭csrf
|
||||
.csrf().disable()
|
||||
//不会创建HttpSession并且不通过Session获取SecurityContext对象,因为前后端分离基本session就已经灭有用了
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
.and()
|
||||
.authorizeRequests()//对请求认证规则进行相应配置
|
||||
//对于登录,修改密码和注册接口放行(antMatchers)
|
||||
.antMatchers("/**").permitAll()
|
||||
.anyRequest().authenticated();
|
||||
}
|
||||
@Bean
|
||||
@Override
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.flyingpig.cloudmusic.auth.constant;
|
||||
|
||||
public class RedisConstants {
|
||||
|
||||
public static final String USER_INFO_KEY="user:info:";
|
||||
|
||||
public static final Long USER_INFO_TTL=30L;
|
||||
|
||||
public static final String USER_LOGIN_KEY="user:login:";
|
||||
|
||||
public static final Long USER_LOGIN_TTL = 30L;
|
||||
|
||||
public static final String EMAIL_VERIFYCODE_KEY="email:verifycode:";
|
||||
|
||||
public static final Long EMAIL_VERIFYCODE_TTL=120L;
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package com.flyingpig.cloudmusic.auth.controller;
|
||||
|
||||
import com.flyingpig.cloudmusic.auth.constant.RedisConstants;
|
||||
import com.flyingpig.cloudmusic.auth.dataobject.entity.User;
|
||||
import com.flyingpig.cloudmusic.security.util.JwtUtil;
|
||||
import com.flyingpig.cloudmusic.auth.service.UserService;
|
||||
import com.flyingpig.cloudmusic.web.Result;
|
||||
import com.flyingpig.cloudmusic.web.StatusCode;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.RedisConnectionFailureException;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/users")
|
||||
@Api("用户操作相关的api")
|
||||
@Slf4j
|
||||
public class AuthController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@PostMapping("/login")
|
||||
@ApiOperation("用户登录")
|
||||
public Result login(@RequestBody User user) {
|
||||
log.info("用户登录:{}", user);
|
||||
return userService.login(user);
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
@ApiOperation("用户登出")
|
||||
public Result logout(@RequestHeader String Authorization) {
|
||||
return userService.logout(JwtUtil.parseJwt(Authorization).getSubject());
|
||||
}
|
||||
|
||||
@GetMapping("/whitelist")
|
||||
public boolean uuidIsInWhiteListOrNot(String userId, String uuid) {
|
||||
String redisValue = stringRedisTemplate.opsForValue().get(RedisConstants.USER_LOGIN_KEY + userId);
|
||||
// 去掉引号和空格后再进行比较
|
||||
if (redisValue != null) {
|
||||
redisValue = redisValue.replace("\"", "").trim();
|
||||
}
|
||||
return Objects.equals(redisValue, uuid);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.flyingpig.cloudmusic.auth.controller;
|
||||
|
||||
|
||||
import com.flyingpig.cloudmusic.auth.constant.RedisConstants;
|
||||
import com.flyingpig.cloudmusic.auth.dataobject.entity.User;
|
||||
import com.flyingpig.cloudmusic.auth.dataobject.vo.EmailRegisterVO;
|
||||
import com.flyingpig.cloudmusic.auth.service.UserService;
|
||||
import com.flyingpig.cloudmusic.auth.util.EmailUtil;
|
||||
import com.flyingpig.cloudmusic.web.Result;
|
||||
import com.flyingpig.cloudmusic.web.StatusCode;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/email")
|
||||
@Api("与邮件处理相关的api")
|
||||
@Slf4j
|
||||
public class MailController {
|
||||
@Autowired
|
||||
UserService userService;
|
||||
@Autowired
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Autowired
|
||||
PasswordEncoder passwordEncoder;
|
||||
|
||||
@GetMapping("/verificationCode")
|
||||
@ApiOperation("用户获取验证码")
|
||||
public Result sendEmailVerificationCode(String email) {
|
||||
//检查email是否符合格式
|
||||
if (!EmailUtil.judgeEmailFormat(email)) {
|
||||
throw new RuntimeException("邮箱不符合格式");
|
||||
}
|
||||
userService.sendVerificationCode(email);
|
||||
return Result.success("验证码已发送");
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/register")
|
||||
@ApiOperation("通过验证码完成注册")
|
||||
public Result emailRegister(@RequestBody EmailRegisterVO emailRegisterVO) {
|
||||
String verificationCode = stringRedisTemplate.opsForValue().get(RedisConstants.EMAIL_VERIFYCODE_KEY + emailRegisterVO.getEmail());
|
||||
log.info("邮箱{}请求验证码{}",emailRegisterVO.getEmail(),verificationCode);
|
||||
if (verificationCode != null && verificationCode.equals(emailRegisterVO.getVerificationCode())) {
|
||||
// 添加用户
|
||||
userService.addUser(new User().setRole("user")
|
||||
.setUsername(emailRegisterVO.getUsername())
|
||||
.setPassword(passwordEncoder.encode(emailRegisterVO.getPassword()))
|
||||
.setEmail(emailRegisterVO.getEmail()));
|
||||
return Result.success("添加成功,请联系管理员审核");
|
||||
} else {
|
||||
throw new RuntimeException("验证码验证错误");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package com.flyingpig.cloudmusic.auth.controller;
|
||||
|
||||
|
||||
import com.flyingpig.cloudmusic.auth.service.UserService;
|
||||
import com.flyingpig.cloudmusic.security.aop.BeforeAuthorize;
|
||||
import com.flyingpig.cloudmusic.security.util.UserContext;
|
||||
import com.flyingpig.cloudmusic.web.Result;
|
||||
import com.flyingpig.feign.dataobject.dto.UserInfo;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/users")
|
||||
@Api("用户操作相关的api")
|
||||
public class UserController {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
|
||||
@GetMapping("/info")
|
||||
@ApiOperation("获取用户信息")
|
||||
public Result selectUserInfoByUserId() {
|
||||
//封装完毕后调用service层的add方法
|
||||
return Result.success(userService.selectUserInfoByUserId(UserContext.getUser().getUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/avatar")
|
||||
@ApiOperation("修改用户头像")
|
||||
public Result updateUserAvatar(@RequestParam MultipartFile avatar) throws IOException {
|
||||
//封装完毕后调用service层的add方法
|
||||
userService.updateAvatar(UserContext.getUser().getUserId(), avatar);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PutMapping("/username")
|
||||
@ApiOperation("修改用户名")
|
||||
public Result updateUserName(String userName) {
|
||||
userService.updateUserName(UserContext.getUser().getUserId(), userName);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiOperation("内部调用查询用户信息")
|
||||
@GetMapping("/user-info/{userId}")
|
||||
UserInfo selectUserInfoByUserId(@PathVariable("userId") Long userId) {
|
||||
return userService.selectUserInfoByUserId(userId);
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@BeforeAuthorize(role = "admin")
|
||||
@ApiOperation("管理员删除用户")
|
||||
public Result deleteUser(Long userId) {
|
||||
userService.deleteUserById(userId);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package com.flyingpig.cloudmusic.auth.dataobject.dto;
|
||||
|
||||
|
||||
import com.flyingpig.cloudmusic.auth.dataobject.entity.User;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LoginUser implements UserDetails {
|
||||
private User user;
|
||||
|
||||
//获取用户权限
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return null;
|
||||
}
|
||||
|
||||
//判断用户名和密码是否没过期
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//返回用户名
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return user.getEmail();
|
||||
}
|
||||
|
||||
//返回密码
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return user.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.flyingpig.cloudmusic.auth.dataobject.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@TableName("user")
|
||||
@Accessors(chain = true)
|
||||
public class User {
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
private String username;
|
||||
private String password;
|
||||
private String email;
|
||||
|
||||
private String avatar;
|
||||
private String role;
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.flyingpig.cloudmusic.auth.dataobject.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class EmailRegisterVO {
|
||||
public String email;
|
||||
public String verificationCode;
|
||||
//用户名
|
||||
private String username;
|
||||
//密码
|
||||
public String password;
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.flyingpig.cloudmusic.auth.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.flyingpig.cloudmusic.auth.dataobject.entity.User;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.flyingpig.cloudmusic.auth.service;
|
||||
|
||||
|
||||
import com.flyingpig.cloudmusic.auth.dataobject.entity.User;
|
||||
import com.flyingpig.cloudmusic.web.Result;
|
||||
import com.flyingpig.feign.dataobject.dto.UserInfo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
|
||||
public interface UserService {
|
||||
Result login(User user);
|
||||
|
||||
Result logout(String userId);
|
||||
|
||||
void addUser(User user);
|
||||
|
||||
UserInfo selectUserInfoByUserId(Long userId);
|
||||
|
||||
void updateUserName(Long userId, String userName);
|
||||
|
||||
void updateAvatar(Long userId, MultipartFile avatarUrl);
|
||||
|
||||
void deleteUserById(Long userId);
|
||||
|
||||
void sendVerificationCode(String email);
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.flyingpig.cloudmusic.auth.service.impl;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.flyingpig.cloudmusic.auth.dataobject.entity.User;
|
||||
import com.flyingpig.cloudmusic.auth.mapper.UserMapper;
|
||||
import com.flyingpig.cloudmusic.auth.dataobject.dto.LoginUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
|
||||
//查询用户信息
|
||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("email", email);
|
||||
User user = userMapper.selectOne(queryWrapper);
|
||||
//如果没有查询到用户就抛出异常
|
||||
if (Objects.isNull(user)) {
|
||||
throw new RuntimeException("用户名或者密码错误");
|
||||
}
|
||||
//把数据封装成UserDetails返回
|
||||
return new LoginUser(user);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.flyingpig.cloudmusic.auth.util;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class EmailUtil {
|
||||
//判断邮箱格式
|
||||
public static boolean judgeEmailFormat(String email) {
|
||||
String regex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
|
||||
if (email.matches(regex)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//生成验证码
|
||||
public static String createVerificationCode() {
|
||||
String result = new String();
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int randomNumber = random.nextInt(10); // 生成0到9之间的随机整数
|
||||
result = result + randomNumber;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//测试
|
||||
public static void main(String[] args) {
|
||||
String result = createVerificationCode();
|
||||
System.out.println(judgeEmailFormat("1839976096@qq.com"));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
server:
|
||||
port: 9094
|
||||
spring:
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
max-request-size: 10MB
|
||||
application:
|
||||
name: auth-service # 服务名称
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/cloudmusic
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
username: root
|
||||
password: '@Aa123456'
|
||||
cloud:
|
||||
nacos:
|
||||
server-addr: http://common-nacos-dev.magestack.cn:8848
|
||||
discovery:
|
||||
cluster-name: FJ # 集群名称
|
||||
ip: 8.210.250.29 # 注册到nacos的ip与端口
|
||||
port: 9094
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
database: 0
|
||||
mail:
|
||||
host: smtp.qq.com
|
||||
username: flying_pig_z@qq.com
|
||||
password:
|
||||
default-encoding: UTF-8
|
||||
port: 465
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
socketFactory:
|
||||
class: javax.net.ssl.SSLSocketFactory
|
||||
ssl:
|
||||
enable: true
|
||||
|
||||
|
||||
#??sql
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
mybatis:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
|
||||
#swagger配置
|
||||
swagger:
|
||||
title: "鉴权模块"
|
||||
description: "鉴权模块接口"
|
||||
base-package: com.flyingpig.cloudmusic.auth
|
||||
enabled: true
|
||||
version: 1.0.0
|
||||
#feign远程调用配置
|
||||
feign:
|
||||
httpclient:
|
||||
enabled: true # 开启feign对HttpClient的支持
|
||||
max-connections: 200 # 最大的连接数
|
||||
max-connections-per-route: 50 # 每个路径的最大连接数
|
||||
sentinel:
|
||||
enabled: true
|
||||
@ -0,0 +1,10 @@
|
||||
spring:
|
||||
application:
|
||||
name: auth-service # 服务名称
|
||||
profiles:
|
||||
active: prod #运行环境
|
||||
cloud:
|
||||
nacos:
|
||||
server-addr: http://47.122.56.65:8848 # Nacos地址
|
||||
config:
|
||||
file-extension: yaml # 文件后缀名
|
||||
@ -0,0 +1,12 @@
|
||||
package com.flyingpig.cloudmusic.auth;
|
||||
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args){
|
||||
BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
|
||||
String encodeString=bCryptPasswordEncoder.encode("1");
|
||||
System.out.println(encodeString);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>common-cache</artifactId>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.53</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>6.2.5.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.16</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.28</version> <!-- 版本号可根据需要调整 -->
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>3.21.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,14 @@
|
||||
package com.flyingpig.cloudmusic.cache;
|
||||
|
||||
/**
|
||||
* 缓存加载器
|
||||
* 用于将数据库信息加载到缓存中
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface CacheLoader<T> {
|
||||
|
||||
/**
|
||||
* 加载缓存
|
||||
*/
|
||||
T load();
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.flyingpig.cloudmusic.cache.config;
|
||||
|
||||
import com.flyingpig.cloudmusic.cache.StringCacheUtil;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class CacheAutoConfiguration {
|
||||
@Bean
|
||||
public StringCacheUtil stringCacheUtil() {
|
||||
return new StringCacheUtil();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.flyingpig.cloudmusic.cache.config.CacheAutoConfiguration
|
||||
@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>common-file</artifactId>
|
||||
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>3.15.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,13 @@
|
||||
package com.flyingpig.cloudmusic.file.config;
|
||||
|
||||
import com.flyingpig.cloudmusic.file.AliOSSUtils;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class AutoFileConfiguration {
|
||||
@Bean
|
||||
public AliOSSUtils aliOSSUtils() {
|
||||
return new AliOSSUtils();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.flyingpig.cloudmusic.file.config.AutoFileConfiguration
|
||||
@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<artifactId>common-idempotent</artifactId>
|
||||
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common-cache</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common-security</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,16 @@
|
||||
package com.flyingpig.cloudmusic.idempotent.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 幂等属性配置
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = IdempotentProperties.PREFIX)
|
||||
public class IdempotentProperties {
|
||||
|
||||
public static final String PREFIX = "flyingpig.idempotent.token";
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.flyingpig.cloudmusic.idempotent.core;
|
||||
|
||||
import com.flyingpig.cloudmusic.idempotent.annotation.Idempotent;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
|
||||
|
||||
public abstract class AbstractIdempotentExecuteHandler implements IdempotentExecuteHandler {
|
||||
|
||||
/**
|
||||
* 构建幂等验证过程中所需要的参数包装器
|
||||
*
|
||||
* @param joinPoint AOP 方法处理
|
||||
* @return 幂等参数包装器
|
||||
*/
|
||||
protected abstract IdempotentParamWrapper buildWrapper(ProceedingJoinPoint joinPoint);
|
||||
|
||||
/**
|
||||
* 执行幂等处理逻辑
|
||||
*
|
||||
* @param joinPoint AOP 方法处理
|
||||
* @param idempotent 幂等注解
|
||||
*/
|
||||
public void execute(ProceedingJoinPoint joinPoint, Idempotent idempotent) {
|
||||
// 模板方法模式:构建幂等参数包装器
|
||||
IdempotentParamWrapper idempotentParamWrapper = buildWrapper(joinPoint).setIdempotent(idempotent);
|
||||
handler(idempotentParamWrapper);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package com.flyingpig.cloudmusic.idempotent.core;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 幂等上下文
|
||||
*/
|
||||
public final class IdempotentContext {
|
||||
|
||||
private static final ThreadLocal<Map<String, Object>> CONTEXT = new ThreadLocal<>();
|
||||
|
||||
public static Map<String, Object> get() {
|
||||
return CONTEXT.get();
|
||||
}
|
||||
|
||||
public static Object getKey(String key) {
|
||||
Map<String, Object> context = get();
|
||||
if (CollUtil.isNotEmpty(context)) {
|
||||
return context.get(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getString(String key) {
|
||||
Object actual = getKey(key);
|
||||
if (actual != null) {
|
||||
return actual.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void put(String key, Object val) {
|
||||
// 获得上下文
|
||||
Map<String, Object> context = get();
|
||||
if (CollUtil.isEmpty(context)) {
|
||||
// 如果为空,创建一个新的上下文
|
||||
context = Maps.newHashMap();
|
||||
}
|
||||
// 锁
|
||||
context.put(key, val);
|
||||
putContext(context);
|
||||
}
|
||||
|
||||
public static void putContext(Map<String, Object> context) {
|
||||
// 获得上下文
|
||||
Map<String, Object> threadContext = CONTEXT.get();
|
||||
if (CollUtil.isNotEmpty(threadContext)) {
|
||||
// 如果不为空,放入所有的值
|
||||
threadContext.putAll(context);
|
||||
return;
|
||||
}
|
||||
// 设置上下文
|
||||
CONTEXT.set(context);
|
||||
}
|
||||
|
||||
public static void clean() {
|
||||
CONTEXT.remove();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.flyingpig.cloudmusic.idempotent.core;
|
||||
|
||||
import com.flyingpig.cloudmusic.idempotent.annotation.Idempotent;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
|
||||
/**
|
||||
* 幂等执行处理器
|
||||
*/
|
||||
public interface IdempotentExecuteHandler {
|
||||
|
||||
/**
|
||||
* 幂等处理逻辑
|
||||
*
|
||||
* @param wrapper 幂等参数包装器
|
||||
*/
|
||||
void handler(IdempotentParamWrapper wrapper);
|
||||
|
||||
/**
|
||||
* 执行幂等处理逻辑
|
||||
*
|
||||
* @param joinPoint AOP 方法处理
|
||||
* @param idempotent 幂等注解
|
||||
*/
|
||||
void execute(ProceedingJoinPoint joinPoint, Idempotent idempotent);
|
||||
|
||||
/**
|
||||
* 异常流程处理
|
||||
*/
|
||||
default void exceptionProcessing() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 后置处理
|
||||
*/
|
||||
default void postProcessing() {
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.flyingpig.cloudmusic.idempotent.core;
|
||||
|
||||
|
||||
import com.flyingpig.cloudmusic.idempotent.core.bases.ApplicationContextHolder;
|
||||
import com.flyingpig.cloudmusic.idempotent.core.param.IdempotentParamService;
|
||||
import com.flyingpig.cloudmusic.idempotent.core.spel.IdempotentSpELByMQExecuteHandler;
|
||||
import com.flyingpig.cloudmusic.idempotent.core.spel.IdempotentSpELByRestAPIExecuteHandler;
|
||||
import com.flyingpig.cloudmusic.idempotent.enums.IdempotentSceneEnum;
|
||||
import com.flyingpig.cloudmusic.idempotent.enums.IdempotentTypeEnum;
|
||||
|
||||
/**
|
||||
* 幂等执行处理器工厂
|
||||
*/
|
||||
public final class IdempotentExecuteHandlerFactory {
|
||||
|
||||
/**
|
||||
* 获取幂等执行处理器
|
||||
*
|
||||
* @param scene 指定幂等验证场景类型
|
||||
* @param type 指定幂等处理类型
|
||||
* @return 幂等执行处理器
|
||||
*/
|
||||
public static IdempotentExecuteHandler getInstance(IdempotentSceneEnum scene, IdempotentTypeEnum type) {
|
||||
IdempotentExecuteHandler result = null;
|
||||
switch (scene) {
|
||||
case RESTAPI:
|
||||
switch (type) {
|
||||
case PARAM:
|
||||
result = ApplicationContextHolder.getBean(IdempotentParamService.class);
|
||||
break;
|
||||
case SPEL:
|
||||
result = ApplicationContextHolder.getBean(IdempotentSpELByRestAPIExecuteHandler.class);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MQ:
|
||||
result = ApplicationContextHolder.getBean(IdempotentSpELByMQExecuteHandler.class);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.flyingpig.cloudmusic.idempotent.core;
|
||||
|
||||
import com.flyingpig.cloudmusic.idempotent.annotation.Idempotent;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
|
||||
/**
|
||||
* 幂等参数包装
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public final class IdempotentParamWrapper {
|
||||
|
||||
/**
|
||||
* 幂等注解
|
||||
*/
|
||||
private Idempotent idempotent;
|
||||
|
||||
/**
|
||||
* AOP 处理连接点
|
||||
*/
|
||||
private ProceedingJoinPoint joinPoint;
|
||||
|
||||
/**
|
||||
* 锁标识
|
||||
*/
|
||||
private String lockKey;
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.flyingpig.cloudmusic.idempotent.core.bases;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Application context holder.
|
||||
*/
|
||||
public class ApplicationContextHolder implements ApplicationContextAware {
|
||||
|
||||
private static ApplicationContext CONTEXT;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
ApplicationContextHolder.CONTEXT = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ioc container bean by type.
|
||||
*/
|
||||
public static <T> T getBean(Class<T> clazz) {
|
||||
return CONTEXT.getBean(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ioc container bean by name.
|
||||
*/
|
||||
public static Object getBean(String name) {
|
||||
return CONTEXT.getBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ioc container bean by name and type.
|
||||
*/
|
||||
public static <T> T getBean(String name, Class<T> clazz) {
|
||||
return CONTEXT.getBean(name, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of ioc container beans by type.
|
||||
*/
|
||||
public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {
|
||||
return CONTEXT.getBeansOfType(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find whether the bean has annotations.
|
||||
*/
|
||||
public static <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) {
|
||||
return CONTEXT.findAnnotationOnBean(beanName, annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get application context.
|
||||
*/
|
||||
public static ApplicationContext getInstance() {
|
||||
return CONTEXT;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.flyingpig.cloudmusic.idempotent.core.spel;
|
||||
|
||||
|
||||
import com.flyingpig.cloudmusic.idempotent.core.IdempotentExecuteHandler;
|
||||
|
||||
/**
|
||||
* SpEL 方式幂等实现接口
|
||||
*/
|
||||
public interface IdempotentSpELService extends IdempotentExecuteHandler {
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.flyingpig.cloudmusic.idempotent.enums;
|
||||
|
||||
/**
|
||||
* 幂等验证场景枚举
|
||||
*/
|
||||
public enum IdempotentSceneEnum {
|
||||
|
||||
/**
|
||||
* 基于 RestAPI 场景验证
|
||||
*/
|
||||
RESTAPI,
|
||||
|
||||
/**
|
||||
* 基于 MQ 场景验证
|
||||
*/
|
||||
MQ
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.flyingpig.cloudmusic.idempotent.enums;
|
||||
|
||||
/**
|
||||
* 幂等验证类型枚举
|
||||
*/
|
||||
public enum IdempotentTypeEnum {
|
||||
|
||||
/**
|
||||
* 基于 Token 方式验证
|
||||
*/
|
||||
TOKEN,
|
||||
|
||||
/**
|
||||
* 基于方法参数方式验证
|
||||
*/
|
||||
PARAM,
|
||||
|
||||
/**
|
||||
* 基于 SpEL 表达式方式验证
|
||||
*/
|
||||
SPEL
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.flyingpig.cloudmusic.idempotent.toolkit;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 日志工具类
|
||||
*/
|
||||
public class LogUtil {
|
||||
|
||||
/**
|
||||
* 获取 Logger
|
||||
*/
|
||||
public static Logger getLog(ProceedingJoinPoint joinPoint) {
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
return LoggerFactory.getLogger(methodSignature.getDeclaringType());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.flyingpig.cloudmusic.idempotent.toolkit;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* SpEL 表达式解析工具
|
||||
*/
|
||||
public class SpELUtil {
|
||||
|
||||
/**
|
||||
* 校验并返回实际使用的 spEL 表达式
|
||||
*
|
||||
* @param spEl spEL 表达式
|
||||
* @return 实际使用的 spEL 表达式
|
||||
*/
|
||||
public static Object parseKey(String spEl, Method method, Object[] contextObj) {
|
||||
// 校验,是否包含 # 或 T(,如果包含则需要解析
|
||||
ArrayList<String> spELFlag = Lists.newArrayList("#", "T(");
|
||||
Optional<String> optional = spELFlag.stream().filter(spEl::contains).findFirst();
|
||||
if (optional.isPresent()) {
|
||||
// 解析并返回
|
||||
return parse(spEl, method, contextObj);
|
||||
}
|
||||
// 直接返回
|
||||
return spEl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换参数为字符串
|
||||
*
|
||||
* @param spEl spEl 表达式
|
||||
* @param contextObj 上下文对象
|
||||
* @return 解析的字符串值
|
||||
*/
|
||||
public static Object parse(String spEl, Method method, Object[] contextObj) {
|
||||
DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
// 解析 SpEL 表达式
|
||||
Expression exp = parser.parseExpression(spEl);
|
||||
// 获取方法参数名
|
||||
String[] params = discoverer.getParameterNames(method);
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
if (ArrayUtil.isNotEmpty(params)) {
|
||||
// 设置参数
|
||||
for (int len = 0; len < params.length; len++) {
|
||||
context.setVariable(params[len], contextObj[len]);
|
||||
}
|
||||
}
|
||||
// 解析并返回
|
||||
return exp.getValue(context);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.flyingpig.cloudmusic.idempotent.config.IdempotentAutoConfiguration
|
||||
@ -0,0 +1,23 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>cloud-music</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>common</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
||||
<modules>
|
||||
<module>/security</module>
|
||||
<module>/file</module>
|
||||
<module>/cache</module>
|
||||
<module>/sentinel</module>
|
||||
<module>/web</module>
|
||||
</modules>
|
||||
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>common-security</artifactId>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common-web</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,30 @@
|
||||
package com.flyingpig.cloudmusic.security.aop;
|
||||
|
||||
|
||||
import com.flyingpig.cloudmusic.security.util.UserContext;
|
||||
import com.flyingpig.cloudmusic.web.Result;
|
||||
import com.flyingpig.cloudmusic.web.StatusCode;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class AuthorizationAspect {
|
||||
|
||||
@Around("@annotation(beforeAuthorize)")
|
||||
public Object checkAuthorization(ProceedingJoinPoint proceedingJoinPoint, BeforeAuthorize beforeAuthorize) throws Throwable {
|
||||
String role = UserContext.getUser().getRole();
|
||||
|
||||
String requiredRoles = beforeAuthorize.role();
|
||||
|
||||
if (!role.equals(requiredRoles)) {
|
||||
return Result.error(StatusCode.UNAUTHORIZED, "权限不足");
|
||||
} else {
|
||||
return proceedingJoinPoint.proceed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.flyingpig.cloudmusic.security.aop;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface BeforeAuthorize {
|
||||
String role();
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.flyingpig.cloudmusic.security.config;
|
||||
|
||||
import com.flyingpig.cloudmusic.security.interceptor.UserInfoInterceptor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class MvcConfig implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new UserInfoInterceptor());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.flyingpig.cloudmusic.security.interceptor;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LocalUserInfo {
|
||||
Long userId;
|
||||
String role;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.flyingpig.cloudmusic.security.util;
|
||||
|
||||
|
||||
import com.flyingpig.cloudmusic.security.interceptor.LocalUserInfo;
|
||||
|
||||
public class UserContext {
|
||||
private static final ThreadLocal<LocalUserInfo> tl =new ThreadLocal<>();
|
||||
|
||||
//保存当前登录用户信息到ThreadLocal
|
||||
public static void setUser(LocalUserInfo localUserInfo){
|
||||
tl.set(localUserInfo);
|
||||
}
|
||||
//获取当前登录的用户信息
|
||||
public static LocalUserInfo getUser(){
|
||||
return tl.get();
|
||||
}
|
||||
|
||||
//移除当前登录用户信息
|
||||
public static void removeUser(){
|
||||
tl.remove();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.flyingpig.cloudmusic.security.config.MvcConfig
|
||||
@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>common-sentinel</artifactId>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,21 @@
|
||||
package com.flyingpig.cloudmusic.sentinel;
|
||||
|
||||
import com.alibaba.cloud.commons.lang.StringUtils;
|
||||
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Component
|
||||
public class HeaderOriginParser implements RequestOriginParser {
|
||||
@Override
|
||||
public String parseOrigin(HttpServletRequest request) {
|
||||
// 1.获取请求头
|
||||
String origin = request.getHeader("origin");
|
||||
// 2.非空判断
|
||||
if (StringUtils.isEmpty(origin)) {
|
||||
origin = "blank";
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.flyingpig.cloudmusic.sentinel.exception;
|
||||
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@Component
|
||||
public class SentinelExceptionHandler implements BlockExceptionHandler {
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
|
||||
String msg = "未知异常";
|
||||
int status = 429;
|
||||
|
||||
if (e instanceof FlowException) {
|
||||
msg = "请求被限流了";
|
||||
} else if (e instanceof ParamFlowException) {
|
||||
msg = "请求被热点参数限流";
|
||||
} else if (e instanceof DegradeException) {
|
||||
msg = "请求被降级了";
|
||||
} else if (e instanceof AuthorityException) {
|
||||
msg = "没有权限访问";
|
||||
status = 401;
|
||||
}
|
||||
|
||||
response.setContentType("application/json;charset=utf-8");
|
||||
response.setStatus(status);
|
||||
response.getWriter().println("{\"msg\": " + msg + ", \"status\": " + status + "}");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.flyingpig.cloud-music</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>common-web</artifactId>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>6.2.5.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.16</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor.addons</groupId>
|
||||
<artifactId>reactor-extra</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.28</version> <!-- 版本号可根据需要调整 -->
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,34 @@
|
||||
package com.flyingpig.cloudmusic.web;
|
||||
|
||||
public class StatusCode {
|
||||
/**
|
||||
* 操作成功
|
||||
*/
|
||||
public static final int OK = 200;
|
||||
|
||||
/**
|
||||
* 请求参数异常或缺失
|
||||
*/
|
||||
public static final int PARAMETERERROR = 400;
|
||||
|
||||
/**
|
||||
* 资源不存在
|
||||
*/
|
||||
public static final int NOTFOUND = 404;
|
||||
|
||||
/**
|
||||
* 请求方法错误
|
||||
*/
|
||||
public static final int METHODERROR = 405;
|
||||
|
||||
/**
|
||||
* 服务端错误
|
||||
*/
|
||||
public static final int SERVERERROR = 500;
|
||||
|
||||
/**
|
||||
* 未经授权
|
||||
*/
|
||||
public static final int UNAUTHORIZED = 401;
|
||||
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.flyingpig.cloudmusic.web.config;
|
||||
|
||||
import com.flyingpig.cloudmusic.web.exception.GlobalExceptionHandler;
|
||||
import com.flyingpig.cloudmusic.web.init.InitializeDispatcherServletController;
|
||||
import com.flyingpig.cloudmusic.web.init.InitializeDispatcherServletHandler;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
public class WebAutoConfiguration {
|
||||
|
||||
public final static String INITIALIZE_PATH = "/initialize/dispatcher-servlet";
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean// 只有在 Spring 容器中没有定义特定类型的 Bean 时,才会创建该 Bean
|
||||
@ConditionalOnMissingClass("org.springframework.web.reactive.DispatcherHandler") // 检查 WebFlux 是否存在
|
||||
public GlobalExceptionHandler globalExceptionHandler() {
|
||||
return new GlobalExceptionHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingClass("org.springframework.web.reactive.DispatcherHandler") // 检查 WebFlux 是否存在
|
||||
public InitializeDispatcherServletController initializeDispatcherServletController() {
|
||||
return new InitializeDispatcherServletController();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingClass("org.springframework.web.reactive.DispatcherHandler") // 检查 WebFlux 是否存在
|
||||
public RestTemplate simpleRestTemplate(ClientHttpRequestFactory factory) {
|
||||
return new RestTemplate(factory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingClass("org.springframework.web.reactive.DispatcherHandler") // 检查 WebFlux 是否存在
|
||||
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
|
||||
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
|
||||
factory.setReadTimeout(5000);
|
||||
factory.setConnectTimeout(5000);
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingClass("org.springframework.web.reactive.DispatcherHandler") // 检查 WebFlux 是否存在
|
||||
public InitializeDispatcherServletHandler initializeDispatcherServletHandler(RestTemplate simpleRestTemplate, ConfigurableEnvironment configurableEnvironment) {
|
||||
return new InitializeDispatcherServletHandler(simpleRestTemplate, configurableEnvironment);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package com.flyingpig.cloudmusic.web.exception;
|
||||
|
||||
|
||||
import com.flyingpig.cloudmusic.web.Result;
|
||||
import com.flyingpig.cloudmusic.web.StatusCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.data.redis.RedisConnectionFailureException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
|
||||
import java.net.BindException;
|
||||
|
||||
//全局异常处理器
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 请求参数异常/缺少--400
|
||||
*
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler({
|
||||
MissingServletRequestParameterException.class,
|
||||
MethodArgumentTypeMismatchException.class,
|
||||
BindException.class}
|
||||
)
|
||||
public Result missingServletRequestParameterException(Exception e) {
|
||||
return Result.error(StatusCode.PARAMETERERROR, "缺少参数或参数错误");
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求方法错误--405
|
||||
*
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
||||
public Result httpRequestMethodNotSupportedExceptionHandler(Exception e) {
|
||||
log.error("请求方法错误");
|
||||
return Result.error(StatusCode.METHODERROR, "请求方法错误");
|
||||
}
|
||||
|
||||
/**
|
||||
* Redis没连接上--500
|
||||
*/
|
||||
@ExceptionHandler(RedisConnectionFailureException.class)
|
||||
public Result edisConnectionFailureExceptionHandler(RedisConnectionFailureException e) {
|
||||
log.error("redis连接错误啦啦啦啦啦啦");
|
||||
return Result.error(StatusCode.SERVERERROR, "redis连接错误啦啦啦啦啦啦");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 其他异常--500
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Result exceptionHandler(Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error(StatusCode.SERVERERROR, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.flyingpig.cloudmusic.web.init;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static com.flyingpig.cloudmusic.web.config.WebAutoConfiguration.INITIALIZE_PATH;
|
||||
|
||||
@Slf4j(topic = "Initialize DispatcherServlet")
|
||||
@RestController
|
||||
public final class InitializeDispatcherServletController {
|
||||
|
||||
@GetMapping(INITIALIZE_PATH)
|
||||
public void initializeDispatcherServlet() {
|
||||
log.info("Initialized the dispatcherServlet to improve the first response time of the interface...");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.flyingpig.cloudmusic.web.init;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import static com.flyingpig.cloudmusic.web.config.WebAutoConfiguration.INITIALIZE_PATH;
|
||||
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class InitializeDispatcherServletHandler implements CommandLineRunner {
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
private final ConfigurableEnvironment configurableEnvironment;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
String url = String.format("http://127.0.0.1:%s%s",
|
||||
configurableEnvironment.getProperty("server.port", "8080") + configurableEnvironment.getProperty("server.servlet.context-path", ""),
|
||||
INITIALIZE_PATH);
|
||||
try {
|
||||
restTemplate.execute(url, HttpMethod.GET, null, null);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.flyingpig.cloudmusic.web.config.WebAutoConfiguration
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue