V13-FE-005: Complete KBX v60 frontend components, T01-T12 screen recipes, and WBS progress tracker
This commit is contained in:
@@ -1,65 +1,81 @@
|
||||
<template>
|
||||
<PageLayout title="시장 데이터 수집" subtitle="KRX 과거 시세 데이터 수집을 예약합니다.">
|
||||
<KsFormSection title="1. 데이터 소스 및 기간 선택">
|
||||
<KsFormGrid :columns="1" aria-label="데이터 소스 및 기간">
|
||||
<KsSelect v-model="form.dataSource" label="데이터 소스" :options="dataSourceOptions" />
|
||||
<p class="hint"><strong>KRX:</strong> 시세 데이터(시가/고가/저가/종가/거래량) · <strong>OpenDart:</strong> 기업 공시</p>
|
||||
</KsFormGrid>
|
||||
<KsFormGrid :columns="2" aria-label="수집 기간">
|
||||
<KsDateField v-model="form.fromDate" label="시작일" :min="minDateValue" :max="maxDateValue" />
|
||||
<KsDateField v-model="form.toDate" label="종료일" :min="form.fromDate ? new Date(form.fromDate) : minDateValue" :max="maxDateValue" />
|
||||
</KsFormGrid>
|
||||
<div class="presets">
|
||||
<KsButton severity="secondary" label="최근 1년" @click="setPreset('1y')" />
|
||||
<KsButton severity="secondary" label="최근 2년" @click="setPreset('2y')" />
|
||||
<KsButton severity="secondary" label="최근 5년" @click="setPreset('5y')" />
|
||||
<KsButton severity="secondary" label="전체 가능 기간" @click="setPreset('all')" />
|
||||
</div>
|
||||
</KsFormSection>
|
||||
<EditFormPage
|
||||
title="시장 데이터 수집 (Market Data Ingestion Form)"
|
||||
subtitle="KRX 과거 시세 및 OpenDart 공시 데이터 수집 작업을 등록합니다."
|
||||
:state="screenState"
|
||||
:evidence="evidence"
|
||||
@retry="handleRetry"
|
||||
>
|
||||
<!-- Default Slot: Form Section -->
|
||||
<div class="content">
|
||||
<KsFormSection title="1. 데이터 소스 및 기간 선택">
|
||||
<KsFormGrid :columns="1" aria-label="데이터 소스 및 기간">
|
||||
<KsSelect v-model="form.dataSource" label="데이터 소스" :options="dataSourceOptions" />
|
||||
<p class="hint"><strong>KRX:</strong> 시세 데이터(시가/고가/저가/종가/거래량) · <strong>OpenDart:</strong> 기업 공시</p>
|
||||
</KsFormGrid>
|
||||
<KsFormGrid :columns="2" aria-label="수집 기간">
|
||||
<KsDateField v-model="form.fromDate" label="시작일" :min="minDateValue" :max="maxDateValue" />
|
||||
<KsDateField v-model="form.toDate" label="종료일" :min="form.fromDate ? new Date(form.fromDate) : minDateValue" :max="maxDateValue" />
|
||||
</KsFormGrid>
|
||||
<div class="presets">
|
||||
<KsButton severity="secondary" label="최근 1년" @click="setPreset('1y')" />
|
||||
<KsButton severity="secondary" label="최근 2년" @click="setPreset('2y')" />
|
||||
<KsButton severity="secondary" label="최근 5년" @click="setPreset('5y')" />
|
||||
<KsButton severity="secondary" label="전체 가능 기간" @click="setPreset('all')" />
|
||||
</div>
|
||||
</KsFormSection>
|
||||
|
||||
<KsFormSection v-if="validationErrors.length" title="입력 오류">
|
||||
<KsValidationSummary :errors="validationErrorObjects" />
|
||||
</KsFormSection>
|
||||
<KsFormSection v-if="validationErrors.length" title="입력 오류">
|
||||
<KsValidationSummary :errors="validationErrorObjects" />
|
||||
</KsFormSection>
|
||||
|
||||
<KsFormSection v-else title="수집 요약">
|
||||
<dl class="summary-grid">
|
||||
<div class="summary-item"><dt>데이터 소스</dt><dd>{{ form.dataSource }}</dd></div>
|
||||
<div class="summary-item"><dt>기간</dt><dd>{{ form.fromDate }} ~ {{ form.toDate }}</dd></div>
|
||||
<div class="summary-item"><dt>일수</dt><dd>{{ formatQuantity(daysCount, 0) }}</dd></div>
|
||||
<div class="summary-item"><dt>예상 행 수</dt><dd>{{ estimatedRows }}</dd></div>
|
||||
</dl>
|
||||
<template #actions>
|
||||
<KsButton severity="secondary" label="초기화" @click="resetForm" />
|
||||
<KsButton severity="primary" :label="isLoading ? '처리 중...' : '수집 예약'" :loading="isLoading" :disabled="validationErrors.length > 0" @click="triggerIngestion" />
|
||||
</template>
|
||||
</KsFormSection>
|
||||
<KsFormSection v-else title="수집 요약">
|
||||
<dl class="summary-grid">
|
||||
<div class="summary-item"><dt>데이터 소스</dt><dd>{{ form.dataSource }}</dd></div>
|
||||
<div class="summary-item"><dt>기간</dt><dd class="ks-financial-number">{{ form.fromDate }} ~ {{ form.toDate }}</dd></div>
|
||||
<div class="summary-item"><dt>일수</dt><dd class="ks-financial-number">{{ formatQuantity(daysCount, 0) }}일</dd></div>
|
||||
<div class="summary-item"><dt>예상 행 수</dt><dd class="ks-financial-number">{{ estimatedRows }}</dd></div>
|
||||
</dl>
|
||||
<template #actions>
|
||||
<KsButton severity="secondary" label="초기화" @click="resetForm" />
|
||||
<KsButton severity="primary" :label="isLoading ? '처리 중...' : '수집 예약'" :loading="isLoading" :disabled="validationErrors.length > 0" @click="triggerIngestion" />
|
||||
</template>
|
||||
</KsFormSection>
|
||||
|
||||
<KsFormSection v-if="jobId" title="수집 작업이 등록되었습니다">
|
||||
<dl class="summary-grid">
|
||||
<div class="summary-item"><dt>Job ID</dt><dd class="mono">{{ jobId }}</dd></div>
|
||||
<div class="summary-item"><dt>상태</dt><dd><KsStatusTag value="대기" severity="info" /></dd></div>
|
||||
<div class="summary-item"><dt>등록 시각</dt><dd>{{ formatAsOf(new Date()) }}</dd></div>
|
||||
</dl>
|
||||
<p class="hint">수집은 백그라운드에서 실행됩니다. 진행 상태는 수집 이력 화면에서 확인할 수 있습니다.</p>
|
||||
<RouterLink to="/ops/market-data-history">수집 이력 보기 →</RouterLink>
|
||||
</KsFormSection>
|
||||
</PageLayout>
|
||||
<KsFormSection v-if="jobId" title="수집 작업이 등록되었습니다">
|
||||
<dl class="summary-grid">
|
||||
<div class="summary-item"><dt>Job ID</dt><dd class="mono ks-financial-number">{{ jobId }}</dd></div>
|
||||
<div class="summary-item"><dt>상태</dt><dd><KsStatusTag value="대기" severity="info" /></dd></div>
|
||||
<div class="summary-item"><dt>등록 시각</dt><dd class="ks-financial-number">{{ formatAsOf(new Date()) }}</dd></div>
|
||||
</dl>
|
||||
<p class="hint">수집은 백그라운드에서 실행됩니다. 진행 상태는 수집 이력 화면에서 확인할 수 있습니다.</p>
|
||||
<RouterLink to="/ops/market-data-history">수집 이력 보기 →</RouterLink>
|
||||
</KsFormSection>
|
||||
</div>
|
||||
</EditFormPage>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref, computed, reactive } from 'vue'
|
||||
import { RouterLink } from 'vue-router'
|
||||
import PageLayout from '../../../shared/ui/layouts/PageLayout.vue'
|
||||
import EditFormPage from '../../../shared/ui/screen-types/v2/EditFormPage.vue'
|
||||
import { KsButton, KsDateField, KsFormGrid, KsFormSection, KsSelect, KsStatusTag, KsValidationSummary } from '../../../shared/ui/components'
|
||||
import { formatAsOf, formatQuantity } from '../../../shared/formatters/financial'
|
||||
import type { StandardScreenState } from '../../../shared/ui/contracts/screenContract'
|
||||
|
||||
// KBX T03 Governance Audit & Form State
|
||||
const screenState = ref<StandardScreenState>('READY')
|
||||
const evidence = reactive({
|
||||
asOf: '2026-08-15T19:42:00Z',
|
||||
version: 'v60-T03-Contract',
|
||||
})
|
||||
|
||||
const isLoading = ref(false)
|
||||
const jobId = ref<string | null>(null)
|
||||
|
||||
const dataSourceOptions = [
|
||||
{ label: 'KRX (한국거래소) - KOSPI/KOSDAQ 일봉', value: 'KRX' },
|
||||
{ label: 'OpenDart - 기업 공시(T+2)', value: 'OpenDart' },
|
||||
{ label: 'Stub - 테스트 데이터', value: 'Stub' }
|
||||
{ label: 'OpenDart (금융감독원) - 기업 공시', value: 'OpenDart' },
|
||||
]
|
||||
|
||||
const form = ref({
|
||||
|
||||
Reference in New Issue
Block a user