|
|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
<template>
|
|
|
|
|
<template>
|
|
|
|
|
<div class="qrcode-action-card">
|
|
|
|
|
<el-image
|
|
|
|
|
v-if="imageUrl"
|
|
|
|
|
@ -40,6 +40,8 @@ import HiprintPreviewDialog from '@/components/HiprintPreviewDialog/index.vue'
|
|
|
|
|
import { createImageViewer } from '@/components/ImageViewer'
|
|
|
|
|
import { ElLoading } from 'element-plus'
|
|
|
|
|
import { getSimpleDictDataList } from '@/api/system/dict/dict.data'
|
|
|
|
|
import { ConfigApi } from '@/api/mes/printconfig'
|
|
|
|
|
import { autoConnect, defaultElementTypeProvider, hiwebSocket, hiprint } from 'vue-plugin-hiprint'
|
|
|
|
|
|
|
|
|
|
const { t } = useI18n()
|
|
|
|
|
const message = useMessage()
|
|
|
|
|
@ -68,6 +70,7 @@ const props = withDefaults(
|
|
|
|
|
templateJson?: any
|
|
|
|
|
printData?: Record<string, any>
|
|
|
|
|
printTemplateType?: string | number
|
|
|
|
|
businessScene?: string
|
|
|
|
|
}>(),
|
|
|
|
|
{
|
|
|
|
|
imageUrl: '',
|
|
|
|
|
@ -91,7 +94,8 @@ const props = withDefaults(
|
|
|
|
|
templateJsonUrl: '',
|
|
|
|
|
templateJson: undefined,
|
|
|
|
|
printData: () => ({}),
|
|
|
|
|
printTemplateType: undefined
|
|
|
|
|
printTemplateType: undefined,
|
|
|
|
|
businessScene: ''
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
@ -110,6 +114,17 @@ type TemplateFieldMap = {
|
|
|
|
|
|
|
|
|
|
let printTemplateDictCache: any[] | undefined
|
|
|
|
|
|
|
|
|
|
// ========== 打印客户端状态 ==========
|
|
|
|
|
let hiprintInited = false
|
|
|
|
|
const clientConnected = ref(false)
|
|
|
|
|
const clientConnecting = ref(false)
|
|
|
|
|
const clientPrinting = ref(false)
|
|
|
|
|
const clientHostStorageKey = 'hiprint-client-host'
|
|
|
|
|
const defaultClientHost = 'http://192.168.2.58:17521'
|
|
|
|
|
const clientHost = ref(localStorage.getItem(clientHostStorageKey) || defaultClientHost)
|
|
|
|
|
const selectedPrinter = ref('')
|
|
|
|
|
const printerList = ref<Array<{ name: string; [key: string]: any }>>([])
|
|
|
|
|
|
|
|
|
|
const showActionMask = computed(() => props.showPreview || props.showPrint || props.showRefresh)
|
|
|
|
|
|
|
|
|
|
const parseTemplateFieldMap = (remark: any): TemplateFieldMap | undefined => {
|
|
|
|
|
@ -331,6 +346,52 @@ const replaceTemplateValues = (templateJson: any, printData: Record<string, any>
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ========== 打印客户端辅助方法 ==========
|
|
|
|
|
const getHiwebSocket = () => {
|
|
|
|
|
return ((hiwebSocket as any) || (window as any).hiwebSocket) as any
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const normalizeClientHost = () => {
|
|
|
|
|
const host = clientHost.value.trim()
|
|
|
|
|
if (!host) return defaultClientHost
|
|
|
|
|
if (/^https?:\/\//i.test(host)) return host
|
|
|
|
|
return 'http://' + host
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ensureHiprintInit = () => {
|
|
|
|
|
if (hiprintInited) return
|
|
|
|
|
hiprint.init({
|
|
|
|
|
host: normalizeClientHost(),
|
|
|
|
|
providers: [defaultElementTypeProvider()]
|
|
|
|
|
})
|
|
|
|
|
hiprintInited = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const syncClientState = (printersFromCallback?: Array<{ name: string; [key: string]: any }>) => {
|
|
|
|
|
const socket = getHiwebSocket()
|
|
|
|
|
clientConnected.value = !!socket?.opened
|
|
|
|
|
const printers = printersFromCallback || socket?.printerList || []
|
|
|
|
|
printerList.value = Array.isArray(printers) ? printers : []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const connectClient = () => {
|
|
|
|
|
ensureHiprintInit()
|
|
|
|
|
const socket = getHiwebSocket()
|
|
|
|
|
let host = normalizeClientHost()
|
|
|
|
|
clientHost.value = host
|
|
|
|
|
localStorage.setItem(clientHostStorageKey, host)
|
|
|
|
|
if (socket?.host !== host) {
|
|
|
|
|
socket?.stop?.()
|
|
|
|
|
socket.host = host
|
|
|
|
|
}
|
|
|
|
|
clientConnecting.value = true
|
|
|
|
|
autoConnect((status: boolean) => {
|
|
|
|
|
clientConnecting.value = false
|
|
|
|
|
clientConnected.value = !!status
|
|
|
|
|
syncClientState()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handlePrint = async () => {
|
|
|
|
|
if (!props.imageUrl || !props.showPrint) return
|
|
|
|
|
|
|
|
|
|
@ -368,6 +429,55 @@ const handlePrint = async () => {
|
|
|
|
|
templateJson = buildQrcodeTemplateJson(props.imageUrl, printData, imageWidth, imageHeight, paperHeight, templateFieldMap)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果传入了 businessScene,直接查询打印机配置并通过客户端打印
|
|
|
|
|
if (props.businessScene) {
|
|
|
|
|
try {
|
|
|
|
|
const pageRes = await ConfigApi.getConfigPage({
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
pageSize: 100,
|
|
|
|
|
businessScenario: props.businessScene
|
|
|
|
|
})
|
|
|
|
|
const configs = pageRes?.list || []
|
|
|
|
|
if (!configs.length) {
|
|
|
|
|
message.warning('未找到匹配业务场景「' + props.businessScene + '」的打印机配置')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const printerConfig = configs[0]
|
|
|
|
|
const printerName = printerConfig.systemPrinterName
|
|
|
|
|
|
|
|
|
|
ensureHiprintInit()
|
|
|
|
|
syncClientState()
|
|
|
|
|
|
|
|
|
|
if (!clientConnected.value) {
|
|
|
|
|
connectClient()
|
|
|
|
|
message.warning('正在连接本地打印客户端,请稍后重试')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const hiprintTmpl = new hiprint.PrintTemplate({ template: templateJson })
|
|
|
|
|
hiprintTmpl.on('printSuccess', () => {
|
|
|
|
|
message.success('打印已发送到: ' + printerName)
|
|
|
|
|
})
|
|
|
|
|
hiprintTmpl.on('printError', (err: any) => {
|
|
|
|
|
message.error(err?.msg || err?.message || '打印失败')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
clientPrinting.value = true
|
|
|
|
|
try {
|
|
|
|
|
hiprintTmpl.print2(printData, {
|
|
|
|
|
printer: printerName,
|
|
|
|
|
title: props.printTitle
|
|
|
|
|
})
|
|
|
|
|
} finally {
|
|
|
|
|
clientPrinting.value = false
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('打印机配置查询或打印失败', error)
|
|
|
|
|
message.error('打印机配置查询或打印失败')
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const paperSize = templateJson?.panels?.[0] ? {
|
|
|
|
|
width: templateJson.panels[0].width,
|
|
|
|
|
height: templateJson.panels[0].height
|
|
|
|
|
|