diff --git a/jeecgboot-vue3/src/views/print/template/index.vue b/jeecgboot-vue3/src/views/print/template/index.vue
index d4c534bb..44d17575 100644
--- a/jeecgboot-vue3/src/views/print/template/index.vue
+++ b/jeecgboot-vue3/src/views/print/template/index.vue
@@ -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__';
diff --git a/jeecgboot-vue3/src/views/print/template/native/NativePrintDesigner.vue b/jeecgboot-vue3/src/views/print/template/native/NativePrintDesigner.vue
index b97ca25b..6783f556 100644
--- a/jeecgboot-vue3/src/views/print/template/native/NativePrintDesigner.vue
+++ b/jeecgboot-vue3/src/views/print/template/native/NativePrintDesigner.vue
@@ -13,6 +13,19 @@
下移图层
即时预览
打印
+
+
+ 刷新打印机
+
PrintDot 打印
保存模板
@@ -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([]);
+ /** 与模板列表共用 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(['__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(() => {
diff --git a/jeecgboot-vue3/src/views/print/template/utils/printNativeViaPrintDot.ts b/jeecgboot-vue3/src/views/print/template/utils/printNativeViaPrintDot.ts
index b76d64b5..d18e9671 100644
--- a/jeecgboot-vue3/src/views/print/template/utils/printNativeViaPrintDot.ts
+++ b/jeecgboot-vue3/src/views/print/template/utils/printNativeViaPrintDot.ts
@@ -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 后刷新打印机列表');