// src/main/kotlin/ui/AutoTradeSection.kt (신규 파일) package ui import AutoTradeItem import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.* import androidx.compose.material.icons.filled.Refresh import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import model.toAutoTradeItem import network.KisTradeService // src/main/kotlin/ui/AutoTradeSection.kt @Composable fun AutoTradeSection( isDomestic: Boolean, tradeService: KisTradeService, refreshTrigger: Int, // 갱신 트리거 추가 onRefresh: () -> Unit, onItemSelect: (AutoTradeItem) -> Unit, onItemCancel: (AutoTradeItem) -> Unit ) { // 통합 리스트 상태 (ActiveTradeItem은 이전에 정의한 통합 모델) var tradeList by remember { mutableStateOf(emptyList()) } // refreshTrigger가 바뀔 때마다 실행됨 LaunchedEffect(refreshTrigger) { val serverUnfilled = tradeService.fetchUnfilledOrders().getOrNull()?.map { it.toAutoTradeItem(isDomestic) } ?: emptyList() // 2. DB에서 로컬 감시 데이터 가져오기 val localTrades = DatabaseFactory.getActiveAutoTrades() // 3. 동기화 로직: 서버에 없는 주문번호를 가진 로컬 데이터는 EXPIRED로 표시 tradeList = localTrades.map { local -> if (local.status != "COMPLETED" && serverUnfilled.none { it.orderNo == local.orderNo }) { local.copy(status = "EXPIRED") } else local } } Column(modifier = Modifier.fillMaxSize().padding(8.dp)) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Text("진행 중인 거래", style = MaterialTheme.typography.subtitle1, fontWeight = FontWeight.Bold) // 강제 갱신 버튼 IconButton( onClick = onRefresh, modifier = Modifier.size(24.dp) ) { Icon( imageVector = androidx.compose.material.icons.Icons.Default.Refresh, contentDescription = "새로고침", tint = Color(0xFF0E62CF), modifier = Modifier.size(18.dp) ) } } LazyColumn { items(tradeList) { item -> ActiveTradeRow( item = item, onCancelClick = { onItemCancel(item) }, // 이미 스코프에 있는 item을 그대로 사용 onClick = { onItemSelect(item) } ) } } } }