初始化git 基础代码

This commit is contained in:
bao
2026-01-14 08:37:21 +08:00
commit e52b622a52
295 changed files with 18426 additions and 0 deletions

BIN
.idea/.cache/.Apifox_Helper/.toolWindow.db generated Normal file

Binary file not shown.

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/../../../../../:\code\news-v2.3\heima-leadnews\.idea/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

6
.idea/ApifoxUploaderProjectSetting.xml generated Normal file
View File

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

55
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,55 @@
<?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="freemarker-demo" />
<module name="heima-leadnews-wemedia-gateway" />
<module name="heima-leadnews-wemedia" />
<module name="tess4j-demo" />
<module name="heima-leadnews-article" />
<module name="heima-leadnews-user" />
<module name="heima-leadnews-feign-api" />
<module name="kafka-demo" />
<module name="heima-leadnews-test" />
<module name="heima-leadnews-schedule" />
<module name="heima-leadnews-utils" />
<module name="heima-leadnews-app-gateway" />
<module name="heima-leadnews-common" />
<module name="heima-leadnews-model" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="heima-file-starter" target="1.8" />
<module name="heima-leadnews-apis" target="1.8" />
<module name="minio-demo" target="1.8" />
</bytecodeTargetLevel>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="freemarker-demo" options="-parameters" />
<module name="heima-file-starter" options="-parameters" />
<module name="heima-leadnews" options="-parameters" />
<module name="heima-leadnews-apis" options="-parameters" />
<module name="heima-leadnews-app-gateway" options="-parameters" />
<module name="heima-leadnews-article" options="-parameters" />
<module name="heima-leadnews-basic" options="-parameters" />
<module name="heima-leadnews-common" options="-parameters" />
<module name="heima-leadnews-feign-api" options="-parameters" />
<module name="heima-leadnews-gateway" options="-parameters" />
<module name="heima-leadnews-model" options="-parameters" />
<module name="heima-leadnews-schedule" options="-parameters" />
<module name="heima-leadnews-service" options="-parameters" />
<module name="heima-leadnews-test" options="-parameters" />
<module name="heima-leadnews-user" options="-parameters" />
<module name="heima-leadnews-utils" options="-parameters" />
<module name="heima-leadnews-wemedia" options="-parameters" />
<module name="heima-leadnews-wemedia-gateway" options="-parameters" />
<module name="tess4j-demo" options="-parameters" />
</option>
</component>
</project>

30
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/heima-leadnews-basic/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-basic/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-common/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-feign-api/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-gateway/heima-leadnews-app-gateway/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-gateway/heima-leadnews-app-geteway/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-gateway/heima-leadnews-wemedia-gateway/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-gateway/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-gateway/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-model/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-article/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-schedule/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-user/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-wemedia/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-service/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-service/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-test/freemarker-demo/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-test/kafka-demo/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-test/kafka-demo/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-test/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-test/tess4j-demo/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-test/tess4j-demo/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/heima-leadnews-utils/src/main/java" 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" />
</component>
</project>

35
.idea/jarRepositories.xml generated Normal file
View File

@@ -0,0 +1,35 @@
<?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="spring" />
<option name="name" value="spring" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</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>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
<remote-repository>
<option name="id" value="spring" />
<option name="name" value="spring" />
<option name="url" value="https://maven.aliyun.com/repository/spring" />
</remote-repository>
</component>
</project>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.apache.kafka:kafka-clients:2.0.1">
<CLASSES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/apache/kafka/kafka-clients/2.0.1/kafka-clients-2.0.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/apache/kafka/kafka-clients/2.0.1/kafka-clients-2.0.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/apache/kafka/kafka-clients/2.0.1/kafka-clients-2.0.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.apache.kafka:kafka-streams:2.0.1">
<CLASSES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/apache/kafka/kafka-streams/2.0.1/kafka-streams-2.0.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/apache/kafka/kafka-streams/2.0.1/kafka-streams-2.0.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/apache/kafka/kafka-streams/2.0.1/kafka-streams-2.0.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.lz4:lz4-java:1.4.1">
<CLASSES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/lz4/lz4-java/1.4.1/lz4-java-1.4.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/lz4/lz4-java/1.4.1/lz4-java-1.4.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/lz4/lz4-java/1.4.1/lz4-java-1.4.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.rocksdb:rocksdbjni:5.7.3">
<CLASSES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/rocksdb/rocksdbjni/5.7.3/rocksdbjni-5.7.3.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/rocksdb/rocksdbjni/5.7.3/rocksdbjni-5.7.3-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/rocksdb/rocksdbjni/5.7.3/rocksdbjni-5.7.3-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

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

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.xerial.snappy:snappy-java:1.1.7.1">
<CLASSES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/xerial/snappy/snappy-java/1.1.7.1/snappy-java-1.1.7.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/xerial/snappy/snappy-java/1.1.7.1/snappy-java-1.1.7.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/../../../respository_new/org/xerial/snappy/snappy-java/1.1.7.1/snappy-java-1.1.7.1-sources.jar!/" />
</SOURCES>
</library>
</component>

41
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-test/minio-demo/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-gateway/heima-leadnews-app-gateway/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-service/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-article/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-user/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-wemedia/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-model/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-gateway/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-gateway/heima-leadnews-wemedia-gateway/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-feign-api/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-common/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-basic/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-test/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-utils/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-test/freemarker-demo/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-test/tess4j-demo/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-schedule/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-test/kafka-demo/pom.xml" />
</list>
</option>
<option name="ignoredFiles">
<set>
<option value="$PROJECT_DIR$/heima-leadnews-basic/heima-file-starter/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-gateway/heima-leadnews-app-geteway/pom.xml" />
<option value="$PROJECT_DIR$/heima-leadnews-test/minio-demo/pom.xml" />
</set>
</option>
</component>
<component name="PWA">
<option name="enabled" value="true" />
<option name="wasEnabledAtLeastOnce" value="true" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>

16
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-article/heima-leadnews-article.iml" filepath="$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-article/heima-leadnews-article.iml" />
<module fileurl="file://$PROJECT_DIR$/heima-leadnews-common/heima-leadnews-common.iml" filepath="$PROJECT_DIR$/heima-leadnews-common/heima-leadnews-common.iml" />
<module fileurl="file://$PROJECT_DIR$/heima-leadnews-feign-api/heima-leadnews-feign-api.iml" filepath="$PROJECT_DIR$/heima-leadnews-feign-api/heima-leadnews-feign-api.iml" />
<module fileurl="file://$PROJECT_DIR$/heima-leadnews-model/heima-leadnews-model.iml" filepath="$PROJECT_DIR$/heima-leadnews-model/heima-leadnews-model.iml" />
<module fileurl="file://$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-schedule/heima-leadnews-schedule.iml" filepath="$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-schedule/heima-leadnews-schedule.iml" />
<module fileurl="file://$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-service.iml" filepath="$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-service.iml" />
<module fileurl="file://$PROJECT_DIR$/heima-leadnews-utils/heima-leadnews-utils.iml" filepath="$PROJECT_DIR$/heima-leadnews-utils/heima-leadnews-utils.iml" />
<module fileurl="file://$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-wemedia/heima-leadnews-wemedia.iml" filepath="$PROJECT_DIR$/heima-leadnews-service/heima-leadnews-wemedia/heima-leadnews-wemedia.iml" />
<module fileurl="file://$PROJECT_DIR$/heima-leadnews-gateway/heima-leadnews-wemedia-gateway/heima-leadnews-wemedia-gateway.iml" filepath="$PROJECT_DIR$/heima-leadnews-gateway/heima-leadnews-wemedia-gateway/heima-leadnews-wemedia-gateway.iml" />
</modules>
</component>
</project>

124
.idea/uiDesigner.xml generated Normal file
View File

@@ -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>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
</module>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>heima-leadnews-basic</artifactId>
<groupId>com.heima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>heima-file-starter</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,31 @@
package com.heima.file.config;
import com.heima.file.service.FileStorageService;
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@EnableConfigurationProperties({MinIOConfigProperties.class})
//当引入FileStorageService接口时
@ConditionalOnClass(FileStorageService.class)
public class MinIOConfig {
@Autowired
private MinIOConfigProperties minIOConfigProperties;
@Bean
public MinioClient buildMinioClient() {
return MinioClient
.builder()
.credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey())
.endpoint(minIOConfigProperties.getEndpoint())
.build();
}
}

View File

@@ -0,0 +1,18 @@
package com.heima.file.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.io.Serializable;
@Data
@ConfigurationProperties(prefix = "minio") // 文件上传 配置前缀file.oss
public class MinIOConfigProperties implements Serializable {
private String accessKey;
private String secretKey;
private String bucket;
private String endpoint;
private String readPath;
}

View File

@@ -0,0 +1,43 @@
package com.heima.file.service;
import java.io.InputStream;
/**
* @author itheima
*/
public interface FileStorageService {
/**
* 上传图片文件
* @param prefix 文件前缀
* @param filename 文件名
* @param inputStream 文件流
* @return 文件全路径
*/
public String uploadImgFile(String prefix, String filename,InputStream inputStream);
/**
* 上传html文件
* @param prefix 文件前缀
* @param filename 文件名
* @param inputStream 文件流
* @return 文件全路径
*/
public String uploadHtmlFile(String prefix, String filename,InputStream inputStream);
/**
* 删除文件
* @param pathUrl 文件全路径
*/
public void delete(String pathUrl);
/**
* 下载文件
* @param pathUrl 文件全路径
* @return
*
*/
public byte[] downLoadFile(String pathUrl);
}

View File

@@ -0,0 +1,164 @@
package com.heima.file.service.impl;
import com.heima.file.config.MinIOConfig;
import com.heima.file.config.MinIOConfigProperties;
import com.heima.file.service.FileStorageService;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;
import org.springframework.util.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
@Slf4j
@EnableConfigurationProperties(MinIOConfigProperties.class)
@Import(MinIOConfig.class)
public class MinIOFileStorageService implements FileStorageService {
@Autowired
private MinioClient minioClient;
@Autowired
private MinIOConfigProperties minIOConfigProperties;
private final static String separator = "/";
/**
* @param dirPath
* @param filename yyyy/mm/dd/file.jpg
* @return
*/
public String builderFilePath(String dirPath,String filename) {
StringBuilder stringBuilder = new StringBuilder(50);
if(!StringUtils.isEmpty(dirPath)){
stringBuilder.append(dirPath).append(separator);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String todayStr = sdf.format(new Date());
stringBuilder.append(todayStr).append(separator);
stringBuilder.append(filename);
return stringBuilder.toString();
}
/**
* 上传图片文件
* @param prefix 文件前缀
* @param filename 文件名
* @param inputStream 文件流
* @return 文件全路径
*/
@Override
public String uploadImgFile(String prefix, String filename,InputStream inputStream) {
String filePath = builderFilePath(prefix, filename);
try {
PutObjectArgs putObjectArgs = PutObjectArgs.builder()
.object(filePath)
.contentType("image/jpg")
.bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1)
.build();
minioClient.putObject(putObjectArgs);
StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());
urlPath.append(separator+minIOConfigProperties.getBucket());
urlPath.append(separator);
urlPath.append(filePath);
return urlPath.toString();
}catch (Exception ex){
log.error("minio put file error.",ex);
throw new RuntimeException("上传文件失败");
}
}
/**
* 上传html文件
* @param prefix 文件前缀
* @param filename 文件名
* @param inputStream 文件流
* @return 文件全路径
*/
@Override
public String uploadHtmlFile(String prefix, String filename,InputStream inputStream) {
String filePath = builderFilePath(prefix, filename);
try {
PutObjectArgs putObjectArgs = PutObjectArgs.builder()
.object(filePath)
.contentType("text/html")
.bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1)
.build();
minioClient.putObject(putObjectArgs);
StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());
urlPath.append(separator+minIOConfigProperties.getBucket());
urlPath.append(separator);
urlPath.append(filePath);
return urlPath.toString();
}catch (Exception ex){
log.error("minio put file error.",ex);
ex.printStackTrace();
throw new RuntimeException("上传文件失败");
}
}
/**
* 删除文件
* @param pathUrl 文件全路径
*/
@Override
public void delete(String pathUrl) {
String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/","");
int index = key.indexOf(separator);
String bucket = key.substring(0,index);
String filePath = key.substring(index+1);
// 删除Objects
RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();
try {
minioClient.removeObject(removeObjectArgs);
} catch (Exception e) {
log.error("minio remove file error. pathUrl:{}",pathUrl);
e.printStackTrace();
}
}
/**
* 下载文件
* @param pathUrl 文件全路径
* @return 文件流
*
*/
@Override
public byte[] downLoadFile(String pathUrl) {
String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/","");
int index = key.indexOf(separator);
String bucket = key.substring(0,index);
String filePath = key.substring(index+1);
InputStream inputStream = null;
try {
inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build());
} catch (Exception e) {
log.error("minio down file error. pathUrl:{}",pathUrl);
e.printStackTrace();
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while (true) {
try {
if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;
} catch (IOException e) {
e.printStackTrace();
}
byteArrayOutputStream.write(buff, 0, rc);
}
return byteArrayOutputStream.toByteArray();
}
}

View File

@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.heima.file.service.impl.MinIOFileStorageService

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>heima-leadnews</artifactId>
<groupId>com.heima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>heima-leadnews-basic</artifactId>
<packaging>pom</packaging>
<modules>
<module>heima-file-starter</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
</module>

View File

@@ -0,0 +1,184 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>heima-leadnews</artifactId>
<groupId>com.heima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>heima-leadnews-common</artifactId>
<packaging>jar</packaging>
<name>heima-leadnews-common</name>
<dependencies>
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>imageaudit20191230</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>com.heima</groupId>
<artifactId>heima-leadnews-utils</artifactId>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring data redis & cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redis依赖commons-pool 这个依赖一定要添加 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!--fastdfs-->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.3</version> <!-- 建议使用最新稳定版 -->
</dependency>
<!--安装OSS SDK-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.16.3</version>
</dependency>
<!-- kafkfa -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</dependency>
<!--kafka stream-->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-green</artifactId>
</dependency>
<!--HBase-->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.1.5</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.5</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>green20220302</artifactId>
<version>2.2.8</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,112 @@
package com.heima.common.aliyun;
import com.alibaba.fastjson.JSON;
import com.aliyun.imageaudit20191230.models.ScanImageRequest;
import com.aliyun.imageaudit20191230.models.ScanImageResponse;
import com.aliyun.imageaudit20191230.models.ScanImageResponseBody;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.*;
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "aliyun")
public class GreenImageScan {
private String accessKeyId;
private String secret;
private String scenes;
public Map imageScan(List<String> imageList) throws Exception {
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
.setAccessKeyId(accessKeyId)
.setAccessKeySecret(secret);
// 访问的域名
config.endpoint = "imageaudit.cn-shanghai.aliyuncs.com";
com.aliyun.imageaudit20191230.Client client = new com.aliyun.imageaudit20191230.Client(config);
List<ScanImageRequest.ScanImageRequestTask> taskList = new ArrayList<>();
for (String img: imageList) {
ScanImageRequest.ScanImageRequestTask task = new ScanImageRequest.ScanImageRequestTask();
task.setImageURL(img); // 修复直接使用图片URL而不是转换为字符数组 task.setDataId(UUID.randomUUID().toString());
task.setImageTimeMillisecond(1L);
task.setInterval(1);
task.setMaxFrames(1);
taskList.add(task);
}
//场景
List<String> sceneList = new ArrayList<>();
// 移除了不支持的"antispam"场景,使用支持的场景
sceneList.add("porn"); // 涉黄识别
sceneList.add("terrorism"); // 暴恐识别
sceneList.add("ad"); // 图片广告
sceneList.add("live"); // 不良场景
sceneList.add("logo"); // logo识别
com.aliyun.imageaudit20191230.models.ScanImageRequest scanImageRequest = new com.aliyun.imageaudit20191230.models.ScanImageRequest()
.setTask(taskList)
.setScene(sceneList);
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
ScanImageResponse scanImageResponse = client.scanImageWithOptions(scanImageRequest, runtime);
Map<String, String> resultMap = new HashMap<>();
if (scanImageResponse.getStatusCode() == 200) {
List<ScanImageResponseBody.ScanImageResponseBodyDataResultsSubResults> subResults = scanImageResponse.body.data.results.get(0).getSubResults();
ListIterator<ScanImageResponseBody.ScanImageResponseBodyDataResultsSubResults> listIterator = subResults.listIterator();
while (listIterator.hasNext()) {
ScanImageResponseBody.ScanImageResponseBodyDataResultsSubResults item = listIterator.next();
/* System.out.println("scene = [" + item.scene + "]");
System.out.println("suggestion = [" + item.suggestion + "]");
System.out.println("label = [" + item.label + "]");*/
if (!item.suggestion.equals("pass")) {
resultMap.put("suggestion", item.suggestion);
resultMap.put("label", item.label);
return resultMap;
}
}
// 所有审核项都通过时返回pass结果
resultMap.put("suggestion", "pass");
resultMap.put("label", "normal");
return resultMap;
} else {
/* *
* 表明请求整体处理失败,原因视具体的情况详细分析
*/
System.out.println("the whole image scan request failed. response:" + JSON.toJSONString(scanImageResponse));
return null;
}
} catch (com.aliyun.tea.TeaException teaException) {
// 获取整体报错信息
System.out.println(com.aliyun.teautil.Common.toJSONString(teaException));
// 获取单个字段
System.out.println(teaException.getCode());
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
/* Map<String, String> resultMap = new HashMap<>();
resultMap.put("suggestion", "pass");
return resultMap;*/
}
}

View File

@@ -0,0 +1,127 @@
package com.heima.common.aliyun;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.TextModerationRequest;
import com.aliyun.green20220302.models.TextModerationResponse;
import com.aliyun.green20220302.models.TextModerationResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "aliyun")
public class GreenTextScan {
private String accessKeyId;
private String secret;
public Map greeTextScan(String content) throws Exception {
// accessKeyId = "LTAI5tKo9TpWH1aW6JxWm1Gp";
// secret = "LHk9DdHECKCwIdaIM9fkGgEuowt18W";
Config config = new Config();
config.setAccessKeyId(accessKeyId);
config.setAccessKeySecret(secret);
//接入区域和地址请根据实际情况修改
config.setRegionId("cn-shanghai");
config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com");
//连接时超时时间单位毫秒ms
config.setReadTimeout(6000);
//读取时超时时间单位毫秒ms
config.setConnectTimeout(3000);
Client client = new Client(config);
// 创建RuntimeObject实例并设置运行参数。
RuntimeOptions runtime = new RuntimeOptions();
runtime.readTimeout = 10000;
runtime.connectTimeout = 10000;
//检测参数构造
JSONObject serviceParameters = new JSONObject();
serviceParameters.put("content", content);
//检测结果构造
Map<String,String> resultMap = new HashMap<>();
if (serviceParameters.get("content") == null || serviceParameters.getString("content").trim().length() == 0) {
resultMap.put("suggestion","检测内容为空");
System.out.println("text moderation content is empty");
return resultMap;
}
TextModerationRequest textModerationRequest = new TextModerationRequest();
/*
文本检测service内容安全控制台文本增强版规则配置的serviceCode示例chat_detection
*/
textModerationRequest.setService("comment_detection");
textModerationRequest.setServiceParameters(serviceParameters.toJSONString());
try {
// 调用方法获取检测结果。
TextModerationResponse response = client.textModerationWithOptions(textModerationRequest, runtime);
// 自动路由。
if (response != null) {
// 服务端错误区域切换到cn-beijing。
if (500 == response.getStatusCode()) {
// 接入区域和地址请根据实际情况修改。
config.setRegionId("cn-beijing");
config.setEndpoint("green-cip.cn-beijing.aliyuncs.com");
client = new Client(config);
response = client.textModerationWithOptions(textModerationRequest, runtime);
}
}
// 打印检测结果。
if (response != null) {
if (response.getStatusCode() == 200) {
TextModerationResponseBody result = response.getBody();
System.out.println(JSON.toJSONString(result));
// 直接使用JSON解析来获取code值避免类型不匹配问题
JSONObject resultJson = JSON.parseObject(JSON.toJSONString(result));
String code = resultJson.getString("code");
if (code != null && "200".equals(code)) {
TextModerationResponseBody.TextModerationResponseBodyData data = result.getData();
if (data.getLabels().isEmpty() && data.getReason().isEmpty()) {
resultMap.put("suggestion", "pass");
}else {
resultMap.put("suggestion","block");
resultMap.put("labels",data.getLabels());
resultMap.put("reason", data.getReason());
}
System.out.println("labels = [" + data.getLabels() + "]");
System.out.println("reason = [" + data.getReason() + "]");
} else {
System.out.println("text moderation not success. code:" + code);
}
} else {
System.out.println("response not success. status:" + response.getStatusCode());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return resultMap;
}
}

View File

@@ -0,0 +1,185 @@
package com.heima.common.aliyun;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Service
public class OssUploadService {
// 从配置文件读取OSS相关配置
@Value("${aliyun.oss.access-key-id}")
private String accessKeyId;
@Value("${aliyun.oss.access-key-secret}")
private String accessKeySecret;
@Value("${aliyun.oss.bucket-name}")
private String bucketName;
// 存储桶区域映射
private static final Map<String, String> BUCKET_ENDPOINT_MAP = new HashMap<>();
static {
// 添加常见的区域映射
BUCKET_ENDPOINT_MAP.put("oss-cn-hangzhou.aliyuncs.com", "杭州");
BUCKET_ENDPOINT_MAP.put("oss-cn-shanghai.aliyuncs.com", "上海");
BUCKET_ENDPOINT_MAP.put("oss-cn-beijing.aliyuncs.com", "北京");
BUCKET_ENDPOINT_MAP.put("oss-cn-shenzhen.aliyuncs.com", "深圳");
BUCKET_ENDPOINT_MAP.put("oss-cn-zhangjiakou.aliyuncs.com", "张家口");
BUCKET_ENDPOINT_MAP.put("oss-cn-huhehaote.aliyuncs.com", "呼和浩特");
BUCKET_ENDPOINT_MAP.put("oss-cn-wulanchabu.aliyuncs.com", "乌兰察布");
BUCKET_ENDPOINT_MAP.put("oss-cn-qingdao.aliyuncs.com", "青岛");
BUCKET_ENDPOINT_MAP.put("oss-cn-chengdu.aliyuncs.com", "成都");
BUCKET_ENDPOINT_MAP.put("oss-cn-hongkong.aliyuncs.com", "香港");
}
// 默认Endpoint
private static final String DEFAULT_ENDPOINT = "oss-cn-beijing.aliyuncs.com";
private OSS ossClient;
private String endpoint;
// 初始化OSS客户端
@PostConstruct
public void init() {
// 根据bucketName确定endpoint
this.endpoint = determineEndpointByBucket(bucketName);
ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
/**
* 根据存储桶名称确定endpoint
* @param bucketName 存储桶名称
* @return endpoint地址
*/
private String determineEndpointByBucket(String bucketName) {
// 在实际应用中您可能需要通过API查询bucket所在的区域
// 这里我们根据错误信息中提示的endpoint进行修正
if ("heimato".equals(bucketName)) {
return "oss-cn-beijing.aliyuncs.com";
}
// 默认返回北京区域endpoint
return DEFAULT_ENDPOINT;
}
/**
* 上传图片到OSS并返回访问链接
* @param file 要上传的图片文件
* @param folder 存储文件夹
* @return 上传后的图片访问链接
* @throws IOException 当文件处理出错时抛出
*/
public String uploadImage(MultipartFile file, String folder) throws IOException {
// 验证文件是否为空
if (file.isEmpty()) {
throw new IllegalArgumentException("上传文件不能为空");
}
// 验证文件类型
String contentType = file.getContentType();
if (contentType == null || !contentType.startsWith("image/")) {
throw new IllegalArgumentException("请上传图片类型的文件");
}
// 生成唯一文件名,避免重复
String originalFilename = file.getOriginalFilename();
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName = UUID.randomUUID().toString() + fileExtension;
// 构建OSS中的文件路径
String key = folder + "/" + fileName;
// 设置文件元数据
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(contentType);
metadata.setContentLength(file.getSize());
// 获取文件输入流
try (InputStream inputStream = file.getInputStream()) {
// 上传文件
PutObjectResult result = ossClient.putObject(bucketName, key, inputStream, metadata);
// 验证上传结果
if (result != null) {
// 构建并返回访问链接
return "https://" + bucketName + "." + endpoint + "/" + key;
} else {
throw new RuntimeException("文件上传失败");
}
}
}
/**
* 上传图片到OSS默认文件夹并返回访问链接
* @param file 要上传的图片文件
* @return 上传后的图片访问链接
* @throws IOException 当文件处理出错时抛出
*/
public String uploadImage(MultipartFile file) throws IOException {
// 默认存储在images文件夹下
return uploadImage(file, "images");
}
/**
* 上传字节数组到OSS并返回访问链接
* @param bytes 图片字节数组
* @param folder 存储文件夹
* @return 上传后的图片访问链接
*/
public String uploadImage(byte[] bytes, String folder) {
if (bytes == null || bytes.length == 0) {
throw new IllegalArgumentException("上传字节数组不能为空");
}
// 生成唯一文件名
String fileName = UUID.randomUUID().toString() + ".jpg";
// 构建OSS中的文件路径
String key = folder + "/" + fileName;
// 设置文件元数据
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("image/jpeg");
metadata.setContentLength(bytes.length);
// 上传文件
PutObjectResult result = ossClient.putObject(bucketName, key, new ByteArrayInputStream(bytes), metadata);
// 构建并返回访问链接
if (result != null) {
return "https://" + bucketName + "." + endpoint + "/" + key;
} else {
throw new RuntimeException("文件上传失败");
}
}
/**
* 上传字节数组到OSS默认文件夹并返回访问链接
* @param bytes 图片字节数组
* @return 上传后的图片访问链接
*/
public String uploadImage(byte[] bytes) {
// 默认存储在images文件夹下
return uploadImage(bytes, "images");
}
// 销毁OSS客户端
public void destroy() {
if (ossClient != null) {
ossClient.shutdown();
}
}
}

View File

@@ -0,0 +1,195 @@
package com.heima.common.aliyun.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.model.v20180509.UploadCredentialsRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.IClientProfile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 用于本地图片文件检测时,上传本地图片
*/
public class ClientUploader {
private IClientProfile profile;
private volatile UploadCredentials uploadCredentials;
private Map<String, String> headers;
private String prefix;
private boolean internal = false;
private Object lock = new Object();
private ClientUploader(IClientProfile profile, String prefix, boolean internal) {
this.profile = profile;
this.uploadCredentials = null;
this.headers = new HashMap<String, String>();
this.prefix = prefix;
this.internal = internal;
}
public static ClientUploader getImageClientUploader(IClientProfile profile, boolean internal){
return new ClientUploader(profile, "images", internal);
}
public static ClientUploader getVideoClientUploader(IClientProfile profile, boolean internal){
return new ClientUploader(profile, "videos", internal);
}
public static ClientUploader getVoiceClientUploader(IClientProfile profile, boolean internal){
return new ClientUploader(profile, "voices", internal);
}
public static ClientUploader getFileClientUploader(IClientProfile profile, boolean internal){
return new ClientUploader(profile, "files", internal);
}
/**
* 上传并获取上传后的图片链接
* @param filePath
* @return
*/
public String uploadFile(String filePath){
FileInputStream inputStream = null;
OSSClient ossClient = null;
try {
File file = new File(filePath);
UploadCredentials uploadCredentials = getCredentials();
if(uploadCredentials == null){
throw new RuntimeException("can not get upload credentials");
}
ObjectMetadata meta = new ObjectMetadata();
meta.setContentLength(file.length());
inputStream = new FileInputStream(file);
ossClient = new OSSClient(getOssEndpoint(uploadCredentials), uploadCredentials.getAccessKeyId(), uploadCredentials.getAccessKeySecret(), uploadCredentials.getSecurityToken());
String object = uploadCredentials.getUploadFolder() + '/' + this.prefix + '/' + String.valueOf(filePath.hashCode());
PutObjectResult ret = ossClient.putObject(uploadCredentials.getUploadBucket(), object, inputStream, meta);
return "oss://" + uploadCredentials.getUploadBucket() + "/" + object;
} catch (Exception e) {
throw new RuntimeException("upload file fail.", e);
} finally {
if(ossClient != null){
ossClient.shutdown();
}
if(inputStream != null){
try {
inputStream.close();
}catch (Exception e){
}
}
}
}
private String getOssEndpoint(UploadCredentials uploadCredentials){
if(this.internal){
return uploadCredentials.getOssInternalEndpoint();
}else{
return uploadCredentials.getOssEndpoint();
}
}
/**
* 上传并获取上传后的图片链接
* @param bytes
* @return
*/
public String uploadBytes(byte[] bytes){
OSSClient ossClient = null;
try {
UploadCredentials uploadCredentials = getCredentials();
if(uploadCredentials == null){
throw new RuntimeException("can not get upload credentials");
}
ossClient = new OSSClient(getOssEndpoint(uploadCredentials), uploadCredentials.getAccessKeyId(), uploadCredentials.getAccessKeySecret(), uploadCredentials.getSecurityToken());
String object = uploadCredentials.getUploadFolder() + '/' + this.prefix + '/' + UUID.randomUUID().toString();
PutObjectResult ret = ossClient.putObject(uploadCredentials.getUploadBucket(), object, new ByteArrayInputStream(bytes));
return "oss://" + uploadCredentials.getUploadBucket() + "/" + object;
} catch (Exception e) {
throw new RuntimeException("upload file fail.", e);
} finally {
if(ossClient != null){
ossClient.shutdown();
}
}
}
public void addHeader(String key, String value){
this.headers.put(key, value);
}
private UploadCredentials getCredentials() throws Exception{
if(this.uploadCredentials == null || this.uploadCredentials.getExpiredTime() < System.currentTimeMillis()){
synchronized(lock){
if(this.uploadCredentials == null || this.uploadCredentials.getExpiredTime() < System.currentTimeMillis()){
this.uploadCredentials = getCredentialsFromServer();
}
}
}
return this.uploadCredentials;
}
/**
* 从服务器端获取上传凭证
* @return
* @throws Exception
*/
private UploadCredentials getCredentialsFromServer() throws Exception{
UploadCredentialsRequest uploadCredentialsRequest = new UploadCredentialsRequest();
uploadCredentialsRequest.setAcceptFormat(FormatType.JSON); // 指定api返回格式
uploadCredentialsRequest.setMethod(com.aliyuncs.http.MethodType.POST); // 指定请求方法
uploadCredentialsRequest.setEncoding("utf-8");
uploadCredentialsRequest.setProtocol(ProtocolType.HTTP);
for (Map.Entry<String, String> kv : this.headers.entrySet()) {
uploadCredentialsRequest.putHeaderParameter(kv.getKey(), kv.getValue());
}
uploadCredentialsRequest.setHttpContent(new JSONObject().toJSONString().getBytes("UTF-8"), "UTF-8", FormatType.JSON);
IAcsClient client = null;
try{
client = new DefaultAcsClient(profile);
HttpResponse httpResponse = client.doAction(uploadCredentialsRequest);
if (httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
if (200 == scrResponse.getInteger("code")) {
JSONObject data = scrResponse.getJSONObject("data");
return new UploadCredentials(data.getString("accessKeyId"), data.getString("accessKeySecret"),
data.getString("securityToken"), data.getLongValue("expiredTime"),
data.getString("ossEndpoint"), data.getString("ossInternalEndpoint"), data.getString("uploadBucket"), data.getString("uploadFolder"));
}
String requestId = scrResponse.getString("requestId");
throw new RuntimeException("get upload credential from server fail. requestId:" + requestId + ", code:" + scrResponse.getInteger("code"));
}
throw new RuntimeException("get upload credential from server fail. http response status:" + httpResponse.getStatus());
}finally {
client.shutdown();
}
}
}

View File

@@ -0,0 +1,159 @@
package com.heima.common.aliyun.util;
import javax.activation.MimetypesFileTypeMap;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
/**
* 用于自定义图库上传图片
*/
public class CustomLibUploader {
public String uploadFile(String host, String uploadFolder, String ossAccessKeyId,
String policy, String signature,
String filepath) throws Exception {
LinkedHashMap<String, String> textMap = new LinkedHashMap<String, String>();
// key
String objectName = uploadFolder + "/imglib_" + UUID.randomUUID().toString() + ".jpg";
textMap.put("key", objectName);
// Content-Disposition
textMap.put("Content-Disposition", "attachment;filename="+filepath);
// OSSAccessKeyId
textMap.put("OSSAccessKeyId", ossAccessKeyId);
// policy
textMap.put("policy", policy);
// Signature
textMap.put("Signature", signature);
Map<String, String> fileMap = new HashMap<String, String>();
fileMap.put("file", filepath);
String ret = formUpload(host, textMap, fileMap);
System.out.println("[" + host + "] post_object:" + objectName);
System.out.println("post reponse:" + ret);
return objectName;
}
private static String formUpload(String urlStr, Map<String, String> textMap, Map<String, String> fileMap) throws Exception {
String res = "";
HttpURLConnection conn = null;
String BOUNDARY = "9431149156168";
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + BOUNDARY);
OutputStream out = new DataOutputStream(conn.getOutputStream());
// text
if (textMap != null) {
StringBuffer strBuf = new StringBuffer();
Iterator iter = textMap.entrySet().iterator();
int i = 0;
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String inputName = (String) entry.getKey();
String inputValue = (String) entry.getValue();
if (inputValue == null) {
continue;
}
if (i == 0) {
strBuf.append("--").append(BOUNDARY).append(
"\r\n");
strBuf.append("Content-Disposition: form-data; name=\""
+ inputName + "\"\r\n\r\n");
strBuf.append(inputValue);
} else {
strBuf.append("\r\n").append("--").append(BOUNDARY).append(
"\r\n");
strBuf.append("Content-Disposition: form-data; name=\""
+ inputName + "\"\r\n\r\n");
strBuf.append(inputValue);
}
i++;
}
out.write(strBuf.toString().getBytes());
}
// file
if (fileMap != null) {
Iterator iter = fileMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String inputName = (String) entry.getKey();
String inputValue = (String) entry.getValue();
if (inputValue == null) {
continue;
}
File file = new File(inputValue);
String filename = file.getName();
String contentType = new MimetypesFileTypeMap().getContentType(file);
if (contentType == null || contentType.equals("")) {
contentType = "application/octet-stream";
}
StringBuffer strBuf = new StringBuffer();
strBuf.append("\r\n").append("--").append(BOUNDARY).append(
"\r\n");
strBuf.append("Content-Disposition: form-data; name=\""
+ inputName + "\"; filename=\"" + filename
+ "\"\r\n");
strBuf.append("Content-Type: " + contentType + "\r\n\r\n");
out.write(strBuf.toString().getBytes());
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
in.close();
}
StringBuffer strBuf = new StringBuffer();
out.write(strBuf.toString().getBytes());
}
byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
out.write(endData);
out.flush();
out.close();
// 读取返回数据
StringBuffer strBuf = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
strBuf.append(line).append("\n");
}
res = strBuf.toString();
reader.close();
reader = null;
} catch (Exception e) {
System.err.println("发送POST请求出错: " + urlStr);
throw e;
} finally {
if (conn != null) {
conn.disconnect();
conn = null;
}
}
return res;
}
}

View File

@@ -0,0 +1,90 @@
package com.heima.common.aliyun.util;
import java.io.Serializable;
public class UploadCredentials implements Serializable {
private String accessKeyId;
private String accessKeySecret;
private String securityToken;
private Long expiredTime;
private String ossEndpoint;
private String ossInternalEndpoint;
private String uploadBucket;
private String uploadFolder;
public UploadCredentials(String accessKeyId, String accessKeySecret, String securityToken, Long expiredTime, String ossEndpoint, String ossInternalEndpoint, String uploadBucket, String uploadFolder) {
this.accessKeyId = accessKeyId;
this.accessKeySecret = accessKeySecret;
this.securityToken = securityToken;
this.expiredTime = expiredTime;
this.ossEndpoint = ossEndpoint;
this.ossInternalEndpoint = ossInternalEndpoint;
this.uploadBucket = uploadBucket;
this.uploadFolder = uploadFolder;
}
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getSecurityToken() {
return securityToken;
}
public void setSecurityToken(String securityToken) {
this.securityToken = securityToken;
}
public Long getExpiredTime() {
return expiredTime;
}
public void setExpiredTime(Long expiredTime) {
this.expiredTime = expiredTime;
}
public String getOssEndpoint() {
return ossEndpoint;
}
public void setOssEndpoint(String ossEndpoint) {
this.ossEndpoint = ossEndpoint;
}
public String getUploadBucket() {
return uploadBucket;
}
public void setUploadBucket(String uploadBucket) {
this.uploadBucket = uploadBucket;
}
public String getUploadFolder() {
return uploadFolder;
}
public void setUploadFolder(String uploadFolder) {
this.uploadFolder = uploadFolder;
}
public String getOssInternalEndpoint() {
return ossInternalEndpoint;
}
public void setOssInternalEndpoint(String ossInternalEndpoint) {
this.ossInternalEndpoint = ossInternalEndpoint;
}
}

View File

@@ -0,0 +1,8 @@
package com.heima.common.constants;
public class ArticleConstants {
public static final Short LOADTYPE_LOAD_MORE = 1;
public static final Short LOADTYPE_LOAD_NEW = 2;
public static final String DEFAULT_TAG = "__all__";
}

View File

@@ -0,0 +1,15 @@
package com.heima.common.constants;
public class ScheduleConstants {
//task状态
public static final int SCHEDULED=0; //初始化状态
public static final int EXECUTED=1; //已执行状态
public static final int CANCELLED=2; //已取消状态
public static String FUTURE="future_"; //未来数据key前缀
public static String TOPIC="topic_"; //当前数据key前缀
}

View File

@@ -0,0 +1,18 @@
package com.heima.common.constants;
public class WemediaConstants {
public static final Short COLLECT_MATERIAL = 1;//收藏
public static final Short CANCEL_COLLECT_MATERIAL = 0;//取消收藏
public static final String WM_NEWS_TYPE_IMAGE = "image";
public static final Short WM_NEWS_NONE_IMAGE = 0;
public static final Short WM_NEWS_SINGLE_IMAGE = 1;
public static final Short WM_NEWS_MANY_IMAGE = 3;
public static final Short WM_NEWS_TYPE_AUTO = -1;
public static final Short WM_CONTENT_REFERENCE = 0;
public static final Short WM_COVER_REFERENCE = 1;
}

View File

@@ -0,0 +1,16 @@
package com.heima.common.exception;
import com.heima.model.common.enums.AppHttpCodeEnum;
public class CustomException extends RuntimeException {
private AppHttpCodeEnum appHttpCodeEnum;
public CustomException(AppHttpCodeEnum appHttpCodeEnum){
this.appHttpCodeEnum = appHttpCodeEnum;
}
public AppHttpCodeEnum getAppHttpCodeEnum() {
return appHttpCodeEnum;
}
}

View File

@@ -0,0 +1,40 @@
package com.heima.common.exception;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice //控制器增强类
@Slf4j
public class ExceptionCatch {
/**
* 处理不可控异常
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult exception(Exception e){
e.printStackTrace();
log.error("catch exception:{}",e.getMessage());
return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
}
/**
* 处理可控异常 自定义异常
* @param e
* @return
*/
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseResult exception(CustomException e){
log.error("catch exception:{}",e);
return ResponseResult.errorResult(e.getAppHttpCodeEnum());
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
package com.heima.common.swagger;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Configuration {
@Bean(value = "defaultApi2")
public Docket defaultApi2() {
Docket docket=new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
//分组名称
.groupName("1.0")
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.heima"))
.paths(PathSelectors.any())
.build();
return docket;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("黑马头条API文档")
.description("黑马头条API文档")
.version("1.0")
.build();
}
}

View File

@@ -0,0 +1,37 @@
package com.heima.common.swagger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket buildDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(buildApiInfo())
.select()
// 要扫描的API(Controller)基础包
.apis(RequestHandlerSelectors.basePackage("com.heima"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo buildApiInfo() {
Contact contact = new Contact("黑马程序员","","");
return new ApiInfoBuilder()
.title("黑马头条-平台管理API文档")
.description("黑马头条后台api")
.contact(contact)
.version("1.0.0").build();
}
}

View File

@@ -0,0 +1,36 @@
package com.heima.common.tess4j;
import lombok.Getter;
import lombok.Setter;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.awt.image.BufferedImage;
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "tess4j")
public class Tess4jClient {
private String dataPath;
private String language;
public String doOCR(BufferedImage image) throws TesseractException {
//创建Tesseract对象
ITesseract tesseract = new Tesseract();
//设置字体库路径
tesseract.setDatapath(dataPath);
//中文识别
tesseract.setLanguage(language);
//执行ocr识别
String result = tesseract.doOCR(image);
//替换回车和tal键 使结果为一行
result = result.replaceAll("\\r|\\n", "-").replaceAll(" ", "");
return result;
}
}

View File

@@ -0,0 +1,8 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.heima.common.exception.ExceptionCatch,\
com.heima.common.swagger.SwaggerConfiguration,\
com.heima.common.swagger.Swagger2Configuration,\
com.heima.common.aliyun.GreenTextScan,\
com.heima.common.aliyun.GreenImageScan,\
com.heima.common.tess4j.Tess4jClient,\
com.heima.common.redis.CacheService

View File

@@ -0,0 +1,37 @@
# 全局端口定义(原注释保留,注意格式)
server:
tomcat:
uri-encoding: utf-8
# 全局字符集设置
servlet:
encoding:
enabled: true
charset: utf-8
force: true
spring:
aop:
proxy-target-class: true
# 阿里云配置MinIO配置移到这里面
aliyun:
oss:
access-key-id: LTAI5tKo9TpWH1aW6JxWm1Gp
access-key-secret: LHk9DdHECKCwIdaIM9fkGgEuowt18W
bucket-name: heimato
accessKeyId: LTAI5tPk15RZDncsVQsFJgrw
secret: auoKUFsghimbfVQHpy7gtRyBkoR4vc
scenes: antispam
minio-access-key: minio # 对应代码中的 minioAccessKey
minio-secret-key: minio123 # 对应代码中的 minioSecretKey
minio-bucket: leadnews # 对应代码中的 minioBucket
minio-endpoint: http://192.168.200.130:9000 # 对应代码中的 minioEndpoint
# 百度配置(保持不变)
baidu:
api:
api-key: "XbdpAmrvjbzxN74JUWNu3Nqh"
secret-key: "ibcgo1ejyMKWa6XDtEmVCSJuFbgb2TKZ"
appid: "119983858"

View File

@@ -0,0 +1,11 @@
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class TextScan {
public static void main(String[] args) {
/*
调用文本审核
*/
}
}

View File

@@ -0,0 +1,57 @@
{
"groups": [
{
"name": "aliyun",
"type": "com.heima.common.aliyun.GreenImageScan",
"sourceType": "com.heima.common.aliyun.GreenImageScan"
},
{
"name": "aliyun",
"type": "com.heima.common.aliyun.GreenTextScan",
"sourceType": "com.heima.common.aliyun.GreenTextScan"
},
{
"name": "tess4j",
"type": "com.heima.common.tess4j.Tess4jClient",
"sourceType": "com.heima.common.tess4j.Tess4jClient"
}
],
"properties": [
{
"name": "aliyun.access-key-id",
"type": "java.lang.String",
"sourceType": "com.heima.common.aliyun.GreenImageScan"
},
{
"name": "aliyun.access-key-id",
"type": "java.lang.String",
"sourceType": "com.heima.common.aliyun.GreenTextScan"
},
{
"name": "aliyun.scenes",
"type": "java.lang.String",
"sourceType": "com.heima.common.aliyun.GreenImageScan"
},
{
"name": "aliyun.secret",
"type": "java.lang.String",
"sourceType": "com.heima.common.aliyun.GreenImageScan"
},
{
"name": "aliyun.secret",
"type": "java.lang.String",
"sourceType": "com.heima.common.aliyun.GreenTextScan"
},
{
"name": "tess4j.data-path",
"type": "java.lang.String",
"sourceType": "com.heima.common.tess4j.Tess4jClient"
},
{
"name": "tess4j.language",
"type": "java.lang.String",
"sourceType": "com.heima.common.tess4j.Tess4jClient"
}
],
"hints": []
}

View File

@@ -0,0 +1,8 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.heima.common.exception.ExceptionCatch,\
com.heima.common.swagger.SwaggerConfiguration,\
com.heima.common.swagger.Swagger2Configuration,\
com.heima.common.aliyun.GreenTextScan,\
com.heima.common.aliyun.GreenImageScan,\
com.heima.common.tess4j.Tess4jClient,\
com.heima.common.redis.CacheService

View File

@@ -0,0 +1,37 @@
# 全局端口定义(原注释保留,注意格式)
server:
tomcat:
uri-encoding: utf-8
# 全局字符集设置
servlet:
encoding:
enabled: true
charset: utf-8
force: true
spring:
aop:
proxy-target-class: true
# 阿里云配置MinIO配置移到这里面
aliyun:
oss:
access-key-id: LTAI5tKo9TpWH1aW6JxWm1Gp
access-key-secret: LHk9DdHECKCwIdaIM9fkGgEuowt18W
bucket-name: heimato
accessKeyId: LTAI5tPk15RZDncsVQsFJgrw
secret: auoKUFsghimbfVQHpy7gtRyBkoR4vc
scenes: antispam
minio-access-key: minio # 对应代码中的 minioAccessKey
minio-secret-key: minio123 # 对应代码中的 minioSecretKey
minio-bucket: leadnews # 对应代码中的 minioBucket
minio-endpoint: http://192.168.200.130:9000 # 对应代码中的 minioEndpoint
# 百度配置(保持不变)
baidu:
api:
api-key: "XbdpAmrvjbzxN74JUWNu3Nqh"
secret-key: "ibcgo1ejyMKWa6XDtEmVCSJuFbgb2TKZ"
appid: "119983858"

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
</module>

View File

@@ -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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>heima-leadnews</artifactId>
<groupId>com.heima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>heima-leadnews-feign-api</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.heima</groupId>
<artifactId>heima-leadnews-model</artifactId>
</dependency>
<dependency>
<groupId>com.heima</groupId>
<artifactId>heima-leadnews-common</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,18 @@
package com.heima.apis.article;
import com.heima.apis.article.fallback.IArticleClientFallback;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(value = "leadnews-article",fallback = IArticleClientFallback.class)
public interface IArticleClient {
@PostMapping("/api/v1/article/save")
public ResponseResult saveArticle(@RequestBody ArticleDto dto);
}

View File

@@ -0,0 +1,15 @@
package com.heima.apis.article.fallback;
import com.heima.apis.article.IArticleClient;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import org.springframework.stereotype.Component;
@Component
public class IArticleClientFallback implements IArticleClient {
@Override
public ResponseResult saveArticle(ArticleDto dto) {
return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR, "获取数据失败");
}
}

View File

@@ -0,0 +1,38 @@
package com.heima.apis.schedule;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.schedule.dtos.Task;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient("leadnews-schedule")
public interface IScheduleClient {
/**
* 添加任务
* @param task
* @return
*/
@PostMapping("/api/v1/task/add")
public ResponseResult addTask(@RequestBody Task task);
/**
* 取消任务
* @param taskId
* @return
*/
@GetMapping("/api/v1/task/{taskId}")
public ResponseResult cancelTask(@PathVariable("taskId") long taskId);
/**
* 按照类型和优先级获取任务
* @param type
* @param priority
* @return
*/
@GetMapping("/api/v1/task/{type}/{priority}")
public ResponseResult poll(@PathVariable("type") int type,@PathVariable("priority") int priority);
}

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.heima</groupId>
<artifactId>heima-leadnews-gateway</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>heima-leadnews-app-gateway</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -0,0 +1,13 @@
package com.heima.app.gatway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class AppGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(AppGatewayApplication.class,args);
}
}

View File

@@ -0,0 +1,70 @@
package com.heima.app.gatway.filter;
import com.heima.app.gatway.util.AppJwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class AuthorizeFilter implements Ordered, GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.获取request和response对象
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
//2.判断是否是登录
if(request.getURI().getPath().contains("/login")){
//放行
return chain.filter(exchange);
}
//3.获取token
String token = request.getHeaders().getFirst("token");
//4.判断token是否存在
if(StringUtils.isBlank(token)){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
//5.判断token是否有效
try {
Claims claimsBody = AppJwtUtil.getClaimsBody(token);
//是否是过期
int result = AppJwtUtil.verifyToken(claimsBody);
if(result == 1 || result == 2){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
}catch (Exception e){
e.printStackTrace();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
//6.放行
return chain.filter(exchange);
}
/**
* 优先级设置 值越小 优先级越高
* @return
*/
@Override
public int getOrder() {
return 0;
}
}

View File

@@ -0,0 +1,119 @@
package com.heima.app.gatway.util;
import io.jsonwebtoken.*;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;
public class AppJwtUtil {
// TOKEN的有效期一天S
private static final int TOKEN_TIME_OUT = 3_600;
// 加密KEY
private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
// 最小刷新间隔(S)
private static final int REFRESH_TIME = 300;
// 生产ID
public static String getToken(Long id){
Map<String, Object> claimMaps = new HashMap<>();
claimMaps.put("id",id);
long currentTime = System.currentTimeMillis();
return Jwts.builder()
.setId(UUID.randomUUID().toString())
.setIssuedAt(new Date(currentTime)) //签发时间
.setSubject("system") //说明
.setIssuer("heima") //签发者信息
.setAudience("app") //接收用户
.compressWith(CompressionCodecs.GZIP) //数据压缩方式
.signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
.setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳
.addClaims(claimMaps) //cla信息
.compact();
}
/**
* 获取token中的claims信息
*
* @param token
* @return
*/
private static Jws<Claims> getJws(String token) {
return Jwts.parser()
.setSigningKey(generalKey())
.parseClaimsJws(token);
}
/**
* 获取payload body信息
*
* @param token
* @return
*/
public static Claims getClaimsBody(String token) {
try {
return getJws(token).getBody();
}catch (ExpiredJwtException e){
return null;
}
}
/**
* 获取hearder body信息
*
* @param token
* @return
*/
public static JwsHeader getHeaderBody(String token) {
return getJws(token).getHeader();
}
/**
* 是否过期
*
* @param claims
* @return -1有效0有效1过期2过期
*/
public static int verifyToken(Claims claims) {
if(claims==null){
return 1;
}
try {
claims.getExpiration()
.before(new Date());
// 需要自动刷新TOKEN
if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){
return -1;
}else {
return 0;
}
} catch (ExpiredJwtException ex) {
return 1;
}catch (Exception e){
return 2;
}
}
/**
* 由字符串生成加密key
*
* @return
*/
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
public static void main(String[] args) {
/* Map map = new HashMap();
map.put("id","11");*/
System.out.println(AppJwtUtil.getToken(1102L));
Jws<Claims> jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA");
Claims claims = jws.getBody();
System.out.println(claims.get("id"));
}
}

View File

@@ -0,0 +1,12 @@
server:
port: 51601
spring:
application:
name: leadnews-app-gateway
cloud:
nacos:
discovery:
server-addr: 192.168.200.130:8848
config:
server-addr: 192.168.200.130:8848
file-extension: yml

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
</module>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>heima-leadnews-gateway</artifactId>
<groupId>com.heima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>heima-leadnews-wemedia-gateway</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

View File

@@ -0,0 +1,15 @@
package com.heima.wemedia.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class WemediaGatewayAplication {
public static void main(String[] args) {
SpringApplication.run(WemediaGatewayAplication.class,args);
}
}

View File

@@ -0,0 +1,75 @@
package com.heima.wemedia.gateway.filter;
import com.heima.wemedia.gateway.util.AppJwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class AuthorizeFilter implements Ordered, GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.获取request和response对象
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
//2.判断是否是登录
if(request.getURI().getPath().contains("/login")){
//放行
return chain.filter(exchange);
}
//3.获取token
String token = request.getHeaders().getFirst("token");
//4.判断token是否存在
if(StringUtils.isBlank(token)){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
//5.判断token是否有效
try {
Claims claimsBody = AppJwtUtil.getClaimsBody(token);
//是否是过期
int result = AppJwtUtil.verifyToken(claimsBody);
if(result == 1 || result == 2){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
//获取用户信息
Object userId = claimsBody.get("id");
//存储header中
ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> {
httpHeaders.add("userId", userId + "");
}).build();
//重置请求
exchange.mutate().request(serverHttpRequest);
} catch (Exception e) {
e.printStackTrace();
}
//6.放行
return chain.filter(exchange);
}
/**
* 优先级设置 值越小 优先级越高
* @return
*/
@Override
public int getOrder() {
return 0;
}
}

View File

@@ -0,0 +1,109 @@
package com.heima.wemedia.gateway.util;
import io.jsonwebtoken.*;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;
public class AppJwtUtil {
// TOKEN的有效期一天S
private static final int TOKEN_TIME_OUT = 3_600;
// 加密KEY
private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
// 最小刷新间隔(S)
private static final int REFRESH_TIME = 300;
// 生产ID
public static String getToken(Long id) {
Map<String, Object> claimMaps = new HashMap<>();
claimMaps.put("id", id);
long currentTime = System.currentTimeMillis();
return Jwts.builder()
.setId(UUID.randomUUID().toString())
.setIssuedAt(new Date(currentTime)) //签发时间
.setSubject("system") //说明
.setIssuer("heima") //签发者信息
.setAudience("app") //接收用户
.compressWith(CompressionCodecs.GZIP) //数据压缩方式
.signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
.setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳
.addClaims(claimMaps) //cla信息
.compact();
}
/**
* 获取token中的claims信息
*
* @param token
* @return
*/
private static Jws<Claims> getJws(String token) {
return Jwts.parser()
.setSigningKey(generalKey())
.parseClaimsJws(token);
}
/**
* 获取payload body信息
*
* @param token
* @return
*/
public static Claims getClaimsBody(String token) throws ExpiredJwtException {
return getJws(token).getBody();
}
/**
* 获取hearder body信息
*
* @param token
* @return
*/
public static JwsHeader getHeaderBody(String token) {
return getJws(token).getHeader();
}
/**
* 是否过期
*
* @param claims
* @return -1有效0有效1过期2过期
*/
public static int verifyToken(Claims claims) throws Exception {
if (claims == null) {
return 1;
}
claims.getExpiration().before(new Date());
// 需要自动刷新TOKEN
if ((claims.getExpiration().getTime() - System.currentTimeMillis()) > REFRESH_TIME * 1000) {
return -1;
} else {
return 0;
}
}
/**
* 由字符串生成加密key
*
* @return
*/
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
public static void main(String[] args) {
/* Map map = new HashMap();
map.put("id","11");*/
System.out.println(AppJwtUtil.getToken(1102L));
Jws<Claims> jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA");
Claims claims = jws.getBody();
System.out.println(claims.get("id"));
}
}

View File

@@ -0,0 +1,12 @@
server:
port: 51602
spring:
application:
name: leadnews-wemedia-gateway
cloud:
nacos:
discovery:
server-addr: 192.168.200.130:8848
config:
server-addr: 192.168.200.130:8848
file-extension: yml

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>heima-leadnews</artifactId>
<groupId>com.heima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<packaging>pom</packaging>
<modules>
<module>heima-leadnews-app-gateway</module>
<module>heima-leadnews-wemedia-gateway</module>
</modules>
<modelVersion>4.0.0</modelVersion>
<artifactId>heima-leadnews-gateway</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
</module>

View File

@@ -0,0 +1,46 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>heima-leadnews</artifactId>
<groupId>com.heima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>heima-leadnews-model</artifactId>
<packaging>jar</packaging>
<name>heima-leadnews-model</name>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,12 @@
package com.heima.model.article.dtos;
import com.heima.model.common.article.pojos.ApArticle ;
import lombok.Data;
@Data
public class ArticleDto extends ApArticle {
/**
* 文章内容
*/
private String content;
}

View File

@@ -0,0 +1,18 @@
package com.heima.model.common.article.dtos;
import lombok.Data;
import java.util.Date;
@Data
public class ArticleHomeDto {
// 最大时间
Date maxBehotTime;
// 最小时间
Date minBehotTime;
// 分页size
Integer size;
// 频道ID
String tag;
}

View File

@@ -0,0 +1,143 @@
package com.heima.model.common.article.pojos;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 文章信息表,存储已发布的文章
* </p>
*
* @author itheima
*/
@Data
@TableName("ap_article")
public class ApArticle implements Serializable {
@TableId(value = "id",type = IdType.ID_WORKER)
private Long id;
/**
* 标题
*/
private String title;
/**
* 作者id
*/
@TableField("author_id")
private Long authorId;
/**
* 作者名称
*/
@TableField("author_name")
private String authorName;
/**
* 频道id
*/
@TableField("channel_id")
private Integer channelId;
/**
* 频道名称
*/
@TableField("channel_name")
private String channelName;
/**
* 文章布局 0 无图文章 1 单图文章 2 多图文章
*/
private Short layout;
/**
* 文章标记 0 普通文章 1 热点文章 2 置顶文章 3 精品文章 4 大V 文章
*/
private Byte flag;
/**
* 文章封面图片 多张逗号分隔
*/
private String images;
/**
* 标签
*/
private String labels;
/**
* 点赞数量
*/
private Integer likes;
/**
* 收藏数量
*/
private Integer collection;
/**
* 评论数量
*/
private Integer comment;
/**
* 阅读数量
*/
private Integer views;
/**
* 省市
*/
@TableField("province_id")
private Integer provinceId;
/**
* 市区
*/
@TableField("city_id")
private Integer cityId;
/**
* 区县
*/
@TableField("county_id")
private Integer countyId;
/**
* 创建时间
*/
@TableField("created_time")
private Date createdTime;
/**
* 发布时间
*/
@TableField("publish_time")
private Date publishTime;
/**
* 同步状态
*/
@TableField("sync_status")
private Boolean syncStatus;
/**
* 来源
*/
private Boolean origin;
/**
* 静态页面地址
*/
@TableField("static_url")
private String staticUrl;
}

View File

@@ -0,0 +1,73 @@
package com.heima.model.common.article.pojos;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* <p>
* APP已发布文章配置表
* </p>
*
* @author itheima
*/
@Data
@NoArgsConstructor
@TableName("ap_article_config")
public class ApArticleConfig implements Serializable {
public ApArticleConfig(Long articleId){
this.articleId = articleId;
this.isDelete = false;
this.isDown = false;
this.isForward = true;
this.isComment = true;
}
@TableId(value = "id",type = IdType.ID_WORKER)
private Long id;
/**
* 文章id
*/
@TableField("article_id")
private Long articleId;
/**
* 是否可评论
* true: 可以评论 1
* false: 不可评论 0
*/
@TableField("is_comment")
private Boolean isComment;
/**
* 是否转发
* true: 可以转发 1
* false: 不可转发 0
*/
@TableField("is_forward")
private Boolean isForward;
/**
* 是否下架
* true: 下架 1
* false: 没有下架 0
*/
@TableField("is_down")
private Boolean isDown;
/**
* 是否已删除
* true: 删除 1
* false: 没有删除 0
*/
@TableField("is_delete")
private Boolean isDelete;
}

View File

@@ -0,0 +1,28 @@
package com.heima.model.common.article.pojos;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName("ap_article_content")
public class ApArticleContent implements Serializable {
@TableId(value = "id",type = IdType.ID_WORKER)
private Long id;
/**
* 文章id
*/
@TableField("article_id")
private Long articleId;
/**
* 文章内容
*/
private String content;
}

View File

@@ -0,0 +1,21 @@
package com.heima.model.common.dtos;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Data
@Slf4j
public class PageRequestDto {
protected Integer size;
protected Integer page;
public void checkParam() {
if (this.page == null || this.page < 0) {
setPage(1);
}
if (this.size == null || this.size < 0 || this.size > 100) {
setSize(10);
}
}
}

View File

@@ -0,0 +1,44 @@
package com.heima.model.common.dtos;
import java.io.Serializable;
public class PageResponseResult extends ResponseResult implements Serializable {
private Integer currentPage;
private Integer size;
private Integer total;
public PageResponseResult(Integer currentPage, Integer size, Integer total) {
this.currentPage = currentPage;
this.size = size;
this.total = total;
}
public PageResponseResult() {
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
}

View File

@@ -0,0 +1,167 @@
package com.heima.model.common.dtos;
import com.heima.model.common.enums.AppHttpCodeEnum;
import java.io.Serializable;
/**
* 通用的结果返回类
* @param <T>
*/
public class ResponseResult<T> implements Serializable {
private String host;
private Integer code;
private String errorMessage;
private T data;
public ResponseResult() {
this.code = 200;
}
public ResponseResult(Integer code, T data) {
this.code = code;
this.data = data;
}
public ResponseResult(Integer code, String msg, T data) {
this.code = code;
this.errorMessage = msg;
this.data = data;
}
public ResponseResult(Integer code, String msg) {
this.code = code;
this.errorMessage = msg;
}
public ResponseResult(Integer page, Integer size, long total) {
}
public static ResponseResult errorResult(int code, String msg) {
ResponseResult result = new ResponseResult();
return result.error(code, msg);
}
public static ResponseResult okResult(int code, String msg) {
ResponseResult result = new ResponseResult();
return result.ok(code, null, msg);
}
public static ResponseResult okResult(Object data) {
ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getErrorMessage());
if(data!=null) {
result.setData(data);
}
return result;
}
public static ResponseResult errorResult(AppHttpCodeEnum enums){
return setAppHttpCodeEnum(enums,enums.getErrorMessage());
}
public static ResponseResult errorResult(AppHttpCodeEnum enums, String errorMessage){
return setAppHttpCodeEnum(enums,errorMessage);
}
public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){
return okResult(enums.getCode(),enums.getErrorMessage());
}
private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String errorMessage){
return okResult(enums.getCode(),errorMessage);
}
public ResponseResult<?> error(Integer code, String msg) {
this.code = code;
this.errorMessage = msg;
return this;
}
public ResponseResult<?> ok(Integer code, T data) {
this.code = code;
this.data = data;
return this;
}
public ResponseResult<?> ok(Integer code, T data, String msg) {
this.code = code;
this.data = data;
this.errorMessage = msg;
return this;
}
public ResponseResult<?> ok(T data) {
this.data = data;
return this;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public static void main(String[] args) {
//前置
/*AppHttpCodeEnum success = AppHttpCodeEnum.SUCCESS;
System.out.println(success.getCode());
System.out.println(success.getErrorMessage());*/
//查询一个对象
/*Map map = new HashMap();
map.put("name","zhangsan");
map.put("age",18);
ResponseResult result = ResponseResult.okResult(map);
System.out.println(JSON.toJSONString(result));*/
//新增,修改,删除 在项目中统一返回成功即可
/* ResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.SUCCESS);
System.out.println(JSON.toJSONString(result));*/
//根据不用的业务返回不同的提示信息 比如:当前操作需要登录、参数错误
/*ResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
System.out.println(JSON.toJSONString(result));
*/
//查询分页信息
/*PageResponseResult responseResult = new PageResponseResult(1,5,50);
List list = new ArrayList();
list.add("itcast");
list.add("itheima");
responseResult.setData(list);
System.out.println(JSON.toJSONString(responseResult));*/
}
}

View File

@@ -0,0 +1,48 @@
package com.heima.model.common.enums;
public enum AppHttpCodeEnum {
// 成功段0
SUCCESS(200,"操作成功"),
// 登录段1~50
NEED_LOGIN(1,"需要登录后操作"),
LOGIN_PASSWORD_ERROR(2,"密码错误"),
// TOKEN50~100
TOKEN_INVALID(50,"无效的TOKEN"),
TOKEN_EXPIRE(51,"TOKEN已过期"),
TOKEN_REQUIRE(52,"TOKEN是必须的"),
// SIGN验签 100~120
SIGN_INVALID(100,"无效的SIGN"),
SIG_TIMEOUT(101,"SIGN已过期"),
// 参数错误 500~1000
PARAM_REQUIRE(500,"缺少参数"),
PARAM_INVALID(501,"无效参数"),
PARAM_IMAGE_FORMAT_ERROR(502,"图片格式有误"),
SERVER_ERROR(503,"服务器内部错误"),
// 数据错误 1000~2000
DATA_EXIST(1000,"数据已经存在"),
AP_USER_DATA_NOT_EXIST(1001,"ApUser数据不存在"),
DATA_NOT_EXIST(1002,"数据不存在"),
// 数据错误 3000~3500
NO_OPERATOR_AUTH(3000,"无权限操作"),
NEED_ADMIND(3001,"需要管理员权限"),
// 自媒体文章错误 3501~3600
MATERIAL_REFERENCE_FAIL(3501,"素材引用失效");
int code;
String errorMessage;
AppHttpCodeEnum(int code, String errorMessage){
this.code = code;
this.errorMessage = errorMessage;
}
public int getCode() {
return code;
}
public String getErrorMessage() {
return errorMessage;
}
}

View File

@@ -0,0 +1,15 @@
package com.heima.model.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum TaskTypeEnum {
NEWS_SCAN_TIME(1001, 1,"文章定时审核"),
REMOTEERROR(1002, 2,"第三方接口调用失败,重试");
private final int taskType; //对应具体业务
private final int priority; //业务不同级别
private final String desc; //描述信息
}

View File

@@ -0,0 +1,34 @@
package com.heima.model.schedule.dtos;
import lombok.Data;
import java.io.Serializable;
@Data
public class Task implements Serializable {
/**
* 任务id
*/
private Long taskId;
/**
* 类型
*/
private Integer taskType;
/**
* 优先级
*/
private Integer priority;
/**
* 执行id
*/
private long executeTime;
/**
* task参数
*/
private byte[] parameters;
}

View File

@@ -0,0 +1,56 @@
package com.heima.model.schedule.pojos;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @author itheima
*/
@Data
@TableName("taskinfo")
public class Taskinfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 任务id
*/
@TableId(type = IdType.ID_WORKER)
private Long taskId;
/**
* 执行时间
*/
@TableField("execute_time")
private Date executeTime;
/**
* 参数
*/
@TableField("parameters")
private byte[] parameters;
/**
* 优先级
*/
@TableField("priority")
private Integer priority;
/**
* 任务类型
*/
@TableField("task_type")
private Integer taskType;
}

View File

@@ -0,0 +1,65 @@
package com.heima.model.schedule.pojos;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @author itheima
*/
@Data
@TableName("taskinfo_logs")
public class TaskinfoLogs implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 任务id
*/
@TableId(type = IdType.ID_WORKER)
private Long taskId;
/**
* 执行时间
*/
@TableField("execute_time")
private Date executeTime;
/**
* 参数
*/
@TableField("parameters")
private byte[] parameters;
/**
* 优先级
*/
@TableField("priority")
private Integer priority;
/**
* 任务类型
*/
@TableField("task_type")
private Integer taskType;
/**
* 版本号,用乐观锁
*/
@Version
private Integer version;
/**
* 状态 0=int 1=EXECUTED 2=CANCELLED
*/
@TableField("status")
private Integer status;
}

View File

@@ -0,0 +1,20 @@
package com.heima.model.common.user.dtos;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class LoginDto {
/**
* 手机号
*/
@ApiModelProperty(value = "手机号", required = true)
private String phone;
/**
* 密码
*/
@ApiModelProperty(value = "密码", required = true)
private String password;
}

View File

@@ -0,0 +1,103 @@
package com.heima.model.common.user.pojos;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* APP用户信息表
* </p>
*
* @author itheima
*/
@Data
@TableName("ap_user")
public class ApUser implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 密码、通信等加密盐
*/
@TableField("salt")
private String salt;
/**
* 用户名
*/
@TableField("name")
private String name;
/**
* 密码,md5加密
*/
@TableField("password")
private String password;
/**
* 手机号
*/
@TableField("phone")
private String phone;
/**
* 头像
*/
@TableField("image")
private String image;
/**
* 0 男
1 女
2 未知
*/
@TableField("sex")
private Boolean sex;
/**
* 0 未
1 是
*/
@TableField("is_certification")
private Boolean certification;
/**
* 是否身份认证
*/
@TableField("is_identity_authentication")
private Boolean identityAuthentication;
/**
* 0正常
1锁定
*/
@TableField("status")
private Boolean status;
/**
* 0 普通用户
1 自媒体人
2 大V
*/
@TableField("flag")
private Short flag;
/**
* 注册时间
*/
@TableField("created_time")
private Date createdTime;
}

Some files were not shown because too many files have changed in this diff Show More