import type { DmsPrintConfig } from '#/components/GlobalOfficeDocumentModal/types';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
import { defHttp } from '#/api/request';
|
|
export interface DmsPrintBatch {
|
id: string;
|
pages: number[];
|
items: number[];
|
state: 'READY' | 'SENDING' | 'SUBMITTED';
|
token?: string;
|
}
|
|
export interface DmsPrintAttempt {
|
id: string;
|
tenantId: string;
|
userId: string;
|
taskId: string;
|
fileVersionId: string;
|
copies: number;
|
state: 'OPEN' | 'CONFIRMED' | 'CLOSED';
|
batchesJson: string;
|
numbersJson: string;
|
}
|
|
const endpoint = '/api/dms/biz/wenjian/dayin/renwu/';
|
async function request<T>(path: string, data: unknown): Promise<T> {
|
const response = await defHttp.post<{ code: number; data: T; msg?: string }>({ url: endpoint + path, data }, { errorMessageMode: 'none' });
|
if (response.code !== 200) throw new Error(response.msg || '保存打印发送进度失败');
|
return response.data;
|
}
|
|
/** Reuse fixed task numbers; the online form controls barcode display text. */
|
export async function loadDmsPrintPreviewNumber(taskId: string, fileVersionId: string) {
|
return request<import('./dmsPrintBarcode').DmsFixedPrintNumber>('yulan-canshu', { taskId, fileVersionId });
|
}
|
|
export function prepareDmsPrintAttempt(config: DmsPrintConfig, copies: number) {
|
return request<DmsPrintAttempt>('zhunbei-fasong', {
|
requestId: uuidv4(),
|
taskId: config.printTaskId,
|
fileVersionId: config.fileVersionId,
|
copies,
|
});
|
}
|
|
export function attemptContext(attempt: DmsPrintAttempt) {
|
return { requestId: attempt.id, taskId: attempt.taskId, fileVersionId: attempt.fileVersionId, copies: attempt.copies };
|
}
|
|
export function updateDmsPrintAttempt(attempt: DmsPrintAttempt, action: string, data: Record<string, unknown> = {}) {
|
return request<DmsPrintAttempt>(action, { ...attemptContext(attempt), ...data });
|
}
|
|
export function attemptBatches(attempt: DmsPrintAttempt): DmsPrintBatch[] {
|
return JSON.parse(attempt.batchesJson);
|
}
|
|
export async function confirmDmsPrintAttempt(attempt: DmsPrintAttempt) {
|
await request('queren-fasong', { ...attemptContext(attempt), clientResult: 'SUBMITTED' });
|
}
|
|
export async function finishDmsPrintAttempt(attempt: DmsPrintAttempt) {
|
await confirmDmsPrintAttempt(attempt);
|
await request('jieshu-fasong', attemptContext(attempt));
|
}
|
|
function receiptKey(attempt: DmsPrintAttempt, batchId: string) {
|
return `dms-print-receipt:${encodeURIComponent(attempt.tenantId)}:${encodeURIComponent(attempt.userId)}:${attempt.id}:${batchId}`;
|
}
|
|
/** 只有实际成功回调才能写入此 outbox;按租户/账号隔离,恢复时仍由服务端核对令牌。 */
|
export async function recordDmsBatchSubmitted(attempt: DmsPrintAttempt, batch: DmsPrintBatch, token: string) {
|
const key = receiptKey(attempt, batch.id);
|
try {
|
localStorage.setItem(key, token);
|
} catch {
|
/* 服务端仍为权威;本地存储不可用时不能假定成功。 */
|
}
|
const saved = await updateDmsPrintAttempt(attempt, 'queren-pici', { batchId: batch.id, token });
|
try {
|
localStorage.removeItem(key);
|
} catch {
|
/* 重复回执由服务端幂等处理。 */
|
}
|
// 晚回传同样可推进正式确认,即使原页面等待已经超时。
|
if (attemptBatches(saved).every((item) => item.state === 'SUBMITTED')) await confirmDmsPrintAttempt(saved);
|
return saved;
|
}
|
|
export async function recoverDmsBatchReceipts(attempt: DmsPrintAttempt) {
|
let saved = attempt;
|
for (const batch of attemptBatches(attempt)) {
|
let token: null | string = null;
|
try {
|
token = localStorage.getItem(receiptKey(attempt, batch.id));
|
} catch {
|
/* 不具备本地证据时保持未知。 */
|
}
|
if (token) saved = await recordDmsBatchSubmitted(saved, batch, token);
|
}
|
return saved;
|
}
|