From 10bc05f4981e7a0ec75eda668e3702d1cb29ae4d Mon Sep 17 00:00:00 2001 From: 24kycj <1637269896@qq.com> Date: Wed, 3 Jun 2026 12:06:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=87=E5=8D=A1=E4=BD=8D?= =?UTF-8?q?=E7=BB=AD=E5=81=9A=EF=BC=9A=E5=85=BC=E5=AE=B9=20queryCode=20?= =?UTF-8?q?=E5=8D=B3=E5=8D=A1=E4=BD=8D=E5=B9=B6=E7=BC=93=E5=AD=98=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=20JSON?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolveCardPosition 解析 ret=13/out=0 真机语义;续做时重发 lastJobJson;poll tick 发送前统一归一化。 --- app/src/main/services/poll-manager.ts | 3 ++- app/src/renderer/src/stores/job.ts | 5 ++++ .../renderer/src/utils/createDistributeJob.ts | 26 +++++++++++++++---- .../src/views/DistributeRunningView.vue | 18 +++++++------ app/src/shared/card-position.ts | 26 ++++++++++++++----- 5 files changed, 58 insertions(+), 20 deletions(-) diff --git a/app/src/main/services/poll-manager.ts b/app/src/main/services/poll-manager.ts index f0f7978..1131f5a 100644 --- a/app/src/main/services/poll-manager.ts +++ b/app/src/main/services/poll-manager.ts @@ -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 { 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) { diff --git a/app/src/renderer/src/stores/job.ts b/app/src/renderer/src/stores/job.ts index a7da6a5..0f02440 100644 --- a/app/src/renderer/src/stores/job.ts +++ b/app/src/renderer/src/stores/job.ts @@ -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 diff --git a/app/src/renderer/src/utils/createDistributeJob.ts b/app/src/renderer/src/utils/createDistributeJob.ts index 8dd3ebb..002b083 100644 --- a/app/src/renderer/src/utils/createDistributeJob.ts +++ b/app/src/renderer/src/utils/createDistributeJob.ts @@ -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 || '创建任务失败' } diff --git a/app/src/renderer/src/views/DistributeRunningView.vue b/app/src/renderer/src/views/DistributeRunningView.vue index fdfe23e..f870c7c 100644 --- a/app/src/renderer/src/views/DistributeRunningView.vue +++ b/app/src/renderer/src/views/DistributeRunningView.vue @@ -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,11 +324,13 @@ async function resubmitTask(): Promise { return } - const err = await validateJobPreflight(formStore) - if (err) { - notify.warning(err) - await backToWait() - return + if (!jobStore.lastJobJson) { + const err = await validateJobPreflight(formStore) + if (err) { + notify.warning(err) + await backToWait() + return + } } phase.value = 'running' setProgress(0) diff --git a/app/src/shared/card-position.ts b/app/src/shared/card-position.ts index 6d1c66b..5a48419 100644 --- a/app/src/shared/card-position.ts +++ b/app/src/shared/card-position.ts @@ -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 } }