与打印插件获取的打印机做交互

This commit is contained in:
geht
2026-04-17 19:31:09 +08:00
parent efb6a9f838
commit 93b2208675
3 changed files with 75 additions and 7 deletions

View File

@@ -212,6 +212,7 @@
} from './utils/printDotBridge';
import { normalizeImportedNativeSchema } from './native/core/nativeSchemaNormalize';
import { renderNativePrintHtml } from './native/core/printRenderer';
import { PRINT_TEMPLATE_SELECTED_PRINTER_KEY } from './utils/printNativeViaPrintDot';
defineOptions({ name: 'PrintTemplateList' });
@@ -304,7 +305,6 @@
});
let hiprint: any = null;
const PRINTER_STORAGE_KEY = 'print_template_selected_printer';
function resolveHiprint(module: any) {
const defaultExport = module?.default || {};
hiprint = module?.hiprint || defaultExport?.hiprint || (window as any)?.hiprint;
@@ -1637,10 +1637,10 @@
selectedPrinterName,
(value) => {
if (!value) {
localStorage.removeItem(PRINTER_STORAGE_KEY);
localStorage.removeItem(PRINT_TEMPLATE_SELECTED_PRINTER_KEY);
return;
}
localStorage.setItem(PRINTER_STORAGE_KEY, value);
localStorage.setItem(PRINT_TEMPLATE_SELECTED_PRINTER_KEY, value);
},
{ immediate: false },
);
@@ -1651,7 +1651,7 @@
} catch (_error) {
// ignore
}
selectedPrinterName.value = localStorage.getItem(PRINTER_STORAGE_KEY) || '__system_default__';
selectedPrinterName.value = localStorage.getItem(PRINT_TEMPLATE_SELECTED_PRINTER_KEY) || '__system_default__';
await refreshPrinterOptions(false);
if (!selectedPrinterName.value) {
selectedPrinterName.value = '__system_default__';

View File

@@ -13,6 +13,19 @@
<a-button @click="sendBackward">下移图层</a-button>
<a-button @click="previewTemplate">即时预览</a-button>
<a-button @click="printTemplate">打印</a-button>
<a-select
v-model:value="designerPrintDotPrinter"
:options="printDotPrinterSelectOptions"
:loading="printDotPrintersLoading"
placeholder="PrintDot 打印机"
show-search
option-filter-prop="label"
class="toolbar-printdot-printer"
:dropdown-match-select-width="false"
/>
<a-button size="small" :loading="printDotPrintersLoading" @click="refreshDesignerPrintDotPrinters(true)">
刷新打印机
</a-button>
<a-button :loading="printDotLoading" @click="printTemplateViaPrintDot">PrintDot 打印</a-button>
<a-button type="primary" :loading="saving" @click="saveTemplate">保存模板</a-button>
</a-space>
@@ -307,7 +320,8 @@
import PropertiesPanel from './components/PropertiesPanel.vue';
import ToolbarPalette from './components/ToolbarPalette.vue';
import { printHtml } from './core/printService';
import { printNativeSchemaViaPrintDot } from '../utils/printNativeViaPrintDot';
import { fetchPrintDotPrinters, type PrintDotPrinter } from '../utils/printDotBridge';
import { printNativeSchemaViaPrintDot, PRINT_TEMPLATE_SELECTED_PRINTER_KEY } from '../utils/printNativeViaPrintDot';
import { renderNativePrintHtml, resolvePrintPageCount } from './core/printRenderer';
import { generateNativeMockDataObject } from './core/nativeMockData';
import { buildNativeTemplateStylePayload } from './core/nativeTemplateStyleSerialize';
@@ -344,6 +358,56 @@
const templateId = ref('');
const saving = ref(false);
const printDotLoading = ref(false);
/** PrintDot 桥接返回的打印机列表(设计器内下拉) */
const printDotPrintersLoading = ref(false);
const printDotPrinterList = ref<PrintDotPrinter[]>([]);
/** 与模板列表共用 localStorage保证列表与设计器选同一台机 */
const designerPrintDotPrinter = ref(
localStorage.getItem(PRINT_TEMPLATE_SELECTED_PRINTER_KEY) || '__system_default__',
);
const printDotPrinterSelectOptions = computed(() => {
const opts: Array<{ label: string; value: string }> = [
{ label: '系统默认打印机', value: '__system_default__' },
];
const seen = new Set<string>(['__system_default__']);
printDotPrinterList.value.forEach((p) => {
const name = String(p.name || '').trim();
if (!name || seen.has(name)) return;
seen.add(name);
opts.push({
label: p.isDefault ? `${name}PrintDot 默认)` : name,
value: name,
});
});
return opts;
});
watch(designerPrintDotPrinter, (v) => {
if (!v) {
localStorage.removeItem(PRINT_TEMPLATE_SELECTED_PRINTER_KEY);
return;
}
localStorage.setItem(PRINT_TEMPLATE_SELECTED_PRINTER_KEY, v);
});
async function refreshDesignerPrintDotPrinters(showTip = true) {
printDotPrintersLoading.value = true;
try {
const list = await fetchPrintDotPrinters();
printDotPrinterList.value = list;
if (showTip) {
createMessage.success(`PrintDot 已连接,共 ${list.length} 台打印机`);
}
} catch (e: any) {
printDotPrinterList.value = [];
if (showTip) {
createMessage.warning(e?.message || '无法连接 PrintDot请确认本机客户端已启动');
}
} finally {
printDotPrintersLoading.value = false;
}
}
const previewVisible = ref(false);
const previewHtml = ref('');
const selectedTableColumn = ref<{ elementId: string; columnKey: string } | null>(null);
@@ -1333,6 +1397,7 @@
schema: state.schema,
data: previewData.value,
jobName: String(meta.templateCode || '').trim() || 'native-print',
printerSelection: designerPrintDotPrinter.value || '__system_default__',
});
createMessage.success('已通过 PrintDot 提交打印');
} catch (error: any) {
@@ -1707,6 +1772,7 @@
await loadTemplate();
generateCanvasJson();
generateMockData({ syncManual: true, showMessage: false });
void refreshDesignerPrintDotPrinters(false);
});
onUnmounted(() => {

View File

@@ -3,7 +3,8 @@ import { renderNativePrintHtml } from '../native/core/printRenderer';
import { buildPdfBase64FromHtmlFragment, extractBodyInnerHtmlFromFullDocument } from './printHtmlToPdfBase64';
import { fetchPrintDotPrinters, printDotSendPdf, resolvePrintDotPrinterName } from './printDotBridge';
const PRINTER_STORAGE_KEY = 'print_template_selected_printer';
/** 与模板列表页共用,便于设计器与列表选择同一台 PrintDot 打印机 */
export const PRINT_TEMPLATE_SELECTED_PRINTER_KEY = 'print_template_selected_printer';
/**
* 原生模板:渲染 HTML → 转 PDF → 经 PrintDot 本地桥接器送打印机
@@ -21,7 +22,8 @@ export async function printNativeSchemaViaPrintDot(params: {
paginate: true,
});
const printers = await fetchPrintDotPrinters();
const fromStore = params.printerSelection ?? localStorage.getItem(PRINTER_STORAGE_KEY) ?? '__system_default__';
const fromStore =
params.printerSelection ?? localStorage.getItem(PRINT_TEMPLATE_SELECTED_PRINTER_KEY) ?? '__system_default__';
const resolved = resolvePrintDotPrinterName(fromStore, printers);
if (!resolved) {
throw new Error('未解析到可用打印机:请在模板列表选择打印机,或启动 PrintDot 后刷新打印机列表');