根目录原 7 个 app*.go 平铺,现收进 internal/app/ 子包: - package main → package app - NewApp → New(导出) - startup/shutdown → Startup/Shutdown(导出,供 main.go 引用) - main.go 改为薄入口,仅导入 internal/app 并装配 Wails 前端同步更新(Wails 绑定路径 go/main → go/app): - window.go.main.App → window.go.app.App(10 处) - env.d.ts 类型声明路径 wailsjs/go/main/App → wailsjs/go/app/App 根目录 Go 文件从 7 个减至 1 个(main.go),元文件更清晰
230 lines
5.8 KiB
TypeScript
230 lines
5.8 KiB
TypeScript
import { ref } from 'vue'
|
|
import { useToast } from './useToast'
|
|
|
|
export interface Account {
|
|
index: number
|
|
name: string
|
|
cookie: string
|
|
}
|
|
|
|
export interface AccountStatus {
|
|
ok?: boolean
|
|
pending?: boolean
|
|
message?: string
|
|
}
|
|
|
|
const App = window.go.app.App
|
|
|
|
const accounts = ref<Account[]>([])
|
|
const selectedIndices = ref<Set<number>>(new Set())
|
|
const statusMap = ref<Record<string, AccountStatus | boolean>>({})
|
|
const scoreMap = ref<Record<string, string>>({})
|
|
|
|
export function useAccounts() {
|
|
const { showToast } = useToast()
|
|
|
|
const loadAccounts = async () => {
|
|
const data = await App.GetAccounts()
|
|
accounts.value = data || []
|
|
|
|
// 清理无效选择
|
|
selectedIndices.value = new Set(
|
|
[...selectedIndices.value].filter(i => i >= 0 && i < accounts.value.length)
|
|
)
|
|
saveSelection()
|
|
}
|
|
|
|
const reloadAccounts = async () => {
|
|
const data = await App.ReloadAccounts()
|
|
await loadAccounts()
|
|
showToast('账号已刷新', `共 ${data.count} 个账号`, 'success')
|
|
}
|
|
|
|
const toggleAccount = (index: number) => {
|
|
if (selectedIndices.value.has(index)) {
|
|
selectedIndices.value.delete(index)
|
|
} else {
|
|
selectedIndices.value.add(index)
|
|
}
|
|
saveSelection()
|
|
}
|
|
|
|
const toggleAll = () => {
|
|
if (selectedIndices.value.size === accounts.value.length) {
|
|
selectedIndices.value.clear()
|
|
} else {
|
|
accounts.value.forEach((_, i) => selectedIndices.value.add(i))
|
|
}
|
|
saveSelection()
|
|
}
|
|
|
|
const saveSelection = () => {
|
|
localStorage.setItem('selAccs', JSON.stringify([...selectedIndices.value]))
|
|
}
|
|
|
|
const restoreSelection = () => {
|
|
const saved = localStorage.getItem('selAccs')
|
|
if (saved) {
|
|
try {
|
|
selectedIndices.value = new Set(JSON.parse(saved))
|
|
} catch {}
|
|
}
|
|
const savedStatus = localStorage.getItem('statusMap')
|
|
if (savedStatus) {
|
|
try {
|
|
statusMap.value = JSON.parse(savedStatus)
|
|
} catch {}
|
|
}
|
|
}
|
|
|
|
const queryAllScore = async () => {
|
|
showToast('查询积分', '正在并发查询...', 'info')
|
|
const tasks = accounts.value.map(async (a) => {
|
|
try {
|
|
const d = await App.QueryScore(a.name)
|
|
const score = d.score ?? 'N/A'
|
|
scoreMap.value[a.name] = String(score)
|
|
localStorage.setItem('accScore_' + a.name, String(score))
|
|
} catch {}
|
|
})
|
|
await Promise.all(tasks)
|
|
showToast('积分查询完成', '', 'success')
|
|
}
|
|
|
|
const getScore = (name: string): string => {
|
|
return scoreMap.value[name] || localStorage.getItem('accScore_' + name) || '-'
|
|
}
|
|
|
|
const resetStatus = () => {
|
|
statusMap.value = {}
|
|
localStorage.removeItem('statusMap')
|
|
}
|
|
|
|
const setStatuses = (statuses: Record<string, AccountStatus | boolean>) => {
|
|
statusMap.value = statuses
|
|
if (Object.keys(statusMap.value).length > 0) {
|
|
localStorage.setItem('statusMap', JSON.stringify(statusMap.value))
|
|
} else {
|
|
localStorage.removeItem('statusMap')
|
|
}
|
|
}
|
|
|
|
const mergeStatuses = (statuses: Record<string, AccountStatus | boolean>) => {
|
|
setStatuses({
|
|
...statusMap.value,
|
|
...statuses
|
|
})
|
|
}
|
|
|
|
const setStatus = (name: string, status: AccountStatus | boolean) => {
|
|
mergeStatuses({ [name]: status })
|
|
}
|
|
|
|
const selectedAccountNames = (): string[] => {
|
|
return [...selectedIndices.value]
|
|
.map(i => accounts.value[i]?.name)
|
|
.filter(Boolean) as string[]
|
|
}
|
|
|
|
const markSelectedStatus = (status: AccountStatus | boolean) => {
|
|
const next: Record<string, AccountStatus | boolean> = {}
|
|
selectedAccountNames().forEach(name => {
|
|
next[name] = typeof status === 'object' ? { ...status } : status
|
|
})
|
|
mergeStatuses(next)
|
|
}
|
|
|
|
const markSelectedPending = (message = '抢购中,等待后端结果') => {
|
|
markSelectedStatus({ pending: true, message })
|
|
}
|
|
|
|
const buildAccountProducts = (productId: string): Record<string, string> | null => {
|
|
if (selectedIndices.value.size === 0) {
|
|
showToast('提示', '请勾选要抢购的账号', 'warn')
|
|
return null
|
|
}
|
|
if (!productId) {
|
|
showToast('提示', '请先选择商品', 'warn')
|
|
return null
|
|
}
|
|
|
|
const ap: Record<string, string> = {}
|
|
selectedIndices.value.forEach(i => {
|
|
const account = accounts.value[i]
|
|
if (account) {
|
|
ap[account.name] = productId
|
|
}
|
|
})
|
|
|
|
if (Object.keys(ap).length === 0) {
|
|
showToast('提示', '没有有效账号可提交', 'warn')
|
|
return null
|
|
}
|
|
return ap
|
|
}
|
|
|
|
return {
|
|
accounts,
|
|
selectedIndices,
|
|
statusMap,
|
|
scoreMap,
|
|
loadAccounts,
|
|
reloadAccounts,
|
|
toggleAccount,
|
|
toggleAll,
|
|
restoreSelection,
|
|
queryAllScore,
|
|
getScore,
|
|
resetStatus,
|
|
setStatuses,
|
|
mergeStatuses,
|
|
setStatus,
|
|
markSelectedStatus,
|
|
markSelectedPending,
|
|
selectedAccountNames,
|
|
buildAccountProducts
|
|
}
|
|
}
|
|
|
|
export function useVerifyExchange() {
|
|
const { accounts } = useAccounts()
|
|
const verifyResults = ref<Record<string, any>>({})
|
|
const verifying = ref(false)
|
|
|
|
const verifyAccount = async (accountName: string) => {
|
|
try {
|
|
const result = await App.VerifyExchange(accountName)
|
|
verifyResults.value[accountName] = result
|
|
return result
|
|
} catch (e: any) {
|
|
verifyResults.value[accountName] = { success: false, error: e.message }
|
|
return { success: false, error: e.message }
|
|
}
|
|
}
|
|
|
|
const verifyAll = async () => {
|
|
verifying.value = true
|
|
try {
|
|
// 使用后端批量查询接口,自带间隔
|
|
const results = await App.VerifyAllExchange()
|
|
verifyResults.value = results || {}
|
|
} catch (e: any) {
|
|
console.error('批量复验失败:', e)
|
|
} finally {
|
|
verifying.value = false
|
|
}
|
|
}
|
|
|
|
const clearResults = () => {
|
|
verifyResults.value = {}
|
|
}
|
|
|
|
return {
|
|
verifyResults,
|
|
verifying,
|
|
verifyAccount,
|
|
verifyAll,
|
|
clearResults
|
|
}
|
|
}
|