新增手动同步数据功能:点击侧边栏"同步数据"调用批量打分接口,完成后跳转打分列表并刷新
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,20 @@ func (d *Deps) RunPipeline(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = io.Copy(w, resp.Body)
|
||||
}
|
||||
|
||||
func (d *Deps) RunBatch(w http.ResponseWriter, r *http.Request) {
|
||||
client := &http.Client{Timeout: 120 * time.Second}
|
||||
resp, err := client.Post(d.TushareURL+"/api/v1/run/batch", "application/json", nil)
|
||||
if err != nil {
|
||||
writeErr(w, http.StatusBadGateway, fmt.Sprintf("tushare service unavailable: %v", err))
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
_, _ = io.Copy(w, resp.Body)
|
||||
}
|
||||
|
||||
func (d *Deps) GetActiveContract(w http.ResponseWriter, r *http.Request) {
|
||||
symbol := r.URL.Query().Get("symbol")
|
||||
if symbol == "" {
|
||||
|
||||
@@ -31,6 +31,7 @@ func New(d *handlers.Deps, dist fs.FS) http.Handler {
|
||||
r.Get("/contracts/active", d.GetActiveContract)
|
||||
r.Get("/candles", d.ListCandles)
|
||||
r.Post("/run", d.RunPipeline)
|
||||
r.Post("/run/batch", d.RunBatch)
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(mw.RequireAdmin)
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useAuthStore } from '@/stores/auth'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import { useMobile } from '@/composables/useMobile'
|
||||
import { resetAllData } from '@/api/admin'
|
||||
import { runBatch } from '@/api/run'
|
||||
|
||||
const auth = useAuthStore()
|
||||
const theme = useThemeStore()
|
||||
@@ -15,6 +16,7 @@ const { isMobile } = useMobile()
|
||||
|
||||
const drawerOpen = ref(false)
|
||||
const resetting = ref(false)
|
||||
const syncing = ref(false)
|
||||
|
||||
const showLayout = computed(() => route.meta.layout !== 'blank' && !!auth.token)
|
||||
|
||||
@@ -57,6 +59,23 @@ async function handleReset() {
|
||||
resetting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSync() {
|
||||
syncing.value = true
|
||||
try {
|
||||
await runBatch()
|
||||
ElMessage.success('同步完成')
|
||||
if (route.path === '/scores') {
|
||||
router.go(0)
|
||||
} else {
|
||||
router.push('/scores')
|
||||
}
|
||||
} catch {
|
||||
ElMessage.error('同步失败')
|
||||
} finally {
|
||||
syncing.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -73,6 +92,9 @@ async function handleReset() {
|
||||
>
|
||||
<el-menu-item index="/scores">打分列表</el-menu-item>
|
||||
<el-menu-item index="/chart">K 线 / 持仓</el-menu-item>
|
||||
<el-menu-item :index="() => {}" @click="handleSync" :disabled="syncing">
|
||||
同步数据
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/run">手动打分</el-menu-item>
|
||||
<el-menu-item v-if="auth.isAdmin" index="/admin/users">用户管理</el-menu-item>
|
||||
<el-menu-item v-if="auth.isAdmin" :index="() => {}" @click="handleReset" :disabled="resetting">
|
||||
@@ -100,6 +122,9 @@ async function handleReset() {
|
||||
>
|
||||
<el-menu-item index="/scores">打分列表</el-menu-item>
|
||||
<el-menu-item index="/chart">K 线 / 持仓</el-menu-item>
|
||||
<el-menu-item :index="() => {}" @click="handleSync" :disabled="syncing">
|
||||
同步数据
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/run">手动打分</el-menu-item>
|
||||
<el-menu-item v-if="auth.isAdmin" index="/admin/users">用户管理</el-menu-item>
|
||||
</el-menu>
|
||||
|
||||
@@ -30,6 +30,10 @@ export function runPipeline(req: RunRequest) {
|
||||
return client.post<RunResponse>('/run', req).then((r) => r.data)
|
||||
}
|
||||
|
||||
export function runBatch() {
|
||||
return client.post('/run/batch').then((r) => r.data)
|
||||
}
|
||||
|
||||
export function getActiveContract(symbol: string) {
|
||||
return client
|
||||
.get<ActiveContract>('/contracts/active', { params: { symbol } })
|
||||
|
||||
Reference in New Issue
Block a user