This commit is contained in:
2026-03-19 11:41:21 +09:00
parent eee4f1bab7
commit f830163940
3 changed files with 82 additions and 43 deletions
+57 -41
View File
@@ -35,6 +35,7 @@ import network.KisTradeService
import org.jetbrains.exposed.sql.deleteAll
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.transactions.transaction
import service.SystemSleepPreventer
// src/main/kotlin/ui/SettingsScreen.kt
@@ -45,6 +46,61 @@ fun SettingsScreen(onAuthSuccess: () -> Unit) {
var config by remember { mutableStateOf(KisSession.config) }
var statusMessage by remember { mutableStateOf("정보를 입력하세요.") }
val authenticateAndStart: suspend () -> Unit = {
var retryCount = 0
val maxRetries = 3
val totalDelaySeconds = 90
var isAuthCompleted = false
while (retryCount <= maxRetries && !isAuthCompleted) {
if (retryCount > 0) {
for (secondsLeft in totalDelaySeconds downTo 1) {
statusMessage = "⚠️ 인증 실패. ${secondsLeft}초 후 자동으로 다시 시도합니다. (시도 ${retryCount}/${maxRetries})"
delay(1000L)
}
}
statusMessage = if (retryCount == 0) "⏳ 인증 시도 중..." else "${retryCount}차 재시도 중..."
KisSession.config = config
DatabaseFactory.saveConfig(config)
DartCodeManager.updateCorpCodes(HttpClient(CIO) {
install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) }
})
val authSuccess = KisAuthService.refreshAllTokens()
val wsKeySuccess = KisTradeService.refreshWebsocketKey()
if (authSuccess && wsKeySuccess) {
statusMessage = "✅ 인증 성공! LLM 시작 중..."
isAuthCompleted = true
onAuthSuccess() // 여기서 대시보드로 넘어감
} else {
retryCount++
if (retryCount > maxRetries) {
statusMessage = "❌ 인증 실패. 3회 재시도 후 중단되었습니다."
}
}
}
}
LaunchedEffect(config) {
while (true) {
val now = java.time.LocalTime.now(java.time.ZoneId.of("Asia/Seoul"))
// 08:30 ~ 15:30 사이이고, 키값이 최소한 하나라도 존재할 때 자동 실행
if (now.isAfter(java.time.LocalTime.of(8, 30)) && now.isBefore(java.time.LocalTime.of(15, 30))) {
if (config.realAppKey.isNotEmpty() || config.vtsAppKey.isNotEmpty()) {
SystemSleepPreventer.wakeDisplay() // 모니터 켜기
statusMessage = "⏰ 자동 실행 시간(08:30)입니다. 시스템을 가동합니다."
authenticateAndStart()
break // 성공하면 루프 탈출
}
}
delay(60_000 * 2) // 1분마다 시간 체크
}
}
// 계좌번호 입력 시 데이터 자동 로드 함수
fun checkAndLoadConfig(accountNo: String, isReal: Boolean) {
val loaded = DatabaseFactory.findConfigByAccount(accountNo)
@@ -190,47 +246,7 @@ fun SettingsScreen(onAuthSuccess: () -> Unit) {
modifier = Modifier.fillMaxWidth().height(50.dp),
onClick = {
scope.launch {
var retryCount = 0
val maxRetries = 3
val totalDelaySeconds = 90 // 1분 30초 = 90초
var isAuthCompleted = false
while (retryCount <= maxRetries && !isAuthCompleted) {
// 재시도 시 대기 및 카운트다운 표시
if (retryCount > 0) {
for (secondsLeft in totalDelaySeconds downTo 1) {
statusMessage = "⚠️ 인증 실패. ${secondsLeft}초 후 자동으로 다시 시도합니다. (시도 ${retryCount}/${maxRetries})"
delay(1000L) // 1초 대기
}
}
statusMessage = if (retryCount == 0) "⏳ 인증 시도 중..." else "${retryCount}차 재시도 중..."
// 1. 설정값 저장
KisSession.config = config
DatabaseFactory.saveConfig(config)
// 2. 법인코드 업데이트
DartCodeManager.updateCorpCodes(HttpClient(CIO) {
install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) }
})
// 3. 토큰 및 웹소켓 키 갱신
val authSuccess = KisAuthService.refreshAllTokens()
val wsKeySuccess = KisTradeService.refreshWebsocketKey()
if (authSuccess && wsKeySuccess) {
statusMessage = "✅ 인증 성공! LLM 시작 중..."
isAuthCompleted = true
onAuthSuccess()
} else {
retryCount++
if (retryCount > maxRetries) {
statusMessage = "❌ 인증 실패. 3회 재시도 후 중단되었습니다. 키 정보를 확인하세요."
}
// 다음 루프에서 카운트다운 진입
}
}
authenticateAndStart()
}
}
) { Text("설정 저장 및 실행") }