优化了qq微信切换
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import {
|
||||
closeTencentBrowserSession,
|
||||
createTencentBrowserSession,
|
||||
getTencentBrowserSession,
|
||||
getTencentBrowserSessionSummary,
|
||||
getTencentBrowserSessionScreenshotPath,
|
||||
reloadTencentBrowserSession,
|
||||
redeemTencentBrowserSession,
|
||||
} from '../session/session.js'
|
||||
import { findClaimTokenByToken, getClaimTokenById, updateClaimToken } from '../../repositories/claim-token-repo.js'
|
||||
@@ -24,8 +26,8 @@ const CLAIM_TERMINAL_STATUSES = new Set(['expired', 'closed'])
|
||||
|
||||
export async function getClaimDetail(token, { includeQrImage = true } = {}) {
|
||||
const context = await getClaimContext(token)
|
||||
const session = await loadTaskSession(context.task, { includeQrImage })
|
||||
const syncedTask = session ? await syncTaskWithSession(context.task, session) : context.task
|
||||
const { task, session } = await loadTaskSession(context.task, { includeQrImage })
|
||||
const syncedTask = session ? await syncTaskWithSession(task, session) : task
|
||||
|
||||
return buildClaimDetailPayload({
|
||||
claimToken: context.claimToken,
|
||||
@@ -39,30 +41,54 @@ export async function getClaimDetail(token, { includeQrImage = true } = {}) {
|
||||
export async function createClaimSession(token, payload = {}) {
|
||||
const context = await getClaimContext(token)
|
||||
assertTaskCanProceed(context.task)
|
||||
const requestedLoginType = normalizeClaimLoginType(payload.loginType)
|
||||
const forceRecreate = Boolean(payload.forceRecreate)
|
||||
let task = context.task
|
||||
|
||||
if (context.task.browser_session_id) {
|
||||
const existingSession = await getTencentBrowserSession(context.task.browser_session_id)
|
||||
const syncedTask = await syncTaskWithSession(context.task, existingSession)
|
||||
if (task.browser_session_id) {
|
||||
const existing = await loadTaskSession(task, { includeQrImage: true })
|
||||
task = existing.task
|
||||
|
||||
return buildClaimDetailPayload({
|
||||
claimToken: context.claimToken,
|
||||
task: syncedTask,
|
||||
order: context.order,
|
||||
orderItem: context.orderItem,
|
||||
session: existingSession,
|
||||
})
|
||||
if (existing.session) {
|
||||
const existingLoginType = normalizeClaimLoginType(existing.session.loginType || task.login_type)
|
||||
|
||||
if (!forceRecreate && existingLoginType === requestedLoginType) {
|
||||
const syncedTask = await syncTaskWithSession(task, existing.session)
|
||||
|
||||
return buildClaimDetailPayload({
|
||||
claimToken: context.claimToken,
|
||||
task: syncedTask,
|
||||
order: context.order,
|
||||
orderItem: context.orderItem,
|
||||
session: existing.session,
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
await closeTencentBrowserSession(existing.session.sessionId)
|
||||
} catch (error) {
|
||||
if (!isRecoverableSessionError(error)) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
task = await clearTaskSession(task, {
|
||||
lastError: '',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const session = await createTencentBrowserSession({
|
||||
loginType: payload.loginType,
|
||||
loginType: requestedLoginType,
|
||||
})
|
||||
const updatedTask = await updateTask(context.task.id, {
|
||||
const updatedTask = await updateTask(task.id, {
|
||||
task_status: 'claimed',
|
||||
browser_session_id: session.sessionId,
|
||||
login_type: session.loginType,
|
||||
user_action_status: 'claimed',
|
||||
claimed_at: context.task.claimed_at || nowIso(),
|
||||
claimed_at: task.claimed_at || nowIso(),
|
||||
updated_at: nowIso(),
|
||||
last_error: '',
|
||||
})
|
||||
|
||||
return buildClaimDetailPayload({
|
||||
@@ -76,16 +102,21 @@ export async function createClaimSession(token, payload = {}) {
|
||||
|
||||
export async function getClaimSessionSummary(token) {
|
||||
const context = await getClaimContext(token)
|
||||
const { task, session } = await loadTaskSession(context.task, {
|
||||
includeQrImage: false,
|
||||
})
|
||||
|
||||
if (!context.task.browser_session_id) {
|
||||
throw createHttpError('当前任务还没有创建浏览器会话', {
|
||||
statusCode: 409,
|
||||
errorCode: 'claim_session_not_created',
|
||||
if (!session) {
|
||||
return buildClaimDetailPayload({
|
||||
claimToken: context.claimToken,
|
||||
task,
|
||||
order: context.order,
|
||||
orderItem: context.orderItem,
|
||||
session: null,
|
||||
})
|
||||
}
|
||||
|
||||
const session = await getTencentBrowserSession(context.task.browser_session_id)
|
||||
const syncedTask = await syncTaskWithSession(context.task, session)
|
||||
const syncedTask = await syncTaskWithSession(task, session)
|
||||
|
||||
return buildClaimDetailPayload({
|
||||
claimToken: context.claimToken,
|
||||
@@ -96,6 +127,72 @@ export async function getClaimSessionSummary(token) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function reloadClaimSession(token) {
|
||||
const context = await getClaimContext(token)
|
||||
assertTaskCanProceed(context.task)
|
||||
|
||||
const active = await loadTaskSession(context.task, {
|
||||
includeQrImage: true,
|
||||
})
|
||||
|
||||
if (!active.session) {
|
||||
return buildClaimDetailPayload({
|
||||
claimToken: context.claimToken,
|
||||
task: active.task,
|
||||
order: context.order,
|
||||
orderItem: context.orderItem,
|
||||
session: null,
|
||||
})
|
||||
}
|
||||
|
||||
const session = await reloadTencentBrowserSession(active.session.sessionId)
|
||||
const syncedTask = await syncTaskWithSession(active.task, session)
|
||||
|
||||
return buildClaimDetailPayload({
|
||||
claimToken: context.claimToken,
|
||||
task: syncedTask,
|
||||
order: context.order,
|
||||
orderItem: context.orderItem,
|
||||
session,
|
||||
})
|
||||
}
|
||||
|
||||
export async function closeClaimSession(token) {
|
||||
const context = await getClaimContext(token)
|
||||
assertTaskCanProceed(context.task)
|
||||
let task = context.task
|
||||
|
||||
if (!task.browser_session_id) {
|
||||
return buildClaimDetailPayload({
|
||||
claimToken: context.claimToken,
|
||||
task,
|
||||
order: context.order,
|
||||
orderItem: context.orderItem,
|
||||
session: null,
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
await closeTencentBrowserSession(task.browser_session_id)
|
||||
} catch (error) {
|
||||
if (!isRecoverableSessionError(error)) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
task = await clearTaskSession(task, {
|
||||
lastError: '',
|
||||
})
|
||||
|
||||
return buildClaimDetailPayload({
|
||||
claimToken: context.claimToken,
|
||||
task,
|
||||
order: context.order,
|
||||
orderItem: context.orderItem,
|
||||
session: null,
|
||||
})
|
||||
}
|
||||
|
||||
export async function confirmClaimRole(token) {
|
||||
const context = await getClaimContext(token)
|
||||
assertPublicClaimActionAllowed(context.task, 'confirm')
|
||||
@@ -430,12 +527,35 @@ async function expireClaimContext(claimToken, task) {
|
||||
|
||||
async function loadTaskSession(task, { includeQrImage = false } = {}) {
|
||||
if (!task.browser_session_id) {
|
||||
return null
|
||||
return {
|
||||
task,
|
||||
session: null,
|
||||
}
|
||||
}
|
||||
|
||||
return includeQrImage
|
||||
? getTencentBrowserSession(task.browser_session_id)
|
||||
: getTencentBrowserSessionSummary(task.browser_session_id)
|
||||
try {
|
||||
const session = includeQrImage
|
||||
? await getTencentBrowserSession(task.browser_session_id)
|
||||
: await getTencentBrowserSessionSummary(task.browser_session_id)
|
||||
|
||||
return {
|
||||
task,
|
||||
session,
|
||||
}
|
||||
} catch (error) {
|
||||
if (!isRecoverableSessionError(error)) {
|
||||
throw error
|
||||
}
|
||||
|
||||
const nextTask = await clearTaskSession(task, {
|
||||
lastError: '浏览器会话已失效,请重新初始化登录',
|
||||
})
|
||||
|
||||
return {
|
||||
task: nextTask,
|
||||
session: null,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function syncTaskWithSession(task, session) {
|
||||
@@ -550,3 +670,36 @@ function parseTaskState(task) {
|
||||
function isAssistedClaimTask(task) {
|
||||
return String(task?.executor_key || '').trim() === 'tencent_claim_assisted'
|
||||
}
|
||||
|
||||
async function clearTaskSession(task, { lastError = '' } = {}) {
|
||||
const shouldResetClaimProgress = ['link_generated', 'claimed', 'role_confirmed'].includes(String(task.task_status || ''))
|
||||
const nextTaskStatus = shouldResetClaimProgress ? 'link_generated' : task.task_status
|
||||
const nextUserActionStatus = shouldResetClaimProgress ? 'pending_claim' : task.user_action_status
|
||||
const patch = {
|
||||
task_status: nextTaskStatus,
|
||||
user_action_status: nextUserActionStatus,
|
||||
browser_session_id: '',
|
||||
login_type: '',
|
||||
nickname: '',
|
||||
role_id: '',
|
||||
role_name: '',
|
||||
area: '',
|
||||
partition_name: '',
|
||||
artifacts_json: '{}',
|
||||
state_json: '{}',
|
||||
role_confirmed_at: nextTaskStatus === 'link_generated' ? null : task.role_confirmed_at,
|
||||
last_error: String(lastError || ''),
|
||||
updated_at: nowIso(),
|
||||
}
|
||||
|
||||
return updateTask(task.id, patch)
|
||||
}
|
||||
|
||||
function normalizeClaimLoginType(loginType) {
|
||||
return String(loginType || '').trim() === 'wx' ? 'wx' : 'qq'
|
||||
}
|
||||
|
||||
function isRecoverableSessionError(error) {
|
||||
const errorCode = String(error?.errorCode || error?.code || '').trim()
|
||||
return errorCode === 'session_not_found' || errorCode === 'session_closed'
|
||||
}
|
||||
|
||||
@@ -172,6 +172,7 @@ export async function reloadTencentBrowserSession(sessionId) {
|
||||
session.qrImagePath = ''
|
||||
session.qrUpdatedAt = ''
|
||||
await ensureLoginTab(session.page, session.loginType)
|
||||
await captureSessionQr(session)
|
||||
}
|
||||
|
||||
session.notice = credentialReady
|
||||
@@ -247,6 +248,11 @@ export async function refreshTencentBrowserSession(sessionId, { includeQrImage =
|
||||
session.expiresAt = Date.now() + SESSION_TTL_MS
|
||||
|
||||
if (!session.qrImageBase64 || session.status === 'expired') {
|
||||
if (session.status === 'expired') {
|
||||
await reloadActivityPageForPresentation(session.page)
|
||||
await ensureLoginTab(session.page, session.loginType)
|
||||
}
|
||||
|
||||
await captureSessionQr(session)
|
||||
if (session.status === 'expired') {
|
||||
session.notice = '二维码已刷新,请重新扫码'
|
||||
|
||||
Reference in New Issue
Block a user