package network import io.ktor.client.* import io.ktor.client.request.* import io.ktor.client.statement.* import java.io.ByteArrayInputStream import java.util.zip.ZipInputStream import javax.xml.parsers.DocumentBuilderFactory object DartCodeManager { private val corpCodeMap = mutableMapOf() private const val DART_API_KEY = "61143d2af0759f6c28ce372d9e339d1e01687abc" // 지범님의 API 키 입력 /** * 앱 실행 시 호출하여 매핑 테이블 업데이트 */ suspend fun updateCorpCodes(client: HttpClient) { println("📂 [DART] 법인코드 매핑 데이터 업데이트 시작...") try { val url = "https://opendart.fss.or.kr/api/corpCode.xml?crtfc_key=$DART_API_KEY" val response: HttpResponse = client.get(url) val zipBytes = response.readBytes() ZipInputStream(ByteArrayInputStream(zipBytes)).use { zis -> var entry = zis.nextEntry while (entry != null) { if (entry.name == "CORPCODE.xml") { parseXml(zis.readAllBytes()) break } entry = zis.nextEntry } } println("✅ [DART] 매핑 완료: ${corpCodeMap.size}개의 상장사 로드됨") } catch (e: Exception) { println("❌ [DART] 법인코드 업데이트 실패: ${e.message}") } } private fun parseXml(xmlBytes: ByteArray) { val factory = DocumentBuilderFactory.newInstance() val builder = factory.newDocumentBuilder() val doc = builder.parse(ByteArrayInputStream(xmlBytes)) val nodeList = doc.getElementsByTagName("list") for (i in 0 until nodeList.length) { val element = nodeList.item(i) as org.w3c.dom.Element val stockCode = element.getElementsByTagName("stock_code").item(0)?.textContent?.trim() ?: "" val corpCode = element.getElementsByTagName("corp_code").item(0)?.textContent ?: "" // 종목코드(stock_code)가 있는 상장사만 매핑에 추가 if (stockCode.isNotEmpty()) { corpCodeMap[stockCode] = corpCode } } } /** * 6자리 종목코드로 8자리 법인코드 반환 */ fun getCorpCode(stockCode: String): String? { return corpCodeMap[stockCode] } }