Files
dygou_go/frontend/src/composables/useScheduler.ts
T
2026-06-26 10:56:25 +08:00

150 lines
3.9 KiB
TypeScript

import { ref } from 'vue'
import { useToast } from './useToast'
import { useAccounts } from './useAccounts'
import { useProducts } from './useProducts'
const App = window.go.main.App
const scheduleActive = ref(false)
const countdownSeconds = ref(0)
const countdownTimer = ref<number | null>(null)
const runState = ref('等待操作')
export function useScheduler() {
const { showToast } = useToast()
const { resetStatus, buildAccountProducts } = useAccounts()
const { selectedProductId, selectedProductName } = useProducts()
const setRunState = (text: string) => {
runState.value = text || '等待操作'
}
const startNow = async () => {
const ap = buildAccountProducts(selectedProductId.value || '')
if (!ap) return
resetStatus()
setRunState('立即抢购已提交')
showToast('抢购中', `${Object.keys(ap).length} 个账号正在抢购`, 'info', 3000)
try {
const d = await App.StartSeckill(ap)
setRunState(d.msg || '已提交')
} catch (e: any) {
setRunState('提交失败')
showToast('提交失败', e.message, 'error')
}
}
const startSchedule = async (targetTime: string, advance: number) => {
const ap = buildAccountProducts(selectedProductId.value || '')
if (!ap) return
if (!targetTime) {
showToast('提示', '请选择目标时间', 'warn')
return
}
// 格式化时间
let timeStr = targetTime
if (timeStr.split(':').length === 2) timeStr += ':00'
const today = new Intl.DateTimeFormat('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
}).format(new Date()).replace(/\//g, '-')
const fullTime = today + ' ' + timeStr
resetStatus()
setRunState('定时配置中')
try {
const d = await App.SetSchedule({
accountProducts: ap,
targetTime: fullTime,
advance
})
scheduleActive.value = true
localStorage.setItem('targetTime', timeStr)
localStorage.setItem('advance', String(advance))
setRunState(`定时已开启,触发 ${d.triggerTime}`)
showToast(
'定时已开启',
`触发时刻: ${d.triggerTime}<br>剩余时间: ${formatRemain(d.remainSecond)}`,
'success',
5000
)
startCountdown(d.remainSecond)
} catch (e: any) {
setRunState('定时设置失败')
showToast('定时失败', e.message, 'error')
}
}
const cancelSchedule = async () => {
try {
await App.CancelSchedule()
} catch {}
scheduleActive.value = false
localStorage.removeItem('targetTime')
localStorage.removeItem('advance')
stopCountdown()
setRunState('定时已停止')
showToast('定时已停止', '抢购任务已取消', 'warn')
}
const startCountdown = (sec: number) => {
stopCountdown()
const endTime = Date.now() + sec * 1000
countdownTimer.value = window.setInterval(() => {
const remain = Math.max(0, Math.ceil((endTime - Date.now()) / 1000))
countdownSeconds.value = remain
if (remain <= 0) {
scheduleActive.value = false
setRunState('定时已触发')
stopCountdown()
}
}, 500)
}
const stopCountdown = () => {
if (countdownTimer.value) {
clearInterval(countdownTimer.value)
countdownTimer.value = null
}
countdownSeconds.value = 0
}
const formatRemain = (sec: number): string => {
const h = Math.floor(sec / 3600)
const m = Math.floor((sec % 3600) / 60)
const s = sec % 60
return `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
}
const restoreSchedule = () => {
const savedTime = localStorage.getItem('targetTime')
const savedAdv = localStorage.getItem('advance')
return { savedTime, savedAdv: savedAdv ? parseInt(savedAdv) : 300 }
}
return {
scheduleActive,
countdownSeconds,
runState,
setRunState,
startNow,
startSchedule,
cancelSchedule,
formatRemain,
restoreSchedule
}
}