diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 089cf0c..408c5ed 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -5,6 +5,7 @@ diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..648a2a0 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 3cde3b0..cb70f11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,5 +3,5 @@ org.gradle.downloadSources=false org.gradle.parallel=true org.gradle.degree_of_parallelism=16 project_group=top.r3944realms.ltdmanager -project_version=1.22.2 +project_version=1.22.3 dg_lab_version=4.4.14.19 diff --git a/src/main/kotlin/top/r3944realms/ltdmanager/core/config/YamlConfigLoader.kt b/src/main/kotlin/top/r3944realms/ltdmanager/core/config/YamlConfigLoader.kt index 8a8ef33..e1c447c 100644 --- a/src/main/kotlin/top/r3944realms/ltdmanager/core/config/YamlConfigLoader.kt +++ b/src/main/kotlin/top/r3944realms/ltdmanager/core/config/YamlConfigLoader.kt @@ -24,6 +24,7 @@ object YamlConfigLoader { init { ConfigInitializer.initConfig("module.yaml", "config", false) ConfigInitializer.initConfig("application.yaml", "config") + ConfigInitializer.initSqlTemplates() runCatching { ensureConfigEncrypted(_app_config) }.onFailure { e -> diff --git a/src/main/kotlin/top/r3944realms/ltdmanager/module/ModuleFactory.kt b/src/main/kotlin/top/r3944realms/ltdmanager/module/ModuleFactory.kt index c1254af..92a60f7 100644 --- a/src/main/kotlin/top/r3944realms/ltdmanager/module/ModuleFactory.kt +++ b/src/main/kotlin/top/r3944realms/ltdmanager/module/ModuleFactory.kt @@ -30,10 +30,17 @@ object ModuleFactory { UNKNOWN_MODULE -> throw ConfigError(ConfigError.Type.INVALID_PARAMETER, "unknown module") } } - private fun resolveDependency(dep: ModuleConfig.Module.Dependency?, name: String): BaseModule? { - if (dep != null) { - return GlobalManager.moduleManager.getModule(dep.getDepName()) - } else throw ConfigError (ConfigError.Type.MISSING_PARAMETER, "dependency", name) + private fun resolveDependency(dep: ModuleConfig.Module.Dependency?, name: String): BaseModule { + if (dep == null) { + throw ConfigError(ConfigError.Type.MISSING_PARAMETER, "dependency", name) + } + val depName = dep.getDepName() + return GlobalManager.moduleManager.getModule(depName) + ?: throw ConfigError( + ConfigError.Type.OTHER, + "resolveDependency", + "依赖模块 '$depName' 未注册 — 请检查 name/type 是否匹配且目标模块定义在 WHITELIST_AUDIT_MODULE 之前" + ) } private fun createGroupMessagePolling(config: ModuleConfig.Module): GroupMessagePollingModule { val targetGroupId = config.long("target-group-id") diff --git a/src/main/kotlin/top/r3944realms/ltdmanager/utils/ConfigInitializer.kt b/src/main/kotlin/top/r3944realms/ltdmanager/utils/ConfigInitializer.kt index 5e8ddb0..1b534fd 100644 --- a/src/main/kotlin/top/r3944realms/ltdmanager/utils/ConfigInitializer.kt +++ b/src/main/kotlin/top/r3944realms/ltdmanager/utils/ConfigInitializer.kt @@ -2,17 +2,21 @@ package top.r3944realms.ltdmanager.utils import top.r3944realms.ltdmanager.core.config.YamlConfigLoader import java.nio.file.Files +import java.nio.file.Path import java.nio.file.Paths import java.nio.file.StandardCopyOption import kotlin.system.exitProcess object ConfigInitializer { - /** - * 初始化配置文件 - * @param fileName YAML 文件名,如 application.yml - * @param configDir 配置目录,如 config - */ + private val SQL_TEMPLATES = listOf( + "sql/invitation/query_qualification.sql", + "sql/invitation/query_token_info.sql", + "sql/invitation/query_code_ids.sql", + "sql/invitation/upsert_ascription.sql", + "sql/whitelist/query_whitelist_record.sql", + ) + fun initConfig(fileName: String = "application.yml", configDir: String = "config", shouldExit: Boolean = true) { val dirPath = Paths.get(configDir) if (!Files.exists(dirPath)) { @@ -23,7 +27,6 @@ object ConfigInitializer { val filePath = dirPath.resolve(fileName) if (!Files.exists(filePath)) { - // 从 resources 复制默认配置 val resourceStream = YamlConfigLoader::class.java.classLoader.getResourceAsStream(fileName) if (resourceStream != null) { Files.copy(resourceStream, filePath, StandardCopyOption.REPLACE_EXISTING) @@ -33,9 +36,31 @@ object ConfigInitializer { exitProcess(-1); } } else throw Error("Jar内部资源文件缺失") - } else { LoggerUtil.logger.info("配置文件已存在: $filePath") } } + + /** 首次启动时将 SQL 模板从 classpath 复制到 config/sql/ */ + fun initSqlTemplates() { + var copied = 0 + for (resourcePath in SQL_TEMPLATES) { + val target = Paths.get("config", resourcePath) + if (Files.exists(target)) continue + + val resourceStream = YamlConfigLoader::class.java.classLoader + .getResourceAsStream(resourcePath) + if (resourceStream != null) { + Files.createDirectories(target.parent) + Files.copy(resourceStream, target) + resourceStream.close() + copied++ + } else { + LoggerUtil.logger.warn("SQL 模板资源缺失: $resourcePath") + } + } + if (copied > 0) { + LoggerUtil.logger.info("已从 JAR 复制 $copied 个 SQL 模板到 config/sql/") + } + } } \ No newline at end of file diff --git a/src/main/kotlin/top/r3944realms/ltdmanager/whitelist/request/WhitelistSystemRequest.kt b/src/main/kotlin/top/r3944realms/ltdmanager/whitelist/request/WhitelistSystemRequest.kt index 45a6f10..b3fe0e6 100644 --- a/src/main/kotlin/top/r3944realms/ltdmanager/whitelist/request/WhitelistSystemRequest.kt +++ b/src/main/kotlin/top/r3944realms/ltdmanager/whitelist/request/WhitelistSystemRequest.kt @@ -1,8 +1,10 @@ package top.r3944realms.ltdmanager.whitelist.request +import io.ktor.http.HeadersBuilder import kotlinx.serialization.Serializable import kotlinx.serialization.Transient import top.r3944realms.ltdmanager.core.client.request.IRequest +import top.r3944realms.ltdmanager.core.config.YamlConfigLoader import top.r3944realms.ltdmanager.whitelist.response.FailedWhitelistSystemResponse import top.r3944realms.ltdmanager.whitelist.response.WhitelistSystemResponse @@ -10,4 +12,14 @@ import top.r3944realms.ltdmanager.whitelist.response.WhitelistSystemResponse abstract class WhitelistSystemRequest( @Transient override val createTime: Long = System.currentTimeMillis() -) : IRequest +) : IRequest { + + /** 自动注入 X-API-TOKEN 鉴权头 */ + override fun headers(): HeadersBuilder.() -> Unit = { + super.headers().invoke(this) + val token = YamlConfigLoader.loadWhitelistSystemConfig().decryptedToken + if (!token.isNullOrEmpty()) { + append("X-API-TOKEN", token) + } + } +}