From 2e9847e15d3549ce6d93fe20f35f889b75feadef Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sun, 9 Aug 2026 15:08:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=A2=E8=B4=AD=E5=AE=8C=E6=88=90=E5=90=8E?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=88=B7=E6=96=B0=E5=B0=8F=E5=BA=97=E8=B5=84?= =?UTF-8?q?=E4=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/composables/useAccounts.ts | 17 +++++++++++------ frontend/src/composables/useScheduler.ts | 20 ++++++++++++++++++-- internal/seckill/attempt.go | 3 ++- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/frontend/src/composables/useAccounts.ts b/frontend/src/composables/useAccounts.ts index e4b2c6e..679e4ac 100644 --- a/frontend/src/composables/useAccounts.ts +++ b/frontend/src/composables/useAccounts.ts @@ -165,13 +165,12 @@ export function useAccounts() { showToast('积分查询完成', '', 'success') } - const queryAllXiaodianAssets = async () => { - const accountNames = selectedAccountNames() + const queryXiaodianAssets = async (accountNames: string[], automatic = false) => { if (accountNames.length === 0) { - showToast('查询点券和碎片', '请先勾选要查询的账号', 'warn') - return + if (!automatic) showToast('查询点券和碎片', '请先勾选要查询的账号', 'warn') + return false } - showToast('查询点券和碎片', '正在查询账号资产...', 'info') + showToast(automatic ? '抢购完成' : '查询点券和碎片', automatic ? '正在刷新本次抢购账号的资产...' : '正在查询账号资产...', 'info') try { const data = await QueryXiaodianAssets(accountNames) const queriedResults = data?.results || {} @@ -179,13 +178,18 @@ export function useAccounts() { ...xiaodianAssetsMap.value, ...queriedResults } + const successCount = Object.values(queriedResults).filter(item => item.success).length - showToast('资产查询完成', `成功 ${successCount}/${accountNames.length} 个账号`, successCount > 0 ? 'success' : 'warn') + showToast(automatic ? '抢购后资产已刷新' : '资产查询完成', `成功 ${successCount}/${accountNames.length} 个账号`, successCount > 0 ? 'success' : 'warn') + return successCount > 0 } catch (e: any) { showToast('资产查询失败', e?.message || '', 'error') + return false } } + const queryAllXiaodianAssets = async () => queryXiaodianAssets(selectedAccountNames()) + const queryAllXiaodianRoles = async () => { const accountNames = selectedAccountNames() if (accountNames.length === 0) { @@ -359,6 +363,7 @@ export function useAccounts() { clearSelection, restoreSelection, queryAllScore, + queryXiaodianAssets, queryAllXiaodianAssets, queryAllXiaodianRoles, getXiaodianRole, diff --git a/frontend/src/composables/useScheduler.ts b/frontend/src/composables/useScheduler.ts index 8b9416c..2f04368 100644 --- a/frontend/src/composables/useScheduler.ts +++ b/frontend/src/composables/useScheduler.ts @@ -12,11 +12,12 @@ const seckillRunning = ref(false) const countdownSeconds = ref(0) const countdownTimer = ref(null) const runState = ref('等待操作') +const pendingXiaodianAssetAccounts = ref([]) let unsubscribeSeckillState: (() => void) | null = null export function useScheduler() { const { showToast } = useToast() - const { resetStatus, buildAccountProducts, markSelectedPending, markSelectedStatus } = useAccounts() + const { resetStatus, buildAccountProducts, markSelectedPending, markSelectedStatus, queryXiaodianAssets } = useAccounts() const { selectedProductId, selectedProductName } = useProducts() const { currentActivity } = useActivity() const { addLocalLog, clearLocalResults } = useLogs() @@ -34,11 +35,21 @@ export function useScheduler() { } } + const refreshXiaodianAssetsAfterRun = async () => { + const accountNames = pendingXiaodianAssetAccounts.value + pendingXiaodianAssetAccounts.value = [] + if (accountNames.length === 0) return + await queryXiaodianAssets(accountNames, true) + } + const applySeckillState = (state: string) => { seckillRunning.value = state === 'running' || state === 'stopping' if (state === 'stopping') { setRunState('正在停止抢购') } + if (state === 'idle') { + void refreshXiaodianAssetsAfterRun() + } } const subscribeSeckillState = () => { @@ -71,13 +82,15 @@ export function useScheduler() { showToast('抢购中', `${Object.keys(ap).length} 个账号正在抢购`, 'info', 3000) try { - const d = currentActivity.value?.id === 'xiaodian' + const isXiaodianRun = currentActivity.value?.id === 'xiaodian' + const d = isXiaodianRun ? await StartXiaodianSeckill({ accountProducts: ap, attempts, delayMs }) : await StartSeckill(ap) if (d?.success === false) { throw new Error(d.error || '提交失败') } seckillRunning.value = true + pendingXiaodianAssetAccounts.value = isXiaodianRun ? Object.keys(ap) : [] setRunState(d.msg || '已提交') addLocalLog(d.msg || '抢购已提交', 'i') } catch (e: any) { @@ -127,6 +140,7 @@ export function useScheduler() { } scheduleActive.value = true + pendingXiaodianAssetAccounts.value = currentActivity.value?.id === 'xiaodian' ? Object.keys(ap) : [] localStorage.setItem('targetTime', timeStr) markSelectedPending(`定时等待触发: ${d.triggerTime || fullTime}`) @@ -158,6 +172,7 @@ export function useScheduler() { const d = await StartFixedSeckill({ accountProducts: ap, attempts, delayMs }) if (d?.success === false) throw new Error(d.error || '提交失败') seckillRunning.value = true + pendingXiaodianAssetAccounts.value = Object.keys(ap) setRunState(d.msg || '固定抢购已启动') addLocalLog(`固定抢购: ${Object.keys(ap).length} 个账号,${attempts} 次,间隔 ${delayMs}ms`, 'i') showToast('固定抢购已启动', `${Object.keys(ap).length} 个账号`, 'info', 3000) @@ -177,6 +192,7 @@ export function useScheduler() { } catch {} scheduleActive.value = false + pendingXiaodianAssetAccounts.value = [] localStorage.removeItem('targetTime') stopCountdown() setRunState('定时已停止') diff --git a/internal/seckill/attempt.go b/internal/seckill/attempt.go index 6bf6cff..b5cadb1 100644 --- a/internal/seckill/attempt.go +++ b/internal/seckill/attempt.go @@ -199,11 +199,12 @@ func (s *Scheduler) runXiaodianAttempt(attempt types.ExchangeAttempt) types.Exch return result } - roleName, err := cli.RoleName(attempt.Account.Cookie) + role, err := cli.XiaodianRole(attempt.Account.Cookie) if err != nil { logger.LogAccountEvent("抢购", "warn", attempt.Account.Name, "角色名查询失败: 账号=%s err=%v", attempt.Account.Name, err) } + roleName := role.RoleName result.OK = true result.RoleName = roleName if roleName != "" {