修复备卡位 13 自动续做:卡位 API 解析与会话同步

兼容 workDll 返回值即卡位编号的语义,启动卡位轮询时同步主进程 mode,并修正续做失败时的 phase 时序。
This commit is contained in:
24kycj
2026-06-03 10:27:04 +08:00
parent 3ec168350c
commit 75490d8647
5 changed files with 53 additions and 21 deletions
+4 -1
View File
@@ -287,9 +287,12 @@ export function registerIpcHandlers(): void {
return ok()
})
tracedHandle('poll:card-position-start', async () => {
tracedHandle('poll:card-position-start', async (_e, sessionMode?: 'distributing' | 'usbCopying') => {
try {
assertReady()
if (sessionMode === 'distributing' || sessionMode === 'usbCopying') {
mainAppState.mode = sessionMode
}
const dll = await loadDllModule()
if (!dll.isCardPositionApiAvailable()) {
return fail(CS_FAIL, '当前 DLL 不支持卡位查询,无法自动续做')
+4 -3
View File
@@ -1,6 +1,7 @@
import path from 'path'
import koffi from 'koffi'
import log from 'electron-log'
import { normalizeCardPositionQuery } from '@shared/card-position'
import { CS_OK, JOB_ID_BUF_SIZE, LOG_FATAL_FLAG } from '../constants'
import { emitTrace, isTraceEnabled } from '../utils/trace-bridge'
import { getNativeDir } from './native-path'
@@ -396,9 +397,9 @@ export function dllGetPrinterCardPosition(): { queryCode: number; position: numb
return traceCall('SAPI_GetPrinterCardPosition', undefined, () => {
loadLibrary()
if (!SAPI_GetPrinterCardPosition) throw new Error('CARD_POSITION_API_UNAVAILABLE')
const position = [0]
const queryCode = SAPI_GetPrinterCardPosition!(position) as number
return { queryCode, position: position[0] }
const out = [0]
const ret = SAPI_GetPrinterCardPosition!(out) as number
return normalizeCardPositionQuery(ret, out[0])
})
}
+4 -2
View File
@@ -73,8 +73,10 @@ export async function pollUsbStop(opts?: { resetMode?: boolean }): Promise<IpcRe
return api().invoke('poll:usb-stop', opts) as Promise<IpcResult>
}
export async function pollCardPositionStart(): Promise<IpcResult> {
return api().invoke('poll:card-position-start') as Promise<IpcResult>
export async function pollCardPositionStart(
sessionMode?: 'distributing' | 'usbCopying'
): Promise<IpcResult> {
return api().invoke('poll:card-position-start', sessionMode) as Promise<IpcResult>
}
export async function pollCardPositionStop(): Promise<IpcResult> {
@@ -218,16 +218,18 @@ async function stopTaskPollsOnly(): Promise<void> {
}
}
async function startCardPositionWatch(): Promise<void> {
async function startCardPositionWatch(
sessionMode: 'distributing' | 'usbCopying'
): Promise<void> {
await pollCardPositionStop()
const cardStarted = await pollCardPositionStart()
if (!cardStarted.ok) {
notify.warning(cardStarted.message || '无法监控卡位,请手动点击返回或重新提交')
}
unsubCard?.()
unsubCard = onCardPositionTick((payload) =>
applyCardPosition(payload as CardPositionPollPayload)
)
const cardStarted = await pollCardPositionStart(sessionMode)
if (!cardStarted.ok) {
notify.warning(cardStarted.message || '无法监控卡位,请手动点击返回或重新提交')
}
}
async function enterWaitPhase(next: 'completed' | 'failed', errorText = ''): Promise<void> {
@@ -253,9 +255,10 @@ async function enterWaitPhase(next: 'completed' | 'failed', errorText = ''): Pro
failureErrorText.value = errorText
}
await stopTaskPollsOnly()
appStore.setMode(isCollect.value ? 'usbCopying' : 'distributing')
const sessionMode = isCollect.value ? 'usbCopying' : 'distributing'
appStore.setMode(sessionMode)
lastCardPosition = -1
await startCardPositionWatch()
await startCardPositionWatch(sessionMode)
}
async function enterFailedPhase(errorText = ''): Promise<void> {
@@ -287,16 +290,8 @@ async function resubmitTask(): Promise<void> {
await pollCardPositionStop()
unsubCard?.()
unsubCard = null
phase.value = 'running'
setProgress(0)
workflowStep.value = 1
collectHint.value = ''
waitCard.value = false
queryFailStreak = 0
usbQueryFailStreak = 0
const backToWait = async (message?: string): Promise<void> => {
resubmitting = false
if (message) notify.error(message)
if (fromWaitPhase === 'failed') {
await enterFailedPhase(message || failureErrorText.value)
@@ -312,6 +307,12 @@ async function resubmitTask(): Promise<void> {
await backToWait('导入目录无效,无法继续')
return
}
phase.value = 'running'
setProgress(0)
workflowStep.value = 1
collectHint.value = ''
queryFailStreak = 0
usbQueryFailStreak = 0
const r = await dllUsbCopy(dest, collectStore.cardOutput, { resubmit: true })
if (!r.ok) {
await backToWait(r.message || '重新提交收集任务失败')
@@ -329,6 +330,11 @@ async function resubmitTask(): Promise<void> {
await backToWait()
return
}
phase.value = 'running'
setProgress(0)
workflowStep.value = 1
waitCard.value = false
queryFailStreak = 0
const created = await createDistributeJob(formStore, { resubmit: true })
if (!created.ok) {
await backToWait(created.message)
@@ -341,6 +347,8 @@ async function resubmitTask(): Promise<void> {
return
}
unsubJob = onJobPollTick((payload) => applyJobProgress(payload as JobPollPayload))
} catch (e) {
await backToWait(String(e))
} finally {
resubmitting = false
}
+18
View File
@@ -1 +1,19 @@
/** workDll 备卡位:检测到后可自动续做 */
export const POSITION_PREPARE = 13
/** 卡位编号合理上限(用于解析 DLL 返回值) */
export const POSITION_MAX = 32
/** 归一化 SAPI_GetPrinterCardPosition:兼容返回值=CS_OK 与返回值=卡位编号两种 DLL */
export function normalizeCardPositionQuery(
ret: number,
outPosition: number
): { queryCode: number; position: number } {
if (ret === 0) {
return { queryCode: 0, position: outPosition }
}
if (ret > 0 && ret <= POSITION_MAX) {
return { queryCode: 0, position: ret }
}
return { queryCode: ret, position: outPosition }
}