You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
5.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="detect-missing">
<el-card>
<el-form :model="form" label-width="100px">
<el-form-item label="证券类型">
<el-radio-group v-model="form.securityType">
<el-radio-button label="stock">股票</el-radio-button>
<el-radio-button label="future">期货</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="周期">
<el-select v-model="form.periodType" style="width: 120px;">
<el-option label="日线" value="daily" />
<el-option label="1分钟" value="min1" />
<el-option label="5分钟" value="min5" />
</el-select>
</el-form-item>
<el-form-item label="开始日期">
<el-date-picker
v-model="form.startDate"
type="date"
placeholder="开始日期"
value-format="YYYYMMDD"
/>
</el-form-item>
<el-form-item label="结束日期">
<el-date-picker
v-model="form.endDate"
type="date"
placeholder="结束日期"
value-format="YYYYMMDD"
/>
</el-form-item>
<el-form-item label="代码列表">
<el-input
v-model="codeInput"
type="textarea"
:rows="4"
placeholder="输入代码,每行一个或逗号分隔"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleDetect" :loading="detecting">
<el-icon><Search /></el-icon>
</el-button>
<el-button type="success" @click="handleCache" :loading="caching" :disabled="!hasMissing">
<el-icon><Download /></el-icon>
</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="result-card" v-if="detectResult.length > 0">
<template #header>
<span>检测结果</span>
</template>
<el-table :data="detectResult" stripe>
<el-table-column prop="code" label="代码" width="120" />
<el-table-column prop="missingCount" label="缺失天数" width="100" />
<el-table-column label="缺失率">
<template #default="{ row }">
<el-progress
:percentage="Math.round(row.missingRatio * 100)"
:status="row.missingRatio > 0.5 ? 'exception' : 'warning'"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template #default="{ row }">
<el-button type="primary" size="small" @click="showDetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { detectMissingData, batchCacheData } from '@/api/cache'
const detecting = ref(false)
const caching = ref(false)
const codeInput = ref('000001.SZ\n600000.SH')
const detectResult = ref<any[]>([])
const taskId = ref<number | null>(null)
const hasMissing = computed(() => detectResult.value.some(r => r.missingCount > 0))
const form = reactive({
securityType: 'stock',
periodType: 'daily',
startDate: getDefaultStartDate(),
endDate: getDefaultEndDate()
})
function getDefaultStartDate() {
const date = new Date()
date.setFullYear(date.getFullYear() - 1)
return formatDate(date)
}
function getDefaultEndDate() {
return formatDate(new Date())
}
function formatDate(date: Date) {
return date.toISOString().slice(0, 10).replace(/-/g, '')
}
const parseCodes = () => {
return codeInput.value
.split(/[\n,]/)
.map(c => c.trim())
.filter(c => c.length > 0)
}
const handleDetect = async () => {
const codes = parseCodes()
if (codes.length === 0) {
ElMessage.warning('请输入代码')
return
}
detecting.value = true
try {
const res: any = await detectMissingData({
security_type: form.securityType,
period_type: form.periodType,
start_date: form.startDate,
end_date: form.endDate,
code_list: codes
})
if (res.data) {
taskId.value = res.data.task_id
detectResult.value = res.data.missing_codes.map((item: any) => ({
code: item.code,
missingCount: item.missing_dates.length,
missingRatio: item.missing_dates.length > 0
? item.missing_dates.reduce((sum: number, d: any) => sum + d.missing_ratio, 0) / item.missing_dates.length
: 0,
details: item.missing_dates
}))
}
} catch (error) {
console.error(error)
} finally {
detecting.value = false
}
}
const handleCache = async () => {
const codes = parseCodes()
if (codes.length === 0) return
caching.value = true
try {
await batchCacheData({
security_type: form.securityType,
period_type: form.periodType,
start_date: form.startDate,
end_date: form.endDate,
code_list: codes
})
ElMessage.success('缓存任务已启动')
} catch (error) {
console.error(error)
} finally {
caching.value = false
}
}
const showDetail = (row: any) => {
// 显示缺失详情
console.log(row.details)
}
</script>
<style scoped>
.detect-missing {
padding: 10px;
}
.result-card {
margin-top: 20px;
}
</style>