mirror of
https://github.moeyy.xyz/https://github.com/GeWuYou/forgeboot
synced 2025-10-28 02:36:39 +08:00
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
This commit is contained in:
parent
1537973803
commit
3ce3cedc0f
@ -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<MavenPublication>("mavenJava") {
|
||||
@ -148,15 +156,20 @@ subprojects {
|
||||
}
|
||||
}
|
||||
}
|
||||
//endregion
|
||||
|
||||
// 依赖配置
|
||||
dependencies {
|
||||
|
||||
}
|
||||
|
||||
// Java 插件扩展配置
|
||||
configure<JavaPluginExtension> {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
// 任务配置
|
||||
tasks.withType<Jar> {
|
||||
isEnabled = true
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
@ -165,6 +178,8 @@ subprojects {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
// 获取项目布尔属性的辅助函数
|
||||
fun Project.getPropertyByBoolean(key: String): Boolean {
|
||||
return properties[key]?.toString()?.toBoolean() ?: false
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
3
forgeboot-common/.gitattributes
vendored
Normal file
3
forgeboot-common/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/gradlew text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.jar binary
|
||||
40
forgeboot-common/.gitignore
vendored
Normal file
40
forgeboot-common/.gitignore
vendored
Normal file
@ -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
|
||||
7
forgeboot-common/build.gradle.kts
Normal file
7
forgeboot-common/build.gradle.kts
Normal file
@ -0,0 +1,7 @@
|
||||
extra {
|
||||
// 标记为根项目
|
||||
setProperty(ProjectFlags.IS_ROOT_MODULE, true)
|
||||
}
|
||||
dependencies {
|
||||
|
||||
}
|
||||
3
forgeboot-common/forgeboot-common-result/.gitattributes
vendored
Normal file
3
forgeboot-common/forgeboot-common-result/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/gradlew text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.jar binary
|
||||
40
forgeboot-common/forgeboot-common-result/.gitignore
vendored
Normal file
40
forgeboot-common/forgeboot-common-result/.gitignore
vendored
Normal file
@ -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
|
||||
@ -0,0 +1,7 @@
|
||||
extra {
|
||||
// 标记为根项目
|
||||
setProperty(ProjectFlags.IS_ROOT_MODULE, true)
|
||||
}
|
||||
dependencies {
|
||||
|
||||
}
|
||||
3
forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitattributes
vendored
Normal file
3
forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/gradlew text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.jar binary
|
||||
37
forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitignore
vendored
Normal file
37
forgeboot-common/forgeboot-common-result/forgeboot-common-result-api/.gitignore
vendored
Normal file
@ -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/
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
dependencies {
|
||||
|
||||
}
|
||||
@ -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<Any>?): String
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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<Any>?
|
||||
}
|
||||
@ -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<String, Any?>)
|
||||
}
|
||||
3
forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitattributes
vendored
Normal file
3
forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/gradlew text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.jar binary
|
||||
40
forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitignore
vendored
Normal file
40
forgeboot-common/forgeboot-common-result/forgeboot-common-result-impl/.gitignore
vendored
Normal file
@ -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
|
||||
@ -0,0 +1,5 @@
|
||||
|
||||
dependencies {
|
||||
implementation(project(Modules.Common.RESULT_API))
|
||||
}
|
||||
|
||||
@ -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<T>(
|
||||
val code: Int,
|
||||
val success: Boolean,
|
||||
val message: String,
|
||||
val data: T? = null,
|
||||
val requestId: String? = null,
|
||||
val nameMap: Map<String, String> = mapOf(
|
||||
"code" to "code",
|
||||
"success" to "success",
|
||||
"message" to "message",
|
||||
"data" to "data"
|
||||
)
|
||||
) {
|
||||
/**
|
||||
* 将响应对象转换为Map对象
|
||||
*
|
||||
* 此方法用于将响应对象转换为Map,方便在不同层次中传递和处理响应信息
|
||||
* 同时,它允许通过[ResultExtender]来进一步扩展响应信息
|
||||
*
|
||||
* @param extenders 结果扩展器列表,默认为空
|
||||
* @return 转换后的Map对象
|
||||
*/
|
||||
fun toMap(extenders: List<ResultExtender> = emptyList()): MutableMap<String, Any?> {
|
||||
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 <T> success(
|
||||
info: ResponseInformation,
|
||||
data: T? = null,
|
||||
messageResolver: MessageResolver? = null,
|
||||
requestIdProvider: RequestIdProvider? = null,
|
||||
extenders: List<ResultExtender> = emptyList()
|
||||
): R<T> {
|
||||
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 <T> failure(
|
||||
info: ResponseInformation,
|
||||
data: T? = null,
|
||||
messageResolver: MessageResolver? = null,
|
||||
requestIdProvider: RequestIdProvider? = null,
|
||||
extenders: List<ResultExtender> = emptyList()
|
||||
): R<T> {
|
||||
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 <T> success(
|
||||
code: Int = 200,
|
||||
messageCode: String = "success",
|
||||
args: Array<Any>? = null,
|
||||
data: T? = null,
|
||||
messageResolver: MessageResolver? = null,
|
||||
requestIdProvider: RequestIdProvider? = null,
|
||||
extenders: List<ResultExtender> = emptyList()
|
||||
): R<T> {
|
||||
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 <T> failure(
|
||||
code: Int = 400,
|
||||
messageCode: String = "error",
|
||||
args: Array<Any>? = null,
|
||||
data: T? = null,
|
||||
messageResolver: MessageResolver? = null,
|
||||
requestIdProvider: RequestIdProvider? = null,
|
||||
extenders: List<ResultExtender> = emptyList()
|
||||
): R<T> {
|
||||
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()) }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -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<Any>? ): String = code
|
||||
}
|
||||
@ -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 = ""
|
||||
}
|
||||
@ -1,3 +1,8 @@
|
||||
extra {
|
||||
// 标记为根项目
|
||||
setProperty(ProjectFlags.IS_ROOT_MODULE, true)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
dependencies {
|
||||
implementation(project(Modules.Core.EXTENSION))
|
||||
implementation(project(Modules.Common.RESULT_API))
|
||||
|
||||
compileOnly(libs.springBootStarter.web)
|
||||
// Spring Boot WebFlux
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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<String> {
|
||||
val baseNames: MutableList<String> = 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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<Any>?): String {
|
||||
// 使用Spring的MessageSource来获取与当前区域设置相匹配的消息文本
|
||||
return i18nMessageSource.getMessage(code, args, LocaleContextHolder.getLocale())
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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 存在时生效)
|
||||
*
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
@ -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 应用的开发和运行能力
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user