dsh-account-pool 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +53 -27
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -299,22 +299,41 @@ async function createRegionStack({ region, dshHome, config, logger, ctx }) {
|
|
|
299
299
|
let creditsCache = { at: 0, value: null }
|
|
300
300
|
|
|
301
301
|
/** 查各账号积分(带缓存);单个账号失败不影响其他账号。 */
|
|
302
|
+
/**
|
|
303
|
+
* 查本区域各账号的积分(带 60 秒缓存)。
|
|
304
|
+
*
|
|
305
|
+
* 账号之间**并行**查询:每个账号是一次独立的上游请求,串行会让
|
|
306
|
+
* 设置页的等待时间等于所有账号之和(实测 3 个账号串行约 1.5s)。
|
|
307
|
+
* 并行后约等于最慢的那个。
|
|
308
|
+
*
|
|
309
|
+
* 单个账号失败只丢它自己的数据,不影响其他账号。
|
|
310
|
+
*/
|
|
302
311
|
const loadCredits = async (force = false) => {
|
|
303
312
|
const now = Date.now()
|
|
304
313
|
if (!force && creditsCache.value !== null && now - creditsCache.at < 60_000) {
|
|
305
314
|
return creditsCache.value
|
|
306
315
|
}
|
|
307
|
-
const
|
|
308
|
-
|
|
316
|
+
const accounts = await store.list()
|
|
317
|
+
|
|
318
|
+
/** 查一个账号的积分;失败返回 undefined 而不是抛错。 */
|
|
319
|
+
const queryOne = async (account) => {
|
|
309
320
|
try {
|
|
310
321
|
const credential = await store.usable(account.id)
|
|
311
|
-
|
|
322
|
+
const credits = await fetchRegionCredits(credential)
|
|
312
323
|
// 顺手把总积分喂给选号器,让加权用上真实余额。
|
|
313
|
-
picker.setCredits(account.id,
|
|
324
|
+
picker.setCredits(account.id, credits.total)
|
|
325
|
+
return [account.id, credits]
|
|
314
326
|
} catch (error) {
|
|
315
327
|
logger.warn(`账号 ${account.id} 查询积分失败:${error?.message ?? error}`)
|
|
328
|
+
return undefined
|
|
316
329
|
}
|
|
317
330
|
}
|
|
331
|
+
|
|
332
|
+
const settled = await Promise.all(accounts.map(queryOne))
|
|
333
|
+
const out = {}
|
|
334
|
+
for (const entry of settled) {
|
|
335
|
+
if (entry !== undefined) out[entry[0]] = entry[1]
|
|
336
|
+
}
|
|
318
337
|
creditsCache = { at: now, value: out }
|
|
319
338
|
return out
|
|
320
339
|
}
|
|
@@ -625,34 +644,41 @@ export function apply(ctx, config = {}) {
|
|
|
625
644
|
if (!loopbackOrigin(req)) { json(res, 403, { ok: false, error: '仅允许本机访问' }); return }
|
|
626
645
|
try {
|
|
627
646
|
const list = await ready
|
|
628
|
-
|
|
629
|
-
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* 取一个区域的状态。
|
|
650
|
+
*
|
|
651
|
+
* 区域之间**并行**:cn 与 trae 是两套独立上游,串行会让设置页
|
|
652
|
+
* 的等待时间变成两者之和(冷缓存实测约 1.5s);并行后约等于
|
|
653
|
+
* 最慢的那个。
|
|
654
|
+
*/
|
|
655
|
+
const regionState = async (stack) => {
|
|
630
656
|
const snapshot = stack.picker.snapshot()
|
|
631
|
-
|
|
657
|
+
const listed = await stack.store.list()
|
|
658
|
+
const credits = await stack.loadCredits()
|
|
659
|
+
return [stack.region, {
|
|
632
660
|
provider: stack.providerId,
|
|
633
661
|
displayName: REGION_DISPLAY_NAMES[stack.region],
|
|
634
662
|
models: stack.getCatalog().length,
|
|
635
|
-
accounts: (
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
creditPackages: credits[account.id]?.packages?.slice(0, 5) ?? [],
|
|
651
|
-
}))
|
|
652
|
-
})()),
|
|
653
|
-
}
|
|
663
|
+
accounts: listed.map(account => ({
|
|
664
|
+
id: account.id,
|
|
665
|
+
nickname: account.nickname,
|
|
666
|
+
uid: account.uid,
|
|
667
|
+
domain: account.domain,
|
|
668
|
+
expiresAtMs: account.expiresAtMs,
|
|
669
|
+
...snapshot[account.id],
|
|
670
|
+
cooling: snapshot[account.id]?.cooling ?? false,
|
|
671
|
+
// 积分:剩余 + 总量 + 套餐明细(界面展示用)。
|
|
672
|
+
// size 供悬停提示展示「总量 / 已用 / 剩余」构成。
|
|
673
|
+
credits: credits[account.id]?.total,
|
|
674
|
+
creditsSize: credits[account.id]?.size,
|
|
675
|
+
creditPackages: credits[account.id]?.packages?.slice(0, 5) ?? [],
|
|
676
|
+
})),
|
|
677
|
+
}]
|
|
654
678
|
}
|
|
655
|
-
|
|
679
|
+
|
|
680
|
+
const settled = await Promise.all(list.map(regionState))
|
|
681
|
+
json(res, 200, { ok: true, regions: Object.fromEntries(settled) })
|
|
656
682
|
} catch (error) {
|
|
657
683
|
json(res, 500, { ok: false, error: safeMessage(error) })
|
|
658
684
|
}
|