diff --git a/pom.xml b/pom.xml index be47bdd..01a3771 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,11 @@ + + io.lettuce + lettuce-core + 6.4.0.RELEASE + com.moandjiezana.toml toml4j diff --git a/src/main/kotlin/biz/cdkey.kt b/src/main/kotlin/biz/cdkey.kt index d7ad7ea..614700f 100644 --- a/src/main/kotlin/biz/cdkey.kt +++ b/src/main/kotlin/biz/cdkey.kt @@ -1,6 +1,7 @@ package biz +import config.RDS import datasource.DB import exception.ServiceException import model.PlanParams @@ -12,7 +13,9 @@ import org.ktorm.dsl.* import utils.throwIf import utils.throwIfNot import java.nio.ByteBuffer +import java.time.Duration import java.time.LocalDateTime +import java.time.format.DateTimeFormatter import java.util.concurrent.ThreadLocalRandom import java.util.concurrent.atomic.AtomicInteger import kotlin.math.abs @@ -98,6 +101,8 @@ fun validateCDK(params: ValidateParams): Resp { (eId != specId).throwIf("CDK已被使用") } + limit(cdk) + // log DB.insert(OperationLog) { set(OperationLog.cdk, cdk) @@ -108,3 +113,16 @@ fun validateCDK(params: ValidateParams): Resp { return Resp.success() } + +private fun limit(cdk: String) { + val date = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()) + val key = "limit:${date}:${cdk}" + val cnt = RDS.get().get(key).get()?.toIntOrNull() ?: 0 + (cnt > 7).throwIf("您的账号已被限制") + + RDS.get().incr(key).get() + + if (cnt == 0) { + RDS.get().expire(key, Duration.ofDays(1)) + } +} diff --git a/src/main/kotlin/config/props.kt b/src/main/kotlin/config/props.kt index 3c3db0d..970cb47 100644 --- a/src/main/kotlin/config/props.kt +++ b/src/main/kotlin/config/props.kt @@ -47,4 +47,10 @@ object Props { fun get(key: String): String = TomlStore.config.value.getString("datasource.$key") } + + object Redis { + val url: String by lazy { + TomlStore.config.value.getString("redis.url") + } + } } diff --git a/src/main/kotlin/config/redis.kt b/src/main/kotlin/config/redis.kt new file mode 100644 index 0000000..d732b16 --- /dev/null +++ b/src/main/kotlin/config/redis.kt @@ -0,0 +1,17 @@ +package config + +import io.lettuce.core.RedisClient +import io.lettuce.core.api.StatefulRedisConnection +import io.lettuce.core.api.async.RedisAsyncCommands + +object RDS { + private val single = run { + val client: RedisClient = RedisClient.create(Props.Redis.url) + val connection: StatefulRedisConnection = client.connect() + connection.async() + } + + fun get(): RedisAsyncCommands { + return single + } +} \ No newline at end of file