feat(dto): Added extension function and mapper interface

- Added the PredicateExtensions.kt file to provide extension functions for the Predicate list
- Added BaseMapper.kt file to define the base mapper interface
- Added ConversionMapper.kt file to define the conversion mapper interface between entity and DTO
- Modify the DeleteByIdsReq class to open class - Modify the PageQueryReq class to change the date type from LocalDateTime to Instant
- Modify the R class and ResponseInformation interfaces, change the response status code type from String to Int- Add mapstruct dependency in build.gradle.kts
This commit is contained in:
gewuyou 2025-05-31 22:43:14 +08:00
parent 7c914e23af
commit 5c74c42a24
8 changed files with 122 additions and 13 deletions

View File

@ -9,6 +9,7 @@ dependencies {
compileOnly(libs.jackson.annotations) compileOnly(libs.jackson.annotations)
compileOnly(libs.springBootStarter.jpa) compileOnly(libs.springBootStarter.jpa)
compileOnly(libs.springBootStarter.validation) compileOnly(libs.springBootStarter.validation)
compileOnly(libs.org.mapstruct)
} }
i18nKeyGen { i18nKeyGen {
rootPackage.set("com.gewuyou.forgeboot.webmvc.dto.i18n") rootPackage.set("com.gewuyou.forgeboot.webmvc.dto.i18n")

View File

@ -7,8 +7,8 @@ val defaultOkResponseInformation = object : ResponseInformation {
/** /**
* 响应状态码用于表示响应的状态 * 响应状态码用于表示响应的状态
*/ */
override fun responseStateCode(): String { override fun responseStateCode(): Int {
return "200" return 200
} }
/** /**
@ -24,8 +24,8 @@ val defaultFailureResponseInformation = object : ResponseInformation {
/** /**
* 响应状态码用于表示响应的状态 * 响应状态码用于表示响应的状态
*/ */
override fun responseStateCode(): String { override fun responseStateCode(): Int {
return "400" return 400
} }
/** /**
@ -42,7 +42,7 @@ val defaultFailureResponseInformation = object : ResponseInformation {
* @since 2025-05-03 16:04:42 * @since 2025-05-03 16:04:42
*/ */
data class R<T>( data class R<T>(
override val code: String, override val code: Int,
override val success: Boolean, override val success: Boolean,
override val message: String, override val message: String,
override val data: T? = null, override val data: T? = null,
@ -107,7 +107,7 @@ data class R<T>(
* @return 成功响应对象 * @return 成功响应对象
*/ */
fun <T> success( fun <T> success(
code: String = "200", code: Int = 200,
message: String = "success", message: String = "success",
data: T? = null, data: T? = null,
requestIdProvider: RequestIdProvider? = null, requestIdProvider: RequestIdProvider? = null,
@ -129,7 +129,7 @@ data class R<T>(
* @return 失败响应对象 * @return 失败响应对象
*/ */
fun <T> failure( fun <T> failure(
code: String = "400", code: Int = 400,
message: String = "failure", message: String = "failure",
data: T? = null, data: T? = null,
requestIdProvider: RequestIdProvider? = null, requestIdProvider: RequestIdProvider? = null,

View File

@ -13,7 +13,7 @@ interface ResponseInformation {
/** /**
* 响应状态码用于表示响应的状态 * 响应状态码用于表示响应的状态
*/ */
fun responseStateCode(): String fun responseStateCode(): Int
/** /**
* 响应消息用于提供更详细的响应信息 * 响应消息用于提供更详细的响应信息

View File

@ -0,0 +1,33 @@
package com.gewuyou.forgeboot.webmvc.dto.extension
import jakarta.persistence.criteria.Predicate
/**
* 在Predicate列表中添加条件仅当字符串值不为空且不为空白时执行
*
* @param value 待检查的字符串值
* @param block 一个接受字符串并返回Predicate的lambda表达式
*/
inline fun MutableList<Predicate>.addIfNotBlank(
value: String?,
block: (String) -> Predicate
) {
if (!value.isNullOrBlank()) {
add(block(value))
}
}
/**
* 在Predicate列表中添加条件仅当非字符串值不为空时执行
*
* @param value 待检查的非字符串值
* @param block 一个接受非字符串值并返回Predicate的lambda表达式
*/
inline fun <T> MutableList<Predicate>.addIfNotNull(
value: T?,
block: (T) -> Predicate
) {
if (value != null) {
add(block(value))
}
}

View File

@ -0,0 +1,29 @@
package com.gewuyou.forgeboot.webmvc.dto.mapper
import org.mapstruct.BeanMapping
import org.mapstruct.MappingTarget
import org.mapstruct.NullValuePropertyMappingStrategy
/**
*Base Mapper 基础映射器
*
* @since 2025-05-30 22:50:18
* @author gewuyou
*/
interface BaseMapper<T,S> {
/**
* 合并 source target忽略 null
*/
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
fun mergeIgnoreNull(@MappingTarget target: T, source: S)
/**
* 全量覆盖合并source 字段即使为 null 也覆盖 target
*/
fun overwriteMerge(@MappingTarget target: T, source: S)
/**
* 拷贝 source 到新对象
*/
fun copy(source: S): T
}

View File

@ -0,0 +1,47 @@
package com.gewuyou.forgeboot.webmvc.dto.dto.mapper
/**
* 转换 映射器
*
* 定义了一个转换映射器接口用于在实体类和数据传输对象DTO之间进行转换
* 这个接口定义了四个基本转换方法实体到DTODTO到实体实体列表到DTO列表和DTO列表到实体列表
*
* @param <Entity> 实体类类型
* @param <Dto> 数据传输对象类型
*
* @since 2025-05-30 22:53:35
* @author gewuyou
*/
interface ConversionMapper<Entity, Dto>{
/**
* 将实体对象转换为DTO对象
*
* @param entity 实体对象
* @return 转换后的DTO对象
*/
fun toDto(entity: Entity): Dto
/**
* 将DTO对象转换为实体对象
*
* @param dto DTO对象
* @return 转换后的实体对象
*/
fun toEntity(dto: Dto): Entity
/**
* 将实体对象列表转换为DTO对象列表
*
* @param entityList 实体对象列表
* @return 转换后的DTO对象列表
*/
fun toDtoList(entityList: List<Entity>): List<Dto>
/**
* 将DTO对象列表转换为实体对象列表
*
* @param dtoList DTO对象列表
* @return 转换后的实体对象列表
*/
fun toEntityList(dtoList: List<Dto>): List<Entity>
}

View File

@ -13,7 +13,7 @@ import jakarta.validation.constraints.NotEmpty
* @since 2025-01-18 17:39:18 * @since 2025-01-18 17:39:18
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
class DeleteByIdsReq<T>( open class DeleteByIdsReq<T>(
/** /**
* 待删除的实体id列表 * 待删除的实体id列表
* *

View File

@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.gewuyou.forgeboot.webmvc.dto.SortCondition import com.gewuyou.forgeboot.webmvc.dto.SortCondition
import com.gewuyou.forgeboot.webmvc.dto.enums.SortDirection import com.gewuyou.forgeboot.webmvc.dto.enums.SortDirection
import jakarta.validation.constraints.Min import jakarta.validation.constraints.Min
import java.time.LocalDateTime import java.time.Instant
/** /**
* 分页查询条件请求实体类 * 分页查询条件请求实体类
@ -58,13 +58,12 @@ open class PageQueryReq<T> {
/** /**
* 开始日期 * 开始日期
*/ */
var startDate: LocalDateTime? = null var startDate: Instant? = null
/** /**
* 结束日期 * 结束日期
*/ */
var endDate: LocalDateTime? = null var endDate: Instant? = null
/** /**
* 是否启用 * 是否启用
*/ */