refactor(domain): 参数获取修改
This commit is contained in:
parent
278c5eb810
commit
fa18c92a02
@ -17,6 +17,7 @@ object Application {
|
|||||||
Config.init(vertx)
|
Config.init(vertx)
|
||||||
val getIt = InjectConfig.configure(vertx)
|
val getIt = InjectConfig.configure(vertx)
|
||||||
val mainVerticle = getIt.getInstance(MainVerticle::class.java)
|
val mainVerticle = getIt.getInstance(MainVerticle::class.java)
|
||||||
|
|
||||||
vertx.deployVerticle(mainVerticle).onComplete {
|
vertx.deployVerticle(mainVerticle).onComplete {
|
||||||
if (it.failed()) {
|
if (it.failed()) {
|
||||||
logger.error { "MainVerticle startup failed: ${it.cause()?.stackTraceToString()}" }
|
logger.error { "MainVerticle startup failed: ${it.cause()?.stackTraceToString()}" }
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package app.config.auth
|
package app.config.auth
|
||||||
|
|
||||||
import app.domain.account.AccountRepository
|
import app.data.domain.account.AccountRepository
|
||||||
import app.port.reids.RedisClient
|
import app.port.reids.RedisClient
|
||||||
import cn.hutool.core.lang.Snowflake
|
import cn.hutool.core.lang.Snowflake
|
||||||
import cn.hutool.core.util.IdUtil
|
import cn.hutool.core.util.IdUtil
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package app.controller
|
package app.controller
|
||||||
|
|
||||||
import app.domain.account.LoginDTO
|
import app.data.domain.account.LoginDTO
|
||||||
import app.service.account.AccountService
|
import app.service.account.AccountService
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import io.vertx.ext.web.RoutingContext
|
import io.vertx.ext.web.RoutingContext
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
package app.controller
|
package app.controller
|
||||||
|
|
||||||
import app.domain.CargoType
|
import app.data.domain.account.Account
|
||||||
import app.domain.account.Account
|
import app.data.domain.account.AccountRepository
|
||||||
import app.domain.account.AccountRepository
|
import app.data.emun.Status
|
||||||
import app.service.account.AccountService
|
import app.service.account.AccountService
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
@ -28,13 +28,15 @@ class Demo1Controller @Inject constructor(
|
|||||||
@D("name", "姓名") name: String?,
|
@D("name", "姓名") name: String?,
|
||||||
@D("age", "年龄") age: Int?,
|
@D("age", "年龄") age: Int?,
|
||||||
@D("list", "列表") list: List<String>?,
|
@D("list", "列表") list: List<String>?,
|
||||||
@D("cargoType", "货物类型") cargoType: CargoType?
|
@D("status", "状态-0正常,1禁用,2删除") status: Status?,
|
||||||
|
@D("account", "账号") account: Account?
|
||||||
) {
|
) {
|
||||||
logger.info { "你好" }
|
logger.info { "你好" }
|
||||||
println(age)
|
println(age)
|
||||||
println(list)
|
println(list)
|
||||||
println("test-$name")
|
println("test-$name")
|
||||||
println(cargoType)
|
println(status)
|
||||||
|
println(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
@D("事务测试")
|
@D("事务测试")
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package app.domain.account
|
package app.data.domain.account
|
||||||
|
|
||||||
|
import app.data.emun.Status
|
||||||
import org.aikrai.vertx.db.annotation.*
|
import org.aikrai.vertx.db.annotation.*
|
||||||
|
import org.aikrai.vertx.jackson.JsonUtil
|
||||||
import org.aikrai.vertx.utlis.BaseEntity
|
import org.aikrai.vertx.utlis.BaseEntity
|
||||||
import java.sql.Timestamp
|
import java.sql.Timestamp
|
||||||
|
|
||||||
@ -23,7 +25,7 @@ class Account : BaseEntity() {
|
|||||||
|
|
||||||
var password: String? = null
|
var password: String? = null
|
||||||
|
|
||||||
var status: Char? = null
|
var status: Status? = Status.ACTIVE
|
||||||
|
|
||||||
var delFlag: Char? = null
|
var delFlag: Char? = null
|
||||||
|
|
||||||
@ -31,4 +33,8 @@ class Account : BaseEntity() {
|
|||||||
|
|
||||||
@TableField(fill = FieldFill.UPDATE)
|
@TableField(fill = FieldFill.UPDATE)
|
||||||
var loginDate: Timestamp? = null
|
var loginDate: Timestamp? = null
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return JsonUtil.toJsonStr(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package app.domain.account
|
package app.data.domain.account
|
||||||
|
|
||||||
import app.base.domain.auth.modle.AccountRoleDTO
|
import app.data.domain.account.modle.AccountRoleAccessDTO
|
||||||
import app.domain.account.modle.AccountRoleAccessDTO
|
import app.data.domain.account.modle.AccountRoleDTO
|
||||||
import com.google.inject.ImplementedBy
|
import com.google.inject.ImplementedBy
|
||||||
import org.aikrai.vertx.db.Repository
|
import org.aikrai.vertx.db.Repository
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package app.domain.account
|
package app.data.domain.account
|
||||||
|
|
||||||
import app.base.domain.auth.modle.AccountRoleDTO
|
import app.data.domain.account.modle.AccountRoleAccessDTO
|
||||||
import app.domain.account.modle.AccountRoleAccessDTO
|
import app.data.domain.account.modle.AccountRoleDTO
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import io.vertx.sqlclient.SqlClient
|
import io.vertx.sqlclient.SqlClient
|
||||||
import org.aikrai.vertx.db.RepositoryImpl
|
import org.aikrai.vertx.db.RepositoryImpl
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package app.domain.account
|
package app.data.domain.account
|
||||||
|
|
||||||
data class LoginDTO(
|
data class LoginDTO(
|
||||||
var username: String,
|
var username: String,
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package app.domain.account.modle
|
package app.data.domain.account.modle
|
||||||
|
|
||||||
import app.domain.account.Account
|
import app.data.domain.account.Account
|
||||||
import app.domain.menu.Menu
|
import app.data.domain.menu.Menu
|
||||||
import app.domain.role.Role
|
import app.data.domain.role.Role
|
||||||
|
|
||||||
data class AccountRoleAccessDTO(
|
data class AccountRoleAccessDTO(
|
||||||
val account: Account,
|
val account: Account,
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package app.base.domain.auth.modle
|
package app.data.domain.account.modle
|
||||||
|
|
||||||
import app.domain.role.Role
|
import app.data.domain.role.Role
|
||||||
|
|
||||||
data class AccountRoleDTO(
|
data class AccountRoleDTO(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package app.domain.menu
|
package app.data.domain.menu
|
||||||
|
|
||||||
import org.aikrai.vertx.db.annotation.IdType
|
import org.aikrai.vertx.db.annotation.IdType
|
||||||
import org.aikrai.vertx.db.annotation.TableId
|
import org.aikrai.vertx.db.annotation.TableId
|
||||||
@ -1,7 +1,6 @@
|
|||||||
package app.domain.menu
|
package app.data.domain.menu
|
||||||
|
|
||||||
import app.base.domain.auth.menu.MenuRepository
|
import app.data.domain.account.Account
|
||||||
import app.domain.account.Account
|
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import com.google.inject.Singleton
|
import com.google.inject.Singleton
|
||||||
import io.vertx.ext.auth.User
|
import io.vertx.ext.auth.User
|
||||||
@ -1,7 +1,5 @@
|
|||||||
package app.base.domain.auth.menu
|
package app.data.domain.menu
|
||||||
|
|
||||||
import app.domain.menu.Menu
|
|
||||||
import app.domain.menu.MenuRepositoryImpl
|
|
||||||
import com.google.inject.ImplementedBy
|
import com.google.inject.ImplementedBy
|
||||||
import org.aikrai.vertx.db.Repository
|
import org.aikrai.vertx.db.Repository
|
||||||
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
package app.domain.menu
|
package app.data.domain.menu
|
||||||
|
|
||||||
import app.base.domain.auth.menu.MenuRepository
|
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import io.vertx.sqlclient.SqlClient
|
import io.vertx.sqlclient.SqlClient
|
||||||
import org.aikrai.vertx.db.RepositoryImpl
|
import org.aikrai.vertx.db.RepositoryImpl
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package app.base.domain.auth.menu.modle
|
package app.data.domain.menu.modle
|
||||||
|
|
||||||
import app.domain.menu.Menu
|
import app.data.domain.menu.Menu
|
||||||
|
|
||||||
class TreeSelect {
|
class TreeSelect {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package app.domain.role
|
package app.data.domain.role
|
||||||
|
|
||||||
import org.aikrai.vertx.db.annotation.TableName
|
import org.aikrai.vertx.db.annotation.TableName
|
||||||
import org.aikrai.vertx.utlis.BaseEntity
|
import org.aikrai.vertx.utlis.BaseEntity
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package app.domain.role
|
package app.data.domain.role
|
||||||
|
|
||||||
import com.google.inject.ImplementedBy
|
import com.google.inject.ImplementedBy
|
||||||
import org.aikrai.vertx.db.Repository
|
import org.aikrai.vertx.db.Repository
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package app.domain.role
|
package app.data.domain.role
|
||||||
|
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import io.vertx.sqlclient.SqlClient
|
import io.vertx.sqlclient.SqlClient
|
||||||
27
vertx-demo/src/main/kotlin/app/data/emun/DeleteEnum.kt
Normal file
27
vertx-demo/src/main/kotlin/app/data/emun/DeleteEnum.kt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package app.data.emun
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
import org.aikrai.vertx.db.annotation.EnumValue
|
||||||
|
|
||||||
|
enum class DeleteEnum(private val code: Int, private val description: String) {
|
||||||
|
UNDELETED(0, "未删除"),
|
||||||
|
DELETED(2, "已删除");
|
||||||
|
|
||||||
|
@JsonValue
|
||||||
|
@EnumValue
|
||||||
|
fun getCode(): Int {
|
||||||
|
return this.code
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return this.description
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JsonCreator
|
||||||
|
fun parse(code: Int): DeleteEnum? {
|
||||||
|
return entries.find { it.code == code }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
vertx-demo/src/main/kotlin/app/data/emun/Status.kt
Normal file
27
vertx-demo/src/main/kotlin/app/data/emun/Status.kt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package app.data.emun
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
import org.aikrai.vertx.db.annotation.EnumValue
|
||||||
|
|
||||||
|
enum class Status(private val code: Int, private val description: String) {
|
||||||
|
ACTIVE(0, "正常"),
|
||||||
|
INACTIVE(1, "禁用"),
|
||||||
|
DELETED(2, "删除");
|
||||||
|
|
||||||
|
@JsonValue
|
||||||
|
@EnumValue
|
||||||
|
public fun getCode(): Int {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
override fun toString(): String {
|
||||||
|
return description
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JsonCreator
|
||||||
|
fun parse(code: Int): Status? {
|
||||||
|
return entries.find { it.code == code }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package app.domain
|
|
||||||
|
|
||||||
enum class CargoType(val message: String) {
|
|
||||||
|
|
||||||
RECEIVING("收货"),
|
|
||||||
|
|
||||||
SHIPPING("发货"),
|
|
||||||
|
|
||||||
INTERNAL_TRANSFER("内部调拨")
|
|
||||||
;
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun parse(value: String?): CargoType? {
|
|
||||||
if (value.isNullOrBlank()) return null
|
|
||||||
return CargoType.values().find { it.name == value || it.message == value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package app.service.account
|
package app.service.account
|
||||||
|
|
||||||
import app.config.auth.TokenService
|
import app.config.auth.TokenService
|
||||||
import app.domain.account.Account
|
import app.data.domain.account.Account
|
||||||
import app.domain.account.AccountRepository
|
import app.data.domain.account.AccountRepository
|
||||||
import app.domain.account.LoginDTO
|
import app.data.domain.account.LoginDTO
|
||||||
import cn.hutool.core.lang.Snowflake
|
import cn.hutool.core.lang.Snowflake
|
||||||
import cn.hutool.crypto.SecureUtil
|
import cn.hutool.crypto.SecureUtil
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import app.config.RespBean
|
|||||||
import app.config.auth.JwtAuthenticationHandler
|
import app.config.auth.JwtAuthenticationHandler
|
||||||
import app.config.auth.ResponseHandler
|
import app.config.auth.ResponseHandler
|
||||||
import app.config.auth.TokenService
|
import app.config.auth.TokenService
|
||||||
import app.domain.account.Account
|
import app.data.domain.account.Account
|
||||||
import app.port.aipfox.ApifoxClient
|
import app.port.aipfox.ApifoxClient
|
||||||
import cn.hutool.core.lang.Snowflake
|
import cn.hutool.core.lang.Snowflake
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package org.aikrai.vertx.context
|
|||||||
import cn.hutool.core.util.StrUtil
|
import cn.hutool.core.util.StrUtil
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import io.vertx.core.http.HttpMethod
|
import io.vertx.core.http.HttpMethod
|
||||||
|
import io.vertx.core.json.JsonObject
|
||||||
import io.vertx.ext.auth.User
|
import io.vertx.ext.auth.User
|
||||||
import io.vertx.ext.web.Router
|
import io.vertx.ext.web.Router
|
||||||
import io.vertx.ext.web.RoutingContext
|
import io.vertx.ext.web.RoutingContext
|
||||||
@ -11,6 +12,8 @@ import kotlinx.coroutines.launch
|
|||||||
import org.aikrai.vertx.auth.*
|
import org.aikrai.vertx.auth.*
|
||||||
import org.aikrai.vertx.config.resp.DefaultResponseHandler
|
import org.aikrai.vertx.config.resp.DefaultResponseHandler
|
||||||
import org.aikrai.vertx.config.resp.ResponseHandlerInterface
|
import org.aikrai.vertx.config.resp.ResponseHandlerInterface
|
||||||
|
import org.aikrai.vertx.db.annotation.EnumValue
|
||||||
|
import org.aikrai.vertx.jackson.JsonUtil
|
||||||
import org.aikrai.vertx.utlis.ClassUtil
|
import org.aikrai.vertx.utlis.ClassUtil
|
||||||
import org.aikrai.vertx.utlis.Meta
|
import org.aikrai.vertx.utlis.Meta
|
||||||
import org.reflections.Reflections
|
import org.reflections.Reflections
|
||||||
@ -73,8 +76,10 @@ class RouterBuilder(
|
|||||||
isList = parameter.type.classifier == List::class,
|
isList = parameter.type.classifier == List::class,
|
||||||
isComplex = !parameter.type.classifier.toString().startsWith("class kotlin.") &&
|
isComplex = !parameter.type.classifier.toString().startsWith("class kotlin.") &&
|
||||||
!parameter.type.classifier.toString().startsWith("class io.vertx") &&
|
!parameter.type.classifier.toString().startsWith("class io.vertx") &&
|
||||||
|
!(parameter.type.javaType as Class<*>).isEnum &&
|
||||||
!parameter.type.javaType.javaClass.isEnum &&
|
!parameter.type.javaType.javaClass.isEnum &&
|
||||||
parameter.type.javaType is Class<*>
|
parameter.type.javaType is Class<*>,
|
||||||
|
isEnum = typeClass?.isEnum ?: (parameter.type.javaType as Class<*>).isEnum
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
routeInfoCache[reqPath to httpMethod] =
|
routeInfoCache[reqPath to httpMethod] =
|
||||||
@ -163,15 +168,6 @@ class RouterBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getReqPath(prefix: String, clazz: Class<*>): String {
|
|
||||||
val basePath = if (prefix.isNotBlank()) {
|
|
||||||
StrUtil.toCamelCase(StrUtil.toUnderlineCase(prefix))
|
|
||||||
} else {
|
|
||||||
StrUtil.toCamelCase(StrUtil.toUnderlineCase(clazz.simpleName.removeSuffix("Controller")))
|
|
||||||
}
|
|
||||||
return "/$basePath".replace("//", "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getReqPath(prefix: String, clazz: Class<*>, method: Method): String {
|
private fun getReqPath(prefix: String, clazz: Class<*>, method: Method): String {
|
||||||
var classPath = if (prefix.isNotBlank()) {
|
var classPath = if (prefix.isNotBlank()) {
|
||||||
StrUtil.toCamelCase(StrUtil.toUnderlineCase(prefix))
|
StrUtil.toCamelCase(StrUtil.toUnderlineCase(prefix))
|
||||||
@ -189,31 +185,57 @@ class RouterBuilder(
|
|||||||
val queryParams = ctx.queryParams().entries().associate { it.key to it.value }
|
val queryParams = ctx.queryParams().entries().associate { it.key to it.value }
|
||||||
val combinedParams = formAttributes + queryParams
|
val combinedParams = formAttributes + queryParams
|
||||||
// 解析Body
|
// 解析Body
|
||||||
val bodyStr = if (!ctx.body().isEmpty) ctx.body().asString() else ""
|
val bodyObj = if (!ctx.body().isEmpty) ctx.body().asJsonObject() else null
|
||||||
val bodyAsMap = if (bodyStr.isNotBlank()) {
|
val bodyMap = bodyObj?.map ?: emptyMap()
|
||||||
try {
|
|
||||||
objectMapper.readValue(bodyStr, Map::class.java) as Map<String, Any>
|
|
||||||
} catch (e: Exception) {
|
|
||||||
emptyMap()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
emptyMap()
|
|
||||||
}
|
|
||||||
|
|
||||||
paramsInfo.forEach { param ->
|
paramsInfo.forEach { param ->
|
||||||
if (param.isList) {
|
if (param.isList) {
|
||||||
val listParamValue = ctx.queryParams().getAll(param.name)
|
var value = ctx.queryParams().getAll(param.name)
|
||||||
if (listParamValue.isEmpty() && !param.isNullable) throw IllegalArgumentException("Missing required parameter: ${param.name}")
|
if (value.isEmpty() && bodyMap[param.name] != null) {
|
||||||
params.add(listParamValue)
|
value = (bodyMap[param.name] as Collection<*>).map { it.toString() }.toMutableList()
|
||||||
|
}
|
||||||
|
if (value.isEmpty() && !param.isNullable) {
|
||||||
|
throw IllegalArgumentException("Missing required parameter: ${param.name}")
|
||||||
|
}
|
||||||
|
params.add(value.ifEmpty { null })
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (param.isEnum) {
|
||||||
|
val value = sequenceOf(
|
||||||
|
combinedParams[param.name],
|
||||||
|
bodyMap[param.name]
|
||||||
|
).filterNotNull().map { it.toString() }.firstOrNull()
|
||||||
|
|
||||||
|
val enumValueMethod = param.type.methods.find { method ->
|
||||||
|
method.isAnnotationPresent(EnumValue::class.java)
|
||||||
|
}
|
||||||
|
val enumValue = param.type.enumConstants.firstOrNull { enumConstant ->
|
||||||
|
if (enumValueMethod != null) {
|
||||||
|
enumValueMethod.invoke(enumConstant).toString() == value
|
||||||
|
} else {
|
||||||
|
(enumConstant as Enum<*>).name == value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (enumValue != null) params.add(enumValue)
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
if (param.isComplex) {
|
if (param.isComplex) {
|
||||||
try {
|
try {
|
||||||
val value = objectMapper.readValue(bodyStr, param.type)
|
val value = sequenceOf(
|
||||||
params.add(value)
|
if (paramsInfo.size == 1) bodyObj else null,
|
||||||
|
bodyMap[param.name]?.let { JsonUtil.toJsonObject(it) },
|
||||||
|
combinedParams[param.name]?.let { JsonObject(it) },
|
||||||
|
bodyObj
|
||||||
|
).filterNotNull().firstOrNull { !it.isEmpty }
|
||||||
|
if (value?.isEmpty == true && !param.isNullable) {
|
||||||
|
throw IllegalArgumentException("Missing required parameter: ${param.name}")
|
||||||
|
}
|
||||||
|
params.add(if (value == null || value.isEmpty) null else JsonUtil.parseObject(value, param.type))
|
||||||
return@forEach
|
return@forEach
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (!param.isNullable) throw IllegalArgumentException("Failed to parse request body for parameter: ${param.name}")
|
throw IllegalArgumentException(e.message, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +244,7 @@ class RouterBuilder(
|
|||||||
RoutingContext::class.java -> ctx
|
RoutingContext::class.java -> ctx
|
||||||
User::class.java -> ctx.user()
|
User::class.java -> ctx.user()
|
||||||
else -> {
|
else -> {
|
||||||
val bodyValue = bodyAsMap[param.name]
|
val bodyValue = bodyMap[param.name]
|
||||||
val paramValue = bodyValue?.toString() ?: combinedParams[param.name]
|
val paramValue = bodyValue?.toString() ?: combinedParams[param.name]
|
||||||
when {
|
when {
|
||||||
paramValue == null -> {
|
paramValue == null -> {
|
||||||
@ -254,16 +276,12 @@ class RouterBuilder(
|
|||||||
* @return 转换为目标类型的参数值,如果转换失败则返回 `null`。
|
* @return 转换为目标类型的参数值,如果转换失败则返回 `null`。
|
||||||
*/
|
*/
|
||||||
private fun getParamValue(paramValue: String, type: Class<*>): Any? {
|
private fun getParamValue(paramValue: String, type: Class<*>): Any? {
|
||||||
return when {
|
return when (type) {
|
||||||
type.isEnum -> {
|
String::class.java -> paramValue
|
||||||
type.enumConstants.firstOrNull { (it as Enum<*>).name.equals(paramValue, ignoreCase = true) }
|
Int::class.java, Integer::class.java -> paramValue.toIntOrNull()
|
||||||
}
|
Long::class.java, Long::class.java -> paramValue.toLongOrNull()
|
||||||
|
Double::class.java, Double::class.java -> paramValue.toDoubleOrNull()
|
||||||
type == String::class.java -> paramValue
|
Boolean::class.java, Boolean::class.java -> paramValue.toBoolean()
|
||||||
type == Int::class.java || type == Integer::class.java -> paramValue.toIntOrNull()
|
|
||||||
type == Long::class.java || type == Long::class.java -> paramValue.toLongOrNull()
|
|
||||||
type == Double::class.java || type == Double::class.java -> paramValue.toDoubleOrNull()
|
|
||||||
type == Boolean::class.java || type == Boolean::class.java -> paramValue.toBoolean()
|
|
||||||
else -> paramValue
|
else -> paramValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,6 +316,21 @@ class RouterBuilder(
|
|||||||
private fun serializeToJson(obj: Any?): String {
|
private fun serializeToJson(obj: Any?): String {
|
||||||
return objectMapper.writeValueAsString(obj)
|
return objectMapper.writeValueAsString(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getEnumValue(enumValue: Any?): Any? {
|
||||||
|
if (enumValue == null || !enumValue::class.java.isEnum) {
|
||||||
|
return null // 不是枚举或为空,直接返回 null
|
||||||
|
}
|
||||||
|
val enumClass = enumValue::class.java
|
||||||
|
val methods = enumClass.declaredMethods
|
||||||
|
for (method in methods) {
|
||||||
|
if (method.isAnnotationPresent(EnumValue::class.java)) {
|
||||||
|
method.isAccessible = true // 如果方法是私有的,设置为可访问
|
||||||
|
return method.invoke(enumValue) // 调用带有 @EnumValue 注解的方法
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null // 没有找到带有 @EnumValue 注解的方法
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class RouteInfo(
|
private data class RouteInfo(
|
||||||
@ -316,6 +349,7 @@ class RouterBuilder(
|
|||||||
val type: Class<*>,
|
val type: Class<*>,
|
||||||
val isNullable: Boolean,
|
val isNullable: Boolean,
|
||||||
val isList: Boolean,
|
val isList: Boolean,
|
||||||
val isComplex: Boolean
|
val isComplex: Boolean,
|
||||||
|
val isEnum: Boolean
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -263,6 +263,7 @@ class QueryWrapperImpl<T : Any>(
|
|||||||
"IN", "NOT IN" -> {
|
"IN", "NOT IN" -> {
|
||||||
params[it.column] = "(${(it.value as Collection<*>).joinToString(",")})"
|
params[it.column] = "(${(it.value as Collection<*>).joinToString(",")})"
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
params[it.column] = it.value.toString()
|
params[it.column] = it.value.toString()
|
||||||
}
|
}
|
||||||
@ -292,7 +293,7 @@ class QueryWrapperImpl<T : Any>(
|
|||||||
.execute(params)
|
.execute(params)
|
||||||
.coAwait()
|
.coAwait()
|
||||||
.toList()
|
.toList()
|
||||||
return objs.map { JsonUtil.parseObject(it.encode(), clazz) }.also { conditions.clear() }
|
return objs.map { JsonUtil.parseObject(it, clazz, true) }.also { conditions.clear() }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
conditions.clear()
|
conditions.clear()
|
||||||
throw Meta.repository(e.javaClass.simpleName, e.message)
|
throw Meta.repository(e.javaClass.simpleName, e.message)
|
||||||
|
|||||||
@ -35,6 +35,7 @@ open class RepositoryImpl<TId, TEntity : Any>(
|
|||||||
private val idFieldCache = ConcurrentHashMap<String, Field>()
|
private val idFieldCache = ConcurrentHashMap<String, Field>()
|
||||||
private val idFieldNameCache = ConcurrentHashMap<String, String>()
|
private val idFieldNameCache = ConcurrentHashMap<String, String>()
|
||||||
private val tableNameCache = ConcurrentHashMap<String, String>()
|
private val tableNameCache = ConcurrentHashMap<String, String>()
|
||||||
|
|
||||||
// sqlCache
|
// sqlCache
|
||||||
private val baseSqlCache = ConcurrentHashMap<String, ConcurrentHashMap<String, String>>()
|
private val baseSqlCache = ConcurrentHashMap<String, ConcurrentHashMap<String, String>>()
|
||||||
private val queryClientCache = ConcurrentHashMap<String, Any>()
|
private val queryClientCache = ConcurrentHashMap<String, Any>()
|
||||||
@ -120,6 +121,7 @@ open class RepositoryImpl<TId, TEntity : Any>(
|
|||||||
IdType.INPUT -> {
|
IdType.INPUT -> {
|
||||||
if (idValue == 0L || idValue == -1L) throw Meta.repository("CreateError", "must provide ID value")
|
if (idValue == 0L || idValue == -1L) throw Meta.repository("CreateError", "must provide ID value")
|
||||||
}
|
}
|
||||||
|
|
||||||
IdType.ASSIGN_ID -> params[idField.name] = IdUtil.getSnowflakeNextId()
|
IdType.ASSIGN_ID -> params[idField.name] = IdUtil.getSnowflakeNextId()
|
||||||
IdType.ASSIGN_UUID -> params[idField.name] = IdUtil.simpleUUID()
|
IdType.ASSIGN_UUID -> params[idField.name] = IdUtil.simpleUUID()
|
||||||
else -> {}
|
else -> {}
|
||||||
@ -137,6 +139,7 @@ open class RepositoryImpl<TId, TEntity : Any>(
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
if (value != null) params[field.name] = value
|
if (value != null) params[field.name] = value
|
||||||
@ -331,8 +334,33 @@ open class RepositoryImpl<TId, TEntity : Any>(
|
|||||||
|
|
||||||
// 获取非空字段及其值
|
// 获取非空字段及其值
|
||||||
private fun getNonNullFields(t: TEntity): Map<String, Any> {
|
private fun getNonNullFields(t: TEntity): Map<String, Any> {
|
||||||
return fields.filter { !it.isAnnotationPresent(Transient::class.java) && it.get(t) != null }
|
return fields
|
||||||
.associate { it.name to it.get(t) }
|
.filter {
|
||||||
|
!it.isAnnotationPresent(Transient::class.java) && it.get(t) != null
|
||||||
|
}
|
||||||
|
.associate {
|
||||||
|
val value = it.get(t)
|
||||||
|
if (it.type.isEnum) {
|
||||||
|
it.name to (getEnumValue(value) ?: (value as Enum<*>).name)
|
||||||
|
} else {
|
||||||
|
it.name to value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getEnumValue(enumValue: Any?): Any? {
|
||||||
|
if (enumValue == null || !enumValue::class.java.isEnum) {
|
||||||
|
return null // 不是枚举或为空,直接返回 null
|
||||||
|
}
|
||||||
|
val enumClass = enumValue::class.java
|
||||||
|
val methods = enumClass.declaredMethods
|
||||||
|
for (method in methods) {
|
||||||
|
if (method.isAnnotationPresent(EnumValue::class.java)) {
|
||||||
|
method.isAccessible = true // 如果方法是私有的,设置为可访问
|
||||||
|
return method.invoke(enumValue) // 调用带有 @EnumValue 注解的方法
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null // 没有找到带有 @EnumValue 注解的方法
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -366,10 +394,13 @@ open class RepositoryImpl<TId, TEntity : Any>(
|
|||||||
is Number, is Boolean -> value.toString() // 数字和布尔类型,直接转换为字符串
|
is Number, is Boolean -> value.toString() // 数字和布尔类型,直接转换为字符串
|
||||||
is Timestamp -> // 时间戳类型
|
is Timestamp -> // 时间戳类型
|
||||||
"'${OffsetDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault())}'"
|
"'${OffsetDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault())}'"
|
||||||
|
|
||||||
is Array<*> -> // 数组类型处理
|
is Array<*> -> // 数组类型处理
|
||||||
if (value.isEmpty()) "'{}'" else "'{${value.joinToString(",") { escapeSql(it?.toString() ?: "NULL") }}}'"
|
if (value.isEmpty()) "'{}'" else "'{${value.joinToString(",") { escapeSql(it?.toString() ?: "NULL") }}}'"
|
||||||
|
|
||||||
is Collection<*> -> // 集合类型处理
|
is Collection<*> -> // 集合类型处理
|
||||||
if (value.isEmpty()) "'{}'" else "'{${value.joinToString(",") { escapeSql(it?.toString() ?: "NULL") }}}'"
|
if (value.isEmpty()) "'{}'" else "'{${value.joinToString(",") { escapeSql(it?.toString() ?: "NULL") }}}'"
|
||||||
|
|
||||||
else -> "'${escapeSql(value.toString())}'" // 其他类型,调用 toString() 后转义并加单引号
|
else -> "'${escapeSql(value.toString())}'" // 其他类型,调用 toString() 后转义并加单引号
|
||||||
}
|
}
|
||||||
// 构建 VALUES 部分,每个对象对应一组值
|
// 构建 VALUES 部分,每个对象对应一组值
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
package org.aikrai.vertx.db.annotation
|
package org.aikrai.vertx.db.annotation
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented
|
||||||
|
import java.lang.annotation.ElementType
|
||||||
|
import java.lang.annotation.RetentionPolicy
|
||||||
|
|
||||||
@MustBeDocumented
|
@MustBeDocumented
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS)
|
@Target(AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS)
|
||||||
@ -32,6 +36,11 @@ annotation class TableField(
|
|||||||
// val numericScale: String = ""
|
// val numericScale: String = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@MustBeDocumented
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
@Target(AnnotationTarget.FIELD, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FUNCTION)
|
||||||
|
annotation class EnumValue
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IdType
|
* IdType
|
||||||
* @property key Int
|
* @property key Int
|
||||||
|
|||||||
@ -15,8 +15,9 @@ class ColumnAnnotationIntrospector : JacksonAnnotationIntrospector() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getColumnName(annotated: Annotated?): PropertyName? {
|
private fun getColumnName(annotated: Annotated?): PropertyName? {
|
||||||
if (annotated == null) return null
|
return null
|
||||||
val column = annotated.getAnnotation(TableField::class.java)
|
// if (annotated == null) return null
|
||||||
return column?.let { PropertyName(it.value) }
|
// val column = annotated.getAnnotation(TableField::class.java)
|
||||||
|
// return column?.let { PropertyName(it.value) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,20 +14,27 @@ import io.swagger.v3.oas.models.parameters.Parameter
|
|||||||
import io.swagger.v3.oas.models.parameters.RequestBody
|
import io.swagger.v3.oas.models.parameters.RequestBody
|
||||||
import io.swagger.v3.oas.models.responses.ApiResponse
|
import io.swagger.v3.oas.models.responses.ApiResponse
|
||||||
import io.swagger.v3.oas.models.responses.ApiResponses
|
import io.swagger.v3.oas.models.responses.ApiResponses
|
||||||
|
import io.swagger.v3.oas.models.security.SecurityScheme
|
||||||
import io.swagger.v3.oas.models.servers.Server
|
import io.swagger.v3.oas.models.servers.Server
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import org.aikrai.vertx.context.Controller
|
import org.aikrai.vertx.context.Controller
|
||||||
import org.aikrai.vertx.context.CustomizeRequest
|
import org.aikrai.vertx.context.CustomizeRequest
|
||||||
import org.aikrai.vertx.context.D
|
import org.aikrai.vertx.context.D
|
||||||
|
import org.aikrai.vertx.db.annotation.EnumValue
|
||||||
import org.aikrai.vertx.utlis.ClassUtil
|
import org.aikrai.vertx.utlis.ClassUtil
|
||||||
import org.reflections.Reflections
|
import org.reflections.Reflections
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import java.lang.reflect.ParameterizedType
|
import java.lang.reflect.ParameterizedType
|
||||||
|
import java.lang.reflect.Type
|
||||||
import java.sql.Date
|
import java.sql.Date
|
||||||
import java.sql.Time
|
import java.sql.Time
|
||||||
import java.sql.Timestamp
|
import java.sql.Timestamp
|
||||||
import java.time.*
|
import java.time.*
|
||||||
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KParameter
|
import kotlin.reflect.KParameter
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
import kotlin.reflect.full.declaredMemberProperties
|
||||||
|
import kotlin.reflect.jvm.javaField
|
||||||
import kotlin.reflect.jvm.javaType
|
import kotlin.reflect.jvm.javaType
|
||||||
import kotlin.reflect.jvm.kotlinFunction
|
import kotlin.reflect.jvm.kotlinFunction
|
||||||
|
|
||||||
@ -47,6 +54,8 @@ class OpenApiSpecGenerator {
|
|||||||
private val PRIMITIVE_TYPE_MAPPING = mapOf(
|
private val PRIMITIVE_TYPE_MAPPING = mapOf(
|
||||||
// java.lang classes
|
// java.lang classes
|
||||||
String::class.java to "string",
|
String::class.java to "string",
|
||||||
|
Char::class.java to "string",
|
||||||
|
java.lang.Character::class.java to "string",
|
||||||
Int::class.java to "integer",
|
Int::class.java to "integer",
|
||||||
Integer::class.java to "integer",
|
Integer::class.java to "integer",
|
||||||
Long::class.java to "number",
|
Long::class.java to "number",
|
||||||
@ -222,35 +231,17 @@ class OpenApiSpecGenerator {
|
|||||||
* @return ApiResponses 对象
|
* @return ApiResponses 对象
|
||||||
*/
|
*/
|
||||||
private fun generateResponsesFromReturnType(method: Method): ApiResponses {
|
private fun generateResponsesFromReturnType(method: Method): ApiResponses {
|
||||||
val returnType = method.kotlinFunction?.returnType?.javaType
|
val returnType = method.kotlinFunction?.returnType
|
||||||
val schema = when (returnType) {
|
// 创建 RespBean 的架构
|
||||||
// 处理泛型返回类型
|
val respBeanSchema = Schema<Any>().apply {
|
||||||
is ParameterizedType -> {
|
type = "object"
|
||||||
val rawType = returnType.rawType as Class<*>
|
properties = mapOf(
|
||||||
val typeArguments = returnType.actualTypeArguments
|
"code" to Schema<Int>().type("integer").example(200),
|
||||||
when {
|
"message" to Schema<String>().type("string").example("Success"),
|
||||||
// 处理集合类型
|
"data" to generateDataSchema(returnType),
|
||||||
Collection::class.java.isAssignableFrom(rawType) -> {
|
"requestId" to Schema<Long>().type("integer").format("int64").example(1899712678486753280)
|
||||||
Schema<Any>().apply {
|
|
||||||
type = "array"
|
|
||||||
items = generateSchema(
|
|
||||||
typeArguments[0].let {
|
|
||||||
when (it) {
|
|
||||||
is Class<*> -> it
|
|
||||||
is ParameterizedType -> it.rawType as Class<*>
|
|
||||||
else -> Any::class.java
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
required = listOf("code", "message", "data")
|
||||||
}
|
|
||||||
// 可以添加其他泛型类型的处理
|
|
||||||
else -> generateSchema(rawType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 处理普通类型
|
|
||||||
is Class<*> -> generateSchema(returnType)
|
|
||||||
else -> Schema<Any>().type("object")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ApiResponses().addApiResponse(
|
return ApiResponses().addApiResponse(
|
||||||
@ -259,13 +250,69 @@ class OpenApiSpecGenerator {
|
|||||||
description = "OK"
|
description = "OK"
|
||||||
content = Content().addMediaType(
|
content = Content().addMediaType(
|
||||||
"application/json",
|
"application/json",
|
||||||
MediaType().schema(schema)
|
MediaType().schema(respBeanSchema)
|
||||||
)
|
)
|
||||||
headers = mapOf()
|
headers = mapOf()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增辅助方法,用于生成 data 字段的 Schema
|
||||||
|
private fun generateDataSchema(returnType: KType?): Schema<Any> {
|
||||||
|
if (returnType == null) {
|
||||||
|
return Schema<Any>().type("null")
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (val classifier = returnType.classifier) {
|
||||||
|
is KClass<*> -> {
|
||||||
|
when {
|
||||||
|
// 处理集合类型
|
||||||
|
Collection::class.java.isAssignableFrom(classifier.java) -> {
|
||||||
|
Schema<Any>().apply {
|
||||||
|
type = "array"
|
||||||
|
items = generateSchema(
|
||||||
|
(returnType.arguments.firstOrNull()?.type?.classifier as? KClass<*> ?: Any::class).java,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> generateSchema(classifier.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> Schema<Any>().type("object")
|
||||||
|
}
|
||||||
|
|
||||||
|
// return when (returnType) {
|
||||||
|
// // 处理泛型返回类型
|
||||||
|
// is ParameterizedType -> {
|
||||||
|
// val rawType = returnType.rawType as Class<*>
|
||||||
|
// val typeArguments = returnType.actualTypeArguments
|
||||||
|
// when {
|
||||||
|
// // 处理集合类型
|
||||||
|
// Collection::class.java.isAssignableFrom(rawType) -> {
|
||||||
|
// Schema<Any>().apply {
|
||||||
|
// type = "array"
|
||||||
|
// items = generateSchema(
|
||||||
|
// typeArguments[0].let {
|
||||||
|
// when (it) {
|
||||||
|
// is Class<*> -> it
|
||||||
|
// is ParameterizedType -> it.rawType as Class<*>
|
||||||
|
// else -> Any::class.java
|
||||||
|
// }
|
||||||
|
// }, isNullable
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else -> generateSchema(rawType, isNullable)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // 处理普通类型
|
||||||
|
// is Class<*> -> generateSchema(returnType, isNullable)
|
||||||
|
// null -> Schema<Any>().type("null")
|
||||||
|
// else -> Schema<Any>().type("object")
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取方法的参数列表
|
* 获取方法的参数列表
|
||||||
*
|
*
|
||||||
@ -329,7 +376,7 @@ class OpenApiSpecGenerator {
|
|||||||
* @param type 参数类型
|
* @param type 参数类型
|
||||||
* @return OpenAPI Schema 对象
|
* @return OpenAPI Schema 对象
|
||||||
*/
|
*/
|
||||||
private fun generateSchema(type: Class<*>): Schema<Any> {
|
private fun generateSchema(type: Class<*>, isNullable: Boolean = false): Schema<Any> {
|
||||||
// 如果该类型已经处理过,则返回一个空的 Schema,避免循环引用
|
// 如果该类型已经处理过,则返回一个空的 Schema,避免循环引用
|
||||||
if (processedTypes.contains(type)) {
|
if (processedTypes.contains(type)) {
|
||||||
return Schema<Any>().apply {
|
return Schema<Any>().apply {
|
||||||
@ -344,30 +391,66 @@ class OpenApiSpecGenerator {
|
|||||||
PRIMITIVE_TYPE_MAPPING.containsKey(type) -> Schema<Any>().apply {
|
PRIMITIVE_TYPE_MAPPING.containsKey(type) -> Schema<Any>().apply {
|
||||||
this.type = PRIMITIVE_TYPE_MAPPING[type]
|
this.type = PRIMITIVE_TYPE_MAPPING[type]
|
||||||
deprecated = false
|
deprecated = false
|
||||||
|
nullable = isNullable
|
||||||
}
|
}
|
||||||
// 处理枚举类型
|
// 处理枚举类型
|
||||||
type.isEnum -> Schema<Any>().apply {
|
type.isEnum -> Schema<Any>().apply {
|
||||||
this.type = "string"
|
val enumValueMethod = type.methods.find { method ->
|
||||||
enum = type.enumConstants?.map { it.toString() }
|
method.isAnnotationPresent(EnumValue::class.java)
|
||||||
|
}
|
||||||
|
this.type = if (enumValueMethod != null) {
|
||||||
|
when (enumValueMethod.returnType) {
|
||||||
|
String::class.java -> "string"
|
||||||
|
Int::class.java, java.lang.Integer::class.java -> "integer"
|
||||||
|
Long::class.java, java.lang.Long::class.java -> "integer"
|
||||||
|
Double::class.java, java.lang.Double::class.java -> "number"
|
||||||
|
Float::class.java, java.lang.Float::class.java -> "number"
|
||||||
|
Boolean::class.java, java.lang.Boolean::class.java -> "boolean"
|
||||||
|
else -> "string" // 默认情况下使用 string
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"string" // 如果没有 enumValueMethod,默认使用 string
|
||||||
|
}
|
||||||
|
enum = type.enumConstants?.map {
|
||||||
|
if (enumValueMethod != null) {
|
||||||
|
enumValueMethod.invoke(it)
|
||||||
|
} else {
|
||||||
|
it.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nullable = isNullable
|
||||||
}
|
}
|
||||||
type.name.startsWith("java.lang") || type.name.startsWith("java.time") || type.name.startsWith("java.sql") -> Schema<Any>().apply {
|
type.name.startsWith("java.lang") || type.name.startsWith("java.time") || type.name.startsWith("java.sql") -> Schema<Any>().apply {
|
||||||
this.type = type.simpleName.lowercase()
|
this.type = type.simpleName.lowercase()
|
||||||
deprecated = false
|
deprecated = false
|
||||||
|
nullable = isNullable
|
||||||
}
|
}
|
||||||
type.name.startsWith("java") -> Schema<Any>().apply {
|
type.name.startsWith("java") -> Schema<Any>().apply {
|
||||||
this.type = type.simpleName.lowercase()
|
this.type = type.simpleName.lowercase()
|
||||||
deprecated = false
|
deprecated = false
|
||||||
|
nullable = isNullable
|
||||||
}
|
}
|
||||||
// 处理自定义对象
|
|
||||||
else -> Schema<Any>().apply {
|
else -> Schema<Any>().apply {
|
||||||
this.type = "object"
|
this.type = "object"
|
||||||
properties = type.declaredFields
|
properties = type.kotlin.declaredMemberProperties
|
||||||
.filter { !it.isSynthetic }
|
.associate { property ->
|
||||||
.associate { field ->
|
val field = property.javaField
|
||||||
field.isAccessible = true
|
field?.isAccessible = true
|
||||||
field.name to generateSchema(field.type)
|
val nullable = property.returnType.isMarkedNullable
|
||||||
|
val fieldType = field?.type ?: Any::class.java
|
||||||
|
property.name to generateSchema(fieldType, nullable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 处理自定义对象
|
||||||
|
// else -> Schema<Any>().apply {
|
||||||
|
// this.type = "object"
|
||||||
|
// properties = type.declaredFields
|
||||||
|
// .filter { !it.isSynthetic }
|
||||||
|
// .associate { field ->
|
||||||
|
// field.isAccessible = true
|
||||||
|
// field.name to generateSchema(field.type, )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}.also {
|
}.also {
|
||||||
// 处理完后,从已处理集合中移除当前类型
|
// 处理完后,从已处理集合中移除当前类型
|
||||||
processedTypes.remove(type)
|
processedTypes.remove(type)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user