From 1432b2380b3c1c423636cbdc9f6b0b9943a4b4ff Mon Sep 17 00:00:00 2001 From: gewuyou Date: Thu, 24 Jul 2025 22:14:21 +0800 Subject: [PATCH] =?UTF-8?q?refactor(webmvc):=20=E9=87=8D=E6=9E=84=20Web=20?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E9=80=9A=E7=94=A8=20CRUD=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E8=A7=84=E8=8C=83=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 `forgeboot-webmvc-spec` 模块拆分为 `spec-core` 和 `spec-jpa` 两个子模块- 重新组织代码结构,提高模块化和可维护性 - 更新包名和类名,使其更加清晰和一致 - 移除冗余代码,优化接口定义 --- buildSrc/src/main/kotlin/Modules.kt | 4 + forgeboot-webmvc/dto/build.gradle.kts | 2 - .../forgeboot/webmvc/dto/page/Filterable.kt | 38 ------ .../AbstractSortedDateFilterPageRequest.kt | 28 ----- .../{spec => spec-core}/.gitattributes | 0 .../{spec => spec-core}/.gitignore | 0 forgeboot-webmvc/spec-core/build.gradle.kts | 3 + .../spec/core}/entities/DateRangeCondition.kt | 2 +- .../spec/core}/entities/SortCondition.kt | 6 +- .../webmvc/spec/core/enums/SortDirection.kt | 64 ++++++++++ .../spec/core}/page/DateRangeFilterable.kt | 5 +- .../webmvc/spec/core/page/Filterable.kt | 19 +++ .../spec/core}/page/KeywordSearchable.kt | 2 +- .../webmvc/spec/core}/page/Pageable.kt | 2 +- .../webmvc/spec/core}/page/QueryComponent.kt | 2 +- .../webmvc/spec/core}/page/Sortable.kt | 6 +- .../webmvc/spec/core/page/StatusFilterable.kt | 10 ++ .../core}/request/AbstractDatePageRequest.kt | 7 +- .../request/AbstractDateStatusPageRequest.kt | 9 +- .../request/AbstractSearchPageRequest.kt | 7 +- .../request/AbstractSortedDatePageRequest.kt | 9 +- .../request/AbstractSortedPageRequest.kt | 7 +- .../spec/core}/request/BasicPageRequest.kt | 5 +- .../spec/core}/request/DeleteByIdsReq.kt | 8 +- forgeboot-webmvc/spec-jpa/.gitattributes | 3 + forgeboot-webmvc/spec-jpa/.gitignore | 40 ++++++ .../{spec => spec-jpa}/build.gradle.kts | 5 +- .../jpa}/extension/JpaPredicateExtensions.kt | 29 +++-- .../spec/jpa}/extension/PageExtensions.kt | 2 +- .../jpa}/extension/PageResultExtensions.kt | 2 +- .../jpa}/extension/PredicateExtensions.kt | 2 +- .../webmvc/spec/jpa/page/JpaFilterable.kt | 26 ++++ .../spec/jpa/page/JpaStatusFilterable.kt} | 8 +- .../jpa/repository/JpaCrudRepositorySpec.kt} | 6 +- .../request/AbstractFilteredPageRequest.kt | 13 +- .../jpa}/request/AbstractFullPageRequest.kt | 15 ++- .../AbstractSearchFilterPageRequest.kt | 13 +- .../AbstractSortedDateFilterPageRequest.kt | 29 +++++ .../spec/jpa/service/JpaCrudServiceSpec.kt} | 9 +- .../service/impl/JpaCrudServiceImplSpec.kt} | 42 ++++--- forgeboot-webmvc/spec/README.md | 117 ------------------ settings.gradle.kts | 6 +- 42 files changed, 323 insertions(+), 289 deletions(-) delete mode 100644 forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Filterable.kt delete mode 100644 forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedDateFilterPageRequest.kt rename forgeboot-webmvc/{spec => spec-core}/.gitattributes (100%) rename forgeboot-webmvc/{spec => spec-core}/.gitignore (100%) create mode 100644 forgeboot-webmvc/spec-core/build.gradle.kts rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/entities/DateRangeCondition.kt (95%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/entities/SortCondition.kt (57%) create mode 100644 forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/enums/SortDirection.kt rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/page/DateRangeFilterable.kt (87%) create mode 100644 forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Filterable.kt rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/page/KeywordSearchable.kt (95%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/page/Pageable.kt (91%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/page/QueryComponent.kt (83%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/page/Sortable.kt (74%) create mode 100644 forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/StatusFilterable.kt rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/request/AbstractDatePageRequest.kt (77%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/request/AbstractDateStatusPageRequest.kt (71%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/request/AbstractSearchPageRequest.kt (79%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/request/AbstractSortedDatePageRequest.kt (75%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/request/AbstractSortedPageRequest.kt (80%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/request/BasicPageRequest.kt (82%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core}/request/DeleteByIdsReq.kt (62%) create mode 100644 forgeboot-webmvc/spec-jpa/.gitattributes create mode 100644 forgeboot-webmvc/spec-jpa/.gitignore rename forgeboot-webmvc/{spec => spec-jpa}/build.gradle.kts (69%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa}/extension/JpaPredicateExtensions.kt (89%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa}/extension/PageExtensions.kt (94%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa}/extension/PageResultExtensions.kt (94%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa}/extension/PredicateExtensions.kt (94%) create mode 100644 forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/page/JpaFilterable.kt rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/StatusFilterable.kt => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/page/JpaStatusFilterable.kt} (75%) rename forgeboot-webmvc/{spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/repository/CrudRepositorySpec.kt => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/repository/JpaCrudRepositorySpec.kt} (52%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa}/request/AbstractFilteredPageRequest.kt (63%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa}/request/AbstractFullPageRequest.kt (68%) rename forgeboot-webmvc/{dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa}/request/AbstractSearchFilterPageRequest.kt (66%) create mode 100644 forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractSortedDateFilterPageRequest.kt rename forgeboot-webmvc/{spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/service/CrudServiceSpec.kt => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/service/JpaCrudServiceSpec.kt} (95%) rename forgeboot-webmvc/{spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/service/impl/CrudServiceImplSpec.kt => spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/service/impl/JpaCrudServiceImplSpec.kt} (83%) delete mode 100644 forgeboot-webmvc/spec/README.md diff --git a/buildSrc/src/main/kotlin/Modules.kt b/buildSrc/src/main/kotlin/Modules.kt index 2a77ae5..4d2df04 100644 --- a/buildSrc/src/main/kotlin/Modules.kt +++ b/buildSrc/src/main/kotlin/Modules.kt @@ -29,6 +29,10 @@ object Modules { const val VALIDATION = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-validation" const val VERSION = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-version-spring-boot-starter" const val LOGGER = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-logger-spring-boot-starter" + object Spec{ + const val CORE = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-spec-core" + const val JPA = ":forgeboot-webmvc-spring-boot-starter:forgeboot-webmvc-spec-jpa" + } } /** diff --git a/forgeboot-webmvc/dto/build.gradle.kts b/forgeboot-webmvc/dto/build.gradle.kts index 90b691c..df6fd14 100644 --- a/forgeboot-webmvc/dto/build.gradle.kts +++ b/forgeboot-webmvc/dto/build.gradle.kts @@ -7,8 +7,6 @@ dependencies { implementation(libs.kotlinReflect) compileOnly(libs.springBootDependencies.bom) compileOnly(libs.jackson.annotations) - compileOnly(libs.springBootStarter.jpa) - compileOnly(libs.springBootStarter.validation) } i18nKeyGen { rootPackage.set("com.gewuyou.forgeboot.webmvc.dto.i18n") diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Filterable.kt b/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Filterable.kt deleted file mode 100644 index 2acb63c..0000000 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Filterable.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.gewuyou.forgeboot.webmvc.dto.page - -import jakarta.persistence.criteria.CriteriaBuilder -import jakarta.persistence.criteria.Predicate -import jakarta.persistence.criteria.Root - -/** - * 可过滤接口,用于支持泛型类型的过滤操作 - * - * 该接口定义了过滤功能的基本契约,允许实现类根据给定的过滤条件构建查询规范。 - * 主要用于与 JPA Criteria API 集成,以构建动态查询条件。 - * - * @param 过滤条件的类型,通常是一个包含过滤参数的数据传输对象(DTO)。 - * @param 被查询的实体类型,通常对应数据库中的某个实体类。 - * - * @since 2025-07-19 08:56:56 - * @author gewuyou - */ -interface Filterable : QueryComponent { - /** - * 获取当前的过滤条件对象。 - * - * @return 返回一个可空的 FilterType 实例,表示当前的过滤条件。 - */ - val filter: FilterType? - - /** - * 构建查询条件的谓词列表。 - * - * 此方法根据当前的过滤条件,使用给定的 CriteriaBuilder 创建一组 Predicate 对象, - * 这些谓词可以用于构建最终查询语句。 - * - * @param root 代表查询的根实体,用于访问实体的属性。 - * @param cb CriteriaBuilder 实例,用于创建查询条件。 - * @return 返回一个包含查询条件的 Predicate 列表。 - */ - fun buildSpecification(root: Root, cb: CriteriaBuilder): List -} diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedDateFilterPageRequest.kt b/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedDateFilterPageRequest.kt deleted file mode 100644 index eae392d..0000000 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedDateFilterPageRequest.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.gewuyou.forgeboot.webmvc.dto.request - -import com.gewuyou.forgeboot.webmvc.dto.entities.SortCondition -import com.gewuyou.forgeboot.webmvc.dto.page.DateRangeFilterable -import com.gewuyou.forgeboot.webmvc.dto.page.Filterable -import com.gewuyou.forgeboot.webmvc.dto.page.Pageable -import com.gewuyou.forgeboot.webmvc.dto.page.Sortable - -/** - * 抽象排序日期过滤分页请求基类 - * - * 该抽象类为分页请求提供了基础结构,支持以下功能: - * - 分页控制(通过Pageable接口) - * - 排序功能(通过Sortable接口) - * - 日期范围过滤(通过DateRangeFilterable接口) - * - 通用数据过滤(通过Filterable接口) - * - * @property currentPage 当前页码,从1开始计数,默认值为1 - * @property pageSize 每页记录数,默认值为10 - * - * @since 2025-07-19 14:50:36 - * @author gewuyou - */ -abstract class AbstractSortedDateFilterPageRequest( - override val currentPage: Int = 1, - override val pageSize: Int = 10, - override val sortConditions: List = mutableListOf() -) : Pageable, Sortable, DateRangeFilterable, Filterable \ No newline at end of file diff --git a/forgeboot-webmvc/spec/.gitattributes b/forgeboot-webmvc/spec-core/.gitattributes similarity index 100% rename from forgeboot-webmvc/spec/.gitattributes rename to forgeboot-webmvc/spec-core/.gitattributes diff --git a/forgeboot-webmvc/spec/.gitignore b/forgeboot-webmvc/spec-core/.gitignore similarity index 100% rename from forgeboot-webmvc/spec/.gitignore rename to forgeboot-webmvc/spec-core/.gitignore diff --git a/forgeboot-webmvc/spec-core/build.gradle.kts b/forgeboot-webmvc/spec-core/build.gradle.kts new file mode 100644 index 0000000..2e3ca6a --- /dev/null +++ b/forgeboot-webmvc/spec-core/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + +} diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/entities/DateRangeCondition.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/entities/DateRangeCondition.kt similarity index 95% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/entities/DateRangeCondition.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/entities/DateRangeCondition.kt index 53faab4..211f9f9 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/entities/DateRangeCondition.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/entities/DateRangeCondition.kt @@ -1,4 +1,4 @@ -package com.gewuyou.forgeboot.webmvc.dto.entities +package com.gewuyou.webmvc.spec.core.entities import java.time.Instant diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/entities/SortCondition.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/entities/SortCondition.kt similarity index 57% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/entities/SortCondition.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/entities/SortCondition.kt index ee4b03f..f516e50 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/entities/SortCondition.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/entities/SortCondition.kt @@ -1,6 +1,6 @@ -package com.gewuyou.forgeboot.webmvc.dto.entities +package com.gewuyou.webmvc.spec.core.entities -import org.hibernate.query.SortDirection +import com.gewuyou.webmvc.spec.core.enums.SortDirection /** * 排序条件 @@ -17,5 +17,5 @@ class SortCondition { /** * 排序方向 */ - var direction: SortDirection = SortDirection.DESCENDING + var direction: SortDirection = SortDirection.DESC } \ No newline at end of file diff --git a/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/enums/SortDirection.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/enums/SortDirection.kt new file mode 100644 index 0000000..6ea0a8f --- /dev/null +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/enums/SortDirection.kt @@ -0,0 +1,64 @@ +package com.gewuyou.webmvc.spec.core.enums + +import java.util.Locale + +/** + * 排序方向枚举 + * + * @author gewuyou + * @since 2025-01-16 17:56:01 + */ +enum class SortDirection { + ASC, DESC; + + /** + * 获取当前排序方向的反方向 + * + * @return 返回与当前方向相反的排序方向枚举值 + * - 当前为ASC时返回DESC + * - 当前为DESC时返回ASC + */ + fun reverse(): SortDirection = when (this) { + ASC -> DESC + DESC -> ASC + } + + companion object { + /** + * 将字符串解析为排序方向枚举值(忽略大小写) + * + * 支持的输入包括: + * - "asc", "ascending" → ASC + * - "desc", "descending" → DESC + * + * @param value 待解析的字符串,可为空 + * @return 解析成功返回对应的枚举值,value为空时返回null,无法解析时抛出异常 + * @throws IllegalArgumentException 当输入字符串无法识别为有效的排序方向时 + */ + @JvmStatic + fun interpret(value: String?): SortDirection? { + if (value == null) return null + return when (value.lowercase(Locale.ROOT)) { + "asc", "ascending" -> ASC + "desc", "descending" -> DESC + else -> throw IllegalArgumentException("Unknown sort direction: $value") + } + } + + /** + * 安全地将字符串解析为排序方向枚举值,如果解析失败则返回默认值 + * + * @param value 待解析的字符串,可为空 + * @param default 解析失败时返回的默认值,默认为ASC + * @return 解析成功返回对应的枚举值,解析失败或value为空时返回默认值 + */ + fun interpretOrDefault(value: String?, default: SortDirection = ASC): SortDirection { + return try { + interpret(value) ?: default + } catch (_: IllegalArgumentException) { + default + } + } + } + +} diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/DateRangeFilterable.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/DateRangeFilterable.kt similarity index 87% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/DateRangeFilterable.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/DateRangeFilterable.kt index 3497ff4..6e11877 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/DateRangeFilterable.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/DateRangeFilterable.kt @@ -1,6 +1,7 @@ -package com.gewuyou.forgeboot.webmvc.dto.page +package com.gewuyou.webmvc.spec.core.page + +import com.gewuyou.webmvc.spec.core.entities.DateRangeCondition -import com.gewuyou.forgeboot.webmvc.dto.entities.DateRangeCondition /** * 日期范围可过滤接口 diff --git a/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Filterable.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Filterable.kt new file mode 100644 index 0000000..b41c8dd --- /dev/null +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Filterable.kt @@ -0,0 +1,19 @@ +package com.gewuyou.webmvc.spec.core.page + +/** + * 可过滤接口,用于支持泛型类型的过滤操作 + * + * + * @param 过滤条件的类型,通常是一个包含过滤参数的数据传输对象(DTO)。 + * + * @since 2025-07-19 08:56:56 + * @author gewuyou + */ +interface Filterable : QueryComponent { + /** + * 获取当前的过滤条件对象。 + * + * @return 返回一个可空的 FilterType 实例,表示当前的过滤条件。 + */ + val filter: FilterType? +} diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/KeywordSearchable.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/KeywordSearchable.kt similarity index 95% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/KeywordSearchable.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/KeywordSearchable.kt index f84730e..11b8de0 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/KeywordSearchable.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/KeywordSearchable.kt @@ -1,4 +1,4 @@ -package com.gewuyou.forgeboot.webmvc.dto.page +package com.gewuyou.webmvc.spec.core.page /** * 关键字可搜索接口,用于支持包含关键字搜索条件的数据结构 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Pageable.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Pageable.kt similarity index 91% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Pageable.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Pageable.kt index 8ea880e..4c1a0ed 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Pageable.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Pageable.kt @@ -1,4 +1,4 @@ -package com.gewuyou.forgeboot.webmvc.dto.page +package com.gewuyou.webmvc.spec.core.page /** * 可分页接口,用于支持分页功能的类实现 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/QueryComponent.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/QueryComponent.kt similarity index 83% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/QueryComponent.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/QueryComponent.kt index 5d64891..dcc6f43 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/QueryComponent.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/QueryComponent.kt @@ -1,4 +1,4 @@ -package com.gewuyou.forgeboot.webmvc.dto.page +package com.gewuyou.webmvc.spec.core.page /** * QueryComponent 是一个密封接口,用于定义查询组件的公共契约。 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Sortable.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Sortable.kt similarity index 74% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Sortable.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Sortable.kt index e970f94..b643e08 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/Sortable.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/Sortable.kt @@ -1,7 +1,7 @@ -package com.gewuyou.forgeboot.webmvc.dto.page +package com.gewuyou.webmvc.spec.core.page -import com.gewuyou.forgeboot.webmvc.dto.entities.SortCondition -import org.hibernate.query.SortDirection +import com.gewuyou.webmvc.spec.core.entities.SortCondition +import com.gewuyou.webmvc.spec.core.enums.SortDirection /** * 可排序接口,用于定义排序相关属性 diff --git a/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/StatusFilterable.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/StatusFilterable.kt new file mode 100644 index 0000000..3e55d94 --- /dev/null +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/page/StatusFilterable.kt @@ -0,0 +1,10 @@ +package com.gewuyou.webmvc.spec.core.page + +/** + * 启用状态可过滤接口,用于支持启用/禁用状态的过滤功能。 + * + * + * @since 2025-07-19 09:00:42 + * @author gewuyou + */ +interface StatusFilterable : QueryComponent \ No newline at end of file diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractDatePageRequest.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractDatePageRequest.kt similarity index 77% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractDatePageRequest.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractDatePageRequest.kt index ded1cb3..58d7846 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractDatePageRequest.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractDatePageRequest.kt @@ -1,7 +1,8 @@ -package com.gewuyou.forgeboot.webmvc.dto.request +package com.gewuyou.webmvc.spec.core.request + +import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable +import com.gewuyou.webmvc.spec.core.page.Pageable -import com.gewuyou.forgeboot.webmvc.dto.page.DateRangeFilterable -import com.gewuyou.forgeboot.webmvc.dto.page.Pageable /** * 抽象日期分页请求 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractDateStatusPageRequest.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractDateStatusPageRequest.kt similarity index 71% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractDateStatusPageRequest.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractDateStatusPageRequest.kt index 13cc009..45a8ec3 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractDateStatusPageRequest.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractDateStatusPageRequest.kt @@ -1,8 +1,9 @@ -package com.gewuyou.forgeboot.webmvc.dto.request +package com.gewuyou.webmvc.spec.core.request + +import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable +import com.gewuyou.webmvc.spec.core.page.Pageable +import com.gewuyou.webmvc.spec.core.page.StatusFilterable -import com.gewuyou.forgeboot.webmvc.dto.page.DateRangeFilterable -import com.gewuyou.forgeboot.webmvc.dto.page.Pageable -import com.gewuyou.forgeboot.webmvc.dto.page.StatusFilterable /** * 日期状态页面请求 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSearchPageRequest.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractSearchPageRequest.kt similarity index 79% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSearchPageRequest.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractSearchPageRequest.kt index 277006c..408f4cd 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSearchPageRequest.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractSearchPageRequest.kt @@ -1,7 +1,8 @@ -package com.gewuyou.forgeboot.webmvc.dto.request +package com.gewuyou.webmvc.spec.core.request + +import com.gewuyou.webmvc.spec.core.page.KeywordSearchable +import com.gewuyou.webmvc.spec.core.page.Pageable -import com.gewuyou.forgeboot.webmvc.dto.page.KeywordSearchable -import com.gewuyou.forgeboot.webmvc.dto.page.Pageable /** * 抽象搜索分页请求类 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedDatePageRequest.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractSortedDatePageRequest.kt similarity index 75% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedDatePageRequest.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractSortedDatePageRequest.kt index 6dc747b..4c13bc6 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedDatePageRequest.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractSortedDatePageRequest.kt @@ -1,8 +1,9 @@ -package com.gewuyou.forgeboot.webmvc.dto.request +package com.gewuyou.webmvc.spec.core.request + +import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable +import com.gewuyou.webmvc.spec.core.page.Pageable +import com.gewuyou.webmvc.spec.core.page.Sortable -import com.gewuyou.forgeboot.webmvc.dto.page.DateRangeFilterable -import com.gewuyou.forgeboot.webmvc.dto.page.Pageable -import com.gewuyou.forgeboot.webmvc.dto.page.Sortable /** * 抽象排序日期分页请求 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedPageRequest.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractSortedPageRequest.kt similarity index 80% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedPageRequest.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractSortedPageRequest.kt index b002948..5b31531 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSortedPageRequest.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/AbstractSortedPageRequest.kt @@ -1,7 +1,8 @@ -package com.gewuyou.forgeboot.webmvc.dto.request +package com.gewuyou.webmvc.spec.core.request + +import com.gewuyou.webmvc.spec.core.page.Pageable +import com.gewuyou.webmvc.spec.core.page.Sortable -import com.gewuyou.forgeboot.webmvc.dto.page.Pageable -import com.gewuyou.forgeboot.webmvc.dto.page.Sortable /** * 抽象排序分页请求数据类 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/BasicPageRequest.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/BasicPageRequest.kt similarity index 82% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/BasicPageRequest.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/BasicPageRequest.kt index 2ee1040..f6f7479 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/BasicPageRequest.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/BasicPageRequest.kt @@ -1,6 +1,7 @@ -package com.gewuyou.forgeboot.webmvc.dto.request +package com.gewuyou.webmvc.spec.core.request + +import com.gewuyou.webmvc.spec.core.page.Pageable -import com.gewuyou.forgeboot.webmvc.dto.page.Pageable /** * 基本分页请求数据类 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/DeleteByIdsReq.kt b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/DeleteByIdsReq.kt similarity index 62% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/DeleteByIdsReq.kt rename to forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/DeleteByIdsReq.kt index 5e44c37..435dbf0 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/DeleteByIdsReq.kt +++ b/forgeboot-webmvc/spec-core/src/main/kotlin/com/gewuyou/webmvc/spec/core/request/DeleteByIdsReq.kt @@ -1,7 +1,4 @@ -package com.gewuyou.forgeboot.webmvc.dto.request - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties -import jakarta.validation.constraints.NotEmpty +package com.gewuyou.webmvc.spec.core.request /** * 根据id列表删除请求 @@ -12,16 +9,13 @@ import jakarta.validation.constraints.NotEmpty * @author gewuyou * @since 2025-01-18 17:39:18 */ -@JsonIgnoreProperties(ignoreUnknown = true) open class DeleteByIdsReq( /** * 待删除的实体id列表 * * 这个字段是删除操作的核心参数,它不能为空,以确保至少有一个id被指定用于删除 - * 使用@NotNull注解来确保在序列化和反序列化过程中,该字段不能为空 * * @param ids 实体的唯一标识符列表,用于指定哪些实体应当被删除 */ - @field:NotEmpty(message = "The list of Ids requested to be removed cannot be empty!") var ids: List, ) \ No newline at end of file diff --git a/forgeboot-webmvc/spec-jpa/.gitattributes b/forgeboot-webmvc/spec-jpa/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-webmvc/spec-jpa/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-webmvc/spec-jpa/.gitignore b/forgeboot-webmvc/spec-jpa/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-webmvc/spec-jpa/.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-webmvc/spec/build.gradle.kts b/forgeboot-webmvc/spec-jpa/build.gradle.kts similarity index 69% rename from forgeboot-webmvc/spec/build.gradle.kts rename to forgeboot-webmvc/spec-jpa/build.gradle.kts index 67e1bbb..1df93a9 100644 --- a/forgeboot-webmvc/spec/build.gradle.kts +++ b/forgeboot-webmvc/spec-jpa/build.gradle.kts @@ -1,6 +1,5 @@ - dependencies { - compileOnly(libs.springBootStarter.jpa) api(project(Modules.Webmvc.DTO)) - api(project(Modules.Core.EXTENSION)) + api(project(Modules.Webmvc.Spec.CORE)) + compileOnly(libs.springBootStarter.jpa) } diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/JpaPredicateExtensions.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/JpaPredicateExtensions.kt similarity index 89% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/JpaPredicateExtensions.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/JpaPredicateExtensions.kt index a567850..dd0459f 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/JpaPredicateExtensions.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/JpaPredicateExtensions.kt @@ -1,22 +1,31 @@ -package com.gewuyou.forgeboot.webmvc.dto.extension +package com.gewuyou.webmvc.spec.jpa.extension -import com.gewuyou.forgeboot.webmvc.dto.page.* + +import com.gewuyou.webmvc.spec.core.enums.SortDirection +import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable +import com.gewuyou.webmvc.spec.core.page.KeywordSearchable +import com.gewuyou.webmvc.spec.core.page.Pageable +import com.gewuyou.webmvc.spec.core.page.QueryComponent +import com.gewuyou.webmvc.spec.core.page.Sortable +import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable +import com.gewuyou.webmvc.spec.jpa.page.JpaStatusFilterable import jakarta.persistence.criteria.CriteriaBuilder import jakarta.persistence.criteria.Predicate import jakarta.persistence.criteria.Root -import org.hibernate.query.SortDirection + import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Sort import org.springframework.data.jpa.domain.Specification import java.time.Instant + /** - * 将 Hibernate 的 SortDirection 转换为 Spring Data 的 Sort.Direction。 + * 将自定义的排序方向枚举转换为 Spring Data JPA 的排序方向 * - * @return 返回对应的 Sort.Direction 实例 + * @return 对应的 Spring Data Sort.Direction 枚举值 */ fun SortDirection.toSpringDirection(): Sort.Direction = - if (this == SortDirection.DESCENDING) Sort.Direction.DESC else Sort.Direction.ASC + if (this == SortDirection.DESC) Sort.Direction.DESC else Sort.Direction.ASC /** * 将当前排序配置转换为可用于 Spring Data Pageable 的排序条件列表 @@ -140,17 +149,17 @@ fun QueryComponent.toSpecification(): Specification { (this as? DateRangeFilterable)?.let { predicates += it.buildDateRangePredicates(root, cb) } - // 判断并组合 Status - (this as? StatusFilterable)?.let { + // 判断并组合 JpaStatusFilterable + (this as? JpaStatusFilterable)?.let { predicates += it.buildStatusPredicates(root, cb) } // 判断并组合 KeywordSearchable (this as? KeywordSearchable)?.let { predicates += it.buildKeywordPredicates(root, cb) } - // 判断并组合 Filterable + // 判断并组合 JpaFilterable @Suppress("UNCHECKED_CAST") - (this as? Filterable<*, T>)?.let { + (this as? JpaFilterable<*, T>)?.let { predicates += it.buildSpecification(root, cb) } // 组合所有查询条件,返回逻辑 AND 结果 diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/PageExtensions.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/PageExtensions.kt similarity index 94% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/PageExtensions.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/PageExtensions.kt index 09d533d..3ce1385 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/PageExtensions.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/PageExtensions.kt @@ -1,4 +1,4 @@ -package com.gewuyou.forgeboot.webmvc.dto.extension +package com.gewuyou.webmvc.spec.jpa.extension import com.gewuyou.forgeboot.webmvc.dto.PageResult import org.springframework.data.domain.Page diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/PageResultExtensions.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/PageResultExtensions.kt similarity index 94% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/PageResultExtensions.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/PageResultExtensions.kt index d826c5e..223a0cc 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/PageResultExtensions.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/PageResultExtensions.kt @@ -1,4 +1,4 @@ -package com.gewuyou.forgeboot.webmvc.dto.extension +package com.gewuyou.webmvc.spec.jpa.extension import com.gewuyou.forgeboot.webmvc.dto.PageResult diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/PredicateExtensions.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/PredicateExtensions.kt similarity index 94% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/PredicateExtensions.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/PredicateExtensions.kt index ddf1b71..a6785d7 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/extension/PredicateExtensions.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/extension/PredicateExtensions.kt @@ -1,4 +1,4 @@ -package com.gewuyou.forgeboot.webmvc.dto.extension +package com.gewuyou.webmvc.spec.jpa.extension import jakarta.persistence.criteria.Predicate diff --git a/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/page/JpaFilterable.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/page/JpaFilterable.kt new file mode 100644 index 0000000..f5477e9 --- /dev/null +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/page/JpaFilterable.kt @@ -0,0 +1,26 @@ +package com.gewuyou.webmvc.spec.jpa.page + +import com.gewuyou.webmvc.spec.core.page.Filterable +import jakarta.persistence.criteria.CriteriaBuilder +import jakarta.persistence.criteria.Predicate +import jakarta.persistence.criteria.Root + +/** + *JPA可过滤接口 + * + * @since 2025-07-24 21:40:33 + * @author gewuyou + */ +interface JpaFilterable : Filterable { + /** + * 构建JPA查询条件规范 + * + * 根据当前过滤条件构建JPA Criteria查询所需的谓词列表,用于动态生成查询条件。 + * 这些谓词将被用于构建最终的JPA查询语句。 + * + * @param root 查询根对象,用于访问实体属性 + * @param cb CriteriaBuilder对象,用于创建查询条件谓词 + * @return 包含查询条件谓词的列表 + */ + fun buildSpecification(root: Root, cb: CriteriaBuilder): List +} \ No newline at end of file diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/StatusFilterable.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/page/JpaStatusFilterable.kt similarity index 75% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/StatusFilterable.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/page/JpaStatusFilterable.kt index ac7ab1a..5284ca9 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/page/StatusFilterable.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/page/JpaStatusFilterable.kt @@ -1,19 +1,19 @@ -package com.gewuyou.forgeboot.webmvc.dto.page +package com.gewuyou.webmvc.spec.jpa.page +import com.gewuyou.webmvc.spec.core.page.StatusFilterable import jakarta.persistence.criteria.CriteriaBuilder import jakarta.persistence.criteria.Predicate import jakarta.persistence.criteria.Root + /** * 启用状态可过滤接口,用于支持启用/禁用状态的过滤功能。 * - * 此接口定义了构建状态过滤条件的方法,适用于基于 JPA Criteria API 的查询构建。 - * 实现该接口的类可通过 [buildStatusPredicates]方法提供具体过滤逻辑。 * * @since 2025-07-19 09:00:42 * @author gewuyou */ -interface StatusFilterable : QueryComponent { +interface JpaStatusFilterable : StatusFilterable{ /** * 构建与启用状态相关的查询条件列表。 * diff --git a/forgeboot-webmvc/spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/repository/CrudRepositorySpec.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/repository/JpaCrudRepositorySpec.kt similarity index 52% rename from forgeboot-webmvc/spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/repository/CrudRepositorySpec.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/repository/JpaCrudRepositorySpec.kt index 8376466..ace4a4f 100644 --- a/forgeboot-webmvc/spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/repository/CrudRepositorySpec.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/repository/JpaCrudRepositorySpec.kt @@ -1,12 +1,12 @@ -package com.gewuyou.forgeboot.webmvc.spec.repository +package com.gewuyou.webmvc.spec.jpa.repository import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.JpaSpecificationExecutor /** - *CRUD 存储库规范 + * Jpa CRUD 存储库规范 * * @since 2025-05-29 20:39:11 * @author gewuyou */ -interface CrudRepositorySpec: JpaRepository, JpaSpecificationExecutor \ No newline at end of file +interface JpaCrudRepositorySpec: JpaRepository, JpaSpecificationExecutor \ No newline at end of file diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractFilteredPageRequest.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractFilteredPageRequest.kt similarity index 63% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractFilteredPageRequest.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractFilteredPageRequest.kt index 2afc4d0..82f7e9e 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractFilteredPageRequest.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractFilteredPageRequest.kt @@ -1,7 +1,9 @@ -package com.gewuyou.forgeboot.webmvc.dto.request +package com.gewuyou.webmvc.spec.jpa.request -import com.gewuyou.forgeboot.webmvc.dto.page.Filterable -import com.gewuyou.forgeboot.webmvc.dto.page.Pageable + +import com.gewuyou.webmvc.spec.core.page.Pageable +import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable +import org.hibernate.query.SortDirection /** @@ -16,8 +18,9 @@ import com.gewuyou.forgeboot.webmvc.dto.page.Pageable * @since 2025-07-19 09:16:36 * @author gewuyou */ -abstract class AbstractFilteredPageRequest( +abstract class AbstractFilteredPageRequest( override val currentPage: Int = 1, override val pageSize: Int = 10, override val filter: T? = null, -) : Pageable, Filterable \ No newline at end of file + sortDirection: SortDirection +) : Pageable, JpaFilterable \ No newline at end of file diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractFullPageRequest.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractFullPageRequest.kt similarity index 68% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractFullPageRequest.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractFullPageRequest.kt index d8ccb8f..956919d 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractFullPageRequest.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractFullPageRequest.kt @@ -1,6 +1,12 @@ -package com.gewuyou.forgeboot.webmvc.dto.request +package com.gewuyou.webmvc.spec.jpa.request -import com.gewuyou.forgeboot.webmvc.dto.page.* + +import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable +import com.gewuyou.webmvc.spec.core.page.KeywordSearchable +import com.gewuyou.webmvc.spec.core.page.Pageable +import com.gewuyou.webmvc.spec.core.page.Sortable +import com.gewuyou.webmvc.spec.core.page.StatusFilterable +import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable /** * 抽象分页请求类,用于封装分页查询的通用参数 @@ -11,9 +17,6 @@ import com.gewuyou.forgeboot.webmvc.dto.page.* * * @property currentPage 当前页码,默认值为1 * @property pageSize 每页记录数,默认值为10 - * @property sortBy 排序字段,默认值为"createdAt" - * @property sortDirection 排序方向,默认值为降序(SortDirection.DESCENDING) - * @property sortConditions 排序条件列表,默认为空列表 * @property keyword 关键词搜索内容,可为空 * @property filter 自定义过滤条件,可为空,类型为泛型T * @@ -28,6 +31,6 @@ abstract class AbstractFullPageRequest( ) : Pageable, Sortable, KeywordSearchable, - Filterable, + JpaFilterable, DateRangeFilterable, StatusFilterable \ No newline at end of file diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSearchFilterPageRequest.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractSearchFilterPageRequest.kt similarity index 66% rename from forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSearchFilterPageRequest.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractSearchFilterPageRequest.kt index 91e2525..23d31e8 100644 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/request/AbstractSearchFilterPageRequest.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractSearchFilterPageRequest.kt @@ -1,8 +1,9 @@ -package com.gewuyou.forgeboot.webmvc.dto.request +package com.gewuyou.webmvc.spec.jpa.request -import com.gewuyou.forgeboot.webmvc.dto.page.Filterable -import com.gewuyou.forgeboot.webmvc.dto.page.KeywordSearchable -import com.gewuyou.forgeboot.webmvc.dto.page.Pageable + +import com.gewuyou.webmvc.spec.core.page.KeywordSearchable +import com.gewuyou.webmvc.spec.core.page.Pageable +import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable /** * 抽象搜索过滤分页请求 @@ -18,9 +19,9 @@ import com.gewuyou.forgeboot.webmvc.dto.page.Pageable * @since 2025-07-19 10:22:41 * @author gewuyou */ -abstract class AbstractSearchFilterPageRequest( +abstract class AbstractSearchFilterPageRequest( override val currentPage: Int = 1, override val pageSize: Int = 10, override val keyword: String? = null, override val filter: T? = null, -) : Pageable, KeywordSearchable, Filterable +) : Pageable, KeywordSearchable, JpaFilterable diff --git a/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractSortedDateFilterPageRequest.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractSortedDateFilterPageRequest.kt new file mode 100644 index 0000000..466114a --- /dev/null +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/request/AbstractSortedDateFilterPageRequest.kt @@ -0,0 +1,29 @@ +package com.gewuyou.webmvc.spec.jpa.request + + +import com.gewuyou.webmvc.spec.core.entities.SortCondition +import com.gewuyou.webmvc.spec.core.page.DateRangeFilterable +import com.gewuyou.webmvc.spec.core.page.Pageable +import com.gewuyou.webmvc.spec.core.page.Sortable +import com.gewuyou.webmvc.spec.jpa.page.JpaFilterable + +/** + * 抽象排序日期过滤分页请求基类 + * + * 该抽象类为分页请求提供了基础结构,支持以下功能: + * - 分页控制(通过[Pageable]接口) + * - 排序功能(通过[Sortable]接口) + * - 日期范围过滤(通过[DateRangeFilterable]接口) + * - 通用数据过滤(通过[JpaFilterable]接口) + * + * @property currentPage 当前页码,从1开始计数,默认值为1 + * @property pageSize 每页记录数,默认值为10 + * + * @since 2025-07-19 14:50:36 + * @author gewuyou + */ +abstract class AbstractSortedDateFilterPageRequest( + override val currentPage: Int = 1, + override val pageSize: Int = 10, + override val sortConditions: List = mutableListOf(), +) : Pageable, Sortable, DateRangeFilterable, JpaFilterable \ No newline at end of file diff --git a/forgeboot-webmvc/spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/service/CrudServiceSpec.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/service/JpaCrudServiceSpec.kt similarity index 95% rename from forgeboot-webmvc/spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/service/CrudServiceSpec.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/service/JpaCrudServiceSpec.kt index f09f05e..b85a5ce 100644 --- a/forgeboot-webmvc/spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/service/CrudServiceSpec.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/service/JpaCrudServiceSpec.kt @@ -1,10 +1,11 @@ -package com.gewuyou.forgeboot.webmvc.spec.service +package com.gewuyou.webmvc.spec.jpa.service import com.gewuyou.forgeboot.webmvc.dto.PageResult -import com.gewuyou.forgeboot.webmvc.dto.page.QueryComponent +import com.gewuyou.webmvc.spec.core.page.QueryComponent + /** - * CRUD 服务规范 + * Jpa CRUD 服务规范 * * 定义了对实体进行基本操作的服务接口,包括增删查改和分页查询等功能 * @@ -13,7 +14,7 @@ import com.gewuyou.forgeboot.webmvc.dto.page.QueryComponent * @since 2025-05-29 20:18:22 * @author gewuyou */ -interface CrudServiceSpec { +interface JpaCrudServiceSpec { /** * 根据ID获取实体 * diff --git a/forgeboot-webmvc/spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/service/impl/CrudServiceImplSpec.kt b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/service/impl/JpaCrudServiceImplSpec.kt similarity index 83% rename from forgeboot-webmvc/spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/service/impl/CrudServiceImplSpec.kt rename to forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/service/impl/JpaCrudServiceImplSpec.kt index 1edb7a7..260b00d 100644 --- a/forgeboot-webmvc/spec/src/main/kotlin/com/gewuyou/forgeboot/webmvc/spec/service/impl/CrudServiceImplSpec.kt +++ b/forgeboot-webmvc/spec-jpa/src/main/kotlin/com/gewuyou/webmvc/spec/jpa/service/impl/JpaCrudServiceImplSpec.kt @@ -1,24 +1,25 @@ -package com.gewuyou.forgeboot.webmvc.spec.service.impl +package com.gewuyou.webmvc.spec.jpa.service.impl import com.gewuyou.forgeboot.webmvc.dto.PageResult -import com.gewuyou.forgeboot.webmvc.dto.extension.map -import com.gewuyou.forgeboot.webmvc.dto.extension.toJpaQuery -import com.gewuyou.forgeboot.webmvc.dto.extension.toPageResult -import com.gewuyou.forgeboot.webmvc.dto.extension.toSpecification -import com.gewuyou.forgeboot.webmvc.dto.page.QueryComponent -import com.gewuyou.forgeboot.webmvc.spec.repository.CrudRepositorySpec -import com.gewuyou.forgeboot.webmvc.spec.service.CrudServiceSpec + +import com.gewuyou.webmvc.spec.core.page.QueryComponent +import com.gewuyou.webmvc.spec.jpa.extension.map +import com.gewuyou.webmvc.spec.jpa.extension.toJpaQuery +import com.gewuyou.webmvc.spec.jpa.extension.toPageResult +import com.gewuyou.webmvc.spec.jpa.extension.toSpecification +import com.gewuyou.webmvc.spec.jpa.repository.JpaCrudRepositorySpec +import com.gewuyou.webmvc.spec.jpa.service.JpaCrudServiceSpec /** - * CRUD 服务实现的抽象类,提供通用的数据访问操作。 + * Jpa CRUD 服务实现的抽象类,提供通用的数据访问操作。 * * @since 2025-05-29 20:37:27 * @author gewuyou */ -abstract class CrudServiceImplSpec( - private val repository: CrudRepositorySpec, -) : CrudServiceSpec { +abstract class JpaCrudServiceImplSpec( + private val repository: JpaCrudRepositorySpec, +) : JpaCrudServiceSpec { /** * 根据实体的唯一标识符查找实体对象。 @@ -184,15 +185,16 @@ abstract class CrudServiceImplSpec( return repository.saveAll(entities) } - /** - * 标记实体为软删除状态。 - * - * 此方法应在子类中实现,用于定义如何将实体标记为已删除(例如设置一个 deleted 字段)。 - * 软删除不会从数据库中物理移除记录,而是将其标记为已删除状态,以便保留历史数据。 - * - * @param entity 实体对象,表示要标记为删除状态的对象 - */ + /** + * 标记实体为软删除状态。 + * + * 此方法应在子类中实现,用于定义如何将实体标记为已删除(例如设置一个 deleted 字段)。 + * 软删除不会从数据库中物理移除记录,而是将其标记为已删除状态,以便保留历史数据。 + * + * @param entity 实体对象,表示要标记为删除状态的对象 + */ protected abstract fun setDeleted(entity: Entity) + /** * 执行软删除操作。 * diff --git a/forgeboot-webmvc/spec/README.md b/forgeboot-webmvc/spec/README.md deleted file mode 100644 index 51483b1..0000000 --- a/forgeboot-webmvc/spec/README.md +++ /dev/null @@ -1,117 +0,0 @@ -# forgeboot-webmvc-spec - -> 🧩 Web 项目通用 CRUD 接口规范模块,封装 Repository 与 Service 层的标准增删改查接口与默认实现,简化重复代码。 - ---- - -## 🧩 简介 - -`forgeboot-webmvc-spec` 是 ForgeBoot 提供的统一接口规范模块,旨在为常见的 Web 开发提供可复用的 Repository 和 Service 层增删改查基础接口及实现模板。 - -通过继承和组合该模块中的接口和基类,可以快速构建具有一致风格的业务组件,提升开发效率、降低重复代码、统一项目结构。 - ---- - -## ✨ 核心功能 - -- ✅ `CrudRepositorySpec`:通用 Repository 接口规范(继承自 `JpaRepository`) -- ✅ `CrudServiceSpec`:业务层接口标准化定义 -- ✅ `CrudServiceImplSpec`:默认 Service 实现(依赖 Repository) -- ✅ 泛型支持 Entity 类型与主键类型的自动推导 -- ✅ 与 DTO 模块 (`forgeboot-webmvc-dto`) 无缝协作 - ---- - -## 📦 引入依赖 - -使用 Maven: - -```xml - - io.github.gewuyou - forgeboot-webmvc-spec - ${version} - -``` - -使用 Gradle: - -```groovy -implementation "io.github.gewuyou:forgeboot-webmvc-spec:${version}" -``` - ---- - -## 🚀 快速开始 - -### ✅ 定义实体类 - -```kotlin -@Entity -data class Product( - @Id val id: Long, - val name: String, - val status: Int -) -``` - -### ✅ 创建 Repository 接口 - -```kotlin -interface ProductRepository : CrudRepositorySpec -``` - -### ✅ 创建 Service 接口 - -```kotlin -interface ProductService : CrudServiceSpec -``` - -### ✅ 创建默认实现类 - -```kotlin -@Service -class ProductServiceImpl( - override val repository: ProductRepository -) : CrudServiceImplSpec(), ProductService -``` - -现在你就拥有了以下功能: -- 新增:`save(entity)` -- 修改:`updateById(id, modifier)` -- 删除:`deleteById(id)` -- 查询单个:`findById(id)` -- 查询全部:`findAll()` - ---- - -## 🧩 扩展方法(默认实现中提供) - -```kotlin -fun updateById(id: ID, modifier: (T) -> Unit): Boolean -fun existsById(id: ID): Boolean -fun deleteById(id: ID): Boolean -``` - -可自由覆写或组合使用。 - ---- - -## 🧠 与其他模块集成建议 - -| 模块 | 集成方式说明 | -|------------------------|-------------------------------------------| -| `forgeboot-webmvc-dto` | 可配合 `PageResult`, `QueryComponent` 返回分页数据 | ---- - -## 📄 许可协议 - -本项目采用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) 开源协议。 - ---- - -## 📬 联系作者 - -由 [@gewuyou](https://github.com/gewuyou) 维护。 - -欢迎提交 Issue 或 PR 改进本模块! diff --git a/settings.gradle.kts b/settings.gradle.kts index 81c7cd5..fccbead 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -75,7 +75,8 @@ include( ":forgeboot-webmvc:exception-i18n", ":forgeboot-webmvc:dto", ":forgeboot-webmvc:validation", - ":forgeboot-webmvc:spec" + ":forgeboot-webmvc:spec-core", + ":forgeboot-webmvc:spec-jpa", ) project(":forgeboot-webmvc").name = "forgeboot-webmvc-spring-boot-starter" project(":forgeboot-webmvc:version").name = "forgeboot-webmvc-version-spring-boot-starter" @@ -84,7 +85,8 @@ project(":forgeboot-webmvc:exception").name = "forgeboot-webmvc-exception-spring project(":forgeboot-webmvc:exception-i18n").name = "forgeboot-webmvc-exception-i18n-spring-boot-starter" project(":forgeboot-webmvc:dto").name = "forgeboot-webmvc-dto" project(":forgeboot-webmvc:validation").name = "forgeboot-webmvc-validation" -project(":forgeboot-webmvc:spec").name = "forgeboot-webmvc-spec" +project(":forgeboot-webmvc:spec-core").name = "forgeboot-webmvc-spec-core" +project(":forgeboot-webmvc:spec-jpa").name = "forgeboot-webmvc-spec-jpa" //endregion //region module core