feat: sync upstream keys and reorder priorities

This commit is contained in:
SmartUp Developer
2026-06-03 17:03:11 +08:00
parent a42bcba483
commit b866b387e0
8 changed files with 415 additions and 57 deletions
+12
View File
@@ -291,6 +291,16 @@ export interface ImportAccountItem {
raw: Record<string, any>
}
export interface ReorderPriorityItem {
account_id: string | null
group_id: string
upstream_id: number
old_priority: number | null
new_priority: number | null
status: string
message: string
}
export interface WebsiteBatchSyncResponse {
total: number
success: number
@@ -311,6 +321,8 @@ export const websitesApi = {
api.post<{ success: boolean; message: string; items: ImportGroupItem[] }>(`/api/websites/${id}/groups/import-from-upstream/${upstreamId}`, data),
syncImportedUpstreamKeys: (id: number, data: { upstream_id: number }) =>
api.post<{ success: boolean; message: string; items: ImportAccountItem[] }>(`/api/websites/${id}/accounts/sync-imported-upstream-keys`, data),
reorderAccountPriorities: (id: number, data: { upstream_id: number }) =>
api.post<{ success: boolean; message: string; items: ReorderPriorityItem[] }>(`/api/websites/${id}/accounts/reorder-priority`, data),
importAccountsFromUpstreamKeys: (id: number, data: {
upstream_key_ids: number[]
target_group_map: Record<string, string>
+36 -2
View File
@@ -324,6 +324,16 @@
<el-button size="small" text :loading="syncingImportStatus" @click="syncImportStatus">
<el-icon><Refresh /></el-icon>刷新导入状态
</el-button>
<el-button
size="small"
text
type="primary"
:loading="reorderingPriorities"
:disabled="!importAccountsForm.website_id || !importAccountsForm.upstream_id"
@click="reorderImportPriorities"
>
<el-icon><Sort /></el-icon>重排优先级
</el-button>
<span v-if="importSyncStatus" style="font-size:12px;color:var(--text-muted);margin-left:8px">
已校验已导入标记 {{ importSyncStatus.total }} 清除 {{ importSyncStatus.cleared }} 个失效标记
</span>
@@ -353,7 +363,7 @@
<el-form-item label="优先级">
<template #label>
<span>优先级</span>
<el-tooltip content="按倍率自动分配优先级:倍率最低的上游分组优先级最高(priority=1),依次递增" placement="top" :show-after="300">
<el-tooltip content="按倍率自动分配优先级:倍率最低的上游分组优先级最高(priority=1),后续按 10 递增:11、21..." placement="top" :show-after="300">
<el-icon style="margin-left:4px;vertical-align:middle;color:var(--text-muted)"><WarningFilled /></el-icon>
</el-tooltip>
</template>
@@ -447,7 +457,7 @@ import { computed, onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance } from 'element-plus'
import dayjs from 'dayjs'
import { ArrowDown, Delete, Edit, Plus, Grid, Connection, Link, Upload, Key, Refresh, WarningFilled } from '@element-plus/icons-vue'
import { ArrowDown, Delete, Edit, Plus, Grid, Connection, Link, Upload, Key, Refresh, Sort, WarningFilled } from '@element-plus/icons-vue'
import {
upstreamsApi,
websitesApi,
@@ -485,6 +495,7 @@ const importingAccounts = ref(false)
const generatedKeyLoading = ref(false)
const importSyncStatus = ref<{ total: number; cleared: number; failed: number } | null>(null)
const syncingImportStatus = ref(false)
const reorderingPriorities = ref(false)
const statusLabel = (s: string) => ({ healthy: '健康', unhealthy: '异常', unknown: '未知' }[s] || s)
const algorithmLabel = (s: string) => ({ max_plus_percent: '最高倍率', average_plus_percent: '平均倍率', min_plus_percent: '最低倍率' }[s] || s)
@@ -752,6 +763,29 @@ async function syncImportStatus() {
return reloaded
}
async function reorderImportPriorities() {
const websiteId = importAccountsForm.value.website_id
const upstreamId = importAccountsForm.value.upstream_id
if (!websiteId || !upstreamId) {
ElMessage.error('请选择目标网站和来源上游')
return
}
reorderingPriorities.value = true
try {
const res = await websitesApi.reorderAccountPriorities(websiteId, { upstream_id: upstreamId })
if (importAccountsForm.value.website_id !== websiteId || importAccountsForm.value.upstream_id !== upstreamId) return
ElMessage[res.data.success ? 'success' : 'warning'](res.data.message)
await Promise.all([
loadImportGeneratedKeys(upstreamId),
loadLogs(),
])
} catch (e: any) {
ElMessage.error(e.response?.data?.detail || '重排优先级失败')
} finally {
reorderingPriorities.value = false
}
}
async function loadImportGeneratedKeys(upstreamId: number) {
importGeneratedKeys.value = []
if (!upstreamId) return