This commit is contained in:
lunaticbum 2026-03-13 11:06:20 +09:00
parent 6d340b7dc0
commit 8013e80a34
6 changed files with 66 additions and 17 deletions

View File

@ -77,19 +77,19 @@ fun main() = application {
LaunchedEffect(Unit) {
// NewsService나 KisTradeService에서 사용하는 client를 전달
DartCodeManager.updateCorpCodes(HttpClient(CIO) {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
encodeDefaults = true // 기본값이 포함된 요청 바디를 정확히 전송하기 위해 필요
})
}
// [수정] 모든 로그(Headers + Body)를 찍도록 설정
install(Logging) {
logger = Logger.DEFAULT
level = LogLevel.BODY
}
})
// DartCodeManager.updateCorpCodes(HttpClient(CIO) {
// install(ContentNegotiation) {
// json(Json {
// ignoreUnknownKeys = true
// encodeDefaults = true // 기본값이 포함된 요청 바디를 정확히 전송하기 위해 필요
// })
// }
// // [수정] 모든 로그(Headers + Body)를 찍도록 설정
// install(Logging) {
// logger = Logger.DEFAULT
// level = LogLevel.BODY
// }
// })
}
// 앱 실행 시 필요한 바이너리 경로 (실행 파일 위치)
val binPath = getLlamaBinPath()
@ -113,6 +113,9 @@ fun main() = application {
vtsAppKey = it[ConfigTable.vtsAppKey],
vtsSecretKey = it[ConfigTable.vtsSecretKey],
vtsAccountNo = it[ConfigTable.vtsAccountNo],
nAppKey = it[ConfigTable.nAppKey],
nSecretKey = it[ConfigTable.nSecretKey],
dAppKey = it[ConfigTable.dAppKey],
isSimulation = it[ConfigTable.isSimulation],
htsId = it[ConfigTable.htsId],
modelPath = it[ConfigTable.modelPath],
@ -150,6 +153,7 @@ fun main() = application {
AppScreen.Settings -> {
SettingsScreen(
onAuthSuccess = {
// 2. 설정 및 인증 완료 시점의 처리
val config = KisSession.config
AutoTradingManager.isSystemReadyToday = true

View File

@ -26,6 +26,11 @@ object ConfigTable : Table("app_config") {
val vtsAppKey = varchar("vts_app_key", 255).default("")
val vtsSecretKey = varchar("vts_secret_key", 255).default("")
val vtsAccountNo = varchar("vts_account_no", 20).default("")
val nAppKey = varchar("naver_app_key", 255).default("")
val nSecretKey = varchar("naver_secret_key", 255).default("")
val dAppKey = varchar("dart_api_key", 255).default("")
val isSimulation = bool("is_simulation").default(true)
val modelPath = varchar("model_path", 512).default("")
val embedModelPath = varchar("embed_model_path", 512).default("")
@ -207,6 +212,9 @@ object DatabaseFactory {
vtsAppKey = it[ConfigTable.vtsAppKey],
vtsSecretKey = it[ConfigTable.vtsSecretKey],
vtsAccountNo = it[ConfigTable.vtsAccountNo],
nAppKey = it[ConfigTable.nAppKey],
nSecretKey = it[ConfigTable.nSecretKey],
dAppKey = it[ConfigTable.dAppKey],
htsId = it[ConfigTable.htsId],
isSimulation = it[ConfigTable.isSimulation], // htsId 로드
modelPath = it[ConfigTable.modelPath],
@ -243,6 +251,9 @@ object DatabaseFactory {
it[vtsSecretKey] = config.vtsSecretKey
it[realAccountNo] = config.realAccountNo
it[vtsAccountNo] = config.vtsAccountNo
it[ConfigTable.nAppKey] = config.nAppKey
it[ConfigTable.nSecretKey] = config.nSecretKey
it[ConfigTable.dAppKey] = config.dAppKey
it[isSimulation] = config.isSimulation
it[htsId] = config.htsId
it[modelPath] = config.modelPath

View File

@ -44,6 +44,11 @@ data class AppConfig(
val vtsSecretKey: String = "",
val vtsAccountNo: String = "",
// 모의 3종
val nAppKey: String = "",
val nSecretKey: String = "",
val dAppKey: String = "",
// [세션 데이터 - 메모리에서만 관리]
var marketToken: String = "",
var marketTokenExpiredAt: LocalDateTime? = null, // 만료 시간 추가

View File

@ -3,6 +3,7 @@ package network
import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import model.KisSession
import model.RankingStock
import service.AutoTradingManager
import java.io.ByteArrayInputStream
@ -19,7 +20,7 @@ data class CorpInfo(
)
object DartCodeManager {
private val corpCodeMap = mutableMapOf<String, CorpInfo>()
private const val DART_API_KEY = "61143d2af0759f6c28ce372d9e339d1e01687abc" // 지범님의 API 키 입력
private var DART_API_KEY = KisSession.config.dAppKey // 지범님의 API 키 입력
private fun saveXmlDebugFile(xmlBytes: ByteArray) {
try {

View File

@ -18,6 +18,7 @@ import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import model.DartFinancialResponse
import model.KisSession
import model.NaverNewsResponse
import service.DynamicNewsScraper
import service.SafeScraper
@ -37,8 +38,8 @@ object NewsService {
}
suspend fun fetchAndIngestNews(corpInfo: CorpInfo) {
val clientId = "CqXQXHO3h0kqtYsXkePY" // 설정에서 가져오도록 수정 필요
val clientSecret = "DODCxb1M4Z"
val clientId = KisSession.config.nAppKey // 설정에서 가져오도록 수정 필요
val clientSecret = KisSession.config.nSecretKey
val qlistNews = listOf(
"${corpInfo.stockName} 주가",
"${corpInfo.stockName} 실적",
@ -83,7 +84,7 @@ object NewsService {
suspend fun fetchFinancialGrowth(corpCode: String?): String {
if (corpCode != null) {
val apiKey = "61143d2af0759f6c28ce372d9e339d1e01687abc"
val apiKey = KisSession.config.dAppKey
// 단일회사 주요계정 API (재무상태표, 손익계산서 주요 항목)
val url = "https://opendart.fss.or.kr/api/fnlttSinglAcnt.json?crtfc_key=$apiKey&corp_code=$corpCode&bsns_year=2024&reprt_code=11011"

View File

@ -16,9 +16,19 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.logging.DEFAULT
import io.ktor.client.plugins.logging.LogLevel
import io.ktor.client.plugins.logging.Logger
import io.ktor.client.plugins.logging.Logging
import io.ktor.serialization.kotlinx.json.json
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import model.AppConfig
import model.KisSession
import network.DartCodeManager
import network.KisAuthService
import network.KisTradeService
import org.jetbrains.exposed.sql.deleteAll
@ -83,6 +93,10 @@ fun SettingsScreen(onAuthSuccess: () -> Unit) {
Divider(Modifier.padding(vertical = 16.dp))
OutlinedTextField(value = config.nAppKey, onValueChange = { config = config.copy(nAppKey = it,) }, label = { Text("NAVER Client ID") }, modifier = Modifier.fillMaxWidth())
OutlinedTextField(value = config.nSecretKey, onValueChange = { config = config.copy(nSecretKey = it,) }, label = { Text("NAVER Client Secret") }, modifier = Modifier.fillMaxWidth(), visualTransformation = PasswordVisualTransformation())
OutlinedTextField(value = config.dAppKey, onValueChange = { config = config.copy(dAppKey = it,) }, label = { Text("Dart ApiKey") }, modifier = Modifier.fillMaxWidth())
// AI 모델 경로 및 드래그 앤 드롭
Text("AI 모델 설정", fontWeight = FontWeight.Bold)
Box(
@ -122,6 +136,19 @@ fun SettingsScreen(onAuthSuccess: () -> Unit) {
// 1. KisSession.config 업데이트 및 DB 저장
KisSession.config = config
DatabaseFactory.saveConfig(config)
DartCodeManager.updateCorpCodes(HttpClient(CIO) {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
encodeDefaults = true // 기본값이 포함된 요청 바디를 정확히 전송하기 위해 필요
})
}
// [수정] 모든 로그(Headers + Body)를 찍도록 설정
install(Logging) {
logger = Logger.DEFAULT
level = LogLevel.BODY
}
})
val authService = KisAuthService
val tradeService = KisTradeService
val authSuccess = authService.refreshAllTokens()