修复备卡位续做:兼容 queryCode 即卡位并缓存任务 JSON

resolveCardPosition 解析 ret=13/out=0 真机语义;续做时重发 lastJobJson;poll tick 发送前统一归一化。
This commit is contained in:
24kycj
2026-06-03 12:06:13 +08:00
parent 057285ed89
commit 10bc05f498
5 changed files with 58 additions and 20 deletions
+2 -1
View File
@@ -1,5 +1,6 @@
import { BrowserWindow } from 'electron'
import log from 'electron-log'
import { normalizeCardPositionQuery } from '@shared/card-position'
import { POLL_INTERVAL_MS, CS_OK } from '../constants'
import {
USB_TASK_COMPLETED,
@@ -159,7 +160,7 @@ async function pollCardPositionOnce(): Promise<void> {
const dll = await loadDllModule()
if (!dll.isCardPositionApiAvailable()) return
const r = dll.dllGetPrinterCardPosition()
const tick = { queryCode: r.queryCode, position: r.position }
const tick = normalizeCardPositionQuery(r.queryCode, r.position)
emitTrace('[poll] card:position-tick', tick)
send('card:position-tick', tick)
} catch (e) {
+5
View File
@@ -3,6 +3,7 @@ import { defineStore } from 'pinia'
export const useJobStore = defineStore('job', {
state: () => ({
jobId: '',
lastJobJson: '',
submitting: false,
successCount: 0,
failCount: 0
@@ -11,11 +12,15 @@ export const useJobStore = defineStore('job', {
setActiveJob(jobId: string) {
this.jobId = jobId
},
setLastJobJson(json: string) {
this.lastJobJson = json
},
clearActiveJob() {
this.jobId = ''
},
reset() {
this.jobId = ''
this.lastJobJson = ''
this.submitting = false
this.successCount = 0
this.failCount = 0
@@ -2,6 +2,7 @@ import { genTaskId } from '@shared/gen-task-id'
import { buildJobConfig } from '@/utils/buildJobConfig'
import { resolveJobTasks } from '@/utils/validateJobConfig'
import { dllJobCreate, fsWriteJobCsv } from '@/api/cardsoon'
import { useJobStore } from '@/stores/job'
import type { DistributeFormState } from '@/stores/distributeForm'
function printFieldRows(form: DistributeFormState) {
@@ -11,10 +12,7 @@ function printFieldRows(form: DistributeFormState) {
}))
}
export async function createDistributeJob(
form: DistributeFormState,
opts?: { resubmit?: boolean }
): Promise<{ ok: true; jobId: string } | { ok: false; message: string }> {
async function buildJobJson(form: DistributeFormState): Promise<{ ok: true; json: string } | { ok: false; message: string }> {
const { hasCopy, hasPrint } = resolveJobTasks(form)
if (!hasCopy && !hasPrint) {
return { ok: false, message: '请配置拷贝路径或打印模板' }
@@ -33,7 +31,25 @@ export async function createDistributeJob(
}
}
const json = JSON.stringify(buildJobConfig(form, { taskId, udfFile }))
return { ok: true, json: JSON.stringify(buildJobConfig(form, { taskId, udfFile })) }
}
export async function createDistributeJob(
form: DistributeFormState,
opts?: { resubmit?: boolean }
): Promise<{ ok: true; jobId: string } | { ok: false; message: string }> {
const jobStore = useJobStore()
let json: string
if (opts?.resubmit && jobStore.lastJobJson) {
json = jobStore.lastJobJson
} else {
const built = await buildJobJson(form)
if (!built.ok) return built
json = built.json
jobStore.setLastJobJson(json)
}
const created = await dllJobCreate(json, opts)
if (!created.ok || !created.data?.jobId) {
return { ok: false, message: created.message || '创建任务失败' }
@@ -108,7 +108,7 @@ import {
import { createDistributeJob } from '@/utils/createDistributeJob'
import { validateJobPreflight } from '@/utils/validateJobPreflight'
import { mapJobStateToUi } from '@/utils/job-state'
import { POSITION_PREPARE } from '@shared/card-position'
import { POSITION_PREPARE, resolveCardPosition } from '@shared/card-position'
import {
USB_TASK_COPYING,
USB_TASK_PREPARING,
@@ -275,8 +275,8 @@ function canAutoResubmit(): boolean {
function applyCardPosition(p: CardPositionPollPayload): void {
if (!canAutoResubmit() || resubmitting) return
if (p.queryCode !== 0) return
const pos = p.position
const pos = resolveCardPosition(p.queryCode, p.position)
if (pos === null) return
const enteredPrepare = pos === POSITION_PREPARE && lastCardPosition !== POSITION_PREPARE
lastCardPosition = pos
if (!enteredPrepare) return
@@ -324,12 +324,14 @@ async function resubmitTask(): Promise<void> {
return
}
if (!jobStore.lastJobJson) {
const err = await validateJobPreflight(formStore)
if (err) {
notify.warning(err)
await backToWait()
return
}
}
phase.value = 'running'
setProgress(0)
workflowStep.value = 1
+20 -6
View File
@@ -4,16 +4,30 @@ export const POSITION_PREPARE = 13
/** 卡位编号合理上限(用于解析 DLL 返回值) */
export const POSITION_MAX = 32
/** 归一化 SAPI_GetPrinterCardPosition:兼容返回值=CS_OK 与返回值=卡位编号两种 DLL */
/**
* 解析 SAPI_GetPrinterCardPosition。
* 真机常见:ret=13,out=0(返回值即卡位);或 ret=0,out=卡位。
*/
export function resolveCardPosition(queryCode: number, position: number): number | null {
if (queryCode === 0 && position >= 0 && position <= POSITION_MAX) {
return position
}
if (queryCode > 0 && queryCode <= POSITION_MAX) {
return queryCode
}
if (position > 0 && position <= POSITION_MAX) {
return position
}
return null
}
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 }
const pos = resolveCardPosition(ret, outPosition)
if (pos !== null) {
return { queryCode: 0, position: pos }
}
return { queryCode: ret, position: outPosition }
}