更新导入设计
This commit is contained in:
@@ -862,26 +862,12 @@ func (s *TokenService) ImportGrokToken(ctx context.Context, ssoToken, tokenID st
|
||||
return nil, errors.New("not a grok sso token")
|
||||
}
|
||||
sid := grok.SessionIDFromToken(ssoToken)
|
||||
// Resolve the real account email up front (GET /api/auth/session) for dedup +
|
||||
// display — the sso session_id rotates per login, so email is the stable id.
|
||||
email := ""
|
||||
if s.grok != nil {
|
||||
s.applyProxy(ctx)
|
||||
// Best-effort email resolution. A dead/blocked probe must NOT block import:
|
||||
// land the account and let the async checkPendingGrok disable it if the
|
||||
// session is truly dead. Empty email just falls back to the session id.
|
||||
if e, _, ferr := s.grok.FetchSession(ctx, ssoToken); ferr == nil {
|
||||
email = e
|
||||
}
|
||||
}
|
||||
idKey := email
|
||||
if idKey == "" {
|
||||
idKey = sid
|
||||
}
|
||||
// Identity is (pool, email): reuse the row for this account, else mint.
|
||||
if existing, _ := s.tokens.GetByPoolEmail(ctx, "grok", idKey); existing != nil {
|
||||
tokenID = existing.ID
|
||||
} else if idKey != "" || tokenID == "" {
|
||||
// Fully async, no dedup: every import mints a fresh row (a passed-in tokenID is
|
||||
// an explicit edit → update). We do NOT look up an existing account by
|
||||
// email/session_id, and we leave account_email empty — email, quota and
|
||||
// recovery time are all filled off-thread by checkPendingGrok, which also
|
||||
// disables the account if the sso session is dead.
|
||||
if strings.TrimSpace(tokenID) == "" {
|
||||
tokenID = newTokenID("grok")
|
||||
}
|
||||
meta := datatypes.JSONMap{"pending_check": true}
|
||||
@@ -900,11 +886,6 @@ func (s *TokenService) ImportGrokToken(ctx context.Context, ssoToken, tokenID st
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if idKey != "" {
|
||||
if updated, uerr := s.tokens.Update(ctx, "grok", tokenID, map[string]any{"account_email": idKey}); uerr == nil {
|
||||
item = updated
|
||||
}
|
||||
}
|
||||
go s.checkPendingGrok(tokenID, ssoToken)
|
||||
return item, nil
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ async function doSmartImport() {
|
||||
const errs = []
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const it = items[i]
|
||||
setStatus(`正在导入 ${i + 1}/${items.length} (${it.type})…`)
|
||||
try {
|
||||
const r = it.type === 'openai'
|
||||
? await api('/tokens/import-chatgpt-token', jsonBody('POST', { access_token: it.value }))
|
||||
@@ -77,9 +76,10 @@ async function doSmartImport() {
|
||||
// Quota isn't checked here — the server probes each token off-thread and the
|
||||
// account list flips pending → active/dead on its own.
|
||||
if (fail === 0) {
|
||||
setStatus(`✓ 导入 ${ok} 项 · 正在后台检测额度…`)
|
||||
// Close immediately on success — the account lands in the table right away
|
||||
// and the server backfills quota/email off-thread (pending → active/dead).
|
||||
emit('imported')
|
||||
setTimeout(() => emit('close'), 1000)
|
||||
emit('close')
|
||||
} else {
|
||||
setStatus(`成功 ${ok} · 失败 ${fail} · ${errs.slice(0, 3).join(' | ')}`, true)
|
||||
emit('imported')
|
||||
|
||||
Reference in New Issue
Block a user