first commit

This commit is contained in:
zc
2026-02-27 10:16:46 +08:00
commit 0ee56404c2
705 changed files with 47675 additions and 0 deletions

217
.flattened-pom.xml Normal file
View File

@@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.continew</groupId>
<artifactId>continew-starter</artifactId>
<version>2.9.0</version>
</parent>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-admin</artifactId>
<version>3.6.0-SNAPSHOT</version>
<packaging>pom</packaging>
<description>园区管理系统</description>
<url>https://github.com/ysoft-org/ysoft-admin</url>
<licenses>
<license>
<name>GNU LESSER GENERAL PUBLIC LICENSE</name>
<url>http://www.gnu.org/licenses/lgpl.html</url>
</license>
</licenses>
<modules>
<module>ysoft-webapi</module>
<module>ysoft-module-system</module>
<module>ysoft-plugin</module>
<module>ysoft-common</module>
<module>ysoft-extension</module>
</modules>
<properties>
<revision>3.6.0-SNAPSHOT</revision>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-webapi</artifactId>
<version>3.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-module-system</artifactId>
<version>3.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-common</artifactId>
<version>3.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-plugin-schedule</artifactId>
<version>3.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-plugin-open</artifactId>
<version>3.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-plugin-generator</artifactId>
<version>3.6.0-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>huawei-mirror</id>
<name>HuaweiCloud Mirror</name>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
</repository>
<repository>
<id>ali-mirror</id>
<name>AliYun Mirror</name>
<url>https://maven.aliyun.com/repository/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>huawei-mirror</id>
<name>HuaweiCloud Mirror</name>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
</pluginRepository>
<pluginRepository>
<id>ali-mirror</id>
<name>AliYun Mirror</name>
<url>https://maven.aliyun.com/repository/public/</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>apply</goal>
</goals>
</execution>
</executions>
<configuration>
<java>
<removeUnusedImports />
<eclipse>
<file>.style/p3c-codestyle.xml</file>
</eclipse>
<licenseHeader>
<file>.style/license-header</file>
</licenseHeader>
</java>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten-clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sonar</id>
<activation />
<build>
<plugins>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sonar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<sonar.projectKey>Charles7c_ysoft-admin</sonar.projectKey>
<sonar.moduleKey>${project.groupId}:${project.artifactId}</sonar.moduleKey>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<sonar.organization>charles7c</sonar.organization>
</properties>
</profile>
</profiles>
</project>

BIN
.image/qrcode.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

0
.style/license-header Normal file
View File

380
.style/p3c-codestyle.xml Normal file
View File

@@ -0,0 +1,380 @@
<?xml version="1.0" encoding="utf-8"?>
<profiles version="21">
<profile kind="CodeFormatterProfile" name="P3C-CodeStyle" version="21">
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_preserve"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_preserve"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_preserve"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_preserve"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_preserve"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_preserve"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_preserve"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="82"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="82"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="18"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
</profile>
</profiles>

790
CHANGELOG.md Normal file
View File

@@ -0,0 +1,790 @@
## [v3.5.0](https://github.com/ysoft-org/ysoft-admin/compare/v3.4.1...v3.5.0) (2025-03-05)
### ✨ 新特性
* 【generator】生成预览支持批量 ([a7296a3](https://github.com/ysoft-org/ysoft-admin/commit/a7296a36278f68108a0513fe26b3cccd9af5244c))
* 【generator】代码生成新增 Mapper.xml 模板 ([b519364](https://github.com/ysoft-org/ysoft-admin/commit/b51936445d36a76650d94225b3ecfa81b86e066c)) ([98569ae](https://github.com/ysoft-org/ysoft-admin/commit/98569ae20530a3c94cd1a071a29fae3c904761e3))
* 🔥新增终端管理,重构认证体系,多端认证鉴权控制 ([Gitee#40](https://gitee.com/ysoft/ysoft-admin/pulls/40)) ([95f2617](https://github.com/ysoft-org/ysoft-admin/commit/95f2617a4c086e3e5113799fe213c24c42bfbd17)) ([c90e80e](https://github.com/ysoft-org/ysoft-admin/commit/c90e80e9d72eba173df586e7f12a0c9378c82ec9)) ([438615f](https://github.com/ysoft-org/ysoft-admin/commit/438615f87c5583890703c78c4e61aae36e3dab80)) ([229bd9b](https://github.com/ysoft-org/ysoft-admin/commit/229bd9becfda15cbcb049fd1e0842dbe04d7b135)) ([a305eac](https://github.com/ysoft-org/ysoft-admin/commit/a305eac96f766ad3a72051fe19f533f4fd64d304)) ([82cf439](https://github.com/ysoft-org/ysoft-admin/commit/82cf4390e8fdc73da1818dcc9a5dd0c7ff87db02)) ([5f68e84](https://github.com/ysoft-org/ysoft-admin/commit/5f68e84e7dbb5c2d0f793c72df76d69d326e574e))
* 【generator】支持源项目内生成代码文件 ([GitHub#125](https://github.com/ysoft-org/ysoft-admin/pull/125)) ([653802e](https://github.com/ysoft-org/ysoft-admin/commit/653802efbe2debdbfd1fe5097dae7280e80f1e43))
* 新增接口文档配置,支持显示 SaToken 权限码 ([Gitee#44](https://gitee.com/ysoft/ysoft-admin/pulls/44)) ([19c5dbd](https://github.com/ysoft-org/ysoft-admin/commit/19c5dbd2659264cfba59e2b1316420c39f82f731))
* 新增NoHandlerFoundException、HttpRequestMethodNotSupportedException异常处理 ([Gitee#44](https://gitee.com/ysoft/ysoft-admin/pulls/44)) ([4efe025](https://github.com/ysoft-org/ysoft-admin/commit/4efe025b2e36c56162dc8fcbd05482b7ecc21e5f))
### 💎 功能优化
- 菜单路由为空时默认返回空列表而非 null ([43cc429](https://github.com/ysoft-org/ysoft-admin/commit/43cc429234150e185a697b6dbc340bd966bf6133))
- 移除初始数据脚本 update_user、update_time 字段赋值(此优化无需跟进升级) ([9d0e1fc](https://github.com/ysoft-org/ysoft-admin/commit/9d0e1fc8e642c5be46d20173fd573582ad54d5e6))
- 【generator】消除前端红色报警、更新表格创建者和更新者字段索引自定义单选框数据 ([GitHub#108](https://github.com/ysoft-org/ysoft-admin/pull/108)) ([4c8ebf2](https://github.com/ysoft-org/ysoft-admin/commit/4c8ebf2d0f3e65737f6a55c06eb1ff2d31273505))
- 更新 nginx.conf 部署配置文件 ([4920d7b](https://github.com/ysoft-org/ysoft-admin/commit/4920d7b730c2e975c4a50a5b8b8172f5365509c5))
- 调整 starter 内的 BaseResp、BaseDetailResp 到 admin 项目 ([144251b](https://github.com/ysoft-org/ysoft-admin/commit/144251b21ec0d79927164a705f3c846aace53ca1))
- 调整 starter 内的 CommonUserService、ContainerPool 到 admin 项目 ([f1d0b49](https://github.com/ysoft-org/ysoft-admin/commit/f1d0b491b14d806fbe1d0011cdadea64336fe3b0))
- 优化登录日志描述 ([a24136d](https://github.com/ysoft-org/ysoft-admin/commit/a24136d6fe92bcb055c965600caef399df563361))
- 丰富部门、角色、用户初始测试数据,方便开发场景 ([b5bbdb2](https://github.com/ysoft-org/ysoft-admin/commit/b5bbdb27e6e002d52b5a1894e2bf8e24e6f963e8))
- 调整 starter 内的 BaseDO、BaseCreateDO、BaseUpdateDO 到 admin 项目 ([498e680](https://github.com/ysoft-org/ysoft-admin/commit/498e680672df00be9e8f9546f2010fcc54faab23))
- 🔥重构角色管理,更新权限扁平化 ([f6535ef](https://github.com/ysoft-org/ysoft-admin/commit/f6535ef7a35794147d8094eed71a4789c06f3db8)) ([0a62f81](https://github.com/ysoft-org/ysoft-admin/commit/0a62f81ad7c1f7b086379059fe780a609e5d575b)) ([144cfa2](https://github.com/ysoft-org/ysoft-admin/commit/144cfa27ce944dc5b78d2d26466cd149b8ca7959))
- 优化任务调度服务配置,允许用户名密码使用环境变量 ([GitHub#129](https://github.com/ysoft-org/ysoft-admin/pull/129)) ([0e65190](https://github.com/ysoft-org/ysoft-admin/commit/0e651902f267feb8b4997d066285d979429bd56f))
- 优化系统配置 SQL 数据脚本 ([d336911](https://github.com/ysoft-org/ysoft-admin/commit/d3369119e090b62468fda38e1dfb52ddb5dc7df3))
- 调整日志 module 字段长度 50 => 100 ([65941c1](https://github.com/ysoft-org/ysoft-admin/commit/65941c1ee4020e2f9b4fc07f15c249b9d0d7e851))
- 🔥重构存储管理,新增设置默认存储、修改状态接口 ([37d6efb](https://github.com/ysoft-org/ysoft-admin/commit/37d6efb70e5bcfddc8a4ca6becaf440ab05785fb))
### 🐛 问题修复
- 【generator】修复 PostgreSQL 菜单 SQL 脚本模板错误 ([GitHub#107](https://github.com/ysoft-org/ysoft-admin/pull/107)) ([af403d0](https://github.com/ysoft-org/ysoft-admin/commit/af403d055af1c186d7b5976cff894e9dd2afcc01))
- 【generator】生成菜单脚本添加ID ([GitHub#109](https://github.com/ysoft-org/ysoft-admin/pull/109)) ([9ebecdc](https://github.com/ysoft-org/ysoft-admin/commit/9ebecdc1935a99f15ece4e2c933175d9919e9825))
- 【generator】前端页面生成表单类型 ([GitHub#110](https://github.com/ysoft-org/ysoft-admin/pull/110)) ([75d2662](https://github.com/ysoft-org/ysoft-admin/commit/75d26623652d4813643cea9a7c3f821e44edc885))
- 完善部分 in 查询前的空集合处理 ([899354a](https://github.com/ysoft-org/ysoft-admin/commit/899354a6e7239ed00f81155e8ed5f2760b191480))
- 修复公告通知范围字段类型错误 ([fdd0617](https://github.com/ysoft-org/ysoft-admin/commit/fdd0617a2832221bb017d2e17dc5fb82af862707))
- 修复通知公告分页 通知范围字段类型回显错误 ([160ab8d](https://github.com/ysoft-org/ysoft-admin/commit/160ab8d38bb68801ed6efe0ceeb4ccb4c3f4fba3))
- 🔥修复 PageResp 手动分页计算错误 ([6bcff72](https://github.com/ysoft-org/ysoft-admin/commit/6bcff7244f0a37474c39509dfed44d3cf630d898))
- 修复导入用户部门名称校验注解使用错误 ([Gitee#41](https://gitee.com/ysoft/ysoft-admin/pulls/41)) ([c870014](https://github.com/ysoft-org/ysoft-admin/commit/c870014730a47d9a9b567416b2f6736049a25125))
- 修复 PostgreSQL Liquibase 数据脚本缺失 ([8c53700](https://github.com/ysoft-org/ysoft-admin/commit/8c53700cfd8ea20ccece1867161d2315d5346d9b))
- 修复新增用户时日志记录获取 description 为空的问题 ([91924ac](https://github.com/ysoft-org/ysoft-admin/commit/91924acaa15658db88c387f81ff723ca043cd1f1))
- 调整 PostgreSQL 连接配置以消除部分类型使用报错 ([7e3257b](https://github.com/ysoft-org/ysoft-admin/commit/7e3257bd6d3965622ba53a906fd8b27e5209e67f))
- 修复部分过期配置信息 ([3fb9922](https://github.com/ysoft-org/ysoft-admin/commit/3fb9922b524a5c1a40de5bd011c99c9863032f7a))
- 修复邮箱登录,手机号登录对应日志没有记录操作人问题 ([Gitee#42](https://gitee.com/ysoft/ysoft-admin/pulls/42)) ([aab3931](https://github.com/ysoft-org/ysoft-admin/commit/aab3931f3078c1b3468c5f06e1f133862f947d7e))
- mysql 8.x failing to connect to the database correctly issue ([GitHub#128](https://github.com/ysoft-org/ysoft-admin/pull/128)) ([4caada8](https://github.com/ysoft-org/ysoft-admin/commit/4caada8c64c1f6646f312a0038338396ae860305))
### 📦 依赖升级
- 🔥ContiNew Starter 2.7.5 => 2.9.0 (更多特性及依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v3.4.1](https://github.com/ysoft-org/ysoft-admin/compare/v3.4.0...v3.4.1) (2024-12-08)
### ✨ 新特性
* 新增验证码配置开关 ([e314346](https://github.com/ysoft-org/ysoft-admin/commit/e31434617e751f08d12ace7773bb3ba7bf132370)) ([61fe39d](https://github.com/ysoft-org/ysoft-admin/commit/61fe39d439b73c90cfeb989f8f4727ade6b5b3b2)) (Gitee#37@aiming317)
### 💎 功能优化
- 【open】优化 API 参数签名处理 ([22b3564](https://github.com/ysoft-org/ysoft-admin/commit/22b3564a2217dee739fc2172453b23600d82d6de))
- 移除关于项目菜单初始数据(该菜单从动态路由调整为前端静态,且不再需要鉴权) ([88313c8](https://github.com/ysoft-org/ysoft-admin/commit/88313c8b2017e7ec620e5372f34bf5e431ce3e7f))
- 优化代码生成菜单图标 ([9296985](https://github.com/ysoft-org/ysoft-admin/commit/9296985be0ab63ba54c63c71c011681f91aef7fb))
- BaseServiceImpl 所在包调整 ([d7ae7b4](https://github.com/ysoft-org/ysoft-admin/commit/d7ae7b4e42c424a3db51c72a0ed79572c9fd7601))
- BaseController 改为在 Admin common 模块编写(重构权限校验 checkPermission 处理) ([d7ae7b4](https://github.com/ysoft-org/ysoft-admin/commit/d7ae7b4e42c424a3db51c72a0ed79572c9fd7601))
- CRUD ValidateGroup => CrudValidationGroup ([d7ae7b4](https://github.com/ysoft-org/ysoft-admin/commit/d7ae7b4e42c424a3db51c72a0ed79572c9fd7601))
- ValidateGroup => ValidationGroup ([d7ae7b4](https://github.com/ysoft-org/ysoft-admin/commit/d7ae7b4e42c424a3db51c72a0ed79572c9fd7601))
### 🐛 问题修复
- 【generator】修复 columnSize 类型错误,兼容无注释字段配置 ([6b64ae3](https://github.com/ysoft-org/ysoft-admin/commit/6b64ae3e07a76d844eec4bd05302126cbcaca31b))
- 补充能力开放模块接口文档配置 ([270fbf1](https://github.com/ysoft-org/ysoft-admin/commit/270fbf15af338a6ac3e6a686409eea8e9a32b6bf))
- 修复文件管理删除文件异常或不成功的情况 ([361a412](https://github.com/ysoft-org/ysoft-admin/commit/361a41258e9fdece5ba681298f2839b013d6cfab)) (Gitee#35@kiki1373639299)
- 修复本地文件管理删除文件异常或不成功的情况 ([c7b58a0](https://github.com/ysoft-org/ysoft-admin/commit/c7b58a0fd167c566f6680c87cc455b71c42b8eda)) (Gitee#36@kiki1373639299)
- 修复 Query 查询数组范围报错 ([d7ae7b4](https://github.com/ysoft-org/ysoft-admin/commit/d7ae7b4e42c424a3db51c72a0ed79572c9fd7601))
### 📦 依赖升级
- ContiNew Starter 2.7.4 => 2.7.5 (更多特性及依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v3.4.0](https://github.com/ysoft-org/ysoft-admin/compare/v3.3.0...v3.4.0) (2024-11-18)
### ✨ 新特性
* 新增仪表盘分析接口,查询访问时段分析、查询模块分析、查询终端分析、查询浏览器分析 ([dea8dbe](https://github.com/ysoft-org/ysoft-admin/commit/dea8dbe131867a564f7e151a6484db5be6effaa3))
* 新增查询仪表盘数据总览相关接口, 重构仪表盘相关代码 ([e01df09](https://github.com/ysoft-org/ysoft-admin/commit/e01df09127e6efc33971d64e2fe49a2a42282425))
* 公告支持设置通知范围 ([29202ae](https://github.com/ysoft-org/ysoft-admin/commit/29202aea307a7257c9d1e9649dee00140164c59c)) (GitCode#1)
* 角色管理增加分配角色功能 ([73f880e](https://github.com/ysoft-org/ysoft-admin/commit/73f880ec57cfdccfc297aac228410f5bb7fed448)) ([ad3f832](https://github.com/ysoft-org/ysoft-admin/commit/ad3f8329dd07858b0982020db3605200112f09b5)) (GitHub#93)
* 新增能力开放模块应用管理功能 ([f774183](https://github.com/ysoft-org/ysoft-admin/commit/f7741832bdd315039cc5f1aa062d8ffac32ddf0f)) ([d1b3824](https://github.com/ysoft-org/ysoft-admin/commit/d1b38242b9f291c897a8eb82bd330bd775e656cf)) ([4454daa](https://github.com/ysoft-org/ysoft-admin/commit/4454daa9e07af7c7202c386e533ea055bb79f0df)) (Gitee#31)
* 新增查询用户字典接口 ([d4b02ba](https://github.com/ysoft-org/ysoft-admin/commit/d4b02ba9180f82084e5ca844eaa9b4a0966a0164))
* 代码生成新增菜单SQL模板 ([fb947c9](https://github.com/ysoft-org/ysoft-admin/commit/fb947c98fdd075a19c55e1e9e5c137a8482db618)) (GitHub#95)
### 💎 功能优化
- 优化部分 Mapper 方法使用 (替换为 MP 新增方法) ([ad69d44](https://github.com/ysoft-org/ysoft-admin/commit/ad69d44ebda72dbdb639ba4ff48cde9aa7f6e400))
- 优化查询代码生成表性能 ([781d291](https://github.com/ysoft-org/ysoft-admin/commit/781d29142fbcc1f981d3760565f2f96b49570438))
- 移除上传文件时的多余校验 ([8466105](https://github.com/ysoft-org/ysoft-admin/commit/8466105a9b8b2fd807ac9d3029e4da7bc609d551))
- 重构获取登录用户信息方式(线程级存储) ([79ea39d](https://github.com/ysoft-org/ysoft-admin/commit/79ea39dd078639b4e137d576f3d7820bb6c24d0a))
- 完善及优化代码生成模板 ([ffdc971](https://github.com/ysoft-org/ysoft-admin/commit/ffdc9712d4cd1fd3093cec0780f630d672339cdf)) ([2b47ed7](https://github.com/ysoft-org/ysoft-admin/commit/2b47ed711074ad64d98fa0d9d68ccd2777b70bf2)) ([90e3bc0](https://github.com/ysoft-org/ysoft-admin/commit/90e3bc0595fdb692644ed7fd9b1a3735962cb68b)) ([985bc25](https://github.com/ysoft-org/ysoft-admin/commit/985bc25716daae6fb018a856af889919436f26e6))
- 字典项管理日志模块调整为字典管理 ([60cb2e3](https://github.com/ysoft-org/ysoft-admin/commit/60cb2e3b5cae56d9a3117aeea6c57ec02cb9abe4))
- 解决查询日志数据时索引失效的问题 ([4525cb3](https://github.com/ysoft-org/ysoft-admin/commit/4525cb3531c06354e3dc57147c93dd5f7f8a4e8a))
- 重构拆分 liquibase 脚本结构 ([aadaa5b](https://github.com/ysoft-org/ysoft-admin/commit/aadaa5b4a70caaa775a38fd542890aa8d7f951c6))
- 调整系统配置菜单图标 ([872bc1c](https://github.com/ysoft-org/ysoft-admin/commit/872bc1ca8143632ea0ca00eb320e57f61729937c))
- 优化系统管理、代码生成相关代码及初始数据脚本 ([9ecdeb5](https://github.com/ysoft-org/ysoft-admin/commit/9ecdeb52f601b93116f6e89d8db32d8db95cb0c5)) ([5717d03](https://github.com/ysoft-org/ysoft-admin/commit/5717d03d01f8f052688bef873def83a3b8defc21)) ([7870de2](https://github.com/ysoft-org/ysoft-admin/commit/7870de28926cde86a8732ad5d6950616e1078d57))
- 优化项目模块命名(简化、分类、统一) ([c276e53](https://github.com/ysoft-org/ysoft-admin/commit/c276e53a8e02e64f9e5d8270171e20424804382d))
- 优化任务调度配置及 docker 部署脚本 ([b927470](https://github.com/ysoft-org/ysoft-admin/commit/b927470e33bb75594f1546a4f06d48bc2281f5ab)) ([c5cd4e2](https://github.com/ysoft-org/ysoft-admin/commit/c5cd4e2c284fa195411f704e41ca50a70271c6b7))
- 重构仪表盘查询地域分析接口 ([e0e157f](https://github.com/ysoft-org/ysoft-admin/commit/e0e157f0e5b23ff6e27ec7ae0ee028af6f2facd1))
- 完善 PostgreSQL 代码生成类型映射配置 ([4c36f23](https://github.com/ysoft-org/ysoft-admin/commit/4c36f2339830272aa047e46d02f34485b9051ec3))
- 优化通知公告部分代码 ([e1941ec](https://github.com/ysoft-org/ysoft-admin/commit/e1941eca455a066dae631b1533d63f8d9a193161))
- 优化初始数据脚本 ([6abb444](https://github.com/ysoft-org/ysoft-admin/commit/6abb444f9dce7ed1ea4aa90502c21d2ab6c8e247))
- 忽略获取在线用户信息异常 ([4856366](https://github.com/ysoft-org/ysoft-admin/commit/48563663e1fed93154f63f6c9a6c07ea79d741da))
- 优化部分注释 ([3116836](https://github.com/ysoft-org/ysoft-admin/commit/3116836b0139232769797da271a400fa4d9d52fa))
### 🐛 问题修复
- 参数配置支持设值为空 ([d7e8fc9](https://github.com/ysoft-org/ysoft-admin/commit/d7e8fc9bc31409b3652b5ad03a79248726547088))
- 修复修改存储时同时设置默认存储及启用判断顺序错误 ([d9602e8](https://github.com/ysoft-org/ysoft-admin/commit/d9602e8639bcd125b15faea5ca7f618429bcc50e))
- 修复任务日志缺失异常堆栈的问题 ([5cbeddb](https://github.com/ysoft-org/ysoft-admin/commit/5cbeddb97bd38274641ac5d63226a937975d69ba)) (Gitee#29)
- 修复更新在线用户权限信息报错的问题 ([8278032](https://github.com/ysoft-org/ysoft-admin/commit/82780324b7c2faeba22f2dbde440d1cf0e42c3c9))
- 修复查询日志排序错误 ([8b403f4](https://github.com/ysoft-org/ysoft-admin/commit/8b403f4357caeac0c0a4cc9ac67c73043a1f4465))
- 修复部分错误规范代码 ([a83b45f](https://github.com/ysoft-org/ysoft-admin/commit/a83b45f776234274a844337a2f2b541705ba5aff))
- 调整部分实体包 ([3f4331e](https://github.com/ysoft-org/ysoft-admin/commit/3f4331e92b86e73303c4d675f0f1d4bc91a2a71b))
- 修复获取邮箱验证码未进行行为验证码校验错误 ([731bfa0](https://github.com/ysoft-org/ysoft-admin/commit/731bfa065ab3a10ab933aaffd2e9ceebf0a4d16d))
- 完善用户角色变更校验及在线用户权限处理 ([c28d3cf](https://github.com/ysoft-org/ysoft-admin/commit/c28d3cf1c45212e670b90fc0077b5e176a894bd2))
- 修复查询系统配置参数漏洞 :boom: ([8c3fe35](https://github.com/ysoft-org/ysoft-admin/commit/8c3fe353be5d68f1ed252eef12f5fcdc0a1e3c83))
### 📦 依赖升级
- ContiNew Starter 2.6.0 => 2.7.4 (更多特性及依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v3.3.0](https://github.com/ysoft-org/ysoft-admin/compare/v3.2.0...v3.3.0) (2024-09-09)
### ✨ 新特性
* 重构全局响应处理及异常拦截,自定义异常拦截从 Starter 调整到 Admin 项目 ([d7621c6](https://github.com/ysoft-org/ysoft-admin/commit/d7621c6b26bfd253d9295444ea144f5dabf67f44))
* 重构 Controller 接口方法返回值写法,接口文档也已适配处理 ([d7621c6](https://github.com/ysoft-org/ysoft-admin/commit/d7621c6b26bfd253d9295444ea144f5dabf67f44)) ([0f1479f](https://github.com/ysoft-org/ysoft-admin/commit/0f1479f40deef83a5f5d64cbc24a7691b274b112))
* 代码生成字段配置时支持指定排序 ([d56b9aa](https://github.com/ysoft-org/ysoft-admin/commit/d56b9aa35ee2502804f487487d7bac02f4edc9b0))
* 代码生成字段配置时支持选择关联字典 ([fdd21a0](https://github.com/ysoft-org/ysoft-admin/commit/fdd21a01c106e12321d0d1886ff643c72a09943b)) ([ecc98b1](https://github.com/ysoft-org/ysoft-admin/commit/ecc98b1999d90c1a7a29af94dc8705283f34dada))
* 修改角色功能权限、数据权限支持衔接新增角色时的父子联动选项 ([387fb19](https://github.com/ysoft-org/ysoft-admin/commit/387fb194640d4a288f053c3eba1bf5b314d64da7))
### 💎 功能优化
- 移除 WebMvcConfiguration 配置(已迁移到 Starter 项目)([d7621c6](https://github.com/ysoft-org/ysoft-admin/commit/d7621c6b26bfd253d9295444ea144f5dabf67f44))
- 重构日志持久层接口本地实现类 ([2c1eb56](https://github.com/ysoft-org/ysoft-admin/commit/2c1eb5660f69a9ab702d503944a11e47edac1142))
- 优化打包配置,模板等配置文件提取到 jar 包外部 ([75cef77](https://github.com/ysoft-org/ysoft-admin/commit/75cef773187e5b5060a10a12e7c9912002376d7a))
- 优化健康监测接口响应信息 ([bb5a92e](https://github.com/ysoft-org/ysoft-admin/commit/bb5a92e5ca238ed677d9ac3589fdf8009d2ac232))
- 优化代码生成列配置代码,取消后端部分默认值 ([f5ee2b5](https://github.com/ysoft-org/ysoft-admin/commit/f5ee2b5beb9572d3fcd5b7c2f6db0627dedb31aa)) ([ca9f34d](https://github.com/ysoft-org/ysoft-admin/commit/ca9f34d3d5a3f96c6df537036a5fd876cae2e89a))
- 重构权限变更逻辑,修改角色、变更用户角色不再下线用户 ([ad9a600](https://github.com/ysoft-org/ysoft-admin/commit/ad9a6000fcb5d64b04cf230caa3cbacc8c3ac8d7))
### 🐛 问题修复
- 修复打包部署后,下载用户导入模板异常问题 (Gitee#25) ([c7ffc67](https://github.com/ysoft-org/ysoft-admin/commit/c7ffc67cdc9139a4398c7dc819ca453880bd100a))
- 修复日志记录仅支持获取 JSON 结构响应体的问题 ([d7621c6](https://github.com/ysoft-org/ysoft-admin/commit/d7621c6b26bfd253d9295444ea144f5dabf67f44))
- 修复并增强 SQL 注入防御 ([0f1479f](https://github.com/ysoft-org/ysoft-admin/commit/0f1479f40deef83a5f5d64cbc24a7691b274b112))
- 修复目录、菜单的组件名称重复的错误问题 ([9e91f56](https://github.com/ysoft-org/ysoft-admin/commit/9e91f563e2a263ce302dc3bf17c89e37c2b56285))
- 修复 DataPermission 注解表别名配置无效的问题 ([6c4e252](https://github.com/ysoft-org/ysoft-admin/commit/6c4e2522df3f44ba0f5a21228e805b8ac98f8e6b))
- 临时移除 MyBatis Plus saveBatch 不兼容的 rewriteBatchedStatements 配置 ([25240fa](https://github.com/ysoft-org/ysoft-admin/commit/25240fa81957a1677deda294ce8f2b0af5413315))
- 修复更新会导致原加密失效的问题 ([8903195](https://github.com/ysoft-org/ysoft-admin/commit/89031954c0b7daee1c08e1a10fd50139301cd6ab)) ([c87317d](https://github.com/ysoft-org/ysoft-admin/commit/c87317d19946989e86dfbc5f24b155b2ea5abdc9))
- 修复角色查询参数与前端不一致的问题 ([098571f](https://github.com/ysoft-org/ysoft-admin/commit/098571ffb2febc6163d2b9e5b18c4796ea80cbfa))
- 修复特殊校验异常不打印堆栈 ([c87317d](https://github.com/ysoft-org/ysoft-admin/commit/c87317d19946989e86dfbc5f24b155b2ea5abdc9))
- 修复日志全局 includes 配置会被局部修改的问题 ([c87317d](https://github.com/ysoft-org/ysoft-admin/commit/c87317d19946989e86dfbc5f24b155b2ea5abdc9))
- 修复初始数据错误 ([403c72a](https://github.com/ysoft-org/ysoft-admin/commit/403c72aa52a0f0852208f15fa1c7117ee26414f0))
### 📦 依赖升级
- ContiNew Starter 2.4.0 => 2.6.0 (更多特性及依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v3.2.0](https://github.com/ysoft-org/ysoft-admin/compare/v3.1.0...v3.2.0) (2024-08-05)
### ✨ 新特性
* 新增用户批量导入功能 (GitHub#78) ([c2ad055](https://github.com/ysoft-org/ysoft-admin/commit/c2ad055cf82187e132e4cde9e15251e554deadff))
* 新增任务调度模块 SnailJob灵活可靠和快速的分布式任务重试和分布式任务调度平台 (Gitee#22) ([ce1acea](https://github.com/ysoft-org/ysoft-admin/commit/ce1acea1535083345c33bcc427054831faf5d2e3)) ([ed5594b](https://github.com/ysoft-org/ysoft-admin/commit/ed5594b31e1d31b2a9210b65838d545067ca812f)) ([797221b](https://github.com/ysoft-org/ysoft-admin/commit/797221b4dc66c582b95b872b3cb60429247b14e9)) ([7b381b3](https://github.com/ysoft-org/ysoft-admin/commit/7b381b36de4ed4ef657249028188abc2f274b036)) ([ffe75e1](https://github.com/ysoft-org/ysoft-admin/commit/ffe75e111eb333236e923a1ed14dae5257b09357)) ([cef5cb4](https://github.com/ysoft-org/ysoft-admin/commit/cef5cb4fa5e6ee2325fd3738e1c8601a75277dd8)) ([513d8d9](https://github.com/ysoft-org/ysoft-admin/commit/513d8d9324b952438ec5513e9e3c7dfb092d5b83))
* 修改 sys_option sql 脚本以适配 base64 图片 (Gitee#25) ([6848559](https://github.com/ysoft-org/ysoft-admin/commit/68485596c47a884b453e4632b59b525527293e17))
### 💎 功能优化
- 优化更新手机号、邮箱语句 ([9995bf0](https://github.com/ysoft-org/ysoft-admin/commit/9995bf0200e6256ccc4a26d8847e37fb85b4a226))
- 重构适配 ContiNew Starter 最新线程池配置 ([5604fe9](https://github.com/ysoft-org/ysoft-admin/commit/5604fe95784b2627f1c8144144546de05434577e))
- 获取短信、邮箱验证码接口适配 ContiNew Starter 限流器 ([44811fc](https://github.com/ysoft-org/ysoft-admin/commit/44811fc93283f508953f5fc9193c0b03305da5b2))
- 移动 SaToken 配置到 webapi 模块 ([d733b7f](https://github.com/ysoft-org/ysoft-admin/commit/d733b7f1661a5f0df2b6f12b33ba69da8810e0aa))
- 新增 ysoft-admin-plugins 插件模块,代码生成迁移到插件模块,为后续插件化改造铺垫 ([52f3be8](https://github.com/ysoft-org/ysoft-admin/commit/52f3be8ee3a07334c76cdfc06d15698b7ccd65ea))
- 使用分组校验优化存储管理 ([3a23db1](https://github.com/ysoft-org/ysoft-admin/commit/3a23db1a4bdfefc26de67ed9e0317097699d5db6))
- 移动日志配置和依赖至 webapi 模块 ([48aae87](https://github.com/ysoft-org/ysoft-admin/commit/48aae877646e93f20a43fe4002d7f19fa98897c3))
- 调整部分 Query 查询参数类型为对应枚举(目前已支持非 JSON 格式枚举参数转换) ([f80316e](https://github.com/ysoft-org/ysoft-admin/commit/f80316e34d9757225a1a7b6002061e8626018e47))
- 调整部分枚举类的包位置 ([6b69dd4](https://github.com/ysoft-org/ysoft-admin/commit/6b69dd43e1544bd955901d6110fa7d7f65aaa80c))
- 更新通知公告新增、查看菜单数据 ([4554526](https://github.com/ysoft-org/ysoft-admin/commit/45545260a36b57b594eb8329e95b7552cf6893f5))
### 🐛 问题修复
- 修复代码生成前端模板部分错误 (Gitee#20) ([b512ea9](https://github.com/ysoft-org/ysoft-admin/commit/b512ea99f39aaac04bd4db4a9d73e29ddb340d9e))
- 修复文件管理删除图片时未删除缩略图的问题 ([bc523eb](https://github.com/ysoft-org/ysoft-admin/commit/bc523eba30a500a4af62adbd590446c48a5cb0be))
- 修复存储管理私有密钥校验错误 ([eb65cff](https://github.com/ysoft-org/ysoft-admin/commit/eb65cff4c776a8d3e259f8c96d2918acfe038b6a))
- 删除用户未删除用户历史密码 ([f53d6b6](https://github.com/ysoft-org/ysoft-admin/commit/f53d6b6504d5d504581e2697589dcb9b8fbe82ef))
- 修复菜单缓存更新错误 ([10ff4ce](https://github.com/ysoft-org/ysoft-admin/commit/10ff4ce838b950df42994de4dbd2af20ff254949))
- 修复偶发性报错 zip file closed ([b587cb8](https://github.com/ysoft-org/ysoft-admin/commit/b587cb82aa5d48548b5ce75dd4863af037ae8274))
- 修复代码生成器前端新增数据模板错误 ([81de8d0](https://github.com/ysoft-org/ysoft-admin/commit/81de8d060ba081d14873d14d6e4083302a718bef))
### 📦 依赖升级
- ContiNew Starter 2.1.0 => 2.4.0 (更多依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v3.1.0](https://github.com/ysoft-org/ysoft-admin/compare/v3.0.1...v3.1.0) (2024-06-16)
### ✨ 新特性
* 系统配置新增安全设置功能,支持多种密码策略配置,例如:有效期、密码重复使用次数、密码错误锁定等 (GitHub#61) ([1de2a8f](https://github.com/ysoft-org/ysoft-admin/commit/1de2a8f2dcf01ef8eeb7e2d662c09af00b38ffb1)) ([90ecaab](https://github.com/ysoft-org/ysoft-admin/commit/90ecaab63241b8d351ebaffa4faece8c609882b1)) ([3994142](https://github.com/ysoft-org/ysoft-admin/commit/3994142ace6cd6ce9d094b8a4ceed080a2b2ec33)) ([1427c13](https://github.com/ysoft-org/ysoft-admin/commit/1427c13b7a0b4e0f569ccc20a3172ad748c98e14)) ([5f5fee6](https://github.com/ysoft-org/ysoft-admin/commit/5f5fee63f8e584ffd9542bf132ee724762187d83)) ([c1e9d31](https://github.com/ysoft-org/ysoft-admin/commit/c1e9d318e0643c0854a848425955948d05b158d3)) ([48d0f47](https://github.com/ysoft-org/ysoft-admin/commit/48d0f476149ff7bc30fe05fe3dec84e5a947cf19))
* 图片文件支持缩略图 (GitHub#63) ([d320c95](https://github.com/ysoft-org/ysoft-admin/commit/d320c9596a321dce1028ac36d23bcd04535e87a6)) ([d44fb3a](https://github.com/ysoft-org/ysoft-admin/commit/d44fb3a681370b5763f028cc761fbb5fc94a104c))
* 在线用户增加最后活跃时间显示 ([926497a](https://github.com/ysoft-org/ysoft-admin/commit/926497a18acbb6ef170de9f68bd97e025e212f3e))
* 新增 WebSocket 消息通知,站内信重新上线 (GitHub#67) ([9970c46](https://github.com/ysoft-org/ysoft-admin/commit/9970c461cce5c710f1f8479d4bdd258e65558256)) ([94168e2](https://github.com/ysoft-org/ysoft-admin/commit/94168e246f75364605b6fbdb82c9438e2b959c61)) ([5abdb8d](https://github.com/ysoft-org/ysoft-admin/commit/5abdb8d86161e7bd03ace14b3c899f6ad13020e2))
* 文件上传按日期拆分目录 (GitHub#68) ([08aa085](https://github.com/ysoft-org/ysoft-admin/commit/08aa08550589876a821a37d56a5fae8867292978))
* 代码生成增加了 TREE_SELECT/CHECK_GROUP/INPUT_NUMBER/INPUT_PASSWORD控件 (Gitee#17) ([8632b22](https://github.com/ysoft-org/ysoft-admin/commit/8632b22bd5b6d43e31b6aeac930836464849441b)) ([cf18c10](https://github.com/ysoft-org/ysoft-admin/commit/cf18c1046b77c9f38d28b0e6608d345df3bbd5a9))
* 系统参数新增根据类别查询方法 ([694cbb2](https://github.com/ysoft-org/ysoft-admin/commit/694cbb2850c05f7eb35fb982530a6c204f1f64b0))
* 支持动态邮件 ([1dbb339](https://github.com/ysoft-org/ysoft-admin/commit/1dbb33935a05e9fde749191e34682e632c8e1e63))
### 💎 功能优化
- 优化部分命名 ([a3cf39f](https://github.com/ysoft-org/ysoft-admin/commit/a3cf39f9f8611f7f34dd9f55166d0fe75b72145b))
- 优化代码生成预览 (Gitee#14) ([ad7412f](https://github.com/ysoft-org/ysoft-admin/commit/ad7412f9cbee5d851d060d8e9d717b2553d3d4cb))
- 优化个人中心部分参数命名 ([61dd3a4](https://github.com/ysoft-org/ysoft-admin/commit/61dd3a4c3aef2d4a873a1d4de13bc1962179eeb1))
- 根据前端最新 ESLint 配置优化代码生成模板 ([044b4b6](https://github.com/ysoft-org/ysoft-admin/commit/044b4b669aa2b77b3f5ac27095202e57045fd10d))
- 优化代码生成模板 ([3ddcdf0](https://github.com/ysoft-org/ysoft-admin/commit/3ddcdf0f67d12250da4b7f6f6ff3d63a880e6d4c)) ([6396e9a](https://github.com/ysoft-org/ysoft-admin/commit/6396e9a7364bf899023c2399083b43c67efb30cf)) ([2fb4001](https://github.com/ysoft-org/ysoft-admin/commit/2fb40015c1ca2bc58b66891e2cfbfac70b029016))
- 使用 Crane4j 优化在线用户数据填充 ([cb81135](https://github.com/ysoft-org/ysoft-admin/commit/cb811350f36364fcc85355c081b8b60c7d5bfb2a))
- 用户角色名称调整为角色名称列表返回,并全局优化 Crane4j 组件的使用方式 ([857a1c9](https://github.com/ysoft-org/ysoft-admin/commit/857a1c90838c8305f916af9dccfd4ca847ca8c66)) ([0b76d5c](https://github.com/ysoft-org/ysoft-admin/commit/0b76d5ca33f5900862d48321e8384ee8ded6ae4e))
- 优化部分方法排序 ([651cc8a](https://github.com/ysoft-org/ysoft-admin/commit/651cc8ae71bd3f544bd41adac0ef7044011300a7))
- 字典管理分页查询接口 => 查询列表接口 ([b13d0e9](https://github.com/ysoft-org/ysoft-admin/commit/b13d0e9ee530fc1a8b382e08ead065989f2b0e7f))
- 移除部门响应信息中的 getDisabled 方法 ([659144a](https://github.com/ysoft-org/ysoft-admin/commit/659144afdaf5d1b4667437053a770cf39681cdd7))
- 文件管理存储路径改为相对路径 (GitHub#69) ([8854f20](https://github.com/ysoft-org/ysoft-admin/commit/8854f20ce90f6a1c379ac81a27bb40784a838095))
- 查询文件列表增加存储名称信息返回 ([69bc1e5](https://github.com/ysoft-org/ysoft-admin/commit/69bc1e52e122c14a695d2e37589d36cbb64de8a4))
- 系统参数表结构新增ID、类别字段 ([45396f2](https://github.com/ysoft-org/ysoft-admin/commit/45396f2dc23b4de47912c1d77b05711c839672ce))
- 优化公告状态判断 ([a07aedb](https://github.com/ysoft-org/ysoft-admin/commit/a07aedbf35e32f3d09d2e9ed8857b9a9d2e2e13a))
- 重构系统参数相关接口 ([6d0060b](https://github.com/ysoft-org/ysoft-admin/commit/6d0060b21c374afd9880e57490345a140187a7cd))
- 优化用户及部门查询 ([448f9a0](https://github.com/ysoft-org/ysoft-admin/commit/448f9a0a819d6816a5ae3ada2e07690a5f70f7df))
- 用户头像改为Base64存储 ([969216d](https://github.com/ysoft-org/ysoft-admin/commit/969216d7c67332eae826c11233c8745d9d3ad81c)) ([513ea83](https://github.com/ysoft-org/ysoft-admin/commit/513ea83152708194348afeb93d31aed1a9914e57)) ([7a6cafc](https://github.com/ysoft-org/ysoft-admin/commit/7a6cafc6e4ff6914fa62a870538b51759af866a8))
- 优化配置文件 ([5b3d4f5](https://github.com/ysoft-org/ysoft-admin/commit/5b3d4f57788e30b62a1e1af9c2620a4cc8659bfe))
- 优化登录 Helper ([afbd619](https://github.com/ysoft-org/ysoft-admin/commit/afbd619d098ff3d70fc786db9594cebf03c07e10))
- 重构查询参数及字典接口 ([1d60213](https://github.com/ysoft-org/ysoft-admin/commit/1d602134377fc13b062981476b8c17947b36006d))
- 重构查询角色字典接口 ([1e73d06](https://github.com/ysoft-org/ysoft-admin/commit/1e73d06a972d380bbed253eaffd806d8e0698525))
- 使用 CompletableFuture 实现异步加载用户权限、角色代码和角色信息,以提高登录时的性能和响应速度 ([d5f3c74](https://github.com/charles7c/ysoft-admin/commit/d5f3c7417ad7b1178b5a53da3fd6f3cb7cd3b19a))
### 🐛 问题修复
- 补充查询文件资源统计权限校验注解 ([60cbf04](https://github.com/ysoft-org/ysoft-admin/commit/60cbf0402a350d05a09abec57ba94c7758b46499))
- Postgresql startup script fixes (GitHub#60) ([8caad16](https://github.com/ysoft-org/ysoft-admin/commit/8caad16ef226e473a81f79b82485c3d03ded7a42))
- 修复初始菜单数据错误 ([f062797](https://github.com/ysoft-org/ysoft-admin/commit/f062797629bd7fc220ceae1e44859146ef4a14ff))
- 字典编码、存储编码及类型、菜单类型不允许修改 ([79d0101](https://github.com/ysoft-org/ysoft-admin/commit/79d0101e5eb1baa86979b6a6d3c584a2a483320f))
- 修复行为验证码接口请求次数限制 ([573e634](https://github.com/ysoft-org/ysoft-admin/commit/573e634b433c473551244418e695a34bbd3fa675))
- 修复导出用户报错 ([655a695](https://github.com/ysoft-org/ysoft-admin/commit/655a695753d12db624fbf2afaf10d38f67241e31))
- 移除部门名称错误正则 ([0285874](https://github.com/ysoft-org/ysoft-admin/commit/0285874540c0cadc8aae74077f6368b6e7977c35))
- 修复插入第三方登录用户时报错 ([0cfc7a5](https://github.com/ysoft-org/ysoft-admin/commit/0cfc7a5c80c3558028c7225fc459ecb07149ab0d))
- 修复更新手机号、邮箱未加密的问题 ([485d708](https://github.com/ysoft-org/ysoft-admin/commit/485d708cd45df922ec8e601b7bd7344e9ebd9299)) ([e6d7205](https://github.com/ysoft-org/ysoft-admin/commit/e6d720571d3273f27351e81a19fdd97b9b4336f6))
### 📦 依赖升级
- ContiNew Starter 2.0.0 => 2.1.0 (更多依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v3.0.1](https://github.com/ysoft-org/ysoft-admin/compare/v3.0.0...v3.0.1) (2024-05-03)
### ✨ 新特性
* 新增验证码超时显示效果,超时后显示已过期请刷新 (GitHub#56) ([4c6a7fb](https://github.com/ysoft-org/ysoft-admin/commit/4c6a7fb91ad195b86d776f8aef6aef81d07b2eb1))
* 文件管理增加资源统计,统计总存储量、各类型文件存储占用 (GitHub#58) ([15c966f](https://github.com/ysoft-org/ysoft-admin/commit/15c966f7bb255db3edea249f8d3354324cbdbf5b))
### 💎 功能优化
- 获取图片验证码 URL /img => /image ([9a1a472](https://github.com/ysoft-org/ysoft-admin/commit/9a1a472ec996362cb918e79b9ce37bfa2639a10b))
- 移除对部分 API 重复的权限校验 ([53eaef9](https://github.com/ysoft-org/ysoft-admin/commit/53eaef9fbdfd6d0866a3d5e424d783e2e7bc0e17))
- 优化代码生成模板 ([dc92731](https://github.com/ysoft-org/ysoft-admin/commit/dc9273132dc8e266f2d44c834b9c2733256afdfe)) ([def831f](https://github.com/ysoft-org/ysoft-admin/commit/def831f2dca0703f5ef8b84b0e695a32b171461d))
### 🐛 问题修复
- 修复查询用户邮箱、手机号时未自动加密导致的错误 ([faa56d1](https://github.com/ysoft-org/ysoft-admin/commit/faa56d16b92cbdb8f7e16c8b43c2916ae692d881))
- 修复根据部门查询用户列表数据错误 ([42ac82e](https://github.com/ysoft-org/ysoft-admin/commit/42ac82e7ceef9336741c2514470c0db36ab7075e))
- 修复文件类型处理错误 ([9b60e24](https://github.com/ysoft-org/ysoft-admin/commit/9b60e24364bfb4cc7cd9996a43579a062197cdf3))
## [v3.0.0](https://github.com/ysoft-org/ysoft-admin/compare/v2.5.0...v3.0.0) (2024-04-27)
### ✨ 新特性
* 系统日志新增导出 API ([bd0f40c](https://github.com/ysoft-org/ysoft-admin/commit/bd0f40c6ad397174baf80b04923ef1e94ff28e3c))
* 适配 3.0 前端菜单,并梳理菜单数据
* 适配 3.0 前端代码生成模板,代码预览及生成 ([3dbe72f](https://github.com/ysoft-org/ysoft-admin/commit/3dbe72fd570c44b32599d869abd30331137a6c7d))
### 💎 功能优化
- 重构日志管理相关接口 ([7793f82](https://github.com/ysoft-org/ysoft-admin/commit/7793f82009bcdb5fcdfe5e91daab211ab1705bf7))
- 优化部门管理相关 API合并 DeptResp 及 DeptDetailResp ([a2cf072](https://github.com/ysoft-org/ysoft-admin/commit/a2cf072609ac33543605ecbb5f8e498237bc3d91))
- 优化存储管理相关 API合并 StorageResp 及 StorageDetailResp ([f7b5a4f](https://github.com/ysoft-org/ysoft-admin/commit/f7b5a4ff8dd93f444c00d103b0609ae81e0dd70c))
- 优化字典管理相关 API ([9ec5945](https://github.com/ysoft-org/ysoft-admin/commit/9ec594509f2d4b31f46e3aca66d65d139dc8b94f))
- 移除部门、角色、菜单、用户、存储的状态默认值 ([bd5ede2](https://github.com/ysoft-org/ysoft-admin/commit/bd5ede2e2956057376b930ecfed88ca44437cbc1))
- 代码生成新增 MySQL json 数据类型映射 ([fe57350](https://github.com/ysoft-org/ysoft-admin/commit/fe5735090d94f5d900d79142e5e42ba2db9c0249))
- 优化角色管理相关 API角色编码不允许修改 ([df59cee](https://github.com/ysoft-org/ysoft-admin/commit/df59cee98565f9f45b04d16533888be39c3d7a6f))
- 优化用户管理相关 API ([5269608](https://github.com/ysoft-org/ysoft-admin/commit/5269608c61b1f5a6a9f61cd45b349f28db714232))
- 文件管理查询 API 调整为分页查询 ([f8bea90](https://github.com/ysoft-org/ysoft-admin/commit/f8bea901938aec0f0ac21c63179c5bde2a0965a7))
- 移除 Qodana 扫描 ([d88581f](https://github.com/ysoft-org/ysoft-admin/commit/d88581f939afb0caa3589c8ee76c9b296bb9997e))
- 移除菜单导出接口 ([4363c91](https://github.com/ysoft-org/ysoft-admin/commit/4363c91872e6d83e139b22c95a0d7e83183d8f69))
- 优化系统日志、在线用户、存储管理、部门管理相关代码 ([a2e4f9a](https://github.com/ysoft-org/ysoft-admin/commit/a2e4f9a28b744e269c46dc66c60311bb939021a7))
- 优化查询参数字典 API 地址 ([79a3de8](https://github.com/ysoft-org/ysoft-admin/commit/79a3de8971c613277bdcea79463b6f06959e7b85))
- 移除角色状态字段 ([e89ba7d](https://github.com/ysoft-org/ysoft-admin/commit/e89ba7d5cd793e20c3562c7bd1e4655ed1e5a2a3))
### 🐛 问题修复
- 使用字典时,仅查询启用状态字典 ([17c795f](https://github.com/ysoft-org/ysoft-admin/commit/17c795fedef5b6801f2053d97b9d78d067775ca1))
- 获取 Authorization 请求头内容兼容小写请求头场景 ([e68c445](https://github.com/ysoft-org/ysoft-admin/commit/e68c4455a8af1b4d7a25cd63f9fc9e5aabb441ab))
- 修复查询用户权限存在空值的问题 ([fce4a56](https://github.com/ysoft-org/ysoft-admin/commit/fce4a566d7204791650153f0a5507a5d05d2d6c3))
- 存储管理 S3 存储功能修复 (GitHub#51) ([f71c4c2](https://github.com/ysoft-org/ysoft-admin/commit/f71c4c226ffd7c27f6726873be6af125affaf148))
- 修复 sys_role_menu 表初始数据错误 ([70ed667](https://github.com/ysoft-org/ysoft-admin/commit/70ed667c16388093204eecd97e4914076c62d1ff))
- 修复用户管理/角色管理编辑及状态变更问题 (GitHub#53) ([abf1e65](https://github.com/ysoft-org/ysoft-admin/commit/abf1e651e9782a6f7bf2a896018de17130038c57))
- 修复Failed to submit a listener notification task. Event loop shut down? 问题,开发时表现为需要点击两次才能关闭程序 ([f5ab22e](https://github.com/ysoft-org/ysoft-admin/commit/f5ab22eedf594cee43592a2f29409ee9c33a88d3))
### 💥 破坏性变更
- 适配 ysoft-starter 2.0.0top.charles7c.ysoft.starter => top.ysoft.starter ([f5ab22e](https://github.com/ysoft-org/ysoft-admin/commit/f5ab22eedf594cee43592a2f29409ee9c33a88d3))
- 移除 monitor 模块 ([b6206a3](https://github.com/ysoft-org/ysoft-admin/commit/b6206a334671894306043f86ec07d7c045cd757d))
- top.charles7c.ysoft.admin => top.ysoft.admin ([08eeabc](https://github.com/ysoft-org/ysoft-admin/commit/08eeabc47d58db3cfc861a3a527e52bf89f6183b))
- 公告管理 Announcement => Notice ([dbe93df](https://github.com/ysoft-org/ysoft-admin/commit/dbe93df8bcec0b7dfb24fbd92f35928a3156f4e5))
### 📦 依赖升级
- ContiNew Starter 1.5.1 => 2.0.0 (更多依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v2.5.0](https://github.com/ysoft-org/ysoft-admin/compare/v2.4.0...v2.5.0) (2024-03-23)
### ✨ 新特性
* 新增 PostgreSQL 数据源配置示例 ([ee48c80](https://github.com/ysoft-org/ysoft-admin/commit/ee48c80cd10a4c4546d1cb24f1f4716bb2ac08ea))
* 新增 PostgreSQL 部署脚本 ([3129e0a](https://github.com/ysoft-org/ysoft-admin/commit/3129e0a6dcbd809f0013fbf6c53ad029ae9f7a0e))
* 新增 PostgreSQL 初始 SQL 脚本 ([33b8102](https://github.com/ysoft-org/ysoft-admin/commit/33b81029df0b51058b3525b4317b51a2351319dc))
* 新增代码生成器插件模块(后续会改造为独立插件) ([87829d3](https://github.com/ysoft-org/ysoft-admin/commit/87829d3ce8ab5a35091800900f7d7708f15ed9c2))
* 代码生成同步最新数据表结构支持同步排序 ([89546de](https://github.com/ysoft-org/ysoft-admin/commit/89546deced78f83daca7ac0ba2e7d3d8cd101d0c))
* 新增代码批量生成功能 ([Gitee PR#12](https://gitee.com/ysoft/ysoft-admin/pulls/12)) ([040f137](https://github.com/ysoft-org/ysoft-admin/commit/040f137934130451700bc28aeabbced30970c5f6))
### 💎 功能优化
- 移除 ` 符号的使用,保持数据库无关性 ([d6b07bd](https://github.com/ysoft-org/ysoft-admin/commit/d6b07bd6d1b1f9077a7571702b58c5e9c782b446))
- 优化字符串模板方法 API 使用 ([0f39384](https://github.com/ysoft-org/ysoft-admin/commit/0f393845a19432e7c965e811c96774694f4d2372))
- 调整部分 SQL 语句,以兼容 PostgreSQL 数据库 ([9f5049b](https://github.com/ysoft-org/ysoft-admin/commit/9f5049bf26c557738867dfe833261d60d071d4a8)) ([bf60d48](https://github.com/ysoft-org/ysoft-admin/commit/bf60d48d3a53dd5d73a78e73b6b230e3271ec3de))
- 新增插件仓库配置 ([0439252](https://github.com/ysoft-org/ysoft-admin/commit/04392524ac13c2096b549f99d0391fa1d375ca31))
- 优化部分接口响应格式为 kv 格式 ([b40d872](https://github.com/ysoft-org/ysoft-admin/commit/b40d872bc4b8dd30ad952d639158619b43cef999))
- 适配 Crane4j 条件注解 ([bf00747](https://github.com/ysoft-org/ysoft-admin/commit/bf007470b2362159309ff8231a2f0ad180cfc947))
- 重构代码生成配置 ([7031a51](https://github.com/ysoft-org/ysoft-admin/commit/7031a51cd4d7072d4da841736678bb81b2123e9d))
- 重构代码生成功能,由指定路径生成模式调整为下载模式,更方便复杂场景 ([df0c0dd](https://github.com/ysoft-org/ysoft-admin/commit/df0c0dd7dcf39620abaf21bd450620ec3fffcf37))
### 🐛 问题修复
- 修复 MySQL 初始 SQL 脚本数据错误 ([49d6bd6](https://github.com/ysoft-org/ysoft-admin/commit/49d6bd6874b3df66fd2e2051ea273cb43cb7b4f6))
- 修复参数缓存未及时过期的问题 ([976e9c4](https://github.com/ysoft-org/ysoft-admin/commit/976e9c43df5926c533723a75222c59fde05e122e))
- 修复代码生成 text 类型数据的长度校验时,数值显示为 65,535 的问题 ([8026f66](https://github.com/ysoft-org/ysoft-admin/commit/8026f660c7af7bba6d4caaf31535a890e5b40a96))
### 💥 破坏性变更
- 调整 liquibase 目录结构,更适合开源类项目适配多种数据库脚本场景 ([1ca48a6](https://github.com/ysoft-org/ysoft-admin/commit/1ca48a6620cff62f3648cc28042843163589e150))
- 适配 ContiNew Starter 日志及数据库工具的包结构优化 ([3405868](https://github.com/ysoft-org/ysoft-admin/commit/3405868c7f042beafb77a7407a388a40b9a75466))
- 适配 ContiNew Starter Query 组件的包结构优化 ([6be1b6c](https://github.com/ysoft-org/ysoft-admin/commit/6be1b6cfb1e7fef4422b8c38e6073a435ebae5c2))
### 📦 依赖升级
- ContiNew Starter 1.4.0 => 1.5.1 (更多依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v2.4.0](https://github.com/ysoft-org/ysoft-admin/compare/v2.3.0...v2.4.0) (2024-02-16)
### ✨ 新特性
* 集成 TLog轻量级的分布式日志标记追踪神器 ([Gitee PR#10](https://gitee.com/ysoft/ysoft-admin/pulls/10))
* 系统日志新增 traceId 链路号记录,方便查看完整日志链路 ([860ca40](https://github.com/ysoft-org/ysoft-admin/commit/860ca403c2c32cc6395c1608217bc9b6e7c18bd8))
* 取消用户默认密码,改为表单填写密码 ([3d77aa9](https://github.com/ysoft-org/ysoft-admin/commit/3d77aa91ee32065b53d9c47a57c33d6d7e4efb0e))
* 适配 ContiNew Starter 加密模块(安全模块) ([6435175](https://github.com/ysoft-org/ysoft-admin/commit/6435175dc3d853cb170270e39e8f1505adffeae5)) ([43da462](https://github.com/ysoft-org/ysoft-admin/commit/43da462560e224ed92f239cb5af4db64dea51d18))
* 适配 ContiNew Starter 脱敏模块(安全模块) ([2109789](https://github.com/ysoft-org/ysoft-admin/commit/2109789116d9ff18773d8afeb854d1dfc70b935a))
### 💎 功能优化
- 优化 API 文档分组配置 ([2df4cce](https://github.com/ysoft-org/ysoft-admin/commit/2df4cceedd35b1c2c07bcbf38b5a157604a752c2))
- 优化 QueryTypeEnum 枚举值命名 ([9648cf6](https://github.com/ysoft-org/ysoft-admin/commit/9648cf64a4679657f0e609f980805d274563aa53))
- 优化 Query 相关注解使用方式 ([15b1520](https://github.com/ysoft-org/ysoft-admin/commit/15b152008c6ae8ab89704d83a969dcfbbb8b5b88))
- 新增 Qodana 扫描 ([f6a9581](https://github.com/ysoft-org/ysoft-admin/commit/f6a9581adef87a8915639e6cb2d7c4d02315ebd0))
- 新增 SonarCloud 扫描 ([a154abd](https://github.com/ysoft-org/ysoft-admin/commit/a154abde8a39cfecc421c79e01998274b944d2c1)) ([c03c082](https://github.com/ysoft-org/ysoft-admin/commit/c03c082d2e2884962547633f5e98663088bd2c3b))
- 移除 Lombok 私有构造注解使用 ([a2420d3](https://github.com/ysoft-org/ysoft-admin/commit/a2420d3f4b4652a1d9711f513b8fb22a56105141))
- 获取不到当前登录用户信息则抛出未登录异常 ([d972a44](https://github.com/ysoft-org/ysoft-admin/commit/d972a4466a9e8a1a6e6375e4171a4790c2ba156e))
- 优化代码,解决 [Sonar](https://sonarcloud.io/organizations/charles7c/projects)、[Codacy](https://app.codacy.com/gh/ysoft-org/ysoft-admin/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)、[Qodana](https://qodana.cloud/organizations/pQDPD/teams/p5jqd/) 扫描问题点击各链接查看对应实时质量分析报告Codacy 已达到 A
- 优化部署配置 ([b5d668e](https://github.com/ysoft-org/ysoft-admin/commit/b5d668e014690d3f1a8a2bab0d0ad0039083e7bb))
- 使用密码编码器重构密码加密、密码判断等相关处理 ([594f7fd](https://github.com/ysoft-org/ysoft-admin/commit/594f7fd042f1ff96a298f2e59ffdda112113cb51))
- 优化 SaToken 及图形验证码配置 ([70973db](https://github.com/ysoft-org/ysoft-admin/commit/70973db71f2eed49c5878d69d8b93ff04b13a8b9))
- 优化图形验证码使用及部分配置 ([a50d857](https://github.com/ysoft-org/ysoft-admin/commit/a50d857c41d164355d36ae5dfd14c6badbe06202))
### 🐛 问题修复
- 修复 API 响应内容类型错误 ([439f7c7](https://github.com/ysoft-org/ysoft-admin/commit/439f7c7c58ee27ff56b5093df71bc902c46f48fa))
### 💥 破坏性变更
- 调整自增 ID 为分布式 ID ([4779887](https://github.com/ysoft-org/ysoft-admin/commit/4779887751bd3a696e4d31294057e8c03d66eaf3))
### 📦 依赖升级
- ContiNew Starter 1.2.0 => 1.4.0 (更多依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v2.3.0](https://github.com/ysoft-org/ysoft-admin/compare/v2.2.0...v2.3.0) (2024-01-21)
### ✨ 新特性
* 代码生成 Request 实体时,针对字符串类型增加数据长度校验注解 ([ee82558](https://github.com/ysoft-org/ysoft-admin/commit/ee8255876f618137f811e14ee305509e4e6466d0))
* 适配 Crane4j 数据填充组件,优化部分数据填充处理 ([d598408](https://github.com/ysoft-org/ysoft-admin/commit/d5984087a306de31690e9a81d951bd831434a0c9)) ([a2411f7](https://github.com/ysoft-org/ysoft-admin/commit/a2411f728a811910a0918668c0811e7df0345640)) ([7a3ccc2](https://github.com/ysoft-org/ysoft-admin/commit/7a3ccc2dee8f7b938a91df52fd4903ce09e662e5))
* 移除 Spring Cache适配 JetCache ([d4bb39d](https://github.com/ysoft-org/ysoft-admin/commit/d4bb39d9b4483b7d7fed76b5f2b997538d86d719)) ([1b7aa9d](https://github.com/ysoft-org/ysoft-admin/commit/1b7aa9db0c56af733f63f602988dba9e225fe445)) ([8596e47](https://github.com/ysoft-org/ysoft-admin/commit/8596e47ed62e19083d6007448c5369d72fa4f2b6))
### 💎 功能优化
- 优化本地存储库注册 ([918e897](https://github.com/ysoft-org/ysoft-admin/commit/918e897838628b24a160c3a8f3b3dea1eefd1883))
- 增加华为云镜像源仓库配置 ([16ee2b4](https://github.com/ysoft-org/ysoft-admin/commit/16ee2b4b6fe2a663830972ed99d4e80ddf5a3593))
- 优化部分字段名称 ([e3e958b](https://github.com/ysoft-org/ysoft-admin/commit/e3e958b419e1ea23fe146b255fce749050302f63))
- 调整代码生成前端 Vue 页面模板 ([7c34574](https://github.com/ysoft-org/ysoft-admin/commit/7c345745aadc6272e5f1db674c757ff0f9cea604))
- 更新格式配置,优化全局代码格式 ([35e3123](https://github.com/ysoft-org/ysoft-admin/commit/35e31233c531b68b761c73fc0daf7444843b4059))
- 优化配置文件格式 ([a8a4cad](https://github.com/ysoft-org/ysoft-admin/commit/a8a4cad840b6d32fbb8d3df24b193f9e7c826d22))
- 使用钩子方法优化部分增、删、改处理 ([61c5724](https://github.com/ysoft-org/ysoft-admin/commit/61c57242fa481d2668b1d1ac4ff4802c47fd07bc))
- 完善 flatten Maven 插件配置,以覆盖更多使用情况 ([657accd](https://github.com/ysoft-org/ysoft-admin/commit/657accd8a595ab0c2e9ff4d00e49c569eae03123))
- 移除部分无用 Maven 配置 ([5db1f66](https://github.com/ysoft-org/ysoft-admin/commit/5db1f669e0bc5022bcd2164757a0f82dfe8d6c30))
- 优化日志配置,滚动策略调整为基于日志文件大小和时间滚动 ([2fa8c25](https://github.com/ysoft-org/ysoft-admin/commit/2fa8c254fc53cda3d33c56931569822e645dd902))
### 🐛 问题修复
- 完善代码生成前端路径配置校验 ([bee04d5](https://github.com/ysoft-org/ysoft-admin/commit/bee04d5f363b6de88df5249b0fba85607978b303))
### 💥 破坏性变更
- 根据发展需要,拆分前端项目 ysoft-admin-ui 到独立仓库 ([4067eb9](https://github.com/ysoft-org/ysoft-admin/commit/4067eb97bf344dec6ae718433b57bdb7d0b8d6cd))
- PageDataResp => PageResp ([d8c946e](https://github.com/ysoft-org/ysoft-admin/commit/d8c946e8014d205c4fd3f38d1f04b3225faede7a))
- 适配 ContiNew Starter IService 接口CRUD 查询详情方法不再检查是否存在 ([47a133a](https://github.com/ysoft-org/ysoft-admin/commit/47a133a065b5c858b588bf77ad51bb9fc38d1222))
- 适配 ContiNew Starter CRUD 模块注解 ([7fa70e7](https://github.com/ysoft-org/ysoft-admin/commit/7fa70e74070c7c0f487baa5098f85d7dfb808106))
- 调整部分类的所在包 ([8dc42c7](https://github.com/ysoft-org/ysoft-admin/commit/8dc42c7a21e7422399b49690b28899df299e20c7)) ([6efe1ad](https://github.com/ysoft-org/ysoft-admin/commit/6efe1ad6f416c52130b2380a699129e7dae29499))
### 📦 依赖升级
- ContiNew Starter 1.1.0 => 1.2.0 (更多依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
## [v2.2.0](https://github.com/ysoft-org/ysoft-admin/compare/v2.1.0...v2.2.0) (2023-12-31)
### ✨ 新特性
* 发送短信验证码新增限流处理 ([e719d20](https://github.com/ysoft-org/ysoft-admin/commit/e719d207fb76c82b584f2e1ac7210061dc71a89a))
* 代码生成新增生成预览功能 ([4017029](https://github.com/ysoft-org/ysoft-admin/commit/401702972f30c4e556a2cf8d048f78fa9ee1c5ba)) ([505ba49](https://github.com/ysoft-org/ysoft-admin/commit/505ba49a5304fb3e2ba655dea901cd5e3ea74673))
* 适配 ContiNew Starter 行为验证码,系统内所有短信发送新增前置行为验证码验证 ([Gitee PR#9](https://gitee.com/ysoft/ysoft-admin/pulls/9))
* 文件管理:提供文件上传、下载、预览(目前支持图片、音视频)、重命名、切换视图(列表、网格)等功能
* 存储库管理:提供文件存储库新增、编辑、删除、导出等功能
### 💎 功能优化
- 优化 API 文档配置 ([108f1c4](https://github.com/ysoft-org/ysoft-admin/commit/108f1c4ae7b855ac0bab2d3fe028270472a8be71))
- 调整枚举配置值为大写 ([3ece42b](https://github.com/ysoft-org/ysoft-admin/commit/3ece42b94e071ece87e6b4616f7817bf851ba28f))
- 优化由于 Mock 引起的导出报错提示 ([349899b](https://github.com/ysoft-org/ysoft-admin/commit/349899b4fc9572450ca31d9a5e19268ce0b868a8))
- 优化查询访客地域分布信息接口 SQL ([4df887d](https://github.com/ysoft-org/ysoft-admin/commit/4df887d82678ced0d30aa0c7a6f92edcac902052))
- 调整后端部分方法名 save => add ([45bd3e1](https://github.com/ysoft-org/ysoft-admin/commit/45bd3e10b6ac6aecde41ff9484668e557a485b27))
- 优化系统日志详情 ([55effa3](https://github.com/ysoft-org/ysoft-admin/commit/55effa36580a57ddedb688e2ce30bec45c761224)) ([99997c1](https://github.com/ysoft-org/ysoft-admin/commit/99997c160eefc152a6f4e74bcd9c5ef6fc77a9c5))
- 移除部分方法中仅有单个非读操作的事务处理 ([b85d692](https://github.com/ysoft-org/ysoft-admin/commit/b85d69298de1a6c48d15300bb9ff1b3ea569fdbd))
- 优化编译配置 ([ed8bb57](https://github.com/ysoft-org/ysoft-admin/commit/ed8bb57fe24dfbe8f45b8f53370ebb79f1511268))
- 优化配置文件格式 ([3399bc8](https://github.com/ysoft-org/ysoft-admin/commit/3399bc8dde0c8c8ac6d3e583ffbe299f7e6dd80b))
### 🐛 问题修复
- 修复代码生成相关错误 ([3fdc50d](https://github.com/ysoft-org/ysoft-admin/commit/3fdc50d78ec50a878cec2b35c7d5028e741c42d7))
- 更新仪表盘帮助文档部分过期链接 ([ac42836](https://github.com/ysoft-org/ysoft-admin/commit/ac4283679a847ed372db28aae1ea05fd791651b8))
### 💥 破坏性变更
- 适配 ContiNew Starter QueryTypeEnum 命名变更 ([97c273f](https://github.com/ysoft-org/ysoft-admin/commit/97c273f99ecb038e041e3d39dbfacf326d49cc1b))
- 适配 ContiNew Starter Log HttpTracePro日志模块 ([9bf0150](https://github.com/ysoft-org/ysoft-admin/commit/9bf015059b96f41c29f05ecbf7612d611b3a98c3))
- 适配 ContiNew Starter 全局异常处理器 ([4ed4ddd](https://github.com/ysoft-org/ysoft-admin/commit/4ed4ddd4f055cefe1f85482bd6b9ef760978691b))
- 适配 ContiNew Starter 数据权限解决方案(数据访问模块-MyBatis Plus ([0849426](https://github.com/ysoft-org/ysoft-admin/commit/084942630ab0e1846c1836b8dc4bf5b2c9a5b16e))
- 调整 IBaseEnum 所属包 ([e6c6e1c](https://github.com/ysoft-org/ysoft-admin/commit/e6c6e1cb0e326c5f531ca5cb2e17a1e26efac7d9))
- 重构原有文件上传接口并优化配置文件配置格式 ([5e37025](https://github.com/ysoft-org/ysoft-admin/commit/5e370254dd00deaab62438c5feb4de14192ad7e6))
### 📦 依赖升级
- ContiNew Starter 1.0.0 => 1.1.0 ([fc80921](https://github.com/ysoft-org/ysoft-admin/commit/fc80921c047862b424ca625317f4657667bc2c6b)) (更多依赖升级详情,请查看 ContiNew Starter [更新日志](https://github.com/ysoft-org/ysoft-starter/blob/dev/CHANGELOG.md))
- Arco Design Vue 2.53.0 => 2.53.3 ([2720275](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb))
- Vite 4.5.0 => 4.5.1 ([2720275](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb))
- TypeScript 5.2.2 => 5.3.3 ([2720275](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb))
- unplugin-vue-components 0.25.2 => 0.26.0 ([2720275](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb))
- @kangc/v-md-editor 2.3.17 => 2.3.18 ([2720275](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb))
- eslint 8.53.0 => 8.56.0 ([2720275](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb))
- @vueuse/core 10.5.0 => 10.7.0 ([2720275](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb))
- vue-i18n 9.6.5 => 9.8.0 ([2720275](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb))
- vue-json-pretty 2.2.4 => 2.3.0 ([2720275](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb))
- 由于篇幅限制,仅列出部分前端依赖升级情况,更多请查看 [提交记录](https://github.com/ysoft-org/ysoft-admin/commit/2720275b97334545dde71d548173bfcda7e660cb)
## [v2.1.0](https://github.com/ysoft-org/ysoft-admin/compare/v2.0.0...v2.1.0) (2023-12-03)
### 💎 功能优化
- 优化数据权限注解 ([bb59a78](https://github.com/ysoft-org/ysoft-admin/commit/bb59a78573bec521e8852f1c88ce6078fb14b14e))
- 回退全局响应结果处理器 ([c7a4e32](https://github.com/ysoft-org/ysoft-admin/commit/c7a4e329945d8368a9b93a2488c059cf3333feba))
- 优化字典 Controller CRUD 注解使用 ([8c1c4b0](https://github.com/ysoft-org/ysoft-admin/commit/8c1c4b014463d073e848e2f2abc33e089efa2abb))
- 优化常量命名风格XxxConsts => XxxConstants ([ec28705](https://github.com/ysoft-org/ysoft-admin/commit/ec28705b6ff6dd26ec3ef673fb3827259f1b9c41))
- 移除 XML 文件头部的协议信息 ([b476956](https://github.com/ysoft-org/ysoft-admin/commit/b47695603afb0c19679c4100c1e3c23bc8007238))
- 优化菜单标题校验 ([3dd81a1](https://github.com/ysoft-org/ysoft-admin/commit/3dd81a1192c4e340dad0b1bae5e29d1d7218fb25))
### 🐛 问题修复
- 修复 mock 被错误关闭的问题 ([a34070f](https://github.com/ysoft-org/ysoft-admin/commit/a34070ffed3044ad2bea604701b074665e7b4e42))
- 修复保存生成配置校验失效的问题,并优化部分提示效果 ([c34e934](https://github.com/ysoft-org/ysoft-admin/commit/c34e934bb553d7f814d0fb5aa87eac0f565289b4))
### 💥 破坏性变更
- 项目包结构 top.charles7c.cnadmin => top.charles7c.ysoft.admin ([b86fe32](https://github.com/ysoft-org/ysoft-admin/commit/b86fe329d07317fed6a7d0b7015856de4b9e75d1))
- 适配 ContiNew Starter 全局错误处理配置 ([b62095d](https://github.com/ysoft-org/ysoft-admin/commit/b62095d66e2318d35e4af07b128203b5a5e016f7))
- 适配 ContiNew Starter CRUD扩展模块 ([ce5a2ec](https://github.com/ysoft-org/ysoft-admin/commit/ce5a2ec9319b86e69a6bda67a886e1c96079ffc2))
- 适配 ContiNew Starter Mail消息模块 ([ce785dd](https://github.com/ysoft-org/ysoft-admin/commit/ce785ddce28733eeefbf970ed08b01e36e0abd4b))
- 适配 ContiNew Starter Excel文件处理模块 ([1311ae3](https://github.com/ysoft-org/ysoft-admin/commit/1311ae3603a26dc44dfffc5be86ea1ab81ff7958))
- 适配 ContiNew Starter 认证模块-JustAuth ([7ad8d17](https://github.com/ysoft-org/ysoft-admin/commit/7ad8d1773a8e50e37a326b8f73f9ba38a3a7ff3a)) ([f28fbd1](https://github.com/ysoft-org/ysoft-admin/commit/f28fbd14fa83a82df49b07f16070e0ff3385b0ec))
- 适配 ContiNew Starter 认证模块-SaToken ([86ca8f0](https://github.com/ysoft-org/ysoft-admin/commit/86ca8f094ff6d1c00b52c1406985bc00105b297f))
- 适配 ContiNew Starter 图形验证码 ([8a11a02](https://github.com/ysoft-org/ysoft-admin/commit/8a11a020e04e271da7b700b5d73cf8475b50ee5c))
- 适配 ContiNew Starter MyBatis Plus 自动配置 ([7306cd9](https://github.com/ysoft-org/ysoft-admin/commit/7306cd9d2f9492aa39e11b8f0dc8c7c11b534a3f))
- 适配 ContiNew Starter Redisson 自动配置 ([a40e609](https://github.com/ysoft-org/ysoft-admin/commit/a40e609ea14acda840d2771f05ca9690d41236a1))
- 适配 ContiNew Starter Jackson、API 文档Knife4jSpring Doc自动配置 ([a86f3a5](https://github.com/ysoft-org/ysoft-admin/commit/a86f3a5047eda2f67cc9ad7721006d2db1fd710f))
- 适配 ContiNew Starter 线程池自动配置 ([ec1daaf](https://github.com/ysoft-org/ysoft-admin/commit/ec1daaf0456296dbc3704ae700b9577001bdd5bb))
- 引入 ContiNew Starter适配跨域自动配置 ([2c4f511](https://github.com/ysoft-org/ysoft-admin/commit/2c4f5116c999b9316ab0bee4fa661338fea63c11))
- 项目 group id top.charles7c => top.charles7c.ysoft ([3e23acb](https://github.com/ysoft-org/ysoft-admin/commit/3e23acb3e257d5813b858356aa926a96c906acf1))
## [v2.0.0](https://github.com/ysoft-org/ysoft-admin/compare/v1.3.1...v2.0.0) (2023-11-15)
### 💎 功能优化
- 优化部分代码格式 ([2f87310](https://github.com/ysoft-org/ysoft-admin/commit/2f87310bc886af604a2667285a973ec6ae983430))
- 优化 401 状态处理逻辑 ([c70e28a](https://github.com/ysoft-org/ysoft-admin/commit/c70e28a535c78214fe8d68a09824c786c457ef06))
- 优化超时登录处理逻辑 ([d5da184](https://github.com/ysoft-org/ysoft-admin/commit/d5da1847e33e6cd7a0e5c3434335044167c1241c))
### 🐛 问题修复
- sms4j 3.0.3 => 3.0.4 ([23558d4](https://github.com/ysoft-org/ysoft-admin/commit/23558d45620a48ed82b32a5bdd2f948a4a37263d))
- 发送消息增加事务处理 ([Gitee#7](https://gitee.com/ysoft/ysoft-admin/pulls/7)) ([1ca6f6c](https://github.com/ysoft-org/ysoft-admin/commit/1ca6f6c7e5f8a7c78f74df547f14517293241ac4))
- 修复前端控制台 eslint 告警 ([Gitee#6](https://gitee.com/ysoft/ysoft-admin/pulls/6)) ([f4523d2](https://github.com/ysoft-org/ysoft-admin/commit/f4523d24817b4fee5c015eaba6b98fe99f350bba)) ([2304f28](https://github.com/ysoft-org/ysoft-admin/commit/2304f28a942fa8ea3e6d36fbebbe9346b0d3b741))
- 修复仪表盘访问趋势区块 y 轴数值过大时无法展示的问题 ([fea6024](https://github.com/ysoft-org/ysoft-admin/commit/fea602439a3c9589bee078bfa9ff1e7efb378d71))
- 修复控制台报错 Please use theme before using plugins ([98fbe05](https://github.com/ysoft-org/ysoft-admin/commit/98fbe0506c1cbe2f3c16347d9610ebfa5688b506))
- 调整 Logback 配置,取消启动时打印 Logback 状态日志 ([1f7fef5](https://github.com/ysoft-org/ysoft-admin/commit/1f7fef5b31212e94652777be37bea4d4e02eb8c7))
### 💥 破坏性变更
- 优化部署相关脚本mariadb => mysql ([5f4f0f1](https://github.com/ysoft-org/ysoft-admin/commit/5f4f0f1b21fe882dc51801d7c508c10b87d7af36))
- 适配 Java 16 新特性 ([cf30443](https://github.com/ysoft-org/ysoft-admin/commit/cf3044312c8631a8c2b306e466e3d4d663d8eb6d))
- 适配 Java 14 新特性 ([38f52aa](https://github.com/ysoft-org/ysoft-admin/commit/38f52aaafa22ebc958a22b7c38b084c655064fbc))
- 适配 Java 11 新特性 ([5a5bd16](https://github.com/ysoft-org/ysoft-admin/commit/5a5bd1681e076ac6814d552da5415a8f154b93af))
- 升级前端依赖 ([79fa2c8](https://github.com/ysoft-org/ysoft-admin/commit/79fa2c8abcf5f70f96ae7c6de35c47dbae76ee2d)) ([c44162d](https://github.com/ysoft-org/ysoft-admin/commit/c44162d431cb87cae251067fff9a5ae707aed9b3))
- Arco Design Vue 2.52.0 => 2.53.0
- Vue 3.3.4 => 3.3.7
- Vite 3.2.7 => 4.5.0
- vue-router 4.2.4 => 4.2.5
- vue-i18n 9.5.0 => 9.6.5
- vue-tsc 1.2.0 => 1.8.22
- @vueuse/core 9.13.0 => 10.5.0
- pinia 2.1.6 => 2.1.7
- rollup 3.20.2 => 4.3.0
- vue-cropper 1.0.9 => 1.1.1
- crypto-js 4.1.1 => 4.2.0
- vite-svg-loader 3.6.0 => 4.0.0
- highlight.js 11.8.0 => 11.9.0
- mitt 3.0.0 => 3.0.1
- consola 2.15.3 => 3.2.3
- prettier 2.8.7 => 3.0.3
- less 4.1.3 => 4.2.0
- eslint 8.48.0 => 8.53.0
- stylelint 15.10.3 => 15.11.0
- lint-staged 13.2.0 => 3.0.3
- 升级后端依赖 ([dea160a](https://github.com/ysoft-org/ysoft-admin/commit/dea160a7b2d69e1b46edc936c9a697048bbb507a)) ([95c27ea](https://github.com/ysoft-org/ysoft-admin/commit/95c27ea323e015c915d352618158df830b4d1c05)) ([fa23287](https://github.com/ysoft-org/ysoft-admin/commit/fa232874aa88ab14fdc669e54a907e5ef05d2a7e)) ([8dbec9d](https://github.com/ysoft-org/ysoft-admin/commit/8dbec9d1a3bcb0f6d7ef4bbfb9715effd61b2025)) ([3bd56d8](https://github.com/ysoft-org/ysoft-admin/commit/3bd56d8a1ee274aac6d4ea57d61f6d470de0dc9c)) ([7b741d5](https://github.com/ysoft-org/ysoft-admin/commit/7b741d5f8c42d154c5b325326d0cc954fb566502))
- Spring Boot 2.7.16 => 3.0.5 => 3.1.5
- javax.* => jakarta.*
- ServletUtil => JakartaServletUtilHutool
- 其他配置变更
- JDK 8 => JDK 17
- Sa-Token 1.36.0 => 1.37.0(适配 Spring Boot 3.x
- MyBatis Plus 3.5.3.2 => 3.5.4(适配 Spring Boot 3.x
- Dynamic Datasource 3.6.1 => 4.2.0(适配 Spring Boot 3.x
- Redisson 3.20.1 => 3.24.3(适配 Spring Boot 3.x
- Knife4j 适配 Spring Boot 3.x
- ip2region 2.7.15 => 3.1.5.1(适配 Spring Boot 3.x
- spotless 2.30.0 => 2.40.0
## [v1.3.1](https://github.com/ysoft-org/ysoft-admin/compare/v1.3.0...v1.3.1) (2023-11-15)
### 💎 功能优化
- 完善 Redis 部署配置 ([39969eb](https://github.com/ysoft-org/ysoft-admin/commit/39969ebf6173fc379dc3501e9204a344d1cf62cf))
- 优化 401 状态处理逻辑 ([8820c1d](https://github.com/ysoft-org/ysoft-admin/commit/8820c1dfc858b9ef9df470e90dfe9ba4b1166e29))
- 优化超时登录处理逻辑 ([712eedb](https://github.com/ysoft-org/ysoft-admin/commit/712eedba1be0ec371119745d4596cd35c2ce25d6))
- 优化部分变量命名 ([f15494d](https://github.com/ysoft-org/ysoft-admin/commit/f15494d34823ded87efc396d98e2eb0108f74a3d))
### 🐛 问题修复
- sms4j 3.0.3 => 3.0.4 ([3fcdb54](https://github.com/ysoft-org/ysoft-admin/commit/3fcdb54442b380e76838478fa46e8dfb70a2759b))
- 发送消息增加事务处理 ([5d159c6](https://github.com/ysoft-org/ysoft-admin/commit/5d159c6ab337a9432419d84cf246cff506500567))
- 修复仪表盘访问趋势区块 y 轴数值过大时无法展示的问题 ([47a5746](https://github.com/ysoft-org/ysoft-admin/commit/47a5746794e552faf9c41fbcc21af091a878eb95))
- 修复控制台报错 Please use theme before using plugins ([47a8160](https://github.com/ysoft-org/ysoft-admin/commit/47a8160d70862a5ee7284c165004cece2714a10f))
- 修复 Swagger 分组接口缺失 ([b63d7d7](https://github.com/ysoft-org/ysoft-admin/commit/b63d7d725da5e9e9b2db9fd59bd140d64b50040c))
## [v1.3.0](https://github.com/ysoft-org/ysoft-admin/compare/v1.2.0...v1.3.0) (2023-11-04)
### ✨ 新特性
* 消息管理:提供消息查看、标记已读、全部已读、删除等功能(适配对接导航栏站内信功能)
* 新增头像上传前裁剪功能 ([Gitee#5](https://gitee.com/ysoft/ysoft-admin/pulls/5)) ([cbc652d](https://gitee.com/ysoft/ysoft-admin/commit/cbc652de77200d29bcd42bb399c86c2e7df29c4d)) ([28f4791](https://gitee.com/ysoft/ysoft-admin/commit/28f4791833060469d132c4383665e81458f9c852))
* 支持手机号登录(演示环境不开放) ([4d70bc8](https://github.com/ysoft-org/ysoft-admin/commit/4d70bc84db47c36c13d8e41e3a33e5a589483de8))
* 支持邮箱登录 ([17b169e](https://github.com/ysoft-org/ysoft-admin/commit/17b169eb0ea2ded759b6bccb213c78bfb3425941))
* 个人中心-安全设置,支持绑定、解绑三方账号 ([efe4557](https://github.com/ysoft-org/ysoft-admin/commit/efe455736c158e73bf0c6514c31bec5d83fe843b))
* 支持第三方账号登录 ([05cb609](https://github.com/ysoft-org/ysoft-admin/commit/05cb60978017edbd14f1c7af83053f8a91800b5c))
### 💎 功能优化
- 新增接口文档菜单,演示环境开放接口文档 ([4a42336](https://github.com/ysoft-org/ysoft-admin/commit/4a4233647f2ea212b007f591aafc50380b15c099))
- 项目配置增加是否为生产环境配置项 ([38deb95](https://github.com/ysoft-org/ysoft-admin/commit/38deb950ac7b2ed81f0e10816e943156aa076795))
- 优化校验相关方法命名 ([f25de2d](https://github.com/ysoft-org/ysoft-admin/commit/f25de2d7f835a3fa75d59d3de0a014c37b3b32e1))
- 新增全局响应结果处理器 ([Gitee#3](https://gitee.com/ysoft/ysoft-admin/pulls/3)) ([992a8fc](https://gitee.com/ysoft/ysoft-admin/commit/992a8fca173ea76722b388aca462cff8a1128803)) ([Gitee#4](https://gitee.com/ysoft/ysoft-admin/pulls/4)) ([a0b1afc](https://gitee.com/ysoft/ysoft-admin/commit/a0b1afc546657766cb6031794b98ccc2b6e4cb2d))
- 优化部分代码格式及注释 ([3a176ac](https://github.com/ysoft-org/ysoft-admin/commit/3a176ac5efbda4aea1e883b29e68861bd352d642))
- 重构登录页面 UI 以适配多维度认证、第三方登录等场景 ([d40d5b4](https://github.com/ysoft-org/ysoft-admin/commit/d40d5b4ae61d858fbee3ffa0606ebebb4282d9a2)) ([a5a4cd4](https://github.com/ysoft-org/ysoft-admin/commit/a5a4cd49646db3fa1108a8b917ef70c7757e81ad))
- 升级前端依赖 ([698a725](https://github.com/ysoft-org/ysoft-admin/commit/698a7251b742e6b679694f21bfc174904dca8990))
- Arco Design Vue 2.51.0 => 2.52.0
- vue-i18n 9.2.2 => 9.5.0
- dayjs 1.11.9 => 1.11.10
- 升级后端依赖 ([698a725](https://github.com/ysoft-org/ysoft-admin/commit/698a7251b742e6b679694f21bfc174904dca8990))
- Spring Boot 2.7.15 => 2.7.16
- Sa-Token 1.35.0.RC => 1.36.0
- Hutool 5.8.20 => 5.8.22
### 🐛 问题修复
- 开放前端项目IP访问 ([22a291d](https://github.com/ysoft-org/ysoft-admin/commit/22a291d4cf48e33dc2415e44b5d991b46451e7eb))
- 修复获取验证码倒计时显示 ([2f2905e](https://github.com/ysoft-org/ysoft-admin/commit/2f2905efdc0baec2f2c38f686f72306394801ebf))
- 用户邮箱信息增加脱敏处理 ([5bb35a1](https://github.com/ysoft-org/ysoft-admin/commit/5bb35a13d6b5801317a295eacc67d88b2c3e1682))
- 修复重载校验方法定义及使用错误 ([a1ccc42](https://github.com/ysoft-org/ysoft-admin/commit/a1ccc421c440e5fef54e5d22b9bed26d2b16dda5))
- 修复个人中心密码设置状态显示错误的问题 ([b04a228](https://github.com/ysoft-org/ysoft-admin/commit/b04a228a1a5bc0a575dd9e29e515285708b8ca85))
- 修复登录后访问首页却跳转到登录页面的问题 ([Fixes #23](https://github.com/ysoft-org/ysoft-admin/issues/23)) ([7cf5e00](https://github.com/ysoft-org/ysoft-admin/commit/7cf5e0018c87720303f731317b5eb3cb7d127327))
- 修复字典名称表单校验 ([#22](https://github.com/ysoft-org/ysoft-admin/pull/22)) ([c0ee2ea](https://github.com/ysoft-org/ysoft-admin/commit/c0ee2eac026d2d5a950a41b6f0a475b95b71d47a))
### 💥 破坏性变更
- 调整后端请求、响应参数模型命名风格 ([87f9056](https://github.com/ysoft-org/ysoft-admin/commit/87f90567dbd99f873aea1b85510c7b9939a2abb8))
- 枚举接口 BaseEnum => IBaseEnum ([f5e8b09](https://github.com/ysoft-org/ysoft-admin/commit/f5e8b0943c6076c476b7d78bb623707740fb452f))
- 优化前端登录模块 API 路径 ([43590bf](https://github.com/ysoft-org/ysoft-admin/commit/43590bf66e7e4873a85bdd416bd38b269f3af80e))
- 优化后端部分参数模型命名 ([51f5528](https://github.com/ysoft-org/ysoft-admin/commit/51f552892ccb11ed594bf908069a1fd426324b69))
- 优化个人中心路由地址 ([36d52d3](https://github.com/ysoft-org/ysoft-admin/commit/36d52d3e1522cd221cf3f03d76efd3e0eaf1b18f))
- 还原前端 loginStore 命名,重命名为 userStore ([8d39493](https://github.com/ysoft-org/ysoft-admin/commit/8d394937cfc8418799215bd3659d26bed1f834c5))
## [v1.2.0](https://github.com/ysoft-org/ysoft-admin/compare/v1.1.2...v1.2.0) (2023-09-24)
### ✨ 新特性
* 字典管理:提供对系统公用数据字典的维护,例如:公告类型,支持字典标签背景色和排序等配置
* 系统配置提供修改系统标题、Logo、favicon 等基础配置功能,以方便用户系统与其自身品牌形象保持一致
* 完善仪表盘最近访问区块内容 ([36fda57](https://github.com/ysoft-org/ysoft-admin/commit/36fda57d499b0c3fb092a13f269bc9ffb7a26a9e))
* 完善仪表盘访问趋势区块内容 ([a1c20af](https://github.com/ysoft-org/ysoft-admin/commit/a1c20afb1b9eb447f62bfd2e4f2996dfdf37c8ca)) ([1722133](https://github.com/ysoft-org/ysoft-admin/commit/1722133ac4872b40d6d47f65f359dea8a354b91a))
* 完善仪表盘访客地域分布区块内容 ([dc1691f](https://github.com/ysoft-org/ysoft-admin/commit/dc1691f0195ef6c96aee36f50fc7e86cfcf651b9))
* 完善仪表盘热门模块区块内容 ([83b2e2a](https://github.com/ysoft-org/ysoft-admin/commit/83b2e2a7c02d38c7041497e0ac5b3b0e78abac29))
* 完善仪表盘总计区块内容 ([3440aa4](https://github.com/ysoft-org/ysoft-admin/commit/3440aa4faa23e267735f564476d8bccaf8c0208f))
* 完善仪表盘快捷操作区块内容 ([0178fbb](https://github.com/ysoft-org/ysoft-admin/commit/0178fbb89a0e75729aa60443a812496bd5b19cb8))
### 💎 功能优化
- 前端表单重置优化 ([e947312](https://github.com/ysoft-org/ysoft-admin/commit/e947312f244d6af01f18b542ff7395440c68b089))
- 优化登录和菜单加载相关提示 ([d080120](https://github.com/ysoft-org/ysoft-admin/commit/d080120d4228e77200d8f152397b0ebee413b089))
- 完善前后端校验 ([90d825a](https://github.com/ysoft-org/ysoft-admin/commit/90d825a02fdc54e8685508a6fe4fb2d5f20e77f4)) ([8e506dc](https://github.com/ysoft-org/ysoft-admin/commit/8e506dc6e69529627a0aace6118f7310cc2f030a))
- 优化枚举字典处理,增加颜色类型 ([1f73aa7](https://github.com/ysoft-org/ysoft-admin/commit/1f73aa732d101c7f7a58bc678e85d597d54d9770))
- 公告类型适配字典数据 ([3a3a5d6](https://github.com/ysoft-org/ysoft-admin/commit/3a3a5d6b712f435d77ea04301afa0bdd8703567f))
- 优化通用查询注解多字段模糊查询 ([3758107](https://github.com/ysoft-org/ysoft-admin/commit/375810772aa8cb928fb1f6820e781cb43f869e03))
- 合并菜单管理图标和标题列 ([36d38ae](https://github.com/ysoft-org/ysoft-admin/commit/36d38aec1602f5ac6d2afbb5c5adf4d6e455ab97))
- 封装 Spring Boot 默认错误处理 ([b874ca0](https://github.com/ysoft-org/ysoft-admin/commit/b874ca0782eb116bdedfc08023959a977f170a94))
- 优化分页查询登录日志列表接口实现 ([566c9a1](https://github.com/ysoft-org/ysoft-admin/commit/566c9a122453980b585bd68442bb545073504a3d))
- 更换登录页面 banner ([6f19660](https://github.com/ysoft-org/ysoft-admin/commit/6f19660cfbc3be6e0d702e3f488e266c50622f0a))
- 优化登录用户信息角色相关信息命名 ([be394f3](https://github.com/ysoft-org/ysoft-admin/commit/be394f3de4ea7ea692042db3556f706a3d141b51)) ([31f0abb](https://github.com/ysoft-org/ysoft-admin/commit/31f0abbae2e38d1cfa3f6221c9be0b54cf5337ad))
- 升级前端依赖 ([c665902](https://github.com/ysoft-org/ysoft-admin/commit/c6659020f8bac7319c5c407389cd745527a8cd97))
- 升级后端依赖 ([5049e1e](https://github.com/ysoft-org/ysoft-admin/commit/5049e1e312ab500e284abccbbee4186db2710d01)) ([d20aadf](https://github.com/ysoft-org/ysoft-admin/commit/d20aadfc93b54339d19d173fce364310e90b016d)) ([32904b5](https://github.com/ysoft-org/ysoft-admin/commit/32904b54ef63536ef5c5106adc00a7376b907632))
### 🐛 问题修复
- 修复删除列表数据后 Select 选择框重置问题 ([#21](https://github.com/ysoft-org/ysoft-admin/pull/21)) ([3288f2d](https://github.com/ysoft-org/ysoft-admin/commit/3288f2d38dfebc1381842d67cdfb17675c786859))
- 修复前端部分拼写错误 ([62021f8](https://github.com/ysoft-org/ysoft-admin/commit/62021f8fdc171ad04d07c25c5a9357a64cc4a087))
### 💥 破坏性变更
- 优化系统内置类型数据标识 ([8a02401](https://github.com/ysoft-org/ysoft-admin/commit/8a02401a24b546f2a6aab04cf05371ecb4236ca0))
- 分离 HTTP 状态码和业务状态码 ([b3b6446](https://github.com/ysoft-org/ysoft-admin/commit/b3b6446433972422cf62dfc47c031134b91cd7ec))
- 调整生产环境本地存储、日志位置 ([2254e55](https://github.com/ysoft-org/ysoft-admin/commit/2254e555af9cade4897d5335b252a0312d6805eb))
- 调整项目打包结构,分离依赖、配置文件 ([e679abf](https://github.com/ysoft-org/ysoft-admin/commit/e679abfccc6c80198512958b6d07b363074d9d76))
## [v1.1.2](https://github.com/ysoft-org/ysoft-admin/compare/v1.1.1...v1.1.2) (2023-09-24)
### 💎 功能优化
- 优化后端程序启动成功输出内容 ([6322859](https://github.com/ysoft-org/ysoft-admin/commit/63228598d9fcd6e5d00172c12418a371d4c96766))
- 配置子级菜单图标 ([5544836](https://github.com/ysoft-org/ysoft-admin/commit/55448364a39085debb776463f5e95a15b186c447))
### 🐛 问题修复
- 修复生产环境和开发环境样式不一致的问题 ([be8732d](https://github.com/ysoft-org/ysoft-admin/commit/be8732d812e021631864b0ff6225b4da24cafcee))
- 排除路径配置放开 /error ([0428fe7](https://github.com/ysoft-org/ysoft-admin/commit/0428fe776224afb64601901cef4d3100e5d30bd6))
- 修复初始数据缺失字段列表的问题 ([d5138e1](https://github.com/ysoft-org/ysoft-admin/commit/d5138e1e43bdc8b347e061890131ac2646b2dd3c))
- 修复系统日志表索引缺失导致查询耗时较长的问题 ([ac43833](https://github.com/ysoft-org/ysoft-admin/commit/ac438337219f5a160d49b255805774da36ab865c))
- 修复部分菜单数据 component 信息配置错误 ([11ea072](https://github.com/ysoft-org/ysoft-admin/commit/11ea072d600f24fe97fe8145208e821712b84839))
- 修复图标 SVG 内容格式错误 ([20f1e8a](https://github.com/ysoft-org/ysoft-admin/commit/20f1e8aecc737b28ab869d363957513d868b4ab7))
## [v1.1.1](https://github.com/ysoft-org/ysoft-admin/compare/v1.1.0...v1.1.1) (2023-09-06)
### 💎 功能优化
- 调整 Mock 响应时长,以解决前端偶发需重复登录问题 ([df19c5d](https://github.com/ysoft-org/ysoft-admin/commit/df19c5d2197fabb61cbdd4dccf1c427fb23d77d4))
### 🐛 问题修复
- 还原登录 Helper 优化(导致重大登录问题及查询在线用户错误) ([#15](https://github.com/ysoft-org/ysoft-admin/pull/15)) ([7a6db2d](https://github.com/ysoft-org/ysoft-admin/commit/7a6db2d14e60a5fcc1a2786e6eaa3d46a0714e6c)) ([#9](https://github.com/ysoft-org/ysoft-admin/pull/9)) ([9e2a5ef](https://github.com/ysoft-org/ysoft-admin/commit/9e2a5ef1249fd93dd10f2c255bf77c3eaa64a241))
- 修复刷新页面后,选中菜单无法保持展开状态的问题 ([3fc7adb](https://github.com/ysoft-org/ysoft-admin/commit/3fc7adb1e2bd4b648753bd2999df725417e01680))
- 修复侧边栏菜单无法显示自定义图标的问题 ([10ca5d8](https://github.com/ysoft-org/ysoft-admin/commit/10ca5d8c76aa39a207ea7db4442bf63ff4578273))
- 更正 README 文档项目结构部分内容 ([486da2f](https://github.com/ysoft-org/ysoft-admin/commit/486da2f79bfc5379213bf666b8f325fb8096ebc6))
- 修复公告缺失待发布状态的问题 ([#14](https://github.com/ysoft-org/ysoft-admin/pull/14)) ([46cc4c9](https://github.com/ysoft-org/ysoft-admin/commit/46cc4c9307e3cc7060ae436f59f007831104884a))
## [v1.1.0](https://github.com/ysoft-org/ysoft-admin/compare/v1.0.1...v1.1.0) (2023-09-01)
### ✨ 新特性
* 公告管理:提供公告的发布、查看和删除等功能。管理员可以在后台发布公告,并可以设置公告的生效时间、终止时间,以 markdown-it 为内核渲染 Markdown 格式内容显示
* 代码生成:提供根据数据库表自动生成相应的前后端 CRUD 代码的功能
* 允许表格调整列宽,不允许新增/修改类表单对话框按 Esc 关闭 ([1b06a96](https://github.com/ysoft-org/ysoft-admin/commit/1b06a96cfbe5774931d8c4c0d7827703caa096df))
### 💎 功能优化
- 最终适配及启用 Arco Design Pro Vue 动态路由 ([9baf341](https://github.com/ysoft-org/ysoft-admin/commit/9baf3410138cb8a152ec51f70340d500fa009510))
- 优化分页总记录数数据类型 ([bfea689](https://github.com/ysoft-org/ysoft-admin/commit/bfea689b0eaf44c8d54b4fd59c042d72ac71e395))
- 修复在线用户列表等自定义分页查询 NPE 的问题 ([015ff55](https://github.com/ysoft-org/ysoft-admin/commit/015ff5512b3662efce88d02ab1dda6d55501a501))
- 对获取路由信息接口增加缓存处理 ([4639d13](https://github.com/ysoft-org/ysoft-admin/commit/4639d13ba61abfaed3c9d3da0e057892577b5c40))⚡
- 完善前端 axios 请求响应拦截器 ([bb398d8](https://github.com/ysoft-org/ysoft-admin/commit/bb398d8101e3780f450c6508852fc727fb936cee)) ([e18692f](https://github.com/ysoft-org/ysoft-admin/commit/e18692fa74e0a0d9558db6643b945c6c6a00db36))
- 优化仪表盘公告区块、帮助文档区块内容 ([b59a819](https://github.com/ysoft-org/ysoft-admin/commit/b59a819ad5f2bdbd357951f070d155e91f2d7903)) ([315c059](https://github.com/ysoft-org/ysoft-admin/commit/315c059713833be10b0cf05d302259a3146f3707)) ([6d024a9](https://github.com/ysoft-org/ysoft-admin/commit/6d024a90d7a231439c8e260b9bd625e8b5027515))
- 将 Swagger 文档中的额外请求参数隐藏 ([#11](https://github.com/ysoft-org/ysoft-admin/pull/11)) ([a9ed02b](https://github.com/ysoft-org/ysoft-admin/commit/a9ed02bf4ff6a8a4d9f68db2d62d29000c543943))
- 优化前端 CRUD 相关命名 ([6d81928](https://github.com/ysoft-org/ysoft-admin/commit/6d81928541f4da568e9c7138f91d4dc1c5c6dd4e))
- 优化部分超链接标签属性 ([46a75d0](https://github.com/ysoft-org/ysoft-admin/commit/46a75d029798e8d5a162b53b8a61c8e3c3f4dd9e))
- 使用属性变量消除配置文件中分散的 ContiNew Admin 品牌元素 ([54ea410](https://github.com/ysoft-org/ysoft-admin/commit/54ea41048abd096cf1e2c32ee871c1eb85d4ece1))
- 拆分 Swagger 接口文档分组 ([#10](https://github.com/ysoft-org/ysoft-admin/pull/10)) ([72df45e](https://github.com/ysoft-org/ysoft-admin/commit/72df45e9b3373d28f1845af16a81cb8bd8408647))
- 优化登录 Helper ([#9](https://github.com/ysoft-org/ysoft-admin/pull/9)) ([9e2a5ef](https://github.com/ysoft-org/ysoft-admin/commit/9e2a5ef1249fd93dd10f2c255bf77c3eaa64a241))
- 将全局异常处理器未知异常的异常类型从 Exception 调整为 Throwable ([90e1c64](https://github.com/ysoft-org/ysoft-admin/commit/90e1c64db684df97454e4753932b7f4017d8e23d))
- 优化 == 及 != 表达式格式 ([487fa82](https://github.com/ysoft-org/ysoft-admin/commit/487fa82306fbd84033f6c39ad20b72755b03e875))
- 集成 Spring Cache优化查询用户昵称性能 ([b23b00d](https://github.com/ysoft-org/ysoft-admin/commit/b23b00d02a4738a61b4a13676fab6d2c9ec927de)) ([76622c2](https://github.com/ysoft-org/ysoft-admin/commit/76622c238f1d6028826407490e50a14bdba25ade))⚡
- 将验证码唯一标识格式从无符号 UUID 调整为带符号 UUID ([a61196c](https://github.com/ysoft-org/ysoft-admin/commit/a61196cd62cea4f684154bb42a949656650f626b))
- 完善接口文档示例信息 ([#7](https://github.com/ysoft-org/ysoft-admin/pull/7)) ([ad7d699](https://github.com/ysoft-org/ysoft-admin/commit/ad7d6995ba40a0cb70a194693fa450bdbb3cc7a0)) ([#8](https://github.com/ysoft-org/ysoft-admin/pull/8)) ([0ac0213](https://github.com/ysoft-org/ysoft-admin/commit/0ac0213628023c04b5be531522d76f09712f7317)) ([190385e](https://github.com/ysoft-org/ysoft-admin/commit/190385ed3636206224bc90780fcede2e49f9c118)) ([332bd6c](https://github.com/ysoft-org/ysoft-admin/commit/332bd6cd2a9b4e25678a3eec565965c5b2702aa2))
- 使用 DatePattern 中的日期格式常量替代字符串常量中的日期格式 ([241a9cf](https://github.com/ysoft-org/ysoft-admin/commit/241a9cf85b3c19eb093d4d661c35d71c490adf1f))
- 优化分组校验 ([78a5d5e](https://github.com/ysoft-org/ysoft-admin/commit/78a5d5ec7a14ee37d92a9520211adca23f12b287))
- 优化 springdoc-openapi 对象型参数处理 ([ae8d294](https://github.com/ysoft-org/ysoft-admin/commit/ae8d294705536e99d6c30a9ff5257fdb3ee5b35f))
- 升级前端依赖,并更换包管理器 yarn => pnpm ([6164110](https://github.com/ysoft-org/ysoft-admin/commit/6164110462cc3aff66d79539f54e84d47c6d5894))
- 升级后端依赖 ([51a82d8](https://github.com/ysoft-org/ysoft-admin/commit/51a82d8f4eabd6aa27e1a991f05f516171b6ae03))
### 🐛 问题修复
- 完善部分数据库表的唯一索引 ([88d6118](https://github.com/ysoft-org/ysoft-admin/commit/88d6118693586fbd8da573df3b2f942d049e4b3c))
- 修复访问 doc.html 接口文档,控制台报 No mapping for GET /favicon.ico 警告的问题 ([94f88ba](https://github.com/ysoft-org/ysoft-admin/commit/94f88bad2278d64a4b8a3bc930a9f754fb00cba6))
- 登录页面输入错误时,自动清空验证码输入框 ([a76f47f](https://github.com/ysoft-org/ysoft-admin/commit/a76f47fbd86bfa7fbf85440c653ae6259fce7969))
### 💥 破坏性变更
- 更新信息调整为仅在更新数据时自动填充 ([df77e57](https://github.com/ysoft-org/ysoft-admin/commit/df77e574cca605afd89f1b3781f1cde699bcb7e6))
- 将时间戳单位从毫秒调整为秒 ([fa916b9](https://github.com/ysoft-org/ysoft-admin/commit/fa916b93247e10462eb44185ad45cdca4dedda7d))
- 移除所有的 @Accessors(chain = true),并全局配置禁止使用 ([76c6546](https://github.com/ysoft-org/ysoft-admin/commit/76c65463c2e5ddf0c90fa1622fd86706a4373c80))
## [v1.0.1](https://github.com/ysoft-org/ysoft-admin/compare/v1.0.0...v1.0.1) (2023-08-17)
### 💎 功能优化
- 优化根据 ID 查询用户昵称方法 ([4a8af1f](https://github.com/ysoft-org/ysoft-admin/commit/4a8af1f72d9249afa1c013e08674f492f453b020))
- 优化 BaseController 中部分权限码的使用 ([b0b1127](https://github.com/ysoft-org/ysoft-admin/commit/b0b1127b5bd39e9bc431e9fa9c86201bbc18e891))
- 优化分页总记录数数据类型 ([76f04dd](https://github.com/ysoft-org/ysoft-admin/commit/76f04dd38f90aad6abf82d2dccba031d4d9108cf))
- 优化通用查询注解解析器 ([a623acd](https://github.com/ysoft-org/ysoft-admin/commit/a623acd4a5529ae42898ec359f595716acc5bab8)) ([b632c18](https://github.com/ysoft-org/ysoft-admin/commit/b632c183994ac71382180a38bf7bdb7a6315c1e6))
- 优化数据库表结构中部分类型长度 ([f3fabea](https://github.com/ysoft-org/ysoft-admin/commit/f3fabea7dd736d94badecbc08091eec6274f5fb7))
- 使用常量优化部分魔法值 ([e6f7429](https://github.com/ysoft-org/ysoft-admin/commit/e6f7429fa30cbc87c03a073a53b6f7df24d33d8d))
- 优化部分 Properties 用法 ([48de2e8](https://github.com/ysoft-org/ysoft-admin/commit/48de2e85e0fbf60f10769cd3529f79ac3c531e92))
### 🐛 问题修复
- 修复获取字典参数为空时的判断条件 ([#6](https://github.com/ysoft-org/ysoft-admin/pull/6)) ([104f69e](https://github.com/ysoft-org/ysoft-admin/commit/104f69e8a09ce36163f6f9680b2d8d61bb45f11a))
- 完善查询用户数据权限 ([026247f](https://github.com/ysoft-org/ysoft-admin/commit/026247f677110ae199124a67c68503729cbaec92))
- 解决 IDE 报 Delete ␍ eslint(prettier/prettier) 警告的问题 ([8743ed1](https://github.com/ysoft-org/ysoft-admin/commit/8743ed14d927ab52814ed5f5f166afaa7a6b78b2))
- 修复分页查询条件默认值未生效的问题 ([2d2a7e7](https://github.com/ysoft-org/ysoft-admin/commit/2d2a7e7c8e31763ac3ea514d8a92c3938376dd3a))
- 完善各模块事务注解 ([18c54a7](https://github.com/ysoft-org/ysoft-admin/commit/18c54a74fc6ff0650ff53eeadc094d7e1df0b0a5))
- 修复邮箱健康检查报错问题并优化部分配置写法 ([5968f40](https://github.com/ysoft-org/ysoft-admin/commit/5968f402ed478244d36f5825373190ed00d8c1f1))
- 完善各模块参数校验 ([8b955a0](https://github.com/ysoft-org/ysoft-admin/commit/8b955a0b1bde4e8959fc0dfbc11a326d9eec0b45))
## v1.0.0 (2023-03-26)
### ✨ 新特性
* 用户管理:提供用户的相关配置,新增用户后,默认密码为 123456
* 角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限
* 部门管理:可配置系统组织架构,树形表格展示
* 菜单管理:已实现菜单动态路由,后端可配置化,支持多级菜单
* 在线用户:管理当前登录用户,可一键踢下线
* 日志管理:提供在线用户监控、登录日志监控、操作日志监控和系统日志监控等监控功能

202
LICENSE Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

507
README.md Normal file
View File

@@ -0,0 +1,507 @@
# ContiNew Admin 中后台管理框架
<a href="https://github.com/ysoft-org/ysoft-admin" title="Release" target="_blank">
<img src="https://img.shields.io/badge/SNAPSHOT-v3.6.0-%23ff3f59.svg" alt="Release" />
</a>
<a href="https://github.com/ysoft-org/ysoft-starter" title="ContiNew Starter" target="_blank">
<img src="https://img.shields.io/badge/ContiNew Starter-2.9.0-%236CB52D.svg" alt="ContiNew Starter" />
</a>
<a href="https://spring.io/projects/spring-boot" title="Spring Boot" target="_blank">
<img src="https://img.shields.io/badge/Spring Boot-3.2.12-%236CB52D.svg?logo=Spring-Boot" alt="Spring Boot" />
</a>
<a href="https://github.com/ysoft-org/ysoft-admin" title="Open JDK" target="_blank">
<img src="https://img.shields.io/badge/Open JDK-17-%236CB52D.svg?logo=OpenJDK&logoColor=FFF" alt="Open JDK" />
</a>
<a href="https://app.codacy.com/gh/ysoft-org/ysoft-admin/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade" title="Codacy" target="_blank">
<img src="https://app.codacy.com/project/badge/Grade/19e3e2395d554efe902c3822e65db30e" alt="Codacy" />
</a>
<a href="https://sonarcloud.io/summary/new_code?id=Charles7c_ysoft-admin" title="Sonar" target="_blank">
<img src="https://sonarcloud.io/api/project_badges/measure?project=Charles7c_ysoft-admin&metric=alert_status" alt="Sonar" />
</a>
<br />
<a href="https://github.com/ysoft-org/ysoft-admin/blob/dev/LICENSE" title="License" target="_blank">
<img src="https://img.shields.io/badge/License-Apache--2.0-blue.svg" alt="License" />
</a>
<a href="https://github.com/ysoft-org/ysoft-admin" title="GitHub Stars" target="_blank">
<img src="https://img.shields.io/github/stars/ysoft-org/ysoft-admin?style=social" alt="GitHub Stars" />
</a>
<a href="https://github.com/ysoft-org/ysoft-admin" title="GitHub Forks" target="_blank">
<img src="https://img.shields.io/github/forks/ysoft-org/ysoft-admin?style=social" alt="GitHub Forks" />
</a>
<a href="https://gitee.com/ysoft/ysoft-admin" title="Gitee Stars" target="_blank">
<img src="https://gitee.com/ysoft/ysoft-admin/badge/star.svg?theme=dark" alt="Gitee Stars" />
</a>
<a href="https://gitee.com/ysoft/ysoft-admin" title="Gitee Forks" target="_blank">
<img src="https://gitee.com/ysoft/ysoft-admin/badge/fork.svg?theme=dark" alt="Gitee Forks" />
</a>
<a href="https://gitcode.com/ysoft/ysoft-admin" title="GitCode Stars" target="_blank">
<img src="https://gitcode.com/ysoft/ysoft-admin/star/badge.svg" alt="GitCode Stars" />
</a>
📚 [在线文档](https://ysoft.top) | 🚀 [演示地址](https://admin.ysoft.top)(账号/密码admin/admin123
## 简介
ContiNew AdminContinue New Admin持续迭代优化的前后端分离中后台管理系统框架。开箱即用重视每一处代码规范重视每一种解决方案细节持续提供舒适的前、后端开发体验。
当前采用的技术栈Spring Boot3Java17、Vue3 & Arco Design & TS & Vite、Sa-Token、MyBatis Plus、Redisson、JetCache、JustAuth、Crane4j、EasyExcel、Liquibase、Hutool 等。
## 项目源码
| | 后端 | 前端 |
| :------ | :----------------------------------------------------------- | :----------------------------------------------------------- |
| Gitee | [ysoft/ysoft-admin](https://gitee.com/ysoft/ysoft-admin) | [ysoft/ysoft-admin-ui](https://gitee.com/ysoft/ysoft-admin-ui) |
| GitCode | [ysoft/ysoft-admin](https://gitcode.com/ysoft/ysoft-admin) | [ysoft/ysoft-admin-ui](https://gitcode.com/ysoft/ysoft-admin-ui) |
| GitHub | [ysoft-org/ysoft-admin](https://github.com/ysoft-org/ysoft-admin) | [ysoft-org/ysoft-admin-ui](https://github.com/ysoft-org/ysoft-admin-ui) |
## 项目起源
我热衷于做数据归档,归档后的数据可以提高学习/工作效率,为记忆“减负”,在持续的数据归档中,优质的“沉淀”会带来非匀速、跨越式的学习/工作体验。**数据归档是一件需要持续去做的事情**。
从接触程序代码的第一天,我的程序数据归档也随之开始了,刷过的算法题、笔记、对接各种组件的配置文件,甚至于一些亮眼的样式设计、“如诗”的代码片段。这些数据的沉淀丰富了我的解决方案,提高了我的编程效率,逐渐为各种场景落实成了一个个雏形程序。再后来,我意识到,我归档的这些雏形程序,有一个更为妥贴的名称:**程序框架/脚手架**。
技术的发展,导致这些雏形程序的生命周期很是短暂,它们有别于我归档的其他数据,有时由于工作的原因,没有时间很好的去沉淀它们,在使用时变得越来越不顺手。所以,某段时间,我放弃了维护,而是去采用一些更为成熟的框架。
不过,在陆续几年使用了一些成熟框架后,我前后遇到了一些困难:
1. 代码洁癖想要找到一个**扩展性佳,代码规范良好,开发体验舒适**的框架很不容易,总是差些什么
2. 项目上手困难或是基础版功能不全,需要的全在专业版,亦或者代码阅读性差,文档收费
3. 部分解决方案缺失,已有解决方案也过于偏向样板化,无法形成良好的逻辑闭环
4. 好不容易找到一些相较合适的,没过多久,部分作者可能暂时没法对外发“电”了,随着了解深入,很多 Bug 或新技术趋势还是需要自己研究解决
在工作中,很多想法/设计受限于客户需求、开发工期,必须优先以交付为导向,但一些优秀的实践需要花时间持续进行沉淀,只要我没跳出这个圈子,我还是需要一直去做好程序归档。“种一棵树最好的时间是十年前,其次是现在”,最终,我选择在业余时间更加正视这件事,从头归档沉淀,从添加每一个依赖开始,我希望它能持续的迭代优化、演进,所以我把它命名为 **ContiNewContinue New**。并且这次我选择了开源,我希望它不仅仅能吸收我的需求和沉淀,而是依托开源协作模式,及时发现更多的问题,接受更多的可能性,沉淀更优秀的思考,设计。
## 为什么选我们?
> [!TIP]
> 更为完整的图文描述请查阅[《在线文档》](https://ysoft.top/admin/intro/why.html)。
1.**甄选技术栈:** ContiNewContinue New 项目致力于持续迭代优化,让技术不掉队。在技术选型时,进行深度广泛地调研,从流行度、成熟度和发展潜力等多方面甄选技术栈。
2.**Starter 组件:** 从 v2.1.0 版本开始,抽取并封装后端基础组件及各框架集成配置到 ContiNew Starter 项目,且 **[已发布至 Maven 中央仓库](https://central.sonatype.com/search?q=ysoft-starter&namespace=top.ysoft)**,可在你的任意项目中直接引入所需依赖使用。即使你不用脚手架项目,难道能让你搭项目框架更快、更爽、更省力的 Starter 也要 Say No 吗?
3.**CRUD 套件:** 封装通用增删改查套件,适配后端各分层,几分钟即可提供一套 CRUD API包括新增、修改、批量删除、查询详情、分页列表查询、全部列表查询、树型列表查询、导出到 Excel且 API 支持按实际所需开放或扩展。
```java
@Tag(name = "部门管理 API")
@RestController
@CrudRequestMapping(value = "/system/dept", api = {Api.TREE, Api.DETAIL, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
public class DeptController extends BaseController<DeptService, DeptResp, DeptDetailResp, DeptQuery, DeptReq> {}
```
4.**代码生成器:** 提供代码生成器,已配套前、后端代码生成模板,数据表设计完之后,简单配置一下即可生成前、后端 80% 的代码,包含 CRUD API、权限控制、参数校验、接口文档等内容。如果业务不复杂也可能就是 95% 的代码。
5.**改善开发体验:** 持续优化及适配能改善开发体验的组件。
- 适配 ContiNew Starter 各组件,针对 Spring 基础配置、通用解决方案以及流行框架进行了深度封装的 starter 集合,改善你在开发每个 Spring Boot Web 项目的体验。(枚举参数处理、默认线程池、跨域、加密、脱敏、限流、日志、异常及响应通用解决方案等等,更多细节可查看 Starter 源码)
- 适配 Crane4j 数据填充组件,减少因为一个用户名而产生的联表回填;
- 适配 P6Spy SQL 性能分析组件,开发期间方便监控 SQL 执行;
- 适配 TLog 链路追踪组件,方便在杂乱的日志文件中追踪你某次请求的日志记录;
- 适配 JetCache 缓存框架(比 Spring Cache 更强大易用),通过注解声明即可快速实现方法级缓存,极大改善编码式缓存体验,且支持灵活的二级缓存配置、分布式自动刷新等能力;
- 前端适配 Vue DevtoolsVue 官方提供的调试浏览器插件),极大提高 Vue 开发及调试效率
6.**Almost最佳后端规范** 后端严格遵循阿里巴巴 Java 编码规范,注释覆盖率 > 45%,接口参数示例 100%,代码分层使用体验佳,变量、方法命名清晰统一,前端代码也使用严格的 ESLint、StyleLint 等检查。良好的设计,代码复用率极高!写代码时,让你有一种无需多写,理应如此的感觉。我是代码洁癖,我实际写的时候很清楚这到底是不是乱吹。
7.**卓越工程:** 后端采用模块化工程结构,并适配了统一项目版本号、编译项目自动代码格式化、代码混淆等插件,提供了自定义打包部署结构配置(配置文件、三方依赖和主程序分离),提供全套环境及应用的 Docker Compose 部署脚本。为了减少您开发新项目时的改造耗时,项目品牌配置持续进行深度聚合,简单的配置和结构修改即可快速开始独属于你的新项目。
8.**业务脚手架:** 有颜有料,不止是说说而已,持续打磨 UI 设计与色彩主题。提供基于 RBAC 的权限控制、通用数据权限,包含丰富的通用业务功能:第三方登录,邮箱、短信(生产级炸弹漏洞处理方案),个人中心、用户管理、角色管理、部门管理、系统配置(基础站点配置、邮件配置、安全配置)、系统日志、消息中心、通知公告等,设计用心,逻辑合理闭环。
> 一个好的脚手架项目,不仅仅是提供一系列组件集成与配置,也不仅仅是封装一堆好用的工具,还更应该提供一系列通用基础业务解决方案及设计,为初创团队项目减负。
9.**质量与安全:** CI 已集成 Sonar、CodacyPush 即扫描代码质量,定期扫描 CVE 漏洞及时解决潜在问题。封装数据库字段加密、JSON 脱敏、XSS 过滤等工具,提供诸多安全解决方案。
由于篇幅有限,且项目正处于高速发展期,更多功能正在陆续上线(敬请关注仓库或群内动态)。另外像最基本的统一异常、错误处理,基础线程池等配置就不在此赘述,细节优化详情请 clone 代码查看。
> Talk is cheap, show the code.
## 系统功能
> [!TIP]
> 更多功能和优化正在赶来💦,最新项目计划、进展请进群或关注 [需求墙](https://ysoft.top/require.html) 和 [更新日志](https://ysoft.top/admin/other/changelog.html)。
- 仪表盘:提供工作台、分析页,工作台提供功能快捷导航入口、最新公告、动态;分析页提供全面数据可视化能力
- 个人中心:支持基础信息修改、密码修改、邮箱绑定、手机号绑定(并提供行为验证码、短信限流等安全处理)、第三方账号绑定/解绑、头像裁剪上传
- 消息中心:提供站内信消息统一查看、标记已读、全部已读、删除等功能(目前仅支持系统通知消息)
- 用户管理:管理系统用户,包含新增、修改、删除、导入、导出、重置密码、分配角色等功能
- 角色管理:管理系统用户的功能权限及数据权限,包含新增、修改、删除、分配角色等功能
- 菜单管理:管理系统菜单及按钮权限,支持多级菜单,动态路由,包含新增、修改、删除等功能
- 部门管理:管理系统组织架构,包含新增、修改、删除、导出等功能,以树形列表进行展示
- 字典管理:管理系统公用数据字典,例如:消息类型。支持字典标签背景色和排序等配置
- 通知公告:管理系统公告,支持设置公告的生效时间、终止时间、通知范围(所有人、指定用户)
- 文件管理管理系统文件支持上传、下载、预览目前支持图片、音视频、PDF、Word、Excel、PPT、重命名、切换视图列表、网格等功能
- 存储管理:管理文件存储配置,支持本地存储、兼容 S3 协议对象存储
- 终端管理:多端认证管理,可设置不同的 token 有效期
- 系统配置:
- 基础配置提供修改系统标题、Logo、favicon、版权信息等基础配置功能以方便用户系统与其自身品牌形象保持一致
- 邮件配置:提供系统发件箱配置,也支持通过配置文件指定
- 安全配置:提供密码策略修改,支持丰富的密码策略设定,包括但不限于 `密码有效期``密码重复次数``密码错误锁定账号次数、时间`
- 在线用户:管理当前登录用户,可一键踢除下线
- 日志管理:管理系统登录日志、操作日志,支持查看日志详情,包含请求头、响应头等报文信息
- 任务管理:管理系统定时任务,包含新增、修改、删除、执行功能,支持 Cron可配置式生成 Cron 表达式) 和固定频率
- 任务日志:管理定时任务执行日志,包含停止、重试指定批次,查询集群各节点的详细输出日志等功能
- 应用管理:管理第三方系统应用 AK、SK包含新增、修改、删除、查看密钥、重置密钥等功能支持设置密钥有效期
- 代码生成:提供根据数据库表自动生成相应的前后端 CRUD 代码的功能,支持同步最新表结构及代码生成预览
## 系统截图
> [!TIP]
> 受篇幅长度及功能更新频率影响,下方仅为系统 **部分** 功能于 **2024年11月18日** 进行的截图,更多新增功能及细节请登录演示环境或 clone 代码到本地启动查看。
<table border="1" cellpadding="1" cellspacing="1" style="width: 500px">
<tbody>
<tr>
<td><img src=".image/screenshot/000登录页面.png" alt="登录页面" width="1920" /></td>
<td><img src=".image/screenshot/000登录页面-H5.png" alt="登录页面-H5" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/001仪表盘.png" alt="仪表盘" width="1920" /></td>
<td><img src=".image/screenshot/002分析页.png" alt="分析页" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/010个人中心.png" alt="个人中心" width="1920" /></td>
<td><img src=".image/screenshot/013消息中心.png" alt="消息中心" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/011安全设置-修改邮箱.png" alt="安全设置-修改邮箱" width="1920" /></td>
<td><img src=".image/screenshot/012安全设置-修改邮箱-邮箱验证码.png" alt="安全设置-修改邮箱-邮箱验证码" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/060系统管理-系统配置.png" alt="系统管理-系统配置" width="1920" /></td>
<td><img src=".image/screenshot/061系统管理-安全配置.png" alt="系统管理-安全配置" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/020系统管理-用户管理-列表.png" alt="系统管理-用户管理-列表" width="1920" /></td>
<td><img src=".image/screenshot/021系统管理-用户管理-新增.png" alt="系统管理-用户管理-新增" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/025系统管理-角色管理-列表.png" alt="系统管理-角色管理-列表" width="1920" /></td>
<td><img src=".image/screenshot/026系统管理-角色管理-新增.png" alt="系统管理-角色管理-新增" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/030系统管理-菜单管理-列表.png" alt="系统管理-菜单管理-列表" width="1920" /></td>
<td><img src=".image/screenshot/031系统管理-菜单管理-新增.png" alt="系统管理-菜单管理-新增" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/045系统管理-公告管理-列表.png" alt="系统管理-公告管理-列表" width="1920" /></td>
<td><img src=".image/screenshot/046系统管理-公告管理-修改.png" alt="系统管理-公告管理-修改" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/040系统管理-字典管理-列表.png" alt="系统管理-字典管理-列表" width="1920" /></td>
<td><img src=".image/screenshot/041系统管理-字典项管理.png" alt="系统管理-字典项管理" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/051系统管理-文件管理-列表-2.png" alt="系统管理-文件管理-列表-2" width="1920" /></td>
<td><img src=".image/screenshot/052系统管理-文件管理-查看文档.png" alt="系统管理-文件管理-查看文档" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/301系统工具-代码生成-配置.png" alt="系统工具-代码生成-配置" width="1920" /></td>
<td><img src=".image/screenshot/302系统工具-代码生成-预览.png" alt="系统工具-代码生成-预览" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/100系统监控-在线用户.png" alt="系统监控-在线用户" width="1920" /></td>
<td><img src=".image/screenshot/101系统监控-系统日志-登录日志.png" alt="系统监控-系统日志-登录日志" width="1920" /></td>
</tr>
<tr>
<td><img src=".image/screenshot/102系统监控-系统日志-操作日志.png" alt="系统监控-系统日志-操作日志" width="1920" /></td>
<td><img src=".image/screenshot/103系统监控-系统日志-操作日志-详情.png" alt="系统监控-系统日志-操作日志-详情" width="1920" /></td>
</tr>
</tbody>
</table>
## 核心技术栈
| 名称 | 版本 | 简介 |
|:----------------------------------------------------------------------------------------------------------------------------------|:-------------| :----------------------------------------------------------- |
| <a href="https://vuejs.org/" target="_blank">Vue</a> | 3.5.4 | 渐进式 JavaScript 框架,易学易用,性能出色,适用场景丰富的 Web 前端框架。 |
| <a href="https://arco.design/vue/docs/start" target="_blank">Arco Design</a> | 2.56.0 | 字节跳动推出的前端 UI 框架,年轻化的色彩和组件设计。 |
| <a href="https://www.typescriptlang.org/zh/" target="_blank">TypeScript</a> | 5.0.4 | TypeScript 是微软开发的一个开源的编程语言,通过在 JavaScript 的基础上添加静态类型定义构建而成。 |
| <a href="https://vite.dev/" target="_blank">Vite</a> | 5.1.5 | 下一代的前端工具链,为开发提供极速响应。 |
| [ContiNew Starter](https://github.com/ysoft-org/ysoft-starter) | 2.9.0 | ContiNew Starter 包含了一系列经过企业实践优化的依赖包(如 MyBatis-Plus、SaToken可轻松集成到应用中为开发人员减少手动引入依赖及配置的麻烦为 Spring Boot Web 项目的灵活快速构建提供支持。 |
| <a href="https://spring.io/projects/spring-boot" target="_blank">Spring Boot</a> | 3.2.12 | 简化 Spring 应用的初始搭建和开发过程基于“约定优于配置”的理念使开发人员不再需要定义样板化的配置。Spring Boot 3.0 开始,要求 Java 17 作为最低版本) |
| <a href="https://undertow.io/" target="_blank">Undertow</a> | 2.3.17.Final | 采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。 |
| <a href="https://sa-token.dev33.cn/" target="_blank">Sa-Token + JWT</a> | 1.39.0 | 轻量级 Java 权限认证框架,让鉴权变得简单、优雅。 |
| <a href="https://baomidou.com/" target="_blank">MyBatis Plus</a> | 3.5.8 | MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,简化开发、提高效率。 |
| <a href="https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611" target="_blank">dynamic-datasource-spring-boot-starter</a> | 4.3.1 | 基于 Spring Boot 的快速集成多数据源的启动器。 |
| Hikari | 5.0.1 | JDBC 连接池,号称 “史上最快连接池”SpringBoot 在 2.0 之后,采用的默认数据库连接池就是 Hikari。 |
| <a href="https://dev.mysql.com/downloads/mysql/" target="_blank">MySQL</a> | 8.0.33 | 体积小、速度快、总体拥有成本低,是最流行的关系型数据库管理系统之一。 |
| <a href="https://dev.mysql.com/doc/connector-j/8.0/en/" target="_blank">mysql-connector-j</a> | 8.3.0 | MySQL Java 驱动。 |
| <a href="https://github.com/p6spy/p6spy" target="_blank">P6Spy</a> | 3.9.1 | SQL 性能分析组件。 |
| <a href="https://github.com/liquibase/liquibase" target="_blank">Liquibase</a> | 4.24.0 | 用于管理数据库版本,跟踪、管理和应用数据库变化。 |
| [JetCache](https://github.com/alibaba/jetcache/blob/master/docs/CN/Readme.md) | 2.7.7 | 一个基于 Java 的缓存系统封装,提供统一的 API 和注解来简化缓存的使用。提供了比 SpringCache 更加强大的注解,可以原生的支持 TTL、两级缓存、分布式自动刷新还提供了 Cache 接口用于手工缓存操作。 |
| <a href="https://github.com/redisson/redisson/wiki/Redisson%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D" target="_blank">Redisson</a> | 3.41.0 | 不仅仅是一个 Redis Java 客户端Redisson 充分的利用了 Redis 键值数据库提供的一系列优势,为使用者提供了一系列具有分布式特性的常用工具:分布式锁、限流器等。 |
| <a href="https://redis.io/" target="_blank">Redis</a> | 7.2.3 | 高性能的 key-value 数据库。 |
| [Snail Job](https://snailjob.opensnail.com/) | 1.2.0 | 灵活,可靠和快速的分布式任务重试和分布式任务调度平台。 |
| [X File Storage](https://x-file-storage.xuyanwu.cn/#/) | 2.2.1 | 一行代码将文件存储到本地、FTP、SFTP、WebDAV、阿里云 OSS、华为云 OBS...等其它兼容 S3 协议的存储平台。 |
| <a href="https://sms4j.com/" target="_blank">SMS4J</a> | 3.3.3 | 短信聚合框架,轻松集成多家短信服务,解决接入多个短信 SDK 的繁琐流程。 |
| <a href="https://justauth.cn/" target="_blank">Just Auth</a> | 1.16.7 | 开箱即用的整合第三方登录的开源组件,脱离繁琐的第三方登录 SDK让登录变得 So easy |
| <a href="https://easyexcel.opensource.alibaba.com/" target="_blank">Easy Excel</a> | 3.3.4 | 一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具。 |
| [AJ-Captcha](https://ajcaptcha.beliefteam.cn/captcha-doc/) | 1.3.0 | Java 行为验证码包含滑动拼图、文字点选两种方式UI支持弹出和嵌入两种方式。 |
| Easy Captcha | 1.6.2 | Java 图形验证码,支持 gif、中文、算术等类型可用于 Java Web、JavaSE 等项目。 |
| [Crane4j](https://createsequence.gitee.io/crane4j-doc/#/) | 2.9.0 | 一个基于注解的,用于完成一切 “根据 A 的 key 值拿到 B再把 B 的属性映射到 A” 这类需求的字段填充框架。 |
| [CosID](https://cosid.ahoo.me/guide/getting-started.html) | 2.10.1 | 旨在提供通用、灵活、高性能的分布式 ID 生成器。 |
| [Graceful Response](https://doc.feiniaojin.com/graceful-response/home.html) | 5.0.4-boot3 | 一个Spring Boot技术栈下的优雅响应处理组件可以帮助开发者完成响应数据封装、异常处理、错误码填充等过程提高开发效率提高代码质量。 |
| <a href="https://doc.xiaominfo.com/" target="_blank">Knife4j</a> | 4.5.0 | 前身是 swagger-bootstrap-ui集 Swagger2 和 OpenAPI3 为一体的增强解决方案。 |
| <a href="https://www.hutool.cn/" target="_blank">Hutool</a> | 5.8.34 | 小而全的 Java 工具类库,通过静态方法封装,降低相关 API 的学习成本,提高工作效率,使 Java 拥有函数式语言般的优雅,让 Java 语言也可以“甜甜的”。 |
| <a href="https://projectlombok.org/" target="_blank">Lombok</a> | 1.18.36 | 在 Java 开发过程中用注解的方式,简化了 JavaBean 的编写,避免了冗余和样板式代码,让编写的类更加简洁。 |
## 快速开始
> [!TIP]
> 更详细的流程,请查看在线文档[《快速开始》](https://ysoft.top/admin/intro/quick-start.html)。
```bash
# 1.克隆本项目
git clone https://github.com/ysoft-org/ysoft-admin.git
# 2.在 IDEIntelliJ IDEA/Eclipse中打开本项目
# 3.修改配置文件中的数据源配置信息、Redis 配置信息、邮件配置信息等
# [3.也可以在 IntelliJ IDEA 中直接配置程序启动环境变量DB_HOST、DB_PORT、DB_USER、DB_PWD、DB_NAMEREDIS_HOST、REDIS_PORT、REDIS_PWD、REDIS_DB]
# 4.启动程序
# 4.1 启动成功:访问 http://localhost:8000/页面输出Xxx started successfully.
# 4.2 接口文档http://localhost:8000/doc.html
# 5.部署
# 5.1 Docker 部署
# 5.1.1 服务器安装好 docker 及 docker-compose参考https://blog.charles7c.top/categories/fragments/2022/10/31/CentOS%E5%AE%89%E8%A3%85Docker
# 5.1.2 执行 mvn package 进行项目打包,将 target/app 目录下的所有内容放到 /docker/ysoft-admin 目录下
# 5.1.3 将 docker 目录上传到服务器 / 目录下并授权chmod -R 777 /docker
# 5.1.4 修改 docker-compose.yml 中的 MySQL 配置、Redis 配置、ysoft-admin-server 配置、Nginx 配置
# 5.1.5 执行 docker-compose up -d 创建并后台运行所有容器
# 5.2 其他方式部署
```
## 项目结构
> [!TIP]
> 后端采用按功能拆分模块的开发方式,下方项目目录结构是按照模块的层次顺序进行介绍的,实际 IDE 中 `ysoft-admin-common` 模块会因为字母排序原因排在上方。
```
ysoft-admin
├─ ysoft-webapiAPI 及打包部署模块)
│ ├─ src
│ │ ├─ main
│ │ │ ├─ java/top/ysoft/admin
│ │ │ │ ├─ config (配置)
│ │ │ │ ├─ controller
│ │ │ │ │ ├─ auth系统认证相关 API
│ │ │ │ │ ├─ common通用相关 API
│ │ │ │ │ ├─ monitor系统监控相关 API
│ │ │ │ │ ├─ system系统管理相关 API
│ │ │ │ │ └─ tool系统工具相关 API
│ │ │ │ └─ ContiNewAdminApplication.javaContiNew Admin 启动程序)
│ │ │ └─ resources
│ │ │ ├─ config核心配置目录
│ │ │ │ ├─ application-dev.yml开发环境配置文件
│ │ │ │ ├─ application-prod.yml生产环境配置文件
│ │ │ │ └─ application.yml通用配置文件
│ │ │ ├─ db/changelogLiquibase 数据脚本配置目录)
│ │ │ │ ├─ mysqlMySQL 数据库初始 SQL 脚本目录)
│ │ │ │ ├─ postgresqlPostgreSQL 数据库初始 SQL 脚本目录)
│ │ │ │ └─ db.changelog-master.yamlLiquibase 变更记录文件)
│ │ │ ├─ templates模板配置目录例如邮件模板
│ │ │ ├─ banner.txtBanner 配置文件)
│ │ │ └─ logback-spring.xml日志配置文件
│ │ └─ test测试相关代码目录
│ └─ pom.xml包含打包相关配置
├─ ysoft-module-system系统管理模块存放系统管理相关业务功能例如部门管理、角色管理、用户管理等
│ ├─ src
│ │ ├─ main
│ │ │ ├─ java/top/ysoft/admin
│ │ │ │ ├─ auth系统认证相关业务
│ │ │ │ │ ├─ model系统认证相关模型
│ │ │ │ │ │ ├─ query系统认证相关查询条件
│ │ │ │ │ │ ├─ req系统认证相关请求对象Request
│ │ │ │ │ │ └─ resp系统认证相关响应对象Response
│ │ │ │ │ └─ service系统认证相关业务接口及实现类
│ │ │ │ └─ system系统管理相关业务
│ │ │ │ ├─ config系统管理相关配置
│ │ │ │ ├─ enums系统管理相关枚举
│ │ │ │ ├─ mapper系统管理相关 Mapper
│ │ │ │ ├─ model系统管理相关模型
│ │ │ │ │ ├─ entity系统管理相关实体对象
│ │ │ │ │ ├─ query系统管理相关查询条件
│ │ │ │ │ ├─ req系统管理相关请求对象Request
│ │ │ │ │ └─ resp系统管理相关响应对象Response
│ │ │ │ ├─ service系统管理相关业务接口及实现类
│ │ │ │ └─ util系统管理相关工具类
│ │ │ └─ resources
│ │ │ └─ mapper系统管理相关 Mapper XML 文件目录)
│ │ └─ test测试相关代码目录
│ └─ pom.xml
├─ ysoft-plugin插件模块存放代码生成、任务调度等扩展模块后续会进行插件化改造
│ ├─ ysoft-plugin-schedule任务调度插件模块
│ │ ├─ src
│ │ │ ├─ main/java/top/ysoft/admin/schedule
│ │ │ │ ├─ api任务调度中心相关 API
│ │ │ │ ├─ config任务调度相关配置
│ │ │ │ ├─ constant任务调度相关常量
│ │ │ │ ├─ enums任务调度相关枚举
│ │ │ │ ├─ model任务调度相关模型
│ │ │ │ │ ├─ query任务调度相关查询条件
│ │ │ │ │ ├─ req任务调度相关请求对象Request
│ │ │ │ │ └─ resp任务调度相关响应对象Response
│ │ │ │ └─ service代码生成器相关业务接口及实现类
│ │ │ └─ test测试相关代码目录
│ │ └─ pom.xml
│ ├─ ysoft-plugin-open能力开放插件模块
│ │ ├─ src
│ │ │ ├─ main/java/top/ysoft/admin/open
│ │ │ │ ├─ mapper代码生成器相关 Mapper
│ │ │ │ ├─ model能力开放相关模型
│ │ │ │ │ ├─ entity能力开放相关实体对象
│ │ │ │ │ ├─ query能力开放相关查询条件
│ │ │ │ │ ├─ req能力开放相关请求对象Request
│ │ │ │ │ └─ resp能力开放相关响应对象Response
│ │ │ │ └─ service能力开放相关业务接口及实现类
│ │ │ └─ test测试相关代码目录
│ │ └─ pom.xml
│ ├─ ysoft-plugin-generator代码生成器插件模块
│ │ ├─ src
│ │ │ ├─ main
│ │ │ │ ├─ java/top/ysoft/admin/generator
│ │ │ │ │ ├─ config代码生成器相关配置
│ │ │ │ │ ├─ enums代码生成器相关枚举
│ │ │ │ │ ├─ mapper代码生成器相关 Mapper
│ │ │ │ │ ├─ model代码生成器相关模型
│ │ │ │ │ │ ├─ entity代码生成器相关实体对象
│ │ │ │ │ │ ├─ query代码生成器相关查询条件
│ │ │ │ │ │ ├─ req代码生成器相关请求对象Request
│ │ │ │ │ │ └─ resp代码生成器相关响应对象Response
│ │ │ │ │ └─ service代码生成器相关业务接口及实现类
│ │ │ │ └─ resources
│ │ │ │ ├─ templates/generator代码生成相关模板目录
│ │ │ │ ├─ application.yml代码生成配置文件
│ │ │ │ └─ generator.properties代码生成类型映射配置文件
│ │ │ └─ test测试相关代码目录
│ │ └─ pom.xml
│ └─ pom.xml
├─ ysoft-common公共模块存放公共工具类公共配置等
│ ├─ src
│ │ ├─ main/java/top/ysoft/admin/common
│ │ │ ├─ config公共配置
│ │ │ ├─ constant公共常量
│ │ │ ├─ enums公共枚举
│ │ │ ├─ model公共模型
│ │ │ │ ├─ dto公共 DTOData Transfer Object
│ │ │ │ ├─ req公共请求对象Request
│ │ │ │ └─ resp公共响应对象Response
│ │ │ └─ util公共工具类
│ │ └─ test测试相关代码目录
│ └─ pom.xml
├─ ysoft-extension扩展模块
│ ├─ ysoft-extension-schedule-server任务调度服务端模块实际开发时如果是公司统一提供环境可直接删除本模块
│ │ ├─ src
│ │ │ ├─ main
│ │ │ │ ├─ java/top/ysoft/admin/extension/schedule
│ │ │ │ │ └─ ScheduleServerApplication.java任务调度服务端启动程序
│ │ │ │ └─ resources
│ │ │ │ ├─ config核心配置目录
│ │ │ │ │ ├─ application-dev.yml开发环境配置文件
│ │ │ │ │ ├─ application-prod.yml生产环境配置文件
│ │ │ │ │ └─ application.yml通用配置文件
│ │ │ │ ├─ db/changelogLiquibase 数据脚本配置目录)
│ │ │ │ │ ├─ mysqlMySQL 数据库初始 SQL 脚本目录)
│ │ │ │ │ ├─ postgresqlPostgreSQL 数据库初始 SQL 脚本目录)
│ │ │ │ │ └─ db.changelog-master.yamlLiquibase 变更记录文件)
│ │ │ │ └─ logback-spring.xml日志配置文件
│ │ │ └─ test测试相关代码目录
│ │ └─ pom.xml
│ └─ pom.xml
├─ .githubGitHub 相关配置目录,实际开发时直接删除)
├─ .idea
│ └─ icon.pngIDEA 项目图标,实际开发时直接删除)
├─ .image截图目录实际开发时直接删除
├─ .style代码格式、License文件头相关配置目录实际开发时根据需要取舍删除时注意删除 spotless 插件配置)
├─ .gitignoreGit 忽略文件相关配置文件)
├─ docker项目部署相关配置目录实际开发时可备份后直接删除
├─ LICENSE开源协议文件
├─ CHANGELOG.md更新日志文件实际开发时直接删除
├─ README.md项目 README 文件,实际开发时替换为真实内容)
├─ lombok.configLombok 全局配置文件)
└─ pom.xml包含版本锁定及全局插件相关配置
```
## 贡献指南
ContiNew Admin 致力于提供开箱即用持续舒适的开发体验。作为一个开源项目Creator 的初心是希望 ContiNew Admin 依托开源协作模式,提升技术透明度、放大集体智慧、共创优秀实践,源源不断地为企业级项目开发提供助力。
我们非常欢迎广大社区用户为 ContiNew Admin **贡献(开发,测试、文档、答疑等)** 或优化代码,欢迎各位感兴趣的小伙伴儿,[添加微信](https://ysoft.top/support.html) 讨论或认领任务。
### 分支说明
ContiNew Admin 的分支目前分为下个大版本的开发分支和上个大版本的维护分支PR 前请注意对应分支是否处于维护状态,版本支持情况请查看 [更新日志/版本支持](https://ysoft.top/admin/other/changelog.html#%E7%89%88%E6%9C%AC%E6%94%AF%E6%8C%81)。
| 分支 | 说明 |
| ----- | ------------------------------------------------------------ |
| dev | 开发分支,默认为下个大版本的 SNAPSHOT 版本,接受新功能或新功能优化 PR |
| x.x.x | 维护分支,在 vx.x.x 版本维护期终止前(一般为下个大版本发布前),用于修复上个版本的 Bug只接受已有功能修复不接受新功能 PR |
### 贡献代码
如果您想提交新功能或优化现有代码,可以按照以下步骤操作:
1. 首先,在 Gitee 或 Github 上将项目 fork 到您自己的仓库
2. 然后,将 fork 过来的项目(即您的项目)克隆到本地
3. 切换到当前仍在维护的分支(请务必充分了解分支使用说明,可进群联系维护者确认)
4. 开始修改代码,修改完成后,将代码 commit 并 push 到您的远程仓库
5. 在 Gitee 或 Github 上新建 pull requestpr选择好源和目标按模板要求填写说明信息后提交即可多多参考 [已批准合并的 pr 记录](https://github.com/ysoft-org/ysoft-admin/pulls?q=is%3Apr+is%3Amerged),会大大增加批准合并率)
6. 最后,耐心等待维护者合并您的请求即可
请记住,如果您有任何疑问或需要帮助,我们将随时提供支持。
> [!IMPORTANT]
> 欢迎大家为 ContiNew Admin 贡献代码,我们非常感谢您的支持!为了更好地管理项目,维护者有一些要求:
>
> 1. 请确保代码、配置文件的结构和命名规范良好,完善的代码注释甚至包括接口文档参数示例,并遵循阿里巴巴的 <a href="https://github.com/ysoft-org/ysoft-admin/blob/dev/.style/Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C(%E9%BB%84%E5%B1%B1%E7%89%88).pdf" target="_blank">《Java开发手册(黄山版)》</a> 中的代码规范,保证代码质量和可维护性
> 2. 在提交代码前,请按照 [Angular 提交规范](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular) 编写 commit 的 message建议在 IntelliJ IDEA 中下载并安装 Git Commit Template 插件,以便按照规范进行 commit
> 3. 提交代码之前,请关闭所有代码窗口,执行 `mvn compile` 命令(代码格式化插件会在项目编译时对全局代码进行格式修正),编译通过后,不要再打开查看任何代码窗口,直接提交即可,以免不同的 IDE 配置会自动进行代码格式化
## 反馈交流
欢迎各位小伙伴儿扫描下方二维码加入项目交流群,与项目维护团队及其他大佬用户实时交流讨论。
<div align="left">
<img src=".image/qrcode.jpg" alt="二维码" height="230px" />
</div>
## 鸣谢
### 鸣谢
感谢参与贡献的每一位小伙伴🥰
<a href="https://github.com/ysoft-org/ysoft-admin/graphs/contributors">
<img src="https://opencollective.com/ysoft-admin/contributors.svg?width=890&button=false" alt="contributors" />
</a>
### 特别鸣谢
- 感谢 <a href="https://www.jetbrains.com/" target="_blank">JetBrains</a> 提供的 <a href="https://jb.gg/OpenSourceSupport" target="_blank">非商业开源软件开发授权</a>
- 感谢 <a href="https://github.com/baomidou/mybatis-plus" target="_blank">MyBatis Plus</a>、<a href="https://github.com/dromara/sa-token" target="_blank">Sa-Token</a> 、<a href="https://github.com/alibaba/jetcache" target="_blank">JetCache</a>、<a href="https://github.com/opengoofy/crane4j" target="_blank">Crane4j</a>、<a href="https://github.com/xiaoymin/knife4j" target="_blank">Knife4j</a>、<a href="https://github.com/dromara/hutool" target="_blank">Hutool</a> 等开源组件作者为国内开源世界作出的贡献
- 感谢项目使用或未使用到的每一款开源组件,致敬各位开源先驱 :fire:
## License
- 遵循 <a href="https://github.com/ysoft-org/ysoft-admin/blob/dev/LICENSE" target="_blank">Apache-2.0</a> 开源许可协议
- Copyright © 2022-present <a href="https://blog.charles7c.top" target="_blank">Charles7c</a>
## GitHub Star 趋势
![GitHub Star 趋势](https://starchart.cc/charles7c/ysoft-admin.svg)

View File

@@ -0,0 +1,14 @@
FROM openjdk:17
MAINTAINER Charles7c charles7c@126.com
ARG JAR_FILE=./bin/*.jar
COPY ${JAR_FILE} /app/bin/app.jar
WORKDIR /app/bin
ENTRYPOINT ["java", \
"-jar", \
"-XX:+UseZGC", \
"-Djava.security.egd=file:/dev/./urandom", \
"-Dspring.profiles.active=prod", \
"app.jar"]

112
docker/docker-compose.yml Normal file
View File

@@ -0,0 +1,112 @@
version: '3'
services:
mysql:
image: mysql:8.0.33
restart: always
container_name: mysql
ports:
- '3306:3306'
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 你的root用户密码
# 初始化数据库(后续的初始化 SQL 会在这个库执行)
MYSQL_DATABASE: ysoft_admin
#MYSQL_USER: 你的数据库用户名
#MYSQL_PASSWORD: 你的数据库密码
volumes:
- /docker/mysql/conf/:/etc/mysql/conf.d/
- /docker/mysql/data/:/var/lib/mysql/
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
# postgresql:
# image: postgres:14.2
# restart: always
# container_name: postgresql
# ports:
# - '5432:5432'
# environment:
# TZ: Asia/Shanghai
# POSTGRES_USER: 你的用户名
# POSTGRES_PASSWORD: 你的用户密码
# POSTGRES_DB: ysoft_admin
# volumes:
# - /docker/postgresql/data/:/var/lib/postgresql/data/
redis:
image: redis:7.2.3
restart: always
container_name: redis
ports:
- '6379:6379'
environment:
TZ: Asia/Shanghai
volumes:
- /docker/redis/conf/redis.conf:/usr/local/redis/config/redis.conf
- /docker/redis/data/:/data/
- /docker/redis/logs/:/logs/
command: 'redis-server /usr/local/redis/config/redis.conf --appendonly yes --requirepass 你的 Redis 密码'
ysoft-admin-server:
build: ./ysoft-admin
restart: always
container_name: ysoft-admin-server
ports:
- '18000:18000'
- '1789:1789'
environment:
TZ: Asia/Shanghai
DB_HOST: 172.17.0.1
DB_PORT: 3306
DB_USER: 你的数据库用户名
DB_PWD: 你的数据库密码
DB_NAME: ysoft_admin
REDIS_HOST: 172.17.0.1
REDIS_PORT: 6379
REDIS_PWD: 你的 Redis 密码
REDIS_DB: 0
SCHEDULE_HOST: 172.17.0.1
SCHEDULE_PORT: 1788
SCHEDULE_TOKEN: 任务调度服务端 Token
volumes:
- /docker/ysoft-admin/config/:/app/config/
- /docker/ysoft-admin/data/file/:/app/data/file/
- /docker/ysoft-admin/logs/:/app/logs/
- /docker/ysoft-admin/lib/:/app/lib/
depends_on:
- redis
- mysql
schedule-server:
build: ./schedule-server
restart: always
container_name: ysoft-admin-schedule-server
ports:
- '18001:18001'
- '1788:1788'
environment:
TZ: Asia/Shanghai
DB_HOST: 172.17.0.1
DB_PORT: 3306
DB_USER: 你的数据库用户名
DB_PWD: 你的数据库密码
DB_NAME: ysoft_admin_job
volumes:
- /docker/schedule-server/logs/:/app/logs/
depends_on:
- mysql
nginx:
image: nginx:1.25.3
restart: always
container_name: nginx
ports:
- '80:80'
- '443:443'
environment:
TZ: Asia/Shanghai
volumes:
- /docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
- /docker/nginx/cert/:/etc/nginx/cert/
- /docker/nginx/logs/:/var/log/nginx/
# 前端页面目录
- /docker/ysoft-admin/html/:/usr/share/nginx/html/

View File

@@ -0,0 +1,112 @@
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 限制 body 大小
client_max_body_size 100m;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 后端项目
upstream admin-server {
ip_hash;
server 172.17.0.1:18000;
}
server {
listen 443 ssl;
server_name api.ysoft.top;
# 证书直接存放 /docker/nginx/cert 目录下即可(更改证书名称即可,无需更改证书路径)
ssl_certificate /etc/nginx/cert/xxx.local.pem; # /etc/nginx/cert/ 为 docker 映射路径 不允许更改
ssl_certificate_key /etc/nginx/cert/xxx.local.key; # /etc/nginx/cert/ 为 docker 映射路径 不允许更改
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_ignore_client_abort on;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://admin-server/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# HTTP 请求 将转发到 HTTPS
server {
listen 80;
server_name api.ysoft.top;
rewrite ^ https://$http_host$request_uri? permanent;
}
# 前端项目
server {
listen 443 ssl;
server_name admin.ysoft.top;
# 证书直接存放 /docker/nginx/cert 目录下即可(更改证书名称即可,无需更改证书路径)
ssl_certificate /etc/nginx/cert/xxx.local.pem; # /etc/nginx/cert/ 为 docker 映射路径 不允许更改
ssl_certificate_key /etc/nginx/cert/xxx.local.key; # /etc/nginx/cert/ 为 docker 映射路径 不允许更改
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
# Nginx 部署时POST 请求本地静态文件会返回 405 错误Not Allowed
# 用于解决一半 mock 数据,一半后端接口的情况
error_page 405 =200 https://$host$request_uri;
}
# /api/ 代理到后端(如果使用 /api/ 前缀代理而不使用 api 域名提供后端服务,可放开此配置)
#location /api/ {
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# proxy_ignore_client_abort on;
# proxy_set_header Host $http_host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_pass http://admin-server/;
#}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# 将 HTTP 请求转发到 HTTPS
server {
listen 80;
server_name admin.ysoft.top;
rewrite ^ https://$http_host$request_uri? permanent;
}
}

View File

@@ -0,0 +1,29 @@
bind 0.0.0.0
# redis 密码
requirepass 你的 Redis 密码
# key 监听器配置
# notify-keyspace-events Ex
# 配置持久化文件存储路径
dir ../data
# 配置rdb
# 15分钟内有至少1个key被更改则进行快照
save 900 1
# 5分钟内有至少10个key被更改则进行快照
save 300 10
# 1分钟内有至少10000个key被更改则进行快照
save 60 10000
# 开启压缩
rdbcompression yes
# rdb文件名 用默认的即可
dbfilename dump.rdb
# 开启aof
appendonly yes
# 文件名
appendfilename "appendonly.aof"
# 持久化策略,no:不同步,everysec:每秒一次,always:总是同步,速度比较慢
# appendfsync always
appendfsync everysec
# appendfsync no

View File

@@ -0,0 +1 @@
Redis 数据存储目录,请确保赋予了读写权限,否则将无法写入数据

View File

@@ -0,0 +1,14 @@
FROM openjdk:17
MAINTAINER Charles7c charles7c@126.com
ARG JAR_FILE=*.jar
COPY ${JAR_FILE} /app/bin/app.jar
WORKDIR /app/bin
ENTRYPOINT ["java", \
"-jar", \
"-XX:+UseZGC", \
"-Djava.security.egd=file:/dev/./urandom", \
"-Dspring.profiles.active=prod", \
"app.jar"]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

0
logs/continew-admin.log Normal file
View File

307
logs/ysoft-admin.log Normal file
View File

@@ -0,0 +1,307 @@
2026-01-19 10:20:42 INFO [background-preinit] org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 8.0.1.Final
2026-01-19 10:20:42 INFO [main] top.ysoft.admin.YsoftAdminApplication - Starting YsoftAdminApplication using Java 21.0.6 with PID 31392 (D:\ysoft\ysoft-admin\ysoft-webapi\target\classes started by jingy in D:\ysoft\ysoft-admin)
2026-01-19 10:20:42 INFO [main] top.ysoft.admin.YsoftAdminApplication - The following 2 profiles are active: "generator", "prod"
2026-01-19 10:20:44 INFO [main] o.s.d.r.config.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2026-01-19 10:20:44 INFO [main] o.s.d.r.config.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2026-01-19 10:20:44 INFO [main] o.s.d.r.config.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 74 ms. Found 0 Redis repository interfaces.
2026-01-19 10:20:44 WARN [main] org.mybatis.spring.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[top.ysoft.admin]' package. Please check your configuration.
2026-01-19 10:20:45 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'cn.crane4j.spring.boot.config.Crane4jAutoConfiguration' of type [cn.crane4j.spring.boot.config.Crane4jAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). The currently created BeanPostProcessor [namedComponentAliasProcessor] is declared through a non-static factory method on that class; consider declaring it as static instead.
2026-01-19 10:20:45 DEBUG [main] t.c.s.e.c.a.CrudRestControllerAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Extension-CRUD REST Controller' completed initialization.
2026-01-19 10:20:45 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'top.continew.starter.extension.crud.autoconfigure.CrudRestControllerAutoConfiguration' of type [top.continew.starter.extension.crud.autoconfigure.CrudRestControllerAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:20:45 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'crudApiAnnotationInterceptor' of type [top.continew.starter.extension.crud.aop.CrudApiAnnotationInterceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:20:45 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'crudApiAnnotationAdvisor' of type [top.continew.starter.extension.crud.aop.CrudApiAnnotationAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:20:45 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'com.alicp.jetcache.anno.config.JetCacheProxyConfiguration' of type [com.alicp.jetcache.anno.config.JetCacheProxyConfiguration$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:20:45 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'com.alicp.jetcache.anno.config.CommonConfiguration' of type [com.alicp.jetcache.anno.config.CommonConfiguration$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:20:45 WARN [main] io.undertow.websockets.jsr - UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
2026-01-19 10:20:45 INFO [main] io.undertow.servlet - Initializing Spring embedded WebApplicationContext
2026-01-19 10:20:45 INFO [main] o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 3017 ms
2026-01-19 10:20:45 DEBUG [main] t.c.s.w.autoconfigure.trace.TraceAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Web-Trace' completed initialization.
2026-01-19 10:20:45 DEBUG [main] t.c.starter.log.autoconfigure.LogAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Log-Interceptor' completed initialization.
2026-01-19 10:20:45 DEBUG [main] t.c.s.web.autoconfigure.cors.CorsAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Web-CorsFilter' completed initialization.
2026-01-19 10:20:45 DEBUG [main] t.c.s.d.m.a.MybatisPlusAutoConfiguration - [ContiNew Starter] - Auto Configuration 'MyBatis Plus' completed initialization.
2026-01-19 10:20:45 DEBUG [main] t.c.s.e.d.a.DataPermissionAutoConfiguration - [ContiNew Starter] - Auto Configuration 'DataPermission' completed initialization.
2026-01-19 10:20:45 DEBUG [main] t.c.s.s.c.autoconfigure.CryptoAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Security-Crypto' completed initialization.
2026-01-19 10:20:45 DEBUG [main] t.c.s.d.m.a.i.MyBatisPlusIdGeneratorConfiguration - [ContiNew Starter] - Auto Configuration 'MyBatis Plus-IdGenerator-CosId' completed initialization.
2026-01-19 10:20:46 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.peopleBranch.model.entity.BranchRuleDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:20:46 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.system.model.entity.MessageUserDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:20:46 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.system.model.entity.RoleMenuDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:20:46 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.system.model.entity.RuleRelationDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:20:46 INFO [main] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2026-01-19 10:20:48 INFO [main] com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection com.p6spy.engine.wrapper.ConnectionWrapper@765d67dd
2026-01-19 10:20:48 INFO [main] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2026-01-19 10:20:49 INFO [main] liquibase.changelog - Reading from ysoft_admin.DATABASECHANGELOG
2026-01-19 10:20:49 INFO [main] liquibase.changelog - Reading from ysoft_admin.DATABASECHANGELOG
2026-01-19 10:20:49 INFO [main] liquibase.util - UPDATE SUMMARY
2026-01-19 10:20:49 INFO [main] liquibase.util - Run: 0
2026-01-19 10:20:49 INFO [main] liquibase.util - Previously run: 0
2026-01-19 10:20:49 INFO [main] liquibase.util - Filtered out: 0
2026-01-19 10:20:49 INFO [main] liquibase.util - -------------------------------
2026-01-19 10:20:49 INFO [main] liquibase.util - Total change sets: 0
2026-01-19 10:20:49 INFO [main] liquibase.util - Update summary generated
2026-01-19 10:20:50 INFO [main] liquibase.lockservice - Successfully released change log lock
2026-01-19 10:20:50 INFO [main] liquibase.command - Command execution complete
2026-01-19 10:20:50 DEBUG [main] t.c.s.s.p.a.PasswordEncoderAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Security-PasswordEncoder' completed initialization.
2026-01-19 10:20:50 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.system.model.entity.RoleDeptDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:20:50 DEBUG [main] t.c.s.c.a.threadpool.ThreadPoolAutoConfiguration - [ContiNew Starter] - Auto Configuration 'TaskExecutor' completed initialization.
2026-01-19 10:20:50 DEBUG [main] t.c.s.a.j.autoconfigure.JustAuthAutoConfiguration - [ContiNew Starter] - Auto Configuration 'JustAuth' completed initialization.
2026-01-19 10:20:50 DEBUG [main] t.c.s.a.j.autoconfigure.JustAuthAutoConfiguration - [ContiNew Starter] - Auto Configuration 'JustAuth-AuthStateCache-Redis' completed initialization.
2026-01-19 10:20:51 INFO [main] c.anji.captcha.service.impl.CaptchaServiceFactory - supported-captchaCache-service:[local]
2026-01-19 10:20:51 INFO [main] c.anji.captcha.service.impl.CaptchaServiceFactory - supported-captchaTypes-service:[clickWord, default, blockPuzzle]
2026-01-19 10:20:51 DEBUG [main] t.c.s.c.b.a.c.BehaviorCaptchaCacheAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Captcha-Behavior-Cache-Redis' completed initialization.
2026-01-19 10:20:51 DEBUG [main] t.c.s.c.b.a.BehaviorCaptchaAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Captcha-Behavior' completed initialization.
2026-01-19 10:20:51 INFO [main] com.anji.captcha.util.ImageUtils - 初始化底图:[SLIDING_BLOCK=[Ljava.lang.String;@2aec09a3, ORIGINAL=[Ljava.lang.String;@79864d6, PIC_CLICK=[Ljava.lang.String;@472d7f34]
2026-01-19 10:20:51 INFO [main] c.a.c.service.impl.BlockPuzzleCaptchaServiceImpl - --->>>初始化验证码底图<<<---blockPuzzle
2026-01-19 10:20:51 DEBUG [main] t.c.s.c.g.a.GraphicCaptchaAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Captcha-Graphic' completed initialization.
2026-01-19 10:20:51 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.equipment.model.entity.PeopleUpperDeviceDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:20:52 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.post.model.entity.PeoplePostDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:20:52 DEBUG [main] t.c.s.j.j.autoconfigure.JacksonAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Jackson' completed initialization.
2026-01-19 10:20:53 DEBUG [main] t.c.s.s.l.a.RateLimiterAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Security-RateLimiter' completed initialization.
2026-01-19 10:20:53 DEBUG [main] t.c.s.c.r.autoconfigure.RedissonAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Redisson' completed initialization.
2026-01-19 10:20:53 INFO [main] org.redisson.Version - Redisson 3.41.0
2026-01-19 10:20:53 INFO [redisson-netty-1-6] org.redisson.connection.ConnectionsHolder - 1 connections initialized for 121.199.16.218/121.199.16.218:6379
2026-01-19 10:20:54 INFO [redisson-netty-1-19] org.redisson.connection.ConnectionsHolder - 24 connections initialized for 121.199.16.218/121.199.16.218:6379
2026-01-19 10:20:54 DEBUG [main] t.c.s.w.a.response.GlobalResponseAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Web-Global Response' completed initialization.
2026-01-19 10:20:54 DEBUG [main] t.c.s.a.autoconfigure.SpringDocAutoConfiguration - [ContiNew Starter] - Auto Configuration 'ApiDoc' completed initialization.
2026-01-19 10:20:54 DEBUG [main] t.c.s.a.s.autoconfigure.SaTokenAutoConfiguration - [ContiNew Starter] - Auto Configuration 'SaToken' completed initialization.
2026-01-19 10:20:54 DEBUG [main] t.c.s.w.autoconfigure.mvc.WebMvcAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Web MVC' completed initialization.
2026-01-19 10:20:55 DEBUG [main] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - 264 mappings in 'requestMappingHandlerMapping'
2026-01-19 10:20:55 INFO [main] c.c.extension.spring.Crane4jApplicationContext - install container lifecycle processor [containerInstanceLifecycleProcessor]
2026-01-19 10:20:55 INFO [main] c.c.extension.spring.Crane4jApplicationContext - install container lifecycle processor [containerRegisterLogger]
2026-01-19 10:20:55 INFO [main] c.c.extension.spring.Crane4jApplicationContext - install container lifecycle processor [springCacheableContainerProcessor]
2026-01-19 10:20:55 INFO [main] c.c.extension.spring.BeanMethodContainerRegistrar - register method container factory [cn.crane4j.core.support.container.CacheableMethodContainerFactory] with name [cacheableMethodContainerFactory]
2026-01-19 10:20:55 DEBUG [main] t.c.s.a.s.a.dao.SaTokenDaoConfiguration - [ContiNew Starter] - Auto Configuration 'SaToken-Dao-Redis' completed initialization.
2026-01-19 10:20:55 INFO [main] c.a.jetcache.autoconfigure.AbstractCacheAutoInit - init cache area default , type= caffeine
2026-01-19 10:20:55 INFO [main] c.a.jetcache.autoconfigure.AbstractCacheAutoInit - init cache area default , type= redisson
2026-01-19 10:20:55 INFO [main] com.alicp.jetcache.support.DefaultMetricsManager - cache stat period at 15 MINUTES
2026-01-19 10:20:55 INFO [main] m.a.c.spring.redis.SpringRedisMachineIdDistributor - Distribute Remote instanceId:[InstanceId{instanceId=192.168.2.21:31392, stable=false}] - machineBit:[10] @ namespace:[ysoft-admin].
2026-01-19 10:20:55 INFO [main] m.a.c.spring.redis.SpringRedisMachineIdDistributor - Distribute Remote machineState:[MachineState{machineId=15, lastTimeStamp=1768789255758}] - instanceId:[InstanceId{instanceId=192.168.2.21:31392, stable=false}] - machineBit:[10] @ namespace:[ysoft-admin].
2026-01-19 10:20:56 DEBUG [main] t.c.s.c.j.autoconfigure.JetCacheAutoConfiguration - [ContiNew Starter] - Auto Configuration 'JetCache' completed initialization.
2026-01-19 10:20:56 DEBUG [main] t.c.s.c.autoconfigure.ValidatorAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Validator' completed initialization.
2026-01-19 10:20:56 DEBUG [main] t.c.s.m.mail.autoconfigure.MailAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Mail' completed initialization.
2026-01-19 10:20:56 DEBUG [main] t.c.s.m.w.autoconfigure.WebSocketAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Messaging-WebSocket' completed initialization.
2026-01-19 10:20:56 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register container bean [fileInfoContainer] bean from spring context, actual namespace is [FileInfo]
2026-01-19 10:20:56 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register container provider [crane4jApplicationContext] from spring context
2026-01-19 10:20:56 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register property mapping strategy manager [joinAsStringMappingStrategy](cn.crane4j.core.parser.handler.strategy.CollJoinAsStringMappingStrategy@cd7871e) from spring context
2026-01-19 10:20:56 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register property mapping strategy manager [overwriteNotNullMappingStrategy](cn.crane4j.core.parser.handler.strategy.OverwriteNotNullMappingStrategy@b14a2c) from spring context
2026-01-19 10:20:56 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register property mapping strategy manager [overwriteMappingStrategy](cn.crane4j.core.parser.handler.strategy.OverwriteMappingStrategy@b7da2c4) from spring context
2026-01-19 10:20:56 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register property mapping strategy manager [referenceMappingStrategy](cn.crane4j.core.parser.handler.strategy.ReferenceMappingStrategy@3a7c75d9) from spring context
2026-01-19 10:20:56 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [ProductNameAvatar] for method [public java.util.List top.ysoft.admin.equipment.service.impl.ProductServiceImpl.getProductNameAvatarList()], mapping type is [ONE_TO_ONE]
2026-01-19 10:20:56 WARN [main] c.c.c.s.container.DefaultMethodContainerFactory - The container method [public java.util.List top.ysoft.admin.equipment.service.impl.ProductServiceImpl.getProductNameAvatarList()] has no parameters, but it is set skipQueryIfKeyCollIsEmpty= true, Therefore, the method will never be called. Is this correct?
2026-01-19 10:20:56 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [PostName] for method [public java.lang.String top.ysoft.admin.post.service.impl.PostServiceImpl.getPostName(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:20:56 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [SpaceName] for method [public java.lang.String top.ysoft.admin.space.service.impl.SpaceServiceImpl.getSpaceNameById(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:20:56 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserRoleNameList] for method [public java.util.List top.ysoft.admin.system.service.impl.RoleServiceImpl.listNameByIds(java.util.List)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:20:56 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserRoleIdList] for method [public java.util.List top.ysoft.admin.system.service.impl.UserRoleServiceImpl.listRoleIdByUserId(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:20:56 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserNameList] for method [public java.util.List top.ysoft.admin.system.service.impl.UserServiceImpl.listNameByIds(java.util.List)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:20:56 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserName] for method [public java.lang.String top.ysoft.admin.system.service.impl.UserServiceImpl.userNameByIds(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:20:56 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserNickname] for method [public abstract java.lang.String top.ysoft.admin.common.service.CommonUserService.getNicknameById(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:20:56 DEBUG [main] t.c.s.j.j.autoconfigure.JacksonAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Jackson' completed initialization.
2026-01-19 10:20:56 DEBUG [main] t.c.s.c.a.threadpool.AsyncAutoConfiguration - [ContiNew Starter] - Auto Configuration 'AsyncConfigurer' completed initialization.
2026-01-19 10:20:57 DEBUG [main] top.continew.starter.log.LogFilter - Filter 'logFilter' configured for use
2026-01-19 10:20:57 INFO [main] io.undertow - starting server: Undertow - 2.3.17.Final
2026-01-19 10:20:57 INFO [main] org.xnio - XNIO version 3.8.16.Final
2026-01-19 10:20:57 INFO [main] org.xnio.nio - XNIO NIO Implementation Version 3.8.16.Final
2026-01-19 10:20:57 INFO [main] org.jboss.threads - JBoss Threads version 3.5.0.Final
2026-01-19 10:20:57 INFO [main] o.s.boot.web.embedded.undertow.UndertowWebServer - Undertow started on port 6609 (http)
2026-01-19 10:20:57 INFO [main] top.ysoft.admin.YsoftAdminApplication - Started YsoftAdminApplication in 15.268 seconds (process running for 17.266)
2026-01-19 10:20:57 INFO [main] c.c.s.b.c.Crane4jAutoConfiguration$Crane4jInitializer - crane4j component initialization completed.
2026-01-19 10:20:57 INFO [main] o.d.x.file.storage.core.FileStorageServiceBuilder - 加载 Amazon S3 存储平台minio
2026-01-19 10:30:00 INFO [JetCacheDefaultExecutor] com.alicp.jetcache.support.StatInfoLogger - jetcache stat from 2026-01-19 10:20:55,520 to 2026-01-19 10:30:00,013
cache | qps| rate| get| hit| fail| expire|avgLoadTime|maxLoadTime
------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------
USER: | 0.00| 0.00%| 1| 0| 0| 0| 78.0| 78
USER:_local | 0.00| 0.00%| 1| 0| 0| 0| 0.0| 0
USER:_remote| 0.00| 0.00%| 1| 0| 0| 0| 0.0| 0
------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------
2026-01-19 10:32:57 INFO [XNIO-1 task-3] io.undertow.servlet - Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-01-19 10:32:57 INFO [XNIO-1 task-3] org.springframework.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2026-01-19 10:32:57 INFO [XNIO-1 task-3] org.springframework.web.servlet.DispatcherServlet - Completed initialization in 4 ms
2026-01-19 10:32:57 DEBUG [XNIO-1 task-2] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165236278558273537] Mapped to top.ysoft.admin.controller.common.CaptchaController#getImageCaptcha()
2026-01-19 10:32:57 DEBUG [XNIO-1 task-3] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165236278558273536] Mapped to top.ysoft.admin.controller.common.CommonController#listSiteOptionDict()
2026-01-19 10:32:57 INFO [XNIO-1 task-3] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236278558273536] [GET] /common/dict/option/site
2026-01-19 10:32:57 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236278558273537] [GET] /captcha/image
2026-01-19 10:32:58 INFO [XNIO-1 task-3] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236278558273536] [GET] /common/dict/option/site 200 233ms
2026-01-19 10:32:58 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236278558273537] [GET] /captcha/image 200 566ms
2026-01-19 10:33:03 DEBUG [XNIO-1 task-2] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165236301333344256] Mapped to top.ysoft.admin.controller.common.CaptchaController#getImageCaptcha()
2026-01-19 10:33:03 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236301333344256] [GET] /captcha/image
2026-01-19 10:33:03 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236301333344256] [GET] /captcha/image 200 166ms
2026-01-19 10:33:10 DEBUG [XNIO-1 task-2] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165236332908064768] Mapped to top.ysoft.admin.controller.common.CaptchaController#getImageCaptcha()
2026-01-19 10:33:10 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236332908064768] [GET] /captcha/image
2026-01-19 10:33:10 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236332908064768] [GET] /captcha/image 200 116ms
2026-01-19 10:33:16 DEBUG [XNIO-1 task-2] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165236356425527296] Mapped to top.ysoft.admin.controller.common.CommonController#listSiteOptionDict()
2026-01-19 10:33:16 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236356425527296] [GET] /common/dict/option/site
2026-01-19 10:33:16 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236356425527296] [GET] /common/dict/option/site 200 31ms
2026-01-19 10:33:16 DEBUG [XNIO-1 task-2] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165236356849152000] Mapped to top.ysoft.admin.controller.common.CaptchaController#getImageCaptcha()
2026-01-19 10:33:16 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236356849152000] [GET] /captcha/image
2026-01-19 10:33:16 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165236356849152000] [GET] /captcha/image 200 132ms
2026-01-19 10:33:28 INFO [SpringApplicationShutdownHook] m.a.c.spring.redis.SpringRedisMachineIdDistributor - Revert Remote [MachineState{machineId=15, lastTimeStamp=1768790008773}] instanceId:[InstanceId{instanceId=192.168.2.21:31392, stable=false}] @ namespace:[ysoft-admin].
2026-01-19 10:33:28 INFO [SpringApplicationShutdownHook] io.undertow - stopping server: Undertow - 2.3.17.Final
2026-01-19 10:33:28 INFO [SpringApplicationShutdownHook] io.undertow.servlet - Destroying Spring FrameworkServlet 'dispatcherServlet'
2026-01-19 10:33:30 INFO [SpringApplicationShutdownHook] com.alicp.jetcache.support.DefaultMetricsManager - cache stat canceled
2026-01-19 10:33:30 INFO [SpringApplicationShutdownHook] c.c.extension.spring.Crane4jApplicationContext - global configuration has been destroyed.
2026-01-19 10:33:30 INFO [SpringApplicationShutdownHook] cn.crane4j.core.container.DefaultContainerManager - clear all cache for container manager
2026-01-19 10:33:30 INFO [SpringApplicationShutdownHook] o.dromara.x.file.storage.core.FileStorageService - 销毁存储平台 minio 成功
2026-01-19 10:33:30 INFO [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2026-01-19 10:33:31 INFO [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2026-01-19 10:33:31 WARN [SpringApplicationShutdownHook] o.s.beans.factory.support.DisposableBeanAdapter - Invocation of destroy method failed on bean with name 'methodResultAutoOperateAdvisor': org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'methodResultAutoOperateSupport': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
2026-01-19 10:33:31 WARN [SpringApplicationShutdownHook] o.s.beans.factory.support.DisposableBeanAdapter - Invocation of destroy method failed on bean with name 'methodArgumentAutoOperateAdvisor': org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'argAutoOperateProxyMethodFactory': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
2026-01-19 10:33:34 INFO [background-preinit] org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 8.0.1.Final
2026-01-19 10:33:34 INFO [main] top.ysoft.admin.YsoftAdminApplication - Starting YsoftAdminApplication using Java 21.0.6 with PID 19420 (D:\ysoft\ysoft-admin\ysoft-webapi\target\classes started by jingy in D:\ysoft\ysoft-admin)
2026-01-19 10:33:34 INFO [main] top.ysoft.admin.YsoftAdminApplication - The following 2 profiles are active: "generator", "prod"
2026-01-19 10:33:35 INFO [main] o.s.d.r.config.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2026-01-19 10:33:35 INFO [main] o.s.d.r.config.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2026-01-19 10:33:35 INFO [main] o.s.d.r.config.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 73 ms. Found 0 Redis repository interfaces.
2026-01-19 10:33:35 WARN [main] org.mybatis.spring.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[top.ysoft.admin]' package. Please check your configuration.
2026-01-19 10:33:36 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'cn.crane4j.spring.boot.config.Crane4jAutoConfiguration' of type [cn.crane4j.spring.boot.config.Crane4jAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). The currently created BeanPostProcessor [namedComponentAliasProcessor] is declared through a non-static factory method on that class; consider declaring it as static instead.
2026-01-19 10:33:36 DEBUG [main] t.c.s.e.c.a.CrudRestControllerAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Extension-CRUD REST Controller' completed initialization.
2026-01-19 10:33:36 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'top.continew.starter.extension.crud.autoconfigure.CrudRestControllerAutoConfiguration' of type [top.continew.starter.extension.crud.autoconfigure.CrudRestControllerAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:33:36 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'crudApiAnnotationInterceptor' of type [top.continew.starter.extension.crud.aop.CrudApiAnnotationInterceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:33:36 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'crudApiAnnotationAdvisor' of type [top.continew.starter.extension.crud.aop.CrudApiAnnotationAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:33:36 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'com.alicp.jetcache.anno.config.JetCacheProxyConfiguration' of type [com.alicp.jetcache.anno.config.JetCacheProxyConfiguration$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:33:36 WARN [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'com.alicp.jetcache.anno.config.CommonConfiguration' of type [com.alicp.jetcache.anno.config.CommonConfiguration$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [namedComponentAliasProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2026-01-19 10:33:36 WARN [main] io.undertow.websockets.jsr - UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
2026-01-19 10:33:36 INFO [main] io.undertow.servlet - Initializing Spring embedded WebApplicationContext
2026-01-19 10:33:36 INFO [main] o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 2272 ms
2026-01-19 10:33:36 DEBUG [main] t.c.s.w.autoconfigure.trace.TraceAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Web-Trace' completed initialization.
2026-01-19 10:33:36 DEBUG [main] t.c.starter.log.autoconfigure.LogAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Log-Interceptor' completed initialization.
2026-01-19 10:33:36 DEBUG [main] t.c.s.web.autoconfigure.cors.CorsAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Web-CorsFilter' completed initialization.
2026-01-19 10:33:36 DEBUG [main] t.c.s.d.m.a.MybatisPlusAutoConfiguration - [ContiNew Starter] - Auto Configuration 'MyBatis Plus' completed initialization.
2026-01-19 10:33:36 DEBUG [main] t.c.s.e.d.a.DataPermissionAutoConfiguration - [ContiNew Starter] - Auto Configuration 'DataPermission' completed initialization.
2026-01-19 10:33:36 DEBUG [main] t.c.s.s.c.autoconfigure.CryptoAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Security-Crypto' completed initialization.
2026-01-19 10:33:36 DEBUG [main] t.c.s.d.m.a.i.MyBatisPlusIdGeneratorConfiguration - [ContiNew Starter] - Auto Configuration 'MyBatis Plus-IdGenerator-CosId' completed initialization.
2026-01-19 10:33:37 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.peopleBranch.model.entity.BranchRuleDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:33:37 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.system.model.entity.MessageUserDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:33:37 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.system.model.entity.RoleMenuDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:33:37 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.system.model.entity.RuleRelationDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:33:37 INFO [main] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2026-01-19 10:33:38 INFO [main] com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection com.p6spy.engine.wrapper.ConnectionWrapper@25291901
2026-01-19 10:33:38 INFO [main] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2026-01-19 10:33:39 INFO [main] liquibase.changelog - Reading from ysoft_admin.DATABASECHANGELOG
2026-01-19 10:33:39 INFO [main] liquibase.changelog - Reading from ysoft_admin.DATABASECHANGELOG
2026-01-19 10:33:39 INFO [main] liquibase.util - UPDATE SUMMARY
2026-01-19 10:33:39 INFO [main] liquibase.util - Run: 0
2026-01-19 10:33:39 INFO [main] liquibase.util - Previously run: 0
2026-01-19 10:33:39 INFO [main] liquibase.util - Filtered out: 0
2026-01-19 10:33:39 INFO [main] liquibase.util - -------------------------------
2026-01-19 10:33:39 INFO [main] liquibase.util - Total change sets: 0
2026-01-19 10:33:39 INFO [main] liquibase.util - Update summary generated
2026-01-19 10:33:39 INFO [main] liquibase.lockservice - Successfully released change log lock
2026-01-19 10:33:39 INFO [main] liquibase.command - Command execution complete
2026-01-19 10:33:39 DEBUG [main] t.c.s.s.p.a.PasswordEncoderAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Security-PasswordEncoder' completed initialization.
2026-01-19 10:33:39 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.system.model.entity.RoleDeptDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:33:39 DEBUG [main] t.c.s.c.a.threadpool.ThreadPoolAutoConfiguration - [ContiNew Starter] - Auto Configuration 'TaskExecutor' completed initialization.
2026-01-19 10:33:39 DEBUG [main] t.c.s.a.j.autoconfigure.JustAuthAutoConfiguration - [ContiNew Starter] - Auto Configuration 'JustAuth' completed initialization.
2026-01-19 10:33:39 DEBUG [main] t.c.s.a.j.autoconfigure.JustAuthAutoConfiguration - [ContiNew Starter] - Auto Configuration 'JustAuth-AuthStateCache-Redis' completed initialization.
2026-01-19 10:33:40 INFO [main] c.anji.captcha.service.impl.CaptchaServiceFactory - supported-captchaCache-service:[local]
2026-01-19 10:33:40 INFO [main] c.anji.captcha.service.impl.CaptchaServiceFactory - supported-captchaTypes-service:[clickWord, default, blockPuzzle]
2026-01-19 10:33:40 DEBUG [main] t.c.s.c.b.a.c.BehaviorCaptchaCacheAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Captcha-Behavior-Cache-Redis' completed initialization.
2026-01-19 10:33:40 DEBUG [main] t.c.s.c.b.a.BehaviorCaptchaAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Captcha-Behavior' completed initialization.
2026-01-19 10:33:40 INFO [main] com.anji.captcha.util.ImageUtils - 初始化底图:[SLIDING_BLOCK=[Ljava.lang.String;@7a174e4b, ORIGINAL=[Ljava.lang.String;@7a8316fa, PIC_CLICK=[Ljava.lang.String;@46a5aff]
2026-01-19 10:33:40 INFO [main] c.a.c.service.impl.BlockPuzzleCaptchaServiceImpl - --->>>初始化验证码底图<<<---blockPuzzle
2026-01-19 10:33:40 DEBUG [main] t.c.s.c.g.a.GraphicCaptchaAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Captcha-Graphic' completed initialization.
2026-01-19 10:33:40 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.equipment.model.entity.PeopleUpperDeviceDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:33:40 WARN [main] c.b.mybatisplus.core.injector.DefaultSqlInjector - class top.ysoft.admin.post.model.entity.PeoplePostDO ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2026-01-19 10:33:41 DEBUG [main] t.c.s.j.j.autoconfigure.JacksonAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Jackson' completed initialization.
2026-01-19 10:33:41 DEBUG [main] t.c.s.s.l.a.RateLimiterAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Security-RateLimiter' completed initialization.
2026-01-19 10:33:41 DEBUG [main] t.c.s.c.r.autoconfigure.RedissonAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Redisson' completed initialization.
2026-01-19 10:33:41 INFO [main] org.redisson.Version - Redisson 3.41.0
2026-01-19 10:33:41 INFO [redisson-netty-1-6] org.redisson.connection.ConnectionsHolder - 1 connections initialized for 121.199.16.218/121.199.16.218:6379
2026-01-19 10:33:42 INFO [redisson-netty-1-19] org.redisson.connection.ConnectionsHolder - 24 connections initialized for 121.199.16.218/121.199.16.218:6379
2026-01-19 10:33:42 DEBUG [main] t.c.s.w.a.response.GlobalResponseAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Web-Global Response' completed initialization.
2026-01-19 10:33:42 DEBUG [main] t.c.s.a.autoconfigure.SpringDocAutoConfiguration - [ContiNew Starter] - Auto Configuration 'ApiDoc' completed initialization.
2026-01-19 10:33:43 DEBUG [main] t.c.s.a.s.autoconfigure.SaTokenAutoConfiguration - [ContiNew Starter] - Auto Configuration 'SaToken' completed initialization.
2026-01-19 10:33:43 DEBUG [main] t.c.s.w.autoconfigure.mvc.WebMvcAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Web MVC' completed initialization.
2026-01-19 10:33:43 DEBUG [main] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - 264 mappings in 'requestMappingHandlerMapping'
2026-01-19 10:33:43 INFO [main] c.c.extension.spring.Crane4jApplicationContext - install container lifecycle processor [containerInstanceLifecycleProcessor]
2026-01-19 10:33:43 INFO [main] c.c.extension.spring.Crane4jApplicationContext - install container lifecycle processor [containerRegisterLogger]
2026-01-19 10:33:43 INFO [main] c.c.extension.spring.Crane4jApplicationContext - install container lifecycle processor [springCacheableContainerProcessor]
2026-01-19 10:33:43 INFO [main] c.c.extension.spring.BeanMethodContainerRegistrar - register method container factory [cn.crane4j.core.support.container.CacheableMethodContainerFactory] with name [cacheableMethodContainerFactory]
2026-01-19 10:33:43 DEBUG [main] t.c.s.a.s.a.dao.SaTokenDaoConfiguration - [ContiNew Starter] - Auto Configuration 'SaToken-Dao-Redis' completed initialization.
2026-01-19 10:33:43 INFO [main] c.a.jetcache.autoconfigure.AbstractCacheAutoInit - init cache area default , type= caffeine
2026-01-19 10:33:43 INFO [main] c.a.jetcache.autoconfigure.AbstractCacheAutoInit - init cache area default , type= redisson
2026-01-19 10:33:43 INFO [main] com.alicp.jetcache.support.DefaultMetricsManager - cache stat period at 15 MINUTES
2026-01-19 10:33:43 INFO [main] m.a.c.spring.redis.SpringRedisMachineIdDistributor - Distribute Remote instanceId:[InstanceId{instanceId=192.168.2.21:19420, stable=false}] - machineBit:[10] @ namespace:[ysoft-admin].
2026-01-19 10:33:43 INFO [main] m.a.c.spring.redis.SpringRedisMachineIdDistributor - Distribute Remote machineState:[MachineState{machineId=15, lastTimeStamp=1768790023737}] - instanceId:[InstanceId{instanceId=192.168.2.21:19420, stable=false}] - machineBit:[10] @ namespace:[ysoft-admin].
2026-01-19 10:33:44 DEBUG [main] t.c.s.c.j.autoconfigure.JetCacheAutoConfiguration - [ContiNew Starter] - Auto Configuration 'JetCache' completed initialization.
2026-01-19 10:33:44 DEBUG [main] t.c.s.c.autoconfigure.ValidatorAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Validator' completed initialization.
2026-01-19 10:33:44 DEBUG [main] t.c.s.m.mail.autoconfigure.MailAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Mail' completed initialization.
2026-01-19 10:33:44 DEBUG [main] t.c.s.m.w.autoconfigure.WebSocketAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Messaging-WebSocket' completed initialization.
2026-01-19 10:33:44 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register container bean [fileInfoContainer] bean from spring context, actual namespace is [FileInfo]
2026-01-19 10:33:44 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register container provider [crane4jApplicationContext] from spring context
2026-01-19 10:33:44 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register property mapping strategy manager [joinAsStringMappingStrategy](cn.crane4j.core.parser.handler.strategy.CollJoinAsStringMappingStrategy@48f38142) from spring context
2026-01-19 10:33:44 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register property mapping strategy manager [overwriteNotNullMappingStrategy](cn.crane4j.core.parser.handler.strategy.OverwriteNotNullMappingStrategy@16e693c1) from spring context
2026-01-19 10:33:44 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register property mapping strategy manager [overwriteMappingStrategy](cn.crane4j.core.parser.handler.strategy.OverwriteMappingStrategy@43a2b00c) from spring context
2026-01-19 10:33:44 INFO [main] c.c.extension.spring.Crane4jApplicationContext - register property mapping strategy manager [referenceMappingStrategy](cn.crane4j.core.parser.handler.strategy.ReferenceMappingStrategy@5192abb4) from spring context
2026-01-19 10:33:44 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [ProductNameAvatar] for method [public java.util.List top.ysoft.admin.equipment.service.impl.ProductServiceImpl.getProductNameAvatarList()], mapping type is [ONE_TO_ONE]
2026-01-19 10:33:44 WARN [main] c.c.c.s.container.DefaultMethodContainerFactory - The container method [public java.util.List top.ysoft.admin.equipment.service.impl.ProductServiceImpl.getProductNameAvatarList()] has no parameters, but it is set skipQueryIfKeyCollIsEmpty= true, Therefore, the method will never be called. Is this correct?
2026-01-19 10:33:44 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [PostName] for method [public java.lang.String top.ysoft.admin.post.service.impl.PostServiceImpl.getPostName(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:33:44 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [SpaceName] for method [public java.lang.String top.ysoft.admin.space.service.impl.SpaceServiceImpl.getSpaceNameById(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:33:44 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserRoleNameList] for method [public java.util.List top.ysoft.admin.system.service.impl.RoleServiceImpl.listNameByIds(java.util.List)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:33:44 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserRoleIdList] for method [public java.util.List top.ysoft.admin.system.service.impl.UserRoleServiceImpl.listRoleIdByUserId(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:33:44 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserNameList] for method [public java.util.List top.ysoft.admin.system.service.impl.UserServiceImpl.listNameByIds(java.util.List)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:33:44 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserName] for method [public java.lang.String top.ysoft.admin.system.service.impl.UserServiceImpl.userNameByIds(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:33:44 INFO [main] c.c.c.s.container.MethodInvokerContainerCreator - create method invoker container [UserNickname] for method [public abstract java.lang.String top.ysoft.admin.common.service.CommonUserService.getNicknameById(java.lang.Long)], mapping type is [ORDER_OF_KEYS]
2026-01-19 10:33:44 DEBUG [main] t.c.s.j.j.autoconfigure.JacksonAutoConfiguration - [ContiNew Starter] - Auto Configuration 'Jackson' completed initialization.
2026-01-19 10:33:44 DEBUG [main] t.c.s.c.a.threadpool.AsyncAutoConfiguration - [ContiNew Starter] - Auto Configuration 'AsyncConfigurer' completed initialization.
2026-01-19 10:33:44 DEBUG [main] top.continew.starter.log.LogFilter - Filter 'logFilter' configured for use
2026-01-19 10:33:44 INFO [main] io.undertow - starting server: Undertow - 2.3.17.Final
2026-01-19 10:33:44 INFO [main] org.xnio - XNIO version 3.8.16.Final
2026-01-19 10:33:44 INFO [main] org.xnio.nio - XNIO NIO Implementation Version 3.8.16.Final
2026-01-19 10:33:44 INFO [main] org.jboss.threads - JBoss Threads version 3.5.0.Final
2026-01-19 10:33:44 INFO [main] o.s.boot.web.embedded.undertow.UndertowWebServer - Undertow started on port 6609 (http)
2026-01-19 10:33:44 INFO [main] top.ysoft.admin.YsoftAdminApplication - Started YsoftAdminApplication in 11.083 seconds (process running for 11.84)
2026-01-19 10:33:44 INFO [main] c.c.s.b.c.Crane4jAutoConfiguration$Crane4jInitializer - crane4j component initialization completed.
2026-01-19 10:33:45 INFO [main] o.d.x.file.storage.core.FileStorageServiceBuilder - 加载 Amazon S3 存储平台minio
2026-01-19 10:45:00 INFO [JetCacheDefaultExecutor] com.alicp.jetcache.support.StatInfoLogger - jetcache stat from 2026-01-19 10:33:43,615 to 2026-01-19 10:45:00,012
cache | qps| rate| get| hit| fail| expire|avgLoadTime|maxLoadTime
------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------
USER: | 0.00|100.00%| 1| 1| 0| 0| 0.0| 0
USER:_local | 0.00| 0.00%| 1| 0| 0| 0| 0.0| 0
USER:_remote| 0.00|100.00%| 1| 1| 0| 0| 0.0| 0
------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------
2026-01-19 11:00:00 INFO [JetCacheDefaultExecutor] com.alicp.jetcache.support.StatInfoLogger - jetcache stat from 2026-01-19 10:45:00,012 to 2026-01-19 11:00:00,008
cache | qps| rate| get| hit| fail| expire|avgLoadTime|maxLoadTime
------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------
USER: | 0.00| 0.00%| 0| 0| 0| 0| 0.0| 0
USER:_local | 0.00| 0.00%| 0| 0| 0| 0| 0.0| 0
USER:_remote| 0.00| 0.00%| 0| 0| 0| 0| 0.0| 0
------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------
2026-01-19 11:15:00 INFO [JetCacheDefaultExecutor] com.alicp.jetcache.support.StatInfoLogger - jetcache stat from 2026-01-19 11:00:00,008 to 2026-01-19 11:15:00,002
cache | qps| rate| get| hit| fail| expire|avgLoadTime|maxLoadTime
------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------
USER: | 0.00| 0.00%| 0| 0| 0| 0| 0.0| 0
USER:_local | 0.00| 0.00%| 0| 0| 0| 0| 0.0| 0
USER:_remote| 0.00| 0.00%| 0| 0| 0| 0| 0.0| 0
------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------
2026-01-19 11:23:29 INFO [XNIO-1 task-2] io.undertow.servlet - Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-01-19 11:23:29 INFO [XNIO-1 task-2] org.springframework.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2026-01-19 11:23:29 INFO [XNIO-1 task-2] org.springframework.web.servlet.DispatcherServlet - Completed initialization in 51 ms
2026-01-19 11:23:29 DEBUG [XNIO-1 task-3] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165248992630353920] Mapped to top.ysoft.admin.controller.common.CaptchaController#getImageCaptcha()
2026-01-19 11:23:29 DEBUG [XNIO-1 task-2] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165248992630353921] Mapped to top.ysoft.admin.controller.common.CommonController#listSiteOptionDict()
2026-01-19 11:23:29 INFO [XNIO-1 task-3] t.continew.starter.log.interceptor.LogInterceptor - [0][1165248992630353920] [GET] /captcha/image
2026-01-19 11:23:29 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165248992630353921] [GET] /common/dict/option/site
2026-01-19 11:23:29 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165248992630353921] [GET] /common/dict/option/site 200 498ms
2026-01-19 11:23:29 INFO [XNIO-1 task-3] t.continew.starter.log.interceptor.LogInterceptor - [0][1165248992630353920] [GET] /captcha/image 200 498ms
2026-01-19 11:23:31 DEBUG [XNIO-1 task-2] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165249001434198016] Mapped to top.ysoft.admin.controller.common.CaptchaController#getImageCaptcha()
2026-01-19 11:23:31 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165249001434198016] [GET] /captcha/image
2026-01-19 11:23:31 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165249001434198016] [GET] /captcha/image 200 100ms
2026-01-19 11:23:38 DEBUG [XNIO-1 task-2] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165249032904060928] Mapped to top.ysoft.admin.controller.common.CaptchaController#getImageCaptcha()
2026-01-19 11:23:38 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165249032904060928] [GET] /captcha/image
2026-01-19 11:23:38 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165249032904060928] [GET] /captcha/image 200 98ms
2026-01-19 11:23:46 DEBUG [XNIO-1 task-2] t.c.s.e.c.a.CrudRequestMappingHandlerMapping - [0][1165249066890506240] Mapped to top.ysoft.admin.controller.common.CaptchaController#getImageCaptcha()
2026-01-19 11:23:46 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165249066890506240] [GET] /captcha/image
2026-01-19 11:23:47 INFO [XNIO-1 task-2] t.continew.starter.log.interceptor.LogInterceptor - [0][1165249066890506240] [GET] /captcha/image 200 209ms
2026-01-19 11:24:27 INFO [SpringApplicationShutdownHook] m.a.c.spring.redis.SpringRedisMachineIdDistributor - Revert Remote [MachineState{machineId=15, lastTimeStamp=1768793067999}] instanceId:[InstanceId{instanceId=192.168.2.21:19420, stable=false}] @ namespace:[ysoft-admin].
2026-01-19 11:24:28 INFO [SpringApplicationShutdownHook] io.undertow - stopping server: Undertow - 2.3.17.Final
2026-01-19 11:24:28 INFO [SpringApplicationShutdownHook] io.undertow.servlet - Destroying Spring FrameworkServlet 'dispatcherServlet'
2026-01-19 11:24:30 INFO [SpringApplicationShutdownHook] com.alicp.jetcache.support.DefaultMetricsManager - cache stat canceled
2026-01-19 11:24:30 INFO [SpringApplicationShutdownHook] c.c.extension.spring.Crane4jApplicationContext - global configuration has been destroyed.
2026-01-19 11:24:30 INFO [SpringApplicationShutdownHook] cn.crane4j.core.container.DefaultContainerManager - clear all cache for container manager
2026-01-19 11:24:30 INFO [SpringApplicationShutdownHook] o.dromara.x.file.storage.core.FileStorageService - 销毁存储平台 minio 成功
2026-01-19 11:24:30 INFO [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2026-01-19 11:24:30 INFO [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2026-01-19 11:24:30 WARN [SpringApplicationShutdownHook] o.s.beans.factory.support.DisposableBeanAdapter - Invocation of destroy method failed on bean with name 'methodResultAutoOperateAdvisor': org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'methodResultAutoOperateSupport': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
2026-01-19 11:24:30 WARN [SpringApplicationShutdownHook] o.s.beans.factory.support.DisposableBeanAdapter - Invocation of destroy method failed on bean with name 'methodArgumentAutoOperateAdvisor': org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'argAutoOperateProxyMethodFactory': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)

7
lombok.config Normal file
View File

@@ -0,0 +1,7 @@
config.stopBubbling=true
lombok.toString.callSuper=CALL
lombok.equalsAndHashCode.callSuper=CALL
clear lombok.val.flagUsage
lombok.val.flagUsage=ERROR
clear lombok.accessors.flagUsage
lombok.accessors.flagUsage=ERROR

264
pom.xml Normal file
View File

@@ -0,0 +1,264 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--
下方 parent 为 ContiNew StarterContinue New Starter
ContiNew StarterContinue New Starter基于“约定优于配置”的理念
再次精简常规配置,提供一个更为完整的配置解决方案,帮助开发人员更加快速的集成常用第三方库或工具到 Spring Boot Web 应用程序中。
ContiNew Starter 包含了一系列经过企业实践优化的依赖包(如 MyBatis-Plus、SaToken
可轻松集成到应用中,为开发人员减少手动引入依赖及配置的麻烦,为 Spring Boot Web 项目的灵活快速构建提供支持。
-->
<parent>
<groupId>top.continew</groupId>
<artifactId>continew-starter</artifactId>
<version>2.9.0</version>
</parent>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-admin</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<description>园区管理系统</description>
<url>https://github.com/ysoft-org/ysoft-admin</url>
<modules>
<module>ysoft-webapi</module>
<module>ysoft-module-system</module>
<module>ysoft-plugin</module>
<module>ysoft-common</module>
<module>ysoft-extension</module>
</modules>
<properties>
<!-- 项目版本号 -->
<revision>3.6.0-SNAPSHOT</revision>
</properties>
<!-- 全局依赖版本管理 -->
<dependencyManagement>
<dependencies>
<!-- API 模块(存放 Controller 层代码,打包部署的模块) -->
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-webapi</artifactId>
<version>${revision}</version>
</dependency>
<!-- 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等) -->
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-module-system</artifactId>
<version>${revision}</version>
</dependency>
<!-- 公共模块(存放公共工具类,公共配置等) -->
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-common</artifactId>
<version>${revision}</version>
</dependency>
<!-- 任务调度插件(后续会改造为独立插件) -->
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-plugin-schedule</artifactId>
<version>${revision}</version>
</dependency>
<!-- 能力开放插件(后续会改造为独立插件) -->
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-plugin-open</artifactId>
<version>${revision}</version>
</dependency>
<!-- 代码生成器插件(后续会改造为独立插件) -->
<dependency>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-plugin-generator</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Hutool小而全的 Java 工具类库,通过静态方法封装,降低相关 API 的学习成本,提高工作效率,使 Java 拥有函数式语言般的优雅,让 Java 语言也可以“甜甜的”) -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!-- Lombok在 Java 开发过程中用注解的方式,简化了 JavaBean 的编写,避免了冗余和样板式代码,让编写的类更加简洁) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional> <!-- 表示依赖不会被传递 -->
</dependency>
<!-- 引入mapstruct实现类对象的转换 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</dependency>
<!-- Apache Commons FileUpload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- Apache Commons IO -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
<!-- 单元测试相关插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- 跳过单元测试 -->
<skip>true</skip>
</configuration>
</plugin>
<!-- 代码格式化插件 -->
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>apply</goal>
</goals>
</execution>
</executions>
<configuration>
<java>
<removeUnusedImports/>
<eclipse>
<file>.style/p3c-codestyle.xml</file>
</eclipse>
<licenseHeader>
<file>.style/license-header</file>
</licenseHeader>
</java>
</configuration>
</plugin>
<!-- 统一版本号插件 -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten-clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<!-- Sonar 代码质量分析 -->
<profile>
<id>sonar</id>
<properties>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<sonar.organization>charles7c</sonar.organization>
<sonar.projectKey>Charles7c_ysoft-admin</sonar.projectKey>
<sonar.moduleKey>${project.groupId}:${project.artifactId}</sonar.moduleKey>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sonar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<!-- 依赖仓库配置 -->
<repositories>
<repository>
<id>huawei-mirror</id>
<name>HuaweiCloud Mirror</name>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
</repository>
<repository>
<id>ali-mirror</id>
<name>AliYun Mirror</name>
<url>https://maven.aliyun.com/repository/public/</url>
</repository>
</repositories>
<!-- 插件仓库配置 -->
<pluginRepositories>
<pluginRepository>
<id>huawei-mirror</id>
<name>HuaweiCloud Mirror</name>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
</pluginRepository>
<pluginRepository>
<id>ali-mirror</id>
<name>AliYun Mirror</name>
<url>https://maven.aliyun.com/repository/public/</url>
</pluginRepository>
</pluginRepositories>
</project>

1
target/spotless-index Normal file
View File

@@ -0,0 +1 @@
nO9TaZSKPf1ylImyltTZX/68jGy+GEEGnIFWrxOoIa0=

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.ysoft</groupId>
<artifactId>ysoft-admin</artifactId>
<version>3.6.0-SNAPSHOT</version>
</parent>
<artifactId>ysoft-common</artifactId>
<version>3.6.0-SNAPSHOT</version>
<description>公共模块(存放公共工具类,公共配置等)</description>
<licenses>
<license>
<name>GNU LESSER GENERAL PUBLIC LICENSE</name>
<url>http://www.gnu.org/licenses/lgpl.html</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>me.ahoo.cosid</groupId>
<artifactId>cosid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>me.ahoo.cosid</groupId>
<artifactId>cosid-spring-redis</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.sms4j</groupId>
<artifactId>sms4j-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.x-file-storage</groupId>
<artifactId>x-file-storage-spring</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.25.0</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-extension-crud-mp</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-auth-satoken</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-web</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-auth-justauth</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache-jetcache</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-extension-datapermission-mp</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-messaging-websocket</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-web</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-messaging-mail</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-captcha-graphic</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-captcha-behavior</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-limiter</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-mask</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-password</artifactId>
</dependency>
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-json-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies>
</project>

159
wms-common/pom.xml Normal file
View File

@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
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>top.ysoft</groupId>
<artifactId>ysoft-admin</artifactId>
<version>${revision}</version>
</parent>
<artifactId>ysoft-common</artifactId>
<description>公共模块(存放公共工具类,公共配置等)</description>
<dependencies>
<!-- CosId通用、灵活、高性能的分布式 ID 生成器) -->
<dependency>
<groupId>me.ahoo.cosid</groupId>
<artifactId>cosid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>me.ahoo.cosid</groupId>
<artifactId>cosid-spring-redis</artifactId>
</dependency>
<!-- SMS4J短信聚合框架轻松集成多家短信服务解决接入多个短信 SDK 的繁琐流程) -->
<dependency>
<groupId>org.dromara.sms4j</groupId>
<artifactId>sms4j-spring-boot-starter</artifactId>
</dependency>
<!-- X File Storage一行代码将文件存储到本地、FTP、SFTP、WebDAV、阿里云 OSS、华为云 OBS...等其它兼容 S3 协议的存储平台) -->
<dependency>
<groupId>org.dromara.x-file-storage</groupId>
<artifactId>x-file-storage-spring</artifactId>
<version>2.2.1</version>
</dependency>
<!-- Amazon S3Amazon Simple Storage Service亚马逊简单存储服务通用存储协议 S3兼容主流云厂商对象存储 -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.25.0</version>
</dependency>
<!-- FreeMarker模板引擎 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<!-- MySQL Java 驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- ContiNew Starter 扩展模块 - CURD增删改查 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-extension-crud-mp</artifactId>
</dependency>
<!-- ContiNew Starter 认证模块 - SaToken -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-auth-satoken</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- ContiNew Starter 认证模块 - JustAuth -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-auth-justauth</artifactId>
</dependency>
<!-- ContiNew Starter 缓存模块 - JetCache -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-cache-jetcache</artifactId>
</dependency>
<!-- ContiNew Starter 数据权限模块 - MyBatis Plus -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-extension-datapermission-mp</artifactId>
</dependency>
<!-- ContiNew Starter 消息模块 - WebSocket -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-messaging-websocket</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- ContiNew Starter 消息模块 - 邮件 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-messaging-mail</artifactId>
</dependency>
<!-- ContiNew Starter 验证码模块 - 图形验证码 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-captcha-graphic</artifactId>
</dependency>
<!-- ContiNew Starter 验证码模块 - 行为验证码 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-captcha-behavior</artifactId>
</dependency>
<!-- ContiNew Starter 安全模块 - 限流器 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-limiter</artifactId>
</dependency>
<!-- ContiNew Starter 安全模块 - 加密 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-crypto</artifactId>
</dependency>
<!-- ContiNew Starter 安全模块 - 脱敏 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-mask</artifactId>
</dependency>
<!-- ContiNew Starter 安全模块 - 密码编码器 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-password</artifactId>
</dependency>
<!-- ContiNew Starter JSON 模块 - Jackson -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-json-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,200 @@
package top.ysoft.admin.common.config.doc;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.map.MapUtil;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.*;
import top.continew.starter.apidoc.autoconfigure.SpringDocExtensionProperties;
import top.continew.starter.auth.satoken.autoconfigure.SaTokenExtensionProperties;
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
/**
* 全局鉴权参数定制器
*
* @author echo
* @since 2024/12/31 13:36
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class GlobalAuthenticationCustomizer implements GlobalOpenApiCustomizer {
private final SpringDocExtensionProperties properties;
private final SaTokenExtensionProperties saTokenExtensionProperties;
private final ApplicationContext context;
private final AntPathMatcher pathMatcher = new AntPathMatcher();
/**
* 定制 OpenAPI 文档
*
* @param openApi 当前 OpenAPI 对象
*/
@Override
public void customise(OpenAPI openApi) {
if (MapUtil.isEmpty(openApi.getPaths())) {
return;
}
// 收集需要排除的路径(包括 Sa-Token 配置中的排除路径和 @SaIgnore 注解路径)
Set<String> excludedPaths = collectExcludedPaths();
// 遍历所有路径,为需要鉴权的路径添加安全认证配置
openApi.getPaths().forEach((path, pathItem) -> {
if (isPathExcluded(path, excludedPaths)) {
// 路径在排除列表中,跳过处理
return;
}
// 为路径添加安全认证参数
addAuthenticationParameters(pathItem);
});
}
/**
* 收集所有需要排除的路径
*
* @return 排除路径集合
*/
private Set<String> collectExcludedPaths() {
Set<String> excludedPaths = new HashSet<>();
excludedPaths.addAll(Arrays.asList(saTokenExtensionProperties.getSecurity().getExcludes()));
excludedPaths.addAll(resolveSaIgnorePaths());
return excludedPaths;
}
/**
* 为路径项添加认证参数
*
* @param pathItem 当前路径项
*/
private void addAuthenticationParameters(PathItem pathItem) {
Components components = properties.getComponents();
if (components == null || MapUtil.isEmpty(components.getSecuritySchemes())) {
return;
}
Map<String, SecurityScheme> securitySchemes = components.getSecuritySchemes();
List<String> schemeNames = securitySchemes.values().stream().map(SecurityScheme::getName).toList();
pathItem.readOperations().forEach(operation -> {
SecurityRequirement securityRequirement = new SecurityRequirement();
schemeNames.forEach(securityRequirement::addList);
operation.addSecurityItem(securityRequirement);
});
}
/**
* 解析所有带有 @SaIgnore 注解的路径
*
* @return 被忽略的路径集合
*/
private Set<String> resolveSaIgnorePaths() {
// 获取所有标注 @RestController 的 Bean
Map<String, Object> controllers = context.getBeansWithAnnotation(RestController.class);
Set<String> ignoredPaths = new HashSet<>();
// 遍历所有控制器,解析 @SaIgnore 注解路径
controllers.values().forEach(controllerBean -> {
Class<?> controllerClass = AopUtils.getTargetClass(controllerBean);
List<String> classPaths = getClassPaths(controllerClass);
// 类级别的 @SaIgnore 注解
if (controllerClass.isAnnotationPresent(SaIgnore.class)) {
classPaths.forEach(classPath -> ignoredPaths.add(classPath + "/**"));
}
// 方法级别的 @SaIgnore 注解
Arrays.stream(controllerClass.getDeclaredMethods())
.filter(method -> method.isAnnotationPresent(SaIgnore.class))
.forEach(method -> ignoredPaths.addAll(combinePaths(classPaths, getMethodPaths(method))));
});
return ignoredPaths;
}
/**
* 获取类上的所有路径
*
* @param controller 控制器类
* @return 类路径列表
*/
private List<String> getClassPaths(Class<?> controller) {
List<String> classPaths = new ArrayList<>();
// 处理 @RequestMapping 注解
if (controller.isAnnotationPresent(RequestMapping.class)) {
RequestMapping mapping = controller.getAnnotation(RequestMapping.class);
classPaths.addAll(Arrays.asList(mapping.value()));
}
// 处理 @CrudRequestMapping 注解
if (controller.isAnnotationPresent(CrudRequestMapping.class)) {
CrudRequestMapping mapping = controller.getAnnotation(CrudRequestMapping.class);
if (!mapping.value().isEmpty()) {
classPaths.add(mapping.value());
}
}
return classPaths;
}
/**
* 获取方法上的所有路径
*
* @param method 控制器方法
* @return 方法路径列表
*/
private List<String> getMethodPaths(Method method) {
List<String> methodPaths = new ArrayList<>();
// 检查方法上的各种映射注解
if (method.isAnnotationPresent(GetMapping.class)) {
methodPaths.addAll(Arrays.asList(method.getAnnotation(GetMapping.class).value()));
} else if (method.isAnnotationPresent(PostMapping.class)) {
methodPaths.addAll(Arrays.asList(method.getAnnotation(PostMapping.class).value()));
} else if (method.isAnnotationPresent(PutMapping.class)) {
methodPaths.addAll(Arrays.asList(method.getAnnotation(PutMapping.class).value()));
} else if (method.isAnnotationPresent(DeleteMapping.class)) {
methodPaths.addAll(Arrays.asList(method.getAnnotation(DeleteMapping.class).value()));
} else if (method.isAnnotationPresent(RequestMapping.class)) {
methodPaths.addAll(Arrays.asList(method.getAnnotation(RequestMapping.class).value()));
} else if (method.isAnnotationPresent(PatchMapping.class)) {
methodPaths.addAll(Arrays.asList(method.getAnnotation(PatchMapping.class).value()));
}
return methodPaths;
}
/**
* 组合类路径和方法路径
*
* @param classPaths 类路径列表
* @param methodPaths 方法路径列表
* @return 完整路径集合
*/
private Set<String> combinePaths(List<String> classPaths, List<String> methodPaths) {
return classPaths.stream()
.flatMap(classPath -> methodPaths.stream().map(methodPath -> classPath + methodPath))
.collect(Collectors.toSet());
}
/**
* 检查路径是否在排除列表中
*
* @param path 当前路径
* @param excludedPaths 排除路径集合,支持通配符
* @return 是否匹配排除规则
*/
private boolean isPathExcluded(String path, Set<String> excludedPaths) {
return excludedPaths.stream().anyMatch(pattern -> pathMatcher.match(pattern, path));
}
}

View File

@@ -0,0 +1,49 @@
package top.ysoft.admin.common.config.doc;
import cn.hutool.core.util.StrUtil;
import io.swagger.v3.oas.models.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springdoc.core.customizers.GlobalOperationCustomizer;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import java.util.ArrayList;
import java.util.List;
/**
* 全局描述定制器 - 处理 sa-token 的注解权限码
*
* @author echo
* @since 2025/1/24 14:59
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class GlobalDescriptionCustomizer implements GlobalOperationCustomizer {
@Override
public Operation customize(Operation operation, HandlerMethod handlerMethod) {
// 将 sa-token 注解数据添加到 operation 的描述中
// 权限
List<String> noteList = new ArrayList<>(new OperationDescriptionCustomizer().getPermission(handlerMethod));
// 如果注解数据列表为空,直接返回原 operation
if (noteList.isEmpty()) {
return operation;
}
// 拼接注解数据为字符串
String noteStr = StrUtil.join("<br/>", noteList);
// 获取原描述
String originalDescription = operation.getDescription();
// 根据原描述是否为空,更新描述
String newDescription = StringUtils.isNotEmpty(originalDescription)
? originalDescription + "<br/>" + noteStr
: noteStr;
// 设置新描述
operation.setDescription(newDescription);
return operation;
}
}

View File

@@ -0,0 +1,164 @@
package top.ysoft.admin.common.config.doc;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.text.CharSequenceUtil;
import org.springframework.web.method.HandlerMethod;
import top.continew.starter.core.constant.StringConstants;
import top.continew.starter.extension.crud.annotation.CrudApi;
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
import top.continew.starter.extension.crud.enums.Api;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
/**
* Operation 描述定制器 处理 sa-token 鉴权标识符
*
* @author echo
* @since 2024/6/14 11:18
*/
public class OperationDescriptionCustomizer {
/**
* 获取 sa-token 注解信息
*
* @param handlerMethod 处理程序方法
* @return 包含权限和角色校验信息的列表
*/
public List<String> getPermission(HandlerMethod handlerMethod) {
List<String> values = new ArrayList<>();
// 获取权限校验信息
String permissionInfo = getAnnotationInfo(handlerMethod, SaCheckPermission.class, "权限校验:");
if (!permissionInfo.isEmpty()) {
values.add(permissionInfo);
}
// 获取角色校验信息
String roleInfo = getAnnotationInfo(handlerMethod, SaCheckRole.class, "角色校验:");
if (!roleInfo.isEmpty()) {
values.add(roleInfo);
}
// 处理 CrudRequestMapping 和 CrudApi 注解生成的权限信息
String crudPermissionInfo = getCrudPermissionInfo(handlerMethod);
if (!crudPermissionInfo.isEmpty()) {
values.add(crudPermissionInfo);
}
return values;
}
/**
* 获取类和方法上指定注解的信息
*
* @param handlerMethod 处理程序方法
* @param annotationClass 注解类
* @param title 信息标题
* @param <A> 注解类型
* @return 拼接好的注解信息字符串
*/
@SuppressWarnings("unchecked")
private <A extends Annotation> String getAnnotationInfo(HandlerMethod handlerMethod,
Class<A> annotationClass,
String title) {
StringBuilder infoBuilder = new StringBuilder();
// 获取类上的注解
A classAnnotation = handlerMethod.getBeanType().getAnnotation(annotationClass);
if (classAnnotation != null) {
appendAnnotationInfo(infoBuilder, "类:", classAnnotation);
}
// 获取方法上的注解
A methodAnnotation = handlerMethod.getMethodAnnotation(annotationClass);
if (methodAnnotation != null) {
appendAnnotationInfo(infoBuilder, "方法:", methodAnnotation);
}
// 如果有注解信息,添加标题
if (!infoBuilder.isEmpty()) {
infoBuilder.insert(0, "<font style=\"color:red\" class=\"light-red\">" + title + "</font></br>");
}
return infoBuilder.toString();
}
/**
* 拼接注解信息到 StringBuilder 中
*
* @param builder 用于拼接信息的 StringBuilder
* @param prefix 前缀信息,如 "类:" 或 "方法:"
* @param annotation 注解对象
*/
private void appendAnnotationInfo(StringBuilder builder, String prefix, Annotation annotation) {
String[] values = null;
SaMode mode = null;
String type = "";
String[] orRole = new String[0];
if (annotation instanceof SaCheckPermission checkPermission) {
values = checkPermission.value();
mode = checkPermission.mode();
type = checkPermission.type();
orRole = checkPermission.orRole();
} else if (annotation instanceof SaCheckRole checkRole) {
values = checkRole.value();
mode = checkRole.mode();
type = checkRole.type();
}
if (values != null && mode != null) {
builder.append("<font style=\"color:red\" class=\"light-red\">");
builder.append(prefix);
if (!type.isEmpty()) {
builder.append("(类型:").append(type).append("");
}
builder.append(getAnnotationNote(values, mode));
if (orRole.length > 0) {
builder.append(" 或 角色校验(").append(getAnnotationNote(orRole, mode)).append("");
}
builder.append("</font></br>");
}
}
/**
* 根据注解的模式拼接注解值
*
* @param values 注解的值数组
* @param mode 注解的模式AND 或 OR
* @return 拼接好的注解值字符串
*/
private String getAnnotationNote(String[] values, SaMode mode) {
if (mode.equals(SaMode.AND)) {
return String.join("", values);
} else {
return String.join("", values);
}
}
/**
* 处理 CrudRequestMapping 和 CrudApi 注解生成的权限信息
*
* @param handlerMethod 处理程序方法
* @return 拼接好的权限信息字符串
*/
private String getCrudPermissionInfo(HandlerMethod handlerMethod) {
CrudRequestMapping crudRequestMapping = handlerMethod.getBeanType().getAnnotation(CrudRequestMapping.class);
CrudApi crudApi = handlerMethod.getMethodAnnotation(CrudApi.class);
if (crudRequestMapping == null || crudApi == null) {
return "";
}
String path = crudRequestMapping.value();
String prefix = String.join(StringConstants.COLON, CharSequenceUtil.splitTrim(path, StringConstants.SLASH));
Api api = crudApi.value();
String apiName = Api.PAGE.equals(api) || Api.TREE.equals(api) ? Api.LIST.name() : api.name();
String permission = "%s:%s".formatted(prefix, apiName.toLowerCase());
return "<font style=\"color:red\" class=\"light-red\">Crud 权限校验:</font></br><font style=\"color:red\" class=\"light-red\">方法:</font><font style=\"color:red\" class=\"light-red\">" + permission + "</font>";
}
}

View File

@@ -0,0 +1,105 @@
package top.ysoft.admin.common.config.exception;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.CharSequenceUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.NoHandlerFoundException;
import top.continew.starter.core.exception.BadRequestException;
import top.continew.starter.core.exception.BusinessException;
import top.continew.starter.web.model.R;
/**
* 全局异常处理器
*
* @author Charles7c
* @author echo
* @since 2024/8/7 20:21
*/
@Slf4j
@Order(99)
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 拦截业务异常
*/
@ExceptionHandler(BusinessException.class)
public R handleBusinessException(BusinessException e, HttpServletRequest request) {
log.error("[{}] {}", request.getMethod(), request.getRequestURI(), e);
return R.fail(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()), e.getMessage());
}
/**
* 拦截自定义验证异常-错误请求
*/
@ExceptionHandler(BadRequestException.class)
public R handleBadRequestException(BadRequestException e, HttpServletRequest request) {
log.error("[{}] {}", request.getMethod(), request.getRequestURI(), e);
return R.fail(String.valueOf(HttpStatus.BAD_REQUEST.value()), e.getMessage());
}
/**
* 拦截校验异常-方法参数类型不匹配异常
*/
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public R handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e,
HttpServletRequest request) {
log.error("[{}] {}", request.getMethod(), request.getRequestURI(), e);
return R.fail(String.valueOf(HttpStatus.BAD_REQUEST.value()), "参数 '%s' 类型不匹配".formatted(e.getName()));
}
/**
* 拦截文件上传异常-超过上传大小限制
*/
@ExceptionHandler(MultipartException.class)
public R handleMultipartException(MultipartException e, HttpServletRequest request) {
log.error("[{}] {}", request.getMethod(), request.getRequestURI(), e);
String msg = e.getMessage();
R defaultFail = R.fail(String.valueOf(HttpStatus.BAD_REQUEST.value()), msg);
if (CharSequenceUtil.isBlank(msg)) {
return defaultFail;
}
String sizeLimit;
Throwable cause = e.getCause();
if (null != cause) {
msg = msg.concat(cause.getMessage().toLowerCase());
}
if (msg.contains("larger than")) {
sizeLimit = CharSequenceUtil.subAfter(msg, "larger than ", true);
} else if (msg.contains("size") && msg.contains("exceed")) {
sizeLimit = CharSequenceUtil.subBetween(msg, "the maximum size ", " for");
} else {
return defaultFail;
}
return R.fail(String.valueOf(HttpStatus.BAD_REQUEST.value()), "请上传小于 %s 的文件".formatted(FileUtil
.readableFileSize(Long.parseLong(sizeLimit))));
}
/**
* 拦截请求 URL 不存在异常
*/
@ExceptionHandler(NoHandlerFoundException.class)
public R handleNoHandlerFoundException(NoHandlerFoundException e, HttpServletRequest request) {
log.error("[{}] {}", request.getMethod(), request.getRequestURI(), e);
return R.fail(String.valueOf(HttpStatus.NOT_FOUND.value()), "请求 URL '%s' 不存在".formatted(request
.getRequestURI()));
}
/**
* 拦截不支持的 HTTP 请求方法异常
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public R handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e,
HttpServletRequest request) {
log.error("[{}] {}", request.getMethod(), request.getRequestURI(), e);
return R.fail(String.valueOf(HttpStatus.METHOD_NOT_ALLOWED.value()), "请求方式 '%s' 不支持".formatted(e.getMethod()));
}
}

View File

@@ -0,0 +1,56 @@
package top.ysoft.admin.common.config.exception;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import top.continew.starter.web.model.R;
/**
* 全局 SaToken 异常处理器
*
* @author Charles7c
* @since 2024/8/7 20:21
*/
@Slf4j
@Order(99)
@RestControllerAdvice
public class GlobalSaTokenExceptionHandler {
/**
* 认证异常-登录认证
*/
@ExceptionHandler(NotLoginException.class)
public R handleNotLoginException(NotLoginException e, HttpServletRequest request) {
log.error("[{}] {}", request.getMethod(), request.getRequestURI(), e);
String errorMsg = switch (e.getType()) {
case NotLoginException.KICK_OUT -> "您已被踢下线";
case NotLoginException.BE_REPLACED_MESSAGE -> "您已被顶下线";
default -> "您的登录状态已过期,请重新登录";
};
return R.fail(String.valueOf(HttpStatus.UNAUTHORIZED.value()), errorMsg);
}
/**
* 认证异常-权限认证
*/
@ExceptionHandler(NotPermissionException.class)
public R handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
log.error("[{}] {}", request.getMethod(), request.getRequestURI(), e);
return R.fail(String.valueOf(HttpStatus.FORBIDDEN.value()), "没有访问权限,请联系管理员授权");
}
/**
* 认证异常-角色认证
*/
@ExceptionHandler(NotRoleException.class)
public R handleNotRoleException(NotRoleException e, HttpServletRequest request) {
log.error("[{}] {}", request.getMethod(), request.getRequestURI(), e);
return R.fail(String.valueOf(HttpStatus.FORBIDDEN.value()), "没有访问权限,请联系管理员授权");
}
}

View File

@@ -0,0 +1,29 @@
package top.ysoft.admin.common.config.mybatis;
import org.springframework.security.crypto.password.PasswordEncoder;
import top.continew.starter.security.crypto.encryptor.IEncryptor;
/**
* BCrypt 加/解密处理器(不可逆)
*
* @author Charles7c
* @since 2024/2/8 22:29
*/
public class BCryptEncryptor implements IEncryptor {
private final PasswordEncoder passwordEncoder;
public BCryptEncryptor(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
@Override
public String encrypt(String plaintext, String password, String publicKey) throws Exception {
return passwordEncoder.encode(plaintext);
}
@Override
public String decrypt(String ciphertext, String password, String privateKey) throws Exception {
return ciphertext;
}
}

View File

@@ -0,0 +1,41 @@
package top.ysoft.admin.common.config.mybatis;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import top.continew.starter.data.mp.base.BaseMapper;
import top.continew.starter.extension.datapermission.annotation.DataPermission;
import java.util.List;
/**
* 数据权限 Mapper 基类
*
* @param <T> 实体类
* @author Charles7c
* @since 2023/9/3 21:50
*/
public interface DataPermissionMapper<T> extends BaseMapper<T> {
/**
* 根据 entity 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null
* @return 全部记录
*/
@Override
@DataPermission
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件
* @param queryWrapper 实体对象封装操作类(可以为 null
* @return 全部记录(并翻页)
*/
@Override
@DataPermission
List<T> selectList(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

View File

@@ -0,0 +1,37 @@
package top.ysoft.admin.common.config.mybatis;
import cn.hutool.core.convert.Convert;
import top.ysoft.admin.common.context.UserContextHolder;
import top.continew.starter.extension.datapermission.enums.DataScope;
import top.continew.starter.extension.datapermission.filter.DataPermissionUserContextProvider;
import top.continew.starter.extension.datapermission.model.RoleContext;
import top.continew.starter.extension.datapermission.model.UserContext;
import java.util.stream.Collectors;
/**
* 数据权限用户上下文提供者
*
* @author Charles7c
* @since 2023/12/21 21:19
*/
public class DefaultDataPermissionUserContextProvider implements DataPermissionUserContextProvider {
@Override
public boolean isFilter() {
return !UserContextHolder.isAdmin();
}
@Override
public UserContext getUserContext() {
top.ysoft.admin.common.context.UserContext context = UserContextHolder.getContext();
UserContext userContext = new UserContext();
userContext.setUserId(Convert.toStr(context.getId()));
userContext.setDeptId(Convert.toStr(context.getDeptId()));
userContext.setRoles(context.getRoles()
.stream()
.map(r -> new RoleContext(Convert.toStr(r.getId()), DataScope.valueOf(r.getDataScope().name())))
.collect(Collectors.toSet()));
return userContext;
}
}

View File

@@ -0,0 +1,96 @@
package top.ysoft.admin.common.config.mybatis;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import top.ysoft.admin.common.context.UserContextHolder;
import top.ysoft.admin.common.model.entity.BaseDO;
import java.time.LocalDateTime;
/**
* MyBatis Plus 元对象处理器配置(插入或修改时自动填充)
*
* @author Charles7c
* @since 2022/12/22 19:52
*/
public class MyBatisPlusMetaObjectHandler implements MetaObjectHandler {
/**
* 创建人
*/
private static final String CREATE_USER = "createUser";
/**
* 创建时间
*/
private static final String CREATE_TIME = "createTime";
/**
* 修改人
*/
private static final String UPDATE_USER = "updateUser";
/**
* 修改时间
*/
private static final String UPDATE_TIME = "updateTime";
/**
* 插入数据时填充
*
* @param metaObject 元对象
*/
@Override
public void insertFill(MetaObject metaObject) {
if (null == metaObject) {
return;
}
Long createUser = UserContextHolder.getUserId();
LocalDateTime createTime = LocalDateTime.now();
if (metaObject.getOriginalObject() instanceof BaseDO baseDO) {
// 继承了 BaseDO 的类,填充创建信息字段
baseDO.setCreateUser(ObjectUtil.defaultIfNull(baseDO.getCreateUser(), createUser));
baseDO.setCreateTime(ObjectUtil.defaultIfNull(baseDO.getCreateTime(), createTime));
} else {
// 未继承 BaseDO 的类,如存在创建信息字段则进行填充
this.fillFieldValue(metaObject, CREATE_USER, createUser, false);
this.fillFieldValue(metaObject, CREATE_TIME, createTime, false);
}
}
/**
* 修改数据时填充
*
* @param metaObject 元对象
*/
@Override
public void updateFill(MetaObject metaObject) {
if (null == metaObject) {
return;
}
Long updateUser = UserContextHolder.getUserId();
LocalDateTime updateTime = LocalDateTime.now();
if (metaObject.getOriginalObject() instanceof BaseDO baseDO) {
// 继承了 BaseDO 的类,填充修改信息
baseDO.setUpdateUser(updateUser);
baseDO.setUpdateTime(updateTime);
} else {
// 未继承 BaseDO 的类,根据类中拥有的修改信息字段进行填充,不存在修改信息字段不进行填充
this.fillFieldValue(metaObject, UPDATE_USER, updateUser, true);
this.fillFieldValue(metaObject, UPDATE_TIME, updateTime, true);
}
}
/**
* 填充字段值
*
* @param metaObject 元数据对象
* @param fieldName 要填充的字段名
* @param fillFieldValue 要填充的字段值
* @param isOverride 如果字段值不为空是否覆盖true覆盖false不覆盖
*/
private void fillFieldValue(MetaObject metaObject, String fieldName, Object fillFieldValue, boolean isOverride) {
if (metaObject.hasSetter(fieldName)) {
Object fieldValue = metaObject.getValue(fieldName);
setFieldValByName(fieldName, null != fieldValue && !isOverride ? fieldValue : fillFieldValue, metaObject);
}
}
}

View File

@@ -0,0 +1,41 @@
package top.ysoft.admin.common.config.mybatis;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;
import top.continew.starter.extension.datapermission.filter.DataPermissionUserContextProvider;
/**
* MyBatis Plus 配置
*
* @author Charles7c
* @since 2022/12/22 19:51
*/
@Configuration
public class MybatisPlusConfiguration {
/**
* 元对象处理器配置(插入或修改时自动填充)
*/
@Bean
public MetaObjectHandler metaObjectHandler() {
return new MyBatisPlusMetaObjectHandler();
}
/**
* 数据权限用户上下文提供者
*/
@Bean
public DataPermissionUserContextProvider dataPermissionUserContextProvider() {
return new DefaultDataPermissionUserContextProvider();
}
/**
* BCrypt 加/解密处理器
*/
@Bean
public BCryptEncryptor bCryptEncryptor(PasswordEncoder passwordEncoder) {
return new BCryptEncryptor(passwordEncoder);
}
}

View File

@@ -0,0 +1,76 @@
package top.ysoft.admin.common.config.properties;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 验证码配置属性
*
* @author Charles7c
* @since 2022/12/11 13:35
*/
@Data
@Component
@ConfigurationProperties(prefix = "captcha")
public class CaptchaProperties {
/**
* 图形验证码过期时间
*/
@Value("${continew-starter.captcha.graphic.expirationInMinutes}")
private long expirationInMinutes;
/**
* 邮箱验证码配置
*/
private CaptchaMail mail;
/**
* 短信验证码配置
*/
private CaptchaSms sms;
/**
* 邮箱验证码配置
*/
@Data
public static class CaptchaMail {
/**
* 内容长度
*/
private int length;
/**
* 过期时间
*/
private long expirationInMinutes;
/**
* 模板路径
*/
private String templatePath;
}
/**
* 短信验证码配置
*/
@Data
public static class CaptchaSms {
/**
* 内容长度
*/
private int length;
/**
* 过期时间
*/
private long expirationInMinutes;
/**
* 模板 ID
*/
private String templateId;
}
}

View File

@@ -0,0 +1,27 @@
package top.ysoft.admin.common.config.properties;
import cn.hutool.extra.spring.SpringUtil;
/**
* RSA 配置属性
*
* @author Zheng JieELADMIN
* @author Charles7c
* @since 2022/12/21 20:21
*/
public class RsaProperties {
/**
* 私钥
*/
public static final String PRIVATE_KEY;
public static final String PUBLIC_KEY;
static {
PRIVATE_KEY = SpringUtil.getProperty("continew-starter.security.crypto.private-key");
PUBLIC_KEY = SpringUtil.getProperty("continew-starter.security.crypto.public-key");
}
private RsaProperties() {
}
}

View File

@@ -0,0 +1,28 @@
package top.ysoft.admin.common.config.websocket;
import cn.dev33.satoken.stp.StpUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import top.continew.starter.core.exception.BusinessException;
import top.continew.starter.messaging.websocket.core.WebSocketClientService;
/**
* 当前登录用户 Provider
*
* @author Charles7c
* @since 2024/6/4 22:13
*/
@Component
public class WebSocketClientServiceImpl implements WebSocketClientService {
@Override
public String getClientId(ServletServerHttpRequest request) {
HttpServletRequest servletRequest = request.getServletRequest();
String token = servletRequest.getParameter("token");
if (null == StpUtil.getLoginIdByToken(token)) {
throw new BusinessException("登录已过期,请重新登录");
}
return token;
}
}

View File

@@ -0,0 +1,65 @@
package top.ysoft.admin.common.constant;
import top.continew.starter.core.constant.StringConstants;
/**
* 缓存相关常量
*
* @author Charles7c
* @since 2022/12/22 19:30
*/
public class CacheConstants {
/**
* 分隔符
*/
public static final String DELIMITER = StringConstants.COLON;
/**
* 验证码键前缀
*/
public static final String CAPTCHA_KEY_PREFIX = "CAPTCHA" + DELIMITER;
/**
* 用户缓存键前缀
*/
public static final String USER_KEY_PREFIX = "USER" + DELIMITER;
/**
* 角色菜单缓存键前缀
*/
public static final String ROLE_MENU_KEY_PREFIX = "ROLE_MENU" + DELIMITER;
/**
* 字典缓存键前缀
*/
public static final String DICT_KEY_PREFIX = "DICT" + DELIMITER;
/**
* 参数缓存键前缀
*/
public static final String OPTION_KEY_PREFIX = "OPTION" + DELIMITER;
/**
* 仪表盘缓存键前缀
*/
public static final String DASHBOARD_KEY_PREFIX = "DASHBOARD" + DELIMITER;
/**
* 用户密码错误次数缓存键前缀
*/
public static final String USER_PASSWORD_ERROR_KEY_PREFIX = USER_KEY_PREFIX + "PASSWORD_ERROR" + DELIMITER;
/**
* 数据导入临时会话key
*/
public static final String DATA_IMPORT_KEY = "SYSTEM" + DELIMITER + "DATA_IMPORT" + DELIMITER;
/**
* 参数管理 cache key
*/
public static final String SYS_CONFIG_KEY = "sys_config:";
private CacheConstants() {
}
}

View File

@@ -0,0 +1,202 @@
package top.ysoft.admin.common.constant;
/**
* 通用常量信息
*
* @author dcsoft
*/
public class Constants {
/**
* UTF-8 字符集
*/
public static final String UTF8 = "UTF-8";
/**
* GBK 字符集
*/
public static final String GBK = "GBK";
/**
* www主域
*/
public static final String WWW = "www.";
/**
* RMI 远程方法调用
*/
public static final String LOOKUP_RMI = "rmi:";
/**
* LDAP 远程方法调用
*/
public static final String LOOKUP_LDAP = "ldap:";
/**
* LDAPS 远程方法调用
*/
public static final String LOOKUP_LDAPS = "ldaps:";
/**
* http请求
*/
public static final String HTTP = "http://";
/**
* https请求
*/
public static final String HTTPS = "https://";
/**
* 成功标记
*/
public static final Integer SUCCESS = 200;
/**
* 失败标记
*/
public static final Integer FAIL = 500;
/**
* 登录成功状态
*/
public static final String LOGIN_SUCCESS_STATUS = "0";
/**
* 登录失败状态
*/
public static final String LOGIN_FAIL_STATUS = "1";
/**
* 登录成功
*/
public static final String LOGIN_SUCCESS = "Success";
/**
* 注销
*/
public static final String LOGOUT = "Logout";
/**
* 注册
*/
public static final String REGISTER = "Register";
/**
* 登录失败
*/
public static final String LOGIN_FAIL = "Error";
/**
* 当前记录起始索引
*/
public static final String PAGE_NUM = "pageNum";
/**
* 每页显示记录数
*/
public static final String PAGE_SIZE = "pageSize";
/**
* 排序列
*/
public static final String ORDER_BY_COLUMN = "orderByColumn";
/**
* 排序的方向 "desc" 或者 "asc".
*/
public static final String IS_ASC = "isAsc";
/**
* 验证码有效期(分钟)
*/
public static final long CAPTCHA_EXPIRATION = 2;
/**
* 资源映射路径 前缀
*/
public static final String RESOURCE_PREFIX = "/profile";
/**
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
*/
public static final String[] JOB_WHITELIST_STR = {"com.dcsoft"};
/**
* 定时任务违规的字符
*/
public static final String[] JOB_ERROR_STR = {"java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.dcsoft.common.core.utils.file"};
/**
* 0
*/
public static final String ZERO = "0";
/**
* 1
*/
public static final String ONE = "1";
/**
* 2
*/
public static final String TWO = "2";
/**
* 5
*/
public static final String FIVE = "5";
/**
* 200
*/
public static final String CODE = "200";
/**
* OK
*/
public static final String OK = "ok";
/**
* 宇泛门禁设备开关门状态1开门
*/
public static final Integer ACCESS_CONTROL_ONE = 1;
/**
* 宇泛门禁设备开关门状态2关门
*/
public static final Integer ACCESS_CONTROL_TWO = 2;
/**
*
*/
public static final String TTS_MOD_CONTENT = "未授权,请联系管理员";
/**
*
*/
public static final String DISPLAY_MOD_CONTENT = "未授权,请联系管理员";
/**
* 梯控结束时间
*/
public static final String END_TIME = "2099-12-31 23:59:59";
/**
* 梯控起始可用时间
*/
public static final String START_DAY_TIME = "00:00:00";
/**
* 梯控结束可用时间
*/
public static final String END_DAY_TIME = "23:59:59";
/**
* 梯控星期
*/
public static final String WEEK = "1 1 1 1 1 1 1";
public static final String CONTENT = "{\n" + " \"touser\": \"%\", \n" + " \"template_id\": \"wODO_BDj8n1grelUSGTNvpZbSnFdhzC3odWHek0brSM\",\n" + " \"url\": \"#\",\n" + " \"data\": {\n" + " \"first\": {\n" + " \"value\": \"广州腾讯科技有限公司\"\n" + " },\n" + " \"keyword1\": {\n" + " \"value\": \"广州腾讯科技有限公司\"\n" + " },\n" + " \"keyword2\": {\n" + " \"value\": \"2019年8月8日\"\n" + " }\n" + " }\n" + "}";
}

View File

@@ -0,0 +1,73 @@
package top.ysoft.admin.common.constant;
/**
* 数据源容器相关常量Crane4j 数据填充组件使用)
*
* @author Charles7c
* @since 2024/1/20 12:33
*/
public class ContainerConstants {
/**
* 用户昵称
*/
public static final String USER_NICKNAME = "UserNickname";
/**
* 文件信息
*/
public static final String FILE_INFO = "FileInfo";
/**
* 用户角色 ID 列表
*/
public static final String USER_ROLE_ID_LIST = "UserRoleIdList";
/**
* 用户角色名称列表
*/
public static final String USER_ROLE_NAME_LIST = "UserRoleNameList";
/**
* 用户列表
*/
public static final String USER_NAME_LIST = "UserNameList";
/**
* 用户名称
*/
public static final String USER_NAME = "UserName";
/**
* 部门名称
*/
public static final String BRANCH_NAME = "BranchName";
/**
* 空间名称
*/
public static final String SPACE_NAME = "SpaceName";
/**
* 产品名称图片
*/
public static final String PRODUCT_NAME_AVATAR = "ProductNameAvatar";
/**
* 设备名称
*/
public static final String EQUIPMENT_NAME = "EquipmentName";
/**
* 人员名称
*/
public static final String PEOPLE_NAME = "PeopleName";
/**
* 规则名称
*/
public static final String RULE_NAME = "RuleName";
private ContainerConstants() {
}
}

View File

@@ -0,0 +1,53 @@
package top.ysoft.admin.common.constant;
/**
* 正则相关常量
*
* @author Charles7c
* @since 2023/1/10 20:06
*/
public class RegexConstants {
/**
* 用户名正则(用户名长度为 4-64 个字符,支持大小写字母、数字、下划线,以字母开头)
*/
public static final String USERNAME = "^[a-zA-Z][a-zA-Z0-9_]{3,64}$";
/**
* 密码正则模板(密码长度为 min-max 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字)
*/
public static final String PASSWORD_TEMPLATE = "^(?=.*\\d)(?=.*[a-z]).{%s,%s}$";
/**
* 密码正则(密码长度为 8-32 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字)
*/
public static final String PASSWORD = "^(?=.*\\d)(?=.*[a-z]).{8,32}$";
/**
* 特殊字符正则
*/
public static final String SPECIAL_CHARACTER = "[-_`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~@#¥%……&*()——+|{}【】‘;:”“’。,、?]|\\n|\\r|\\t";
/**
* 通用编码正则(长度为 2-30 个字符,支持大小写字母、数字、下划线,以字母开头)
*/
public static final String GENERAL_CODE = "^[a-zA-Z][a-zA-Z0-9_]{1,29}$";
/**
* 通用名称正则(长度为 2-30 个字符,支持中文、字母、数字、下划线,短横线)
*/
public static final String GENERAL_NAME = "^[\\u4e00-\\u9fa5a-zA-Z0-9_-]{2,30}$";
/**
* 包名正则(可以包含大小写字母、数字、下划线,每一级包名不能以数字开头)
*/
public static final String PACKAGE_NAME = "^(?:[a-zA-Z_][a-zA-Z0-9_]*\\.)*[a-zA-Z_][a-zA-Z0-9_]*$";
/**
* 金额正则表达式:纯数字,保留两位小数
*/
public static final String MONEY = "^\\d+(\\.\\d{2})?$";
private RegexConstants() {
}
}

View File

@@ -0,0 +1,68 @@
package top.ysoft.admin.common.constant;
/**
* 系统相关常量
*
* @author Charles7c
* @since 2023/2/9 22:11
*/
public class SysConstants {
/**
* 否
*/
public static final Integer NO = 0;
/**
* 是
*/
public static final Integer YES = 1;
/**
* 超管用户 ID
*/
public static final Long SUPER_USER_ID = 1L;
/**
* 顶级部门 ID
*/
public static final Long SUPER_DEPT_ID = 1L;
/**
* 顶级父 ID
*/
public static final Long SUPER_PARENT_ID = 0L;
/**
* 超管角色编码
*/
public static final String SUPER_ROLE_CODE = "admin";
/**
* 超管角色 ID
*/
public static final Long SUPER_ROLE_ID = 1L;
/**
* 全部权限标识
*/
public static final String ALL_PERMISSION = "*:*:*";
/**
* 登录 URI
*/
public static final String LOGIN_URI = "/auth/login";
/**
* 登出 URI
*/
public static final String LOGOUT_URI = "/auth/logout";
/**
* 描述类字段后缀
*/
public static final String DESCRIPTION_FIELD_SUFFIX = "String";
private SysConstants() {
}
}

View File

@@ -0,0 +1,38 @@
package top.ysoft.admin.common.constant;
/**
* UI 相关常量
*
* @author Charles7c
* @since 2023/9/17 14:12
*/
public class UiConstants {
/**
* 主色(极致蓝)
*/
public static final String COLOR_PRIMARY = "arcoblue";
/**
* 成功色(仙野绿)
*/
public static final String COLOR_SUCCESS = "green";
/**
* 警告色(活力橙)
*/
public static final String COLOR_WARNING = "orangered";
/**
* 错误色(浪漫红)
*/
public static final String COLOR_ERROR = "red";
/**
* 默认色(中性灰)
*/
public static final String COLOR_DEFAULT = "gray";
private UiConstants() {
}
}

View File

@@ -0,0 +1,43 @@
package top.ysoft.admin.common.context;
import lombok.Data;
import lombok.NoArgsConstructor;
import top.ysoft.admin.common.enums.DataScopeEnum;
import java.io.Serial;
import java.io.Serializable;
/**
* 角色上下文
*
* @author Charles7c
* @since 2023/3/7 22:08
*/
@Data
@NoArgsConstructor
public class RoleContext implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
private Long id;
/**
* 角色编码
*/
private String code;
/**
* 数据权限
*/
private DataScopeEnum dataScope;
public RoleContext(Long id, String code, DataScopeEnum dataScope) {
this.id = id;
this.code = code;
this.dataScope = dataScope;
}
}

View File

@@ -0,0 +1,116 @@
package top.ysoft.admin.common.context;
import cn.hutool.core.collection.CollUtil;
import lombok.Data;
import lombok.NoArgsConstructor;
import top.ysoft.admin.common.constant.SysConstants;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 用户上下文
*
* @author Charles7c
* @since 2024/10/9 20:29
*/
@Data
@NoArgsConstructor
public class UserContext implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
private Long id;
/**
* 用户名
*/
private String username;
/**
* 部门 ID
*/
private Long deptId;
/**
* 最后一次修改密码时间
*/
private LocalDateTime pwdResetTime;
/**
* 登录时系统设置的密码过期天数
*/
private Integer passwordExpirationDays;
/**
* 权限码集合
*/
private Set<String> permissions;
/**
* 角色编码集合
*/
private Set<String> roleCodes;
/**
* 角色集合
*/
private Set<RoleContext> roles;
/**
* 终端类型
*/
private String clientType;
/**
* 终端 ID
*/
private String clientId;
public UserContext(Set<String> permissions, Set<RoleContext> roles, Integer passwordExpirationDays) {
this.permissions = permissions;
this.setRoles(roles);
this.passwordExpirationDays = passwordExpirationDays;
}
public void setRoles(Set<RoleContext> roles) {
this.roles = roles;
this.roleCodes = roles.stream().map(RoleContext::getCode).collect(Collectors.toSet());
}
/**
* 是否为管理员
*
* @return truefalse
*/
public boolean isAdmin() {
if (CollUtil.isEmpty(roleCodes)) {
return false;
}
return roleCodes.contains(SysConstants.SUPER_ROLE_CODE);
}
/**
* 密码是否已过期
*
* @return 是否过期
*/
public boolean isPasswordExpired() {
// 永久有效
if (this.passwordExpirationDays == null || this.passwordExpirationDays <= SysConstants.NO) {
return false;
}
// 初始密码(第三方登录用户)暂不提示修改
if (this.pwdResetTime == null) {
return false;
}
return this.pwdResetTime.plusDays(this.passwordExpirationDays).isBefore(LocalDateTime.now());
}
}

View File

@@ -0,0 +1,167 @@
package top.ysoft.admin.common.context;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.extra.spring.SpringUtil;
import top.ysoft.admin.common.service.CommonUserService;
import top.continew.starter.core.util.ExceptionUtils;
/**
* 用户上下文 Holder
*
* @author Charles7c
* @since 2022/12/24 12:58
*/
public class UserContextHolder {
private static final ThreadLocal<UserContext> CONTEXT_HOLDER = new ThreadLocal<>();
private static final ThreadLocal<UserExtraContext> EXTRA_CONTEXT_HOLDER = new ThreadLocal<>();
private UserContextHolder() {
}
/**
* 设置上下文
*
* @param context 上下文
*/
public static void setContext(UserContext context) {
setContext(context, true);
}
/**
* 设置上下文
*
* @param context 上下文
* @param isUpdate 是否更新
*/
public static void setContext(UserContext context, boolean isUpdate) {
CONTEXT_HOLDER.set(context);
if (isUpdate) {
StpUtil.getSessionByLoginId(context.getId()).set(SaSession.USER, context);
}
}
/**
* 获取上下文
*
* @return 上下文
*/
public static UserContext getContext() {
UserContext context = CONTEXT_HOLDER.get();
if (null == context) {
context = StpUtil.getSession().getModel(SaSession.USER, UserContext.class);
CONTEXT_HOLDER.set(context);
}
return context;
}
/**
* 获取指定用户的上下文
*
* @param userId 用户 ID
* @return 上下文
*/
public static UserContext getContext(Long userId) {
SaSession session = StpUtil.getSessionByLoginId(userId, false);
if (null == session) {
return null;
}
return session.getModel(SaSession.USER, UserContext.class);
}
/**
* 设置额外上下文
*
* @param context 额外上下文
*/
public static void setExtraContext(UserExtraContext context) {
EXTRA_CONTEXT_HOLDER.set(context);
}
/**
* 获取额外上下文
*
* @return 额外上下文
*/
public static UserExtraContext getExtraContext() {
UserExtraContext context = EXTRA_CONTEXT_HOLDER.get();
if (null == context) {
context = getExtraContext(StpUtil.getTokenValue());
EXTRA_CONTEXT_HOLDER.set(context);
}
return context;
}
/**
* 获取额外上下文
*
* @param token 令牌
* @return 额外上下文
*/
public static UserExtraContext getExtraContext(String token) {
UserExtraContext context = new UserExtraContext();
context.setIp(Convert.toStr(StpUtil.getExtra(token, "ip")));
context.setAddress(Convert.toStr(StpUtil.getExtra(token, "address")));
context.setBrowser(Convert.toStr(StpUtil.getExtra(token, "browser")));
context.setOs(Convert.toStr(StpUtil.getExtra(token, "os")));
context.setLoginTime(Convert.toLocalDateTime(StpUtil.getExtra(token, "loginTime")));
return context;
}
/**
* 清除上下文
*/
public static void clearContext() {
CONTEXT_HOLDER.remove();
EXTRA_CONTEXT_HOLDER.remove();
}
/**
* 获取用户 ID
*
* @return 用户 ID
*/
public static Long getUserId() {
return ExceptionUtils.exToNull(() -> getContext().getId());
}
/**
* 获取用户名
*
* @return 用户名
*/
public static String getUsername() {
return ExceptionUtils.exToNull(() -> getContext().getUsername());
}
/**
* 获取用户昵称
*
* @return 用户昵称
*/
public static String getNickname() {
return getNickname(getUserId());
}
/**
* 获取用户昵称
*
* @param userId 登录用户 ID
* @return 用户昵称
*/
public static String getNickname(Long userId) {
return ExceptionUtils.exToNull(() -> SpringUtil.getBean(CommonUserService.class).getNicknameById(userId));
}
/**
* 是否为管理员
*
* @return 是否为管理员
*/
public static boolean isAdmin() {
StpUtil.checkLogin();
return getContext().isAdmin();
}
}

View File

@@ -0,0 +1,61 @@
package top.ysoft.admin.common.context;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import lombok.NoArgsConstructor;
import top.continew.starter.core.util.ExceptionUtils;
import top.continew.starter.core.util.IpUtils;
import top.continew.starter.web.util.ServletUtils;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 用户额外上下文
*
* @author Charles7c
* @since 2024/10/9 20:29
*/
@Data
@NoArgsConstructor
public class UserExtraContext implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* IP
*/
private String ip;
/**
* IP 归属地
*/
private String address;
/**
* 浏览器
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 登录时间
*/
private LocalDateTime loginTime;
public UserExtraContext(HttpServletRequest request) {
this.ip = JakartaServletUtil.getClientIP(request);
this.address = ExceptionUtils.exToNull(() -> IpUtils.getIpv4Address(this.ip));
this.setBrowser(ServletUtils.getBrowser(request));
this.setLoginTime(LocalDateTime.now());
this.setOs(StrUtil.subBefore(ServletUtils.getOs(request), " or", false));
}
}

View File

@@ -0,0 +1,51 @@
package top.ysoft.admin.common.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.sign.SaSignTemplate;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.text.CharSequenceUtil;
import top.continew.starter.core.constant.StringConstants;
import top.continew.starter.extension.crud.annotation.CrudApi;
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
import top.continew.starter.extension.crud.controller.AbstractBaseController;
import top.continew.starter.extension.crud.enums.Api;
import top.continew.starter.extension.crud.service.BaseService;
import java.lang.reflect.Method;
import java.util.List;
/**
* 控制器基类
*
* @param <S> 业务接口
* @param <L> 列表类型
* @param <D> 详情类型
* @param <Q> 查询条件
* @param <C> 创建或修改参数类型
* @author Charles7c
* @since 2024/12/6 20:30
*/
public class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q, C> extends AbstractBaseController<S, L, D, Q, C> {
@Override
public void preHandle(CrudApi crudApi, Object[] args, Method targetMethod, Class<?> targetClass) throws Exception {
SaRequest saRequest = SaHolder.getRequest();
List<String> paramNames = saRequest.getParamNames();
if (paramNames.stream().anyMatch(SaSignTemplate.sign::equals)) {
return;
}
if (AnnotationUtil.hasAnnotation(targetMethod, SaIgnore.class) || AnnotationUtil
.hasAnnotation(targetClass, SaIgnore.class)) {
return;
}
CrudRequestMapping crudRequestMapping = targetClass.getDeclaredAnnotation(CrudRequestMapping.class);
String path = crudRequestMapping.value();
String prefix = String.join(StringConstants.COLON, CharSequenceUtil.splitTrim(path, StringConstants.SLASH));
Api api = crudApi.value();
String apiName = Api.PAGE.equals(api) || Api.TREE.equals(api) ? Api.LIST.name() : api.name();
StpUtil.checkPermission("%s:%s".formatted(prefix, apiName.toLowerCase()));
}
}

View File

@@ -0,0 +1,22 @@
package top.ysoft.admin.common.enums;
public enum CommonExceptionEnum {
RULE_ERROR(1000, "您所所在得部门所属规则未绑定设备"), REQUEST_ERROR(1001, "请求异常"), PEOPLE_ERROR(1002, "您的信息未录入"),
QR_CODE_ERROR(1003, "二维码过期"), DEVICE_INITIALIZE_ERROR(1004, "设备序列号不能为空"),;
private Integer errCode;
private String errMsg;
CommonExceptionEnum(Integer errCode, String errMsg) {
this.errCode = errCode;
this.errMsg = errMsg;
}
public Integer getCode() {
return errCode;
}
public String getMessage() {
return errMsg;
}
}

View File

@@ -0,0 +1,24 @@
package top.ysoft.admin.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.continew.starter.core.enums.BaseEnum;
/**
* 交易状态枚举
*
* @author Charles7c
* @since 2022/12/29 22:38
*/
@Getter
@RequiredArgsConstructor
public enum ConsumeOrderTypeEnum implements BaseEnum<Integer> {
/**
* 在线消费
*/
CONSUME(0, "消费");
private final Integer value;
private final String description;
}

View File

@@ -0,0 +1,49 @@
package top.ysoft.admin.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.continew.starter.core.enums.BaseEnum;
/**
* 支付方式枚举
*
* @author Charles7c
* @since 2022/12/29 22:38
*/
@Getter
@RequiredArgsConstructor
public enum ConsumePayModeEnum implements BaseEnum<Integer> {
/**
* 人脸
*/
FACE(0, "人脸"),
/**
* 云卡
*/
CLOUD_CARD(1, "云卡"),
/**
* 刷卡
*/
SWIPE_CARD(2, "刷卡"),
/**
* 支付宝
*/
ALIPAY(3, "支付宝"),
/**
* 微信
*/
WECHAT(4, "微信"),
/**
* 取餐码
*/
MEAL_CODE(5, "取餐码");
private final Integer value;
private final String description;
}

View File

@@ -0,0 +1,39 @@
package top.ysoft.admin.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.continew.starter.core.enums.BaseEnum;
/**
* 消费-充值方式
*
* @author Charles7c
* @since 2022/12/29 22:38
*/
@Getter
@RequiredArgsConstructor
public enum ConsumeRechargeModeEnum implements BaseEnum<Integer> {
/**
* 现金
*/
CASH(0, "现金"),
/**
* 支付宝
*/
ALIPAY(1, "支付宝"),
/**
* 微信
*/
WECHAT(2, "微信"),
/**
* 网银
*/
ONLINE_BANKING(3, "网银");
private final Integer value;
private final String description;
}

View File

@@ -0,0 +1,49 @@
package top.ysoft.admin.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.continew.starter.core.enums.BaseEnum;
/**
* 消费-操作类型
*
* @author Charles7c
* @since 2022/12/29 22:38
*/
@Getter
@RequiredArgsConstructor
public enum ConsumeRechargeTypeEnum implements BaseEnum<Integer> {
/**
* 补贴
*/
SUBSIDY(0, "补贴"),
/**
* 充值
*/
RECHARGE(1, "充值"),
/**
* 退款
*/
REFUND(2, "退款"),
/**
* 清零(全部)
*/
CLEAR(3, "清零(全部)"),
/**
* 清零(充值)
*/
CLEAR_CZ(4, "清零(充值)"),
/**
* 清零(补贴)
*/
CLEAR_BT(5, "清零(补贴)");
private final Integer value;
private final String description;
}

View File

@@ -0,0 +1,29 @@
package top.ysoft.admin.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.continew.starter.core.enums.BaseEnum;
/**
* 消费-充值来源
*
* @author Charles7c
* @since 2022/12/29 22:38
*/
@Getter
@RequiredArgsConstructor
public enum ConsumeRechargeWayEnum implements BaseEnum<Integer> {
/**
* 在线消费
*/
WEB(0, "平台"),
/**
* 离线消费
*/
PHONE(1, "手机");
private final Integer value;
private final String description;
}

View File

@@ -0,0 +1,44 @@
package top.ysoft.admin.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.continew.starter.core.enums.BaseEnum;
/**
* 交易状态枚举
*
* @author Charles7c
* @since 2022/12/29 22:38
*/
@Getter
@RequiredArgsConstructor
public enum ConsumeResultEnum implements BaseEnum<Integer> {
/**
* 在线消费
*/
ONLINE_CONSUME(0, "在线消费"),
/**
* 离线消费
*/
OFFLINE_CONSUME(1, "离线消费"),
/**
* 超时
*/
TIMEOUT(2, "超时"),
/**
* 消费异常
*/
CONSUMPTION_EXCEPTION(3, "消费异常"),
/**
* 异常消费
*/
EXCEPTION_CONSUMPTION(4, "异常消费");
private final Integer value;
private final String description;
}

View File

@@ -0,0 +1,38 @@
package top.ysoft.admin.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.continew.starter.core.enums.BaseEnum;
/**
* 消费-充值来源
*
* @author Charles7c
* @since 2022/12/29 22:38
*/
@Getter
@RequiredArgsConstructor
public enum ConsumeTmrtypeEnum implements BaseEnum<Integer> {
/**
* 早餐
*/
BREAKFAST(0, "早餐"),
/**
* 中餐
*/
LUNCH(1, "中餐"),
/**
* 午餐
*/
DINNER(2, "午餐"),
/**
* 夜餐
*/
NIGHT(3, "夜餐");
private final Integer value;
private final String description;
}

View File

@@ -0,0 +1,49 @@
package top.ysoft.admin.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.continew.starter.core.enums.BaseEnum;
/**
* 消费类型枚举
*
* @author Charles7c
* @since 2022/12/29 22:38
*/
@Getter
@RequiredArgsConstructor
public enum ConsumeTypeConverter implements BaseEnum<Integer> {
/**
* 单价
*/
UNIT_PRICE(0, "单价"),
/**
* 定额
*/
FIXED_PRICE(1, "定额"),
/**
* 时段模式
*/
TIME_PERIOD(2, "时段模式"),
/**
* 计次
*/
COUNTING(3, "计次"),
/**
* 点餐机模式
*/
ORDERING_MACHINE(5, "点餐机模式"),
/**
* 身份模式
*/
IDENTITY(9, "身份模式");
private final Integer value;
private final String description;
}

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