From 3ce3cedc0f57cfef4e1f4a917ab4e8a42033960b Mon Sep 17 00:00:00 2001 From: gewuyou <1063891901@qq.com> Date: Sat, 3 May 2025 17:33:17 +0800 Subject: [PATCH] feat(module): Added forgeboot-common module - Add forgeboot-common result processing related submodules - Implement unified response encapsulation class R and related interfaces - Integrated international message parsing and request ID generation function - Update project configuration to support the construction and release of new modules --- build.gradle.kts | 47 +++-- buildSrc/src/main/kotlin/Modules.kt | 6 + buildSrc/src/main/kotlin/ProjectFlags.kt | 2 - forgeboot-common/.gitattributes | 3 + forgeboot-common/.gitignore | 40 ++++ forgeboot-common/build.gradle.kts | 7 + .../forgeboot-common-result/.gitattributes | 3 + .../forgeboot-common-result/.gitignore | 40 ++++ .../forgeboot-common-result/build.gradle.kts | 7 + .../.gitattributes | 3 + .../forgeboot-common-result-api/.gitignore | 37 ++++ .../build.gradle.kts | 4 + .../common/result/api/MessageResolver.kt | 23 +++ .../common/result/api/RequestIdProvider.kt | 20 ++ .../common/result/api/ResponseInformation.kt | 27 +++ .../common/result/api/ResultExtender.kt | 21 ++ .../.gitattributes | 3 + .../forgeboot-common-result-impl/.gitignore | 40 ++++ .../build.gradle.kts | 5 + .../com/gewuyou/forgeboot/common/result/R.kt | 187 ++++++++++++++++++ .../result/impl/DefaultMessageResolver.kt | 13 ++ .../result/impl/DefaultRequestIdProvider.kt | 13 ++ forgeboot-core/build.gradle.kts | 5 + forgeboot-i18n/build.gradle.kts | 1 + .../i18n/config/entity/I18nProperties.java | 13 ++ .../i18n/config/I18nAutoConfiguration.kt | 29 ++- .../i18n/resolver/I18nMessageResolver.kt | 33 ++++ forgeboot-trace/build.gradle.kts | 2 + .../trace/config/TraceAutoConfiguration.kt | 12 ++ .../trace/provider/TraceRequestIdProvider.kt | 23 +++ gradle/libs.versions.toml | 3 + settings.gradle.kts | 14 ++ 32 files changed, 663 insertions(+), 23 deletions(-) create mode 100644 forgeboot-common/.gitattributes create mode 100644 forgeboot-common/.gitignore create mode 100644 forgeboot-common/build.gradle.kts create mode 100644 forgeboot-common/forgeboot-common-result/.gitattributes create mode 100644 forgeboot-common/forgeboot-common-result/.gitignore create mode 100644 forgeboot-common/forgeboot-common-result/build.gradle.kts create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitattributes create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitignore create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/build.gradle.kts create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/MessageResolver.kt create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/RequestIdProvider.kt create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/ResponseInformation.kt create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/ResultExtender.kt create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitattributes create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitignore create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/build.gradle.kts create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/R.kt create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/impl/DefaultMessageResolver.kt create mode 100644 forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/impl/DefaultRequestIdProvider.kt create mode 100644 forgeboot-i18n/src/main/kotlin/com/gewuyou/forgeboot/i18n/resolver/I18nMessageResolver.kt create mode 100644 forgeboot-trace/src/main/kotlin/com/gewuyou/forgeboot/trace/provider/TraceRequestIdProvider.kt diff --git a/build.gradle.kts b/build.gradle.kts index 7c177ce..549163e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ plugins { // 基本 Java 支持 alias(libs.plugins.java) + alias(libs.plugins.javaLibrary) // Maven 发布支持 alias(libs.plugins.maven.publish) // 语义版本插件 @@ -8,6 +9,8 @@ plugins { // Kotlin Spring 支持 alias(libs.plugins.kotlin.plugin.spring) } + +// 配置 SCM 版本插件 scmVersion { tag { prefix.set("") // 不加 v,生成 1.0.1 而不是 v1.0.1 @@ -24,13 +27,16 @@ scmVersion { pre("commit") post("push") } - } + +// 设置项目版本 version = scmVersion.version +// 配置目录路径 val configDir = "$rootDir/config/" val tasksDir = "$configDir/tasks/" +// 全局项目配置 allprojects { // 设置全局属性 ext { @@ -48,21 +54,18 @@ allprojects { } project.group = "com.gewuyou.forgeboot" } + +// 子项目配置 subprojects { version = rootProject.version afterEvaluate { val isRootModule = project.getPropertyByBoolean(ProjectFlags.IS_ROOT_MODULE) val isStarterModule = project.name.contains("starter") - if (isRootModule) { - dependencies { - project.subprojects.forEach { - if (!it.getPropertyByBoolean(ProjectFlags.IS_ROOT_MODULE)) { - project.dependencies.add("api", project(it.path)) - } - } - } - } - if (isStarterModule&&!isRootModule) { + val parentProject = project.parent + // 让父项目引入子项目 + parentProject?.dependencies?.add("api", project(project.path)) + if (isStarterModule && !isRootModule) { + // Starter 模块依赖配置 dependencies { implementation(platform(libs.springBootDependencies.bom)) implementation(platform(libs.springCloudDependencies.bom)) @@ -70,24 +73,29 @@ subprojects { } } } + // 应用插件和配置 val libs = rootProject.libs apply { plugin(libs.plugins.java.get().pluginId) + plugin(libs.plugins.javaLibrary.get().pluginId) plugin(libs.plugins.maven.publish.get().pluginId) plugin(libs.plugins.kotlin.jvm.get().pluginId) plugin(libs.plugins.axionRelease.get().pluginId) - //导入仓库配置 + // 导入仓库配置 from(file("$configDir/repositories.gradle.kts")) // 导入源代码任务 from(file("$tasksDir/sourceTask.gradle.kts")) } - //region publishing + + // 发布配置 publishing { repositories { + // 本地仓库 maven { name = "localRepo" url = uri("file://D:/Maven/mvn_repository") } + // GitHub Packages 仓库 maven { name = "GitHubPackages" url = uri("https://maven.pkg.github.com/GeWuYou/forgeboot") @@ -96,6 +104,7 @@ subprojects { password = System.getenv("GITHUB_TOKEN") } } + // Gitea 仓库 val host = System.getenv("GEWUYOU_GITEA_HOST") host?.let { maven { @@ -111,7 +120,6 @@ subprojects { } } } - } publications { create("mavenJava") { @@ -148,15 +156,20 @@ subprojects { } } } - //endregion + + // 依赖配置 dependencies { } + + // Java 插件扩展配置 configure { toolchain { languageVersion.set(JavaLanguageVersion.of(21)) } } + + // 任务配置 tasks.withType { isEnabled = true duplicatesStrategy = DuplicatesStrategy.EXCLUDE @@ -165,6 +178,8 @@ subprojects { useJUnitPlatform() } } + +// 获取项目布尔属性的辅助函数 fun Project.getPropertyByBoolean(key: String): Boolean { return properties[key]?.toString()?.toBoolean() ?: false -} \ No newline at end of file +} diff --git a/buildSrc/src/main/kotlin/Modules.kt b/buildSrc/src/main/kotlin/Modules.kt index 7ca2389..4e44073 100644 --- a/buildSrc/src/main/kotlin/Modules.kt +++ b/buildSrc/src/main/kotlin/Modules.kt @@ -16,4 +16,10 @@ object Modules { const val ROOT = ":forgeboot-core" const val EXTENSION = ":forgeboot-core:forgeboot-core-extension" } + object Common { + const val ROOT = ":forgeboot-common" + const val RESULT = ":forgeboot-common:forgeboot-common-result" + const val RESULT_IMPL = ":forgeboot-common:forgeboot-common-result:forgeboot-common-result-impl" + const val RESULT_API = ":forgeboot-common:forgeboot-common-result:forgeboot-common-result-api" + } } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/ProjectFlags.kt b/buildSrc/src/main/kotlin/ProjectFlags.kt index 072052e..4e12102 100644 --- a/buildSrc/src/main/kotlin/ProjectFlags.kt +++ b/buildSrc/src/main/kotlin/ProjectFlags.kt @@ -1,5 +1,3 @@ object ProjectFlags { const val IS_ROOT_MODULE = "isRootModule" - const val USE_SPRING_BOOT_BOM = "useSpringBootBom" - const val USE_CONFIGURATION_PROCESSOR = "useConfigurationProcessor" } \ No newline at end of file diff --git a/forgeboot-common/.gitattributes b/forgeboot-common/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-common/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-common/.gitignore b/forgeboot-common/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-common/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin diff --git a/forgeboot-common/build.gradle.kts b/forgeboot-common/build.gradle.kts new file mode 100644 index 0000000..4cfcfc9 --- /dev/null +++ b/forgeboot-common/build.gradle.kts @@ -0,0 +1,7 @@ +extra { + // 标记为根项目 + setProperty(ProjectFlags.IS_ROOT_MODULE, true) +} +dependencies { + +} diff --git a/forgeboot-common/forgeboot-common-result/.gitattributes b/forgeboot-common/forgeboot-common-result/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-common/forgeboot-common-result/.gitignore b/forgeboot-common/forgeboot-common-result/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin diff --git a/forgeboot-common/forgeboot-common-result/build.gradle.kts b/forgeboot-common/forgeboot-common-result/build.gradle.kts new file mode 100644 index 0000000..5a49bd4 --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/build.gradle.kts @@ -0,0 +1,7 @@ +extra { + // 标记为根项目 + setProperty(ProjectFlags.IS_ROOT_MODULE, true) +} +dependencies { + +} diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitattributes b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitignore b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/build.gradle.kts b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/build.gradle.kts new file mode 100644 index 0000000..52ab83a --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/build.gradle.kts @@ -0,0 +1,4 @@ + +dependencies { + +} diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/MessageResolver.kt b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/MessageResolver.kt new file mode 100644 index 0000000..93aff81 --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/MessageResolver.kt @@ -0,0 +1,23 @@ +package com.gewuyou.forgeboot.common.result.api +/** + * 消息解析器接口 + * + * 用于根据消息代码和参数解析出具体的消息文本 + * 这个接口的主要作用是定义一个标准的消息解析方法,以便在不同的上下文中解析消息 + * + * @since 2025-05-03 16:10:26 + * @author gewuyou + */ +fun interface MessageResolver { + /** + * 解析消息 + * + * 根据给定的消息代码和可选的参数数组,解析并返回具体的消息字符串 + * 这个方法允许在不同的上下文中重用消息解析逻辑,并可以根据需要提供不同的实现 + * + * @param code 消息代码,用于标识特定的消息类型或模板 + * @param args 可选的消息参数数组,用于替换消息模板中的占位符 + * @return 解析后的消息字符串 + */ + fun resolve(code: String, args: Array?): String +} \ No newline at end of file diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/RequestIdProvider.kt b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/RequestIdProvider.kt new file mode 100644 index 0000000..c71b250 --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/RequestIdProvider.kt @@ -0,0 +1,20 @@ +package com.gewuyou.forgeboot.common.result.api +/** + * 请求ID提供商接口 + * + * 该接口用于获取请求ID,请求ID是用于跟踪和调试的唯一标识符 + * 它可以帮助开发者在日志和监控系统中追踪请求的来源和流向 + * + * @since 2025-05-03 16:12:44 + * @author gewuyou + */ +fun interface RequestIdProvider { + /** + * 获取请求ID + * + * 返回一个唯一的字符串标识符作为请求ID + * + * @return 请求ID的字符串表示 + */ + fun getRequestId(): String +} diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/ResponseInformation.kt b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/ResponseInformation.kt new file mode 100644 index 0000000..381efbc --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/ResponseInformation.kt @@ -0,0 +1,27 @@ +package com.gewuyou.forgeboot.common.result.api + +/** + * 响应信息 + * + * @author gewuyou + * @since 2025-05-03 16:31:59 + */ +interface ResponseInformation { + /** + * 获取响应码 + * @return 响应码 + */ + val responseCode: Int + + /** + * 获取i18n响应信息code + * @return 响应信息 code + */ + val responseI8nMessageCode: String + + /** + * 获取i18n响应信息参数 + * @return 响应信息参数 + */ + val responseI8nMessageArgs: Array? +} diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/ResultExtender.kt b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/ResultExtender.kt new file mode 100644 index 0000000..c6d12d0 --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/src/main/java/com/gewuyou/forgeboot/common/result/api/ResultExtender.kt @@ -0,0 +1,21 @@ +package com.gewuyou.forgeboot.common.result.api +/** + * 结果扩展器 + * + * 用于扩展结果映射,通过实现此接口,可以自定义逻辑以向结果映射中添加、修改或删除元素 + * 主要用于在某个处理流程结束后,对结果数据进行额外的处理或装饰 + * + * @since 2025-05-03 16:08:55 + * @author gewuyou + */ +fun interface ResultExtender { + /** + * 扩展结果映射 + * + * 实现此方法以执行扩展逻辑,可以访问并修改传入的结果映射 + * 例如,可以用于添加额外的信息,修改现有值,或者根据某些条件删除条目 + * + * @param resultMap 一个包含结果数据的可变映射,可以在此方法中对其进行修改 + */ + fun extend(resultMap: MutableMap) +} diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitattributes b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitignore b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/build.gradle.kts b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/build.gradle.kts new file mode 100644 index 0000000..8dbb161 --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/build.gradle.kts @@ -0,0 +1,5 @@ + +dependencies { + implementation(project(Modules.Common.RESULT_API)) +} + diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/R.kt b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/R.kt new file mode 100644 index 0000000..d999308 --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/R.kt @@ -0,0 +1,187 @@ +package com.gewuyou.forgeboot.common.result + +import com.gewuyou.forgeboot.common.result.api.MessageResolver +import com.gewuyou.forgeboot.common.result.api.RequestIdProvider +import com.gewuyou.forgeboot.common.result.api.ResponseInformation +import com.gewuyou.forgeboot.common.result.api.ResultExtender +import com.gewuyou.forgeboot.common.result.impl.DefaultMessageResolver +import com.gewuyou.forgeboot.common.result.impl.DefaultRequestIdProvider + +/** + * 统一响应封装类 + * + * 该类用于统一系统中的响应格式,提供基本地响应信息如状态码、是否成功、消息内容、数据体等 + * 并支持通过扩展器[ResultExtender]来扩展响应信息 + * + * @param code 状态码 + * @param success 是否成功 + * @param message 响应消息 + * @param data 响应数据体 + * @param requestId 请求ID + * @param nameMap 响应字段名称映射表 + * + * @since 2025-05-03 16:04:42 + * @author gewuyou + */ +data class R( + val code: Int, + val success: Boolean, + val message: String, + val data: T? = null, + val requestId: String? = null, + val nameMap: Map = mapOf( + "code" to "code", + "success" to "success", + "message" to "message", + "data" to "data" + ) +) { + /** + * 将响应对象转换为Map对象 + * + * 此方法用于将响应对象转换为Map,方便在不同层次中传递和处理响应信息 + * 同时,它允许通过[ResultExtender]来进一步扩展响应信息 + * + * @param extenders 结果扩展器列表,默认为空 + * @return 转换后的Map对象 + */ + fun toMap(extenders: List = emptyList()): MutableMap { + val r = mutableMapOf( + "code" to code, + "success" to success, + "message" to message, + "data" to data + ) + if (!requestId.isNullOrBlank()) { + r["requestId"] = requestId + } + extenders.forEach { it.extend(r) } + return r + } + + companion object { + + /** + * 创建成功地响应对象 + * + * 该方法用于根据[ResponseInformation]创建一个成功地响应对象 + * 它支持国际化消息解析和请求ID的生成,并允许通过[ResultExtender]来扩展响应信息 + * + * @param info 响应信息对象 + * @param data 响应数据体,默认为null + * @param messageResolver 消息解析器,默认为[DefaultMessageResolver] + * @param requestIdProvider 请求ID提供者,默认为[DefaultRequestIdProvider] + * @param extenders 结果扩展器列表,默认为空 + * @return 创建的响应对象 + */ + fun success( + info: ResponseInformation, + data: T? = null, + messageResolver: MessageResolver? = null, + requestIdProvider: RequestIdProvider? = null, + extenders: List = emptyList() + ): R { + val msg = (messageResolver ?: DefaultMessageResolver).resolve( + info.responseI8nMessageCode, + info.responseI8nMessageArgs + ) + val reqId = (requestIdProvider ?: DefaultRequestIdProvider).getRequestId() + return R(info.responseCode, true, msg, data, reqId).also { + extenders.forEach { extender -> extender.extend(it.toMap()) } + } + } + + /** + * 创建失败的响应对象 + * + * 该方法用于根据[ResponseInformation]创建一个失败的响应对象 + * 它支持国际化消息解析和请求ID的生成,并允许通过[ResultExtender]来扩展响应信息 + * + * @param info 响应信息对象 + * @param data 响应数据体,默认为null + * @param messageResolver 消息解析器,默认为[DefaultMessageResolver] + * @param requestIdProvider 请求ID提供者,默认为[DefaultRequestIdProvider] + * @param extenders 结果扩展器列表,默认为空 + * @return 创建的响应对象 + */ + fun failure( + info: ResponseInformation, + data: T? = null, + messageResolver: MessageResolver? = null, + requestIdProvider: RequestIdProvider? = null, + extenders: List = emptyList() + ): R { + val msg = (messageResolver ?: DefaultMessageResolver).resolve( + info.responseI8nMessageCode, + info.responseI8nMessageArgs + ) + val reqId = (requestIdProvider ?: DefaultRequestIdProvider).getRequestId() + return R(info.responseCode, false, msg, data, reqId).also { + extenders.forEach { extender -> extender.extend(it.toMap()) } + } + } + + /** + * 创建成功地响应对象 + * + * 该方法用于创建一个简单的成功响应对象,支持自定义状态码、消息代码、消息参数和数据体 + * 它支持国际化消息解析和请求ID的生成,并允许通过[ResultExtender]来扩展响应信息 + * + * @param code 状态码,默认为200 + * @param messageCode 消息代码,默认为"success" + * @param args 消息参数,默认为null + * @param data 响应数据体,默认为null + * @param messageResolver 消息解析器,默认为[DefaultMessageResolver] + * @param requestIdProvider 请求ID提供者,默认为[DefaultRequestIdProvider] + * @param extenders 结果扩展器列表,默认为空 + * @return 创建的响应对象 + */ + fun success( + code: Int = 200, + messageCode: String = "success", + args: Array? = null, + data: T? = null, + messageResolver: MessageResolver? = null, + requestIdProvider: RequestIdProvider? = null, + extenders: List = emptyList() + ): R { + val msg = (messageResolver ?: DefaultMessageResolver).resolve(messageCode, args) + val reqId = (requestIdProvider ?: DefaultRequestIdProvider).getRequestId() + return R(code, true, msg, data, reqId).also { + extenders.forEach { extender -> extender.extend(it.toMap()) } + } + } + + /** + * 创建失败的响应对象 + * + * 该方法用于创建一个简单的失败响应对象,支持自定义状态码、消息代码、消息参数和数据体 + * 它支持国际化消息解析和请求ID的生成,并允许通过[ResultExtender]来扩展响应信息 + * + * @param code 状态码,默认为400 + * @param messageCode 消息代码,默认为"error" + * @param args 消息参数,默认为null + * @param data 响应数据体,默认为null + * @param messageResolver 消息解析器,默认为[DefaultMessageResolver] + * @param requestIdProvider 请求ID提供者,默认为[DefaultRequestIdProvider] + * @param extenders 结果扩展器列表,默认为空 + * @return 创建的响应对象 + */ + fun failure( + code: Int = 400, + messageCode: String = "error", + args: Array? = null, + data: T? = null, + messageResolver: MessageResolver? = null, + requestIdProvider: RequestIdProvider? = null, + extenders: List = emptyList() + ): R { + val msg = (messageResolver ?: DefaultMessageResolver).resolve(messageCode, args) + val reqId = (requestIdProvider ?: DefaultRequestIdProvider).getRequestId() + return R(code, false, msg, data, reqId).also { + extenders.forEach { extender -> extender.extend(it.toMap()) } + } + } + + } +} diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/impl/DefaultMessageResolver.kt b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/impl/DefaultMessageResolver.kt new file mode 100644 index 0000000..f75f688 --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/impl/DefaultMessageResolver.kt @@ -0,0 +1,13 @@ +package com.gewuyou.forgeboot.common.result.impl + +import com.gewuyou.forgeboot.common.result.api.MessageResolver + +/** + *默认消息解析器 + * + * @since 2025-05-03 16:21:43 + * @author gewuyou + */ +object DefaultMessageResolver : MessageResolver { + override fun resolve(code: String, args: Array? ): String = code +} \ No newline at end of file diff --git a/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/impl/DefaultRequestIdProvider.kt b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/impl/DefaultRequestIdProvider.kt new file mode 100644 index 0000000..0a16dee --- /dev/null +++ b/forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/src/main/kotlin/com/gewuyou/forgeboot/common/result/impl/DefaultRequestIdProvider.kt @@ -0,0 +1,13 @@ +package com.gewuyou.forgeboot.common.result.impl + +import com.gewuyou.forgeboot.common.result.api.RequestIdProvider + +/** + *默认请求ID提供商 + * + * @since 2025-05-03 16:22:18 + * @author gewuyou + */ +object DefaultRequestIdProvider : RequestIdProvider { + override fun getRequestId(): String = "" +} \ No newline at end of file diff --git a/forgeboot-core/build.gradle.kts b/forgeboot-core/build.gradle.kts index 2e3ca6a..a51e0e0 100644 --- a/forgeboot-core/build.gradle.kts +++ b/forgeboot-core/build.gradle.kts @@ -1,3 +1,8 @@ +extra { + // 标记为根项目 + setProperty(ProjectFlags.IS_ROOT_MODULE, true) +} + dependencies { } diff --git a/forgeboot-i18n/build.gradle.kts b/forgeboot-i18n/build.gradle.kts index 2d381df..e0f164b 100644 --- a/forgeboot-i18n/build.gradle.kts +++ b/forgeboot-i18n/build.gradle.kts @@ -1,5 +1,6 @@ dependencies { implementation(project(Modules.Core.EXTENSION)) + implementation(project(Modules.Common.RESULT_API)) compileOnly(libs.springBootStarter.web) // Spring Boot WebFlux diff --git a/forgeboot-i18n/src/main/java/com/gewuyou/forgeboot/i18n/config/entity/I18nProperties.java b/forgeboot-i18n/src/main/java/com/gewuyou/forgeboot/i18n/config/entity/I18nProperties.java index 25392ed..6d239f8 100644 --- a/forgeboot-i18n/src/main/java/com/gewuyou/forgeboot/i18n/config/entity/I18nProperties.java +++ b/forgeboot-i18n/src/main/java/com/gewuyou/forgeboot/i18n/config/entity/I18nProperties.java @@ -24,6 +24,19 @@ public class I18nProperties { */ private String wildPathForLanguageFiles = "classpath*:i18n/**/messages"; + /** + * 位置模式后缀 + */ + private String locationPatternSuffix = ".properties"; + + public String getLocationPatternSuffix() { + return locationPatternSuffix; + } + + public void setLocationPatternSuffix(String locationPatternSuffix) { + this.locationPatternSuffix = locationPatternSuffix; + } + public String getDefaultLocale() { return defaultLocale; } diff --git a/forgeboot-i18n/src/main/kotlin/com/gewuyou/forgeboot/i18n/config/I18nAutoConfiguration.kt b/forgeboot-i18n/src/main/kotlin/com/gewuyou/forgeboot/i18n/config/I18nAutoConfiguration.kt index a1216f7..4769bbf 100644 --- a/forgeboot-i18n/src/main/kotlin/com/gewuyou/forgeboot/i18n/config/I18nAutoConfiguration.kt +++ b/forgeboot-i18n/src/main/kotlin/com/gewuyou/forgeboot/i18n/config/I18nAutoConfiguration.kt @@ -1,9 +1,12 @@ package com.gewuyou.forgeboot.i18n.config +import com.gewuyou.forgeboot.common.result.api.MessageResolver import com.gewuyou.forgeboot.i18n.filter.ReactiveLocaleResolver import com.gewuyou.forgeboot.core.extension.log import com.gewuyou.forgeboot.i18n.config.entity.I18nProperties +import com.gewuyou.forgeboot.i18n.resolver.I18nMessageResolver import jakarta.servlet.http.HttpServletRequest +import org.springframework.beans.factory.annotation.Qualifier import org.springframework.boot.autoconfigure.condition.ConditionalOnClass import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty @@ -28,9 +31,9 @@ import java.util.* */ @Configuration @EnableConfigurationProperties(I18nProperties::class) -open class I18nAutoConfiguration ( +open class I18nAutoConfiguration( private val i18nProperties: I18nProperties -){ +) { /** * 配置并创建一个国际化的消息源 * @@ -54,6 +57,21 @@ open class I18nAutoConfiguration ( return messageSource } + /** + * 创建并配置一个国际化的消息解析器 + * 该方法通过Spring的条件注解有选择性地创建一个MessageResolver实例 + * 主要用于解决国际化消息的解析问题 + * + * @param forgebootI18nMessageSource 一个MessageSource实例,用于解析国际化消息 + * @return 返回一个MessageResolver实例,用于在国际化的环境中解析消息 + */ + @Bean + @ConditionalOnMissingBean(MessageResolver::class) + open fun i18nMessageResolver(@Qualifier(MESSAGE_SOURCE_BEAN_NAME) forgebootI18nMessageSource: MessageSource): MessageResolver { + return I18nMessageResolver(forgebootI18nMessageSource) + } + + /** * 扫描指定路径下的所有国际化属性文件路径 * @@ -65,16 +83,17 @@ open class I18nAutoConfiguration ( */ private fun scanBaseNames(basePath: String): List { val baseNames: MutableList = ArrayList() + val suffix = i18nProperties.locationPatternSuffix log.info("开始扫描 I18n 文件 {}", basePath) try { val resources = PathMatchingResourcePatternResolver().getResources( - "$basePath*.properties" + "$basePath*$suffix" ) for (resource in resources) { val path = resource.uri.toString() log.info("找到 I18n 文件路径: {}", path) // 转换路径为 Spring 的 basename 格式(去掉 .properties 后缀) - val baseName = path.substring(0, path.lastIndexOf(".properties")) + val baseName = path.substring(0, path.lastIndexOf(suffix)) if (!baseNames.contains(baseName)) { baseNames.add(baseName) } @@ -150,6 +169,6 @@ open class I18nAutoConfiguration ( /** * 消息源 bean 的名称 */ - const val MESSAGE_SOURCE_BEAN_NAME: String = "i18nMessageSource" + const val MESSAGE_SOURCE_BEAN_NAME: String = "forgebootI18nMessageSource" } } diff --git a/forgeboot-i18n/src/main/kotlin/com/gewuyou/forgeboot/i18n/resolver/I18nMessageResolver.kt b/forgeboot-i18n/src/main/kotlin/com/gewuyou/forgeboot/i18n/resolver/I18nMessageResolver.kt new file mode 100644 index 0000000..10675d3 --- /dev/null +++ b/forgeboot-i18n/src/main/kotlin/com/gewuyou/forgeboot/i18n/resolver/I18nMessageResolver.kt @@ -0,0 +1,33 @@ +package com.gewuyou.forgeboot.i18n.resolver + +import com.gewuyou.forgeboot.common.result.api.MessageResolver +import org.springframework.context.MessageSource +import org.springframework.context.i18n.LocaleContextHolder + +/** + * i18 n消息解析器 + * + * 该类实现了MessageResolver接口,用于解析国际化消息它依赖于Spring的MessageSource接口 + * 来获取本地化消息文本,并根据当前用户的区域设置来确定使用哪种语言的消息 + * + * @since 2025-05-03 16:58:36 + * @author gewuyou + */ +class I18nMessageResolver( + private val i18nMessageSource: MessageSource +) : MessageResolver { + /** + * 解析消息 + * + * 根据给定的消息代码和可选的参数数组,解析并返回具体的消息字符串 + * 这个方法允许在不同的上下文中重用消息解析逻辑,并可以根据需要提供不同的实现 + * + * @param code 消息代码,用于标识特定的消息类型或模板 + * @param args 可选的消息参数数组,用于替换消息模板中的占位符 + * @return 解析后的消息字符串 + */ + override fun resolve(code: String, args: Array?): String { + // 使用Spring的MessageSource来获取与当前区域设置相匹配的消息文本 + return i18nMessageSource.getMessage(code, args, LocaleContextHolder.getLocale()) + } +} diff --git a/forgeboot-trace/build.gradle.kts b/forgeboot-trace/build.gradle.kts index 8706700..f483163 100644 --- a/forgeboot-trace/build.gradle.kts +++ b/forgeboot-trace/build.gradle.kts @@ -1,5 +1,7 @@ dependencies { implementation(project(Modules.Core.EXTENSION)) + implementation(project(Modules.Common.RESULT_API)) + // Spring Cloud OpenFeign (Compile Only) // https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign compileOnly(libs.springCloudStarter.openfeign) diff --git a/forgeboot-trace/src/main/kotlin/com/gewuyou/forgeboot/trace/config/TraceAutoConfiguration.kt b/forgeboot-trace/src/main/kotlin/com/gewuyou/forgeboot/trace/config/TraceAutoConfiguration.kt index 4166e8a..f7f0d92 100644 --- a/forgeboot-trace/src/main/kotlin/com/gewuyou/forgeboot/trace/config/TraceAutoConfiguration.kt +++ b/forgeboot-trace/src/main/kotlin/com/gewuyou/forgeboot/trace/config/TraceAutoConfiguration.kt @@ -1,11 +1,13 @@ package com.gewuyou.forgeboot.trace.config +import com.gewuyou.forgeboot.common.result.api.RequestIdProvider import com.gewuyou.forgeboot.trace.config.entities.TraceProperties import com.gewuyou.forgeboot.trace.decorator.RequestIdTaskDecorator import com.gewuyou.forgeboot.trace.filter.ReactiveRequestIdFilter import com.gewuyou.forgeboot.trace.filter.RequestIdFilter import com.gewuyou.forgeboot.trace.filter.WebClientRequestIdFilter import com.gewuyou.forgeboot.trace.interceptor.FeignRequestIdInterceptor +import com.gewuyou.forgeboot.trace.provider.TraceRequestIdProvider import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.boot.autoconfigure.condition.ConditionalOnClass import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean @@ -51,6 +53,16 @@ open class TraceAutoConfiguration { open fun reactiveRequestIdFilter(traceProperties: TraceProperties): ReactiveRequestIdFilter = ReactiveRequestIdFilter(traceProperties) + /** + * 请求ID提供者(用于生成请求ID) + * + * 该提供者用于生成请求ID,默认为TraceRequestIdProvider + * @return RequestIdProvider实例 + */ + @Bean + @ConditionalOnMissingBean(RequestIdProvider::class) + open fun traceRequestIdProvider(): TraceRequestIdProvider = TraceRequestIdProvider() + /** * Feign 拦截器(仅当 Feign 存在时生效) * diff --git a/forgeboot-trace/src/main/kotlin/com/gewuyou/forgeboot/trace/provider/TraceRequestIdProvider.kt b/forgeboot-trace/src/main/kotlin/com/gewuyou/forgeboot/trace/provider/TraceRequestIdProvider.kt new file mode 100644 index 0000000..64902f9 --- /dev/null +++ b/forgeboot-trace/src/main/kotlin/com/gewuyou/forgeboot/trace/provider/TraceRequestIdProvider.kt @@ -0,0 +1,23 @@ +package com.gewuyou.forgeboot.trace.provider + +import com.gewuyou.forgeboot.common.result.api.RequestIdProvider +import com.gewuyou.forgeboot.trace.util.RequestIdUtil + +/** + *跟踪请求ID提供商 + * + * @since 2025-05-03 17:26:46 + * @author gewuyou + */ +class TraceRequestIdProvider: RequestIdProvider { + /** + * 获取请求ID + * + * 返回一个唯一的字符串标识符作为请求ID + * + * @return 请求ID的字符串表示 + */ + override fun getRequestId(): String { + return RequestIdUtil.getRequestId() + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 98c6dab..b2df0df 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,6 +40,9 @@ kotlinxEcosystem = ["kotlinxDatetime", "kotlinxSerialization", "kotlinxCoroutine [plugins] # 应用 Java 插件,提供基本的 Java 代码编译和构建能力 java = { id = "java" } +# 应用 Java Library 插件,支持库开发,提供 API 和实现分离的能力 +javaLibrary = { id = "java-library" } + kotlinPluginSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin-version" } axionRelease = { id = "pl.allegro.tech.build.axion-release", version.ref = "axion-release-version" } # 应用 Spring Boot 插件,提供 Spring Boot 应用的开发和运行能力 diff --git a/settings.gradle.kts b/settings.gradle.kts index 241816a..88e6fea 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -63,3 +63,17 @@ include( ) project(":forgeboot-trace").name = "forgeboot-trace-spring-boot-starter" //endregion + +//region module common +include( + "forgeboot-common", + ":forgeboot-common:forgeboot-common-result", + ":forgeboot-common:forgeboot-common-result:forgeboot-common-result-api", + ":forgeboot-common:forgeboot-common-result:forgeboot-common-result-impl", +// ":forgeboot-common:forgeboot-common-result:forgeboot-common-result-extension", +) +project(":forgeboot-common").name = "forgeboot-common" +project(":forgeboot-common:forgeboot-common-result").name = "forgeboot-common-result" +project(":forgeboot-common:forgeboot-common-result:forgeboot-common-result-api").name = "forgeboot-common-result-api" +project(":forgeboot-common:forgeboot-common-result:forgeboot-common-result-impl").name = "forgeboot-common-result-impl" +//endregion