LabelPrinter Implementation
This commit is contained in:
130
components/LabelPrintModal.vue
Normal file
130
components/LabelPrintModal.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<script setup lang="ts">
|
||||
import LabelPrinterButton from "~/components/LabelPrinterButton.vue";
|
||||
|
||||
const labelPrinter = useLabelPrinterStore()
|
||||
|
||||
const props = defineProps({
|
||||
context: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
meta_p: {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
if(!labelPrinter.connected) return
|
||||
printLabel()
|
||||
}
|
||||
},
|
||||
escape: {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
modal.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(["printed"])
|
||||
const modal = useModal()
|
||||
const { $api } = useNuxtApp()
|
||||
|
||||
const loading = ref(true)
|
||||
const printing = ref(false)
|
||||
const labelData = ref<any>(null) // gerendertes Bild vom Backend
|
||||
|
||||
|
||||
|
||||
/** Label vom Backend rendern */
|
||||
async function loadLabel() {
|
||||
loading.value = true
|
||||
try {
|
||||
labelData.value = await $api(`/api/print/label`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
context: props.context || null
|
||||
})
|
||||
})
|
||||
} catch (err) {
|
||||
console.error("Label render error", err)
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
/** Drucken */
|
||||
async function printLabel() {
|
||||
if (!labelPrinter.connected) return
|
||||
|
||||
printing.value = true
|
||||
try {
|
||||
await labelPrinter.print(labelData.value.encoded, { density: 5, pages: 1 })
|
||||
modal.close()
|
||||
} catch (err) {
|
||||
console.error("Print error", err)
|
||||
}
|
||||
printing.value = false
|
||||
}
|
||||
const handleConnect = async () => {
|
||||
await loadLabel()
|
||||
await labelPrinter.connect("ble")
|
||||
}
|
||||
onMounted(() => {
|
||||
if(labelPrinter.connected) {
|
||||
loadLabel()
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal>
|
||||
<UCard>
|
||||
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-semibold">Label drucken</h3>
|
||||
<UButton icon="i-heroicons-x-mark" variant="ghost" @click="modal.close()" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div v-if="!loading && labelPrinter.connected">
|
||||
<img
|
||||
:src="`data:image/png;base64,${labelData.base64}`"
|
||||
alt="Label Preview"
|
||||
class="max-w-full max-h-64 object-contain"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="loading && !labelPrinter.connected">
|
||||
Kein Drucker verbunden
|
||||
|
||||
<LabelPrinterButton/>
|
||||
|
||||
</div>
|
||||
<UProgress animation="carousel" v-else/>
|
||||
|
||||
|
||||
|
||||
<template #footer>
|
||||
<div class="flex justify-between">
|
||||
<UButton variant="ghost" @click="modal.close()">Abbrechen</UButton>
|
||||
|
||||
<UButton
|
||||
color="primary"
|
||||
:disabled="!labelPrinter.connected || printing"
|
||||
:loading="printing"
|
||||
@click="printLabel"
|
||||
>
|
||||
Drucken
|
||||
<UKbd>⌘</UKbd>
|
||||
<UKbd>P</UKbd>
|
||||
</UButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</UCard>
|
||||
</UModal>
|
||||
</template>
|
||||
53
components/LabelPrinterButton.vue
Normal file
53
components/LabelPrinterButton.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
const labelPrinter = useLabelPrinterStore()
|
||||
|
||||
const showPrinterInfo = ref(false)
|
||||
|
||||
const handleClick = async () => {
|
||||
if(labelPrinter.connected) {
|
||||
showPrinterInfo.value = true
|
||||
} else {
|
||||
await labelPrinter.connect('ble')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Printer Button -->
|
||||
|
||||
<UModal v-model="showPrinterInfo">
|
||||
<UCard>
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-semibold">Drucker Informationen</h3>
|
||||
<UButton icon="i-heroicons-x-mark" variant="ghost" @click="showPrinterInfo = false" />
|
||||
</div>
|
||||
</template>
|
||||
<p>Seriennummer: {{labelPrinter.info.serial}}</p>
|
||||
<p>MAC: {{labelPrinter.info.mac}}</p>
|
||||
<p>Modell: {{labelPrinter.info.modelId}}</p>
|
||||
<p>Charge: {{labelPrinter.info.charge}}</p>
|
||||
<p>Hardware Version: {{labelPrinter.info.hardwareVersion}}</p>
|
||||
<p>Software Version: {{labelPrinter.info.softwareVersion}}</p>
|
||||
</UCard>
|
||||
</UModal>
|
||||
|
||||
<UButton
|
||||
:icon="labelPrinter.connected ? 'i-heroicons-printer' : 'i-heroicons-printer'"
|
||||
:color="labelPrinter.connected ? 'green' : 'gray'"
|
||||
variant="soft"
|
||||
class="w-full justify-start"
|
||||
:loading="labelPrinter.connectLoading"
|
||||
@click="handleClick"
|
||||
>
|
||||
<span v-if="labelPrinter.connected">Drucker verbunden</span>
|
||||
<span v-else>Drucker verbinden</span>
|
||||
</UButton>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
60
components/nimbot.vue
Normal file
60
components/nimbot.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
const labelPrinter = useLabelPrinterStore()
|
||||
|
||||
|
||||
const { $api } = useNuxtApp()
|
||||
|
||||
const labelWidth = ref(50)
|
||||
const labelHeight = ref(30)
|
||||
const zpl = ref(`^XA
|
||||
^FO5,5
|
||||
^GB545,325,3^FS
|
||||
^CF0,30
|
||||
^FO20,20^FDHello from Bluetooth!^FS
|
||||
^FO20,100^BY2
|
||||
^BXN,10,200
|
||||
^FD12345678901234567^FS
|
||||
^XZ`)
|
||||
|
||||
|
||||
|
||||
async function handlePrint() {
|
||||
const dpmm = 12
|
||||
const res = await $api("/api/print/label", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
zpl: zpl.value,
|
||||
width: labelWidth.value,
|
||||
height: labelHeight.value,
|
||||
dpmm,
|
||||
}),
|
||||
})
|
||||
await labelPrinter.print(res, { density: 5, pages: 1 })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCard class="p-4">
|
||||
<div class="flex gap-2 mb-2">
|
||||
<UButton @click="labelPrinter.connect('serial')">Connect S </UButton>
|
||||
<UButton @click="labelPrinter.connect('ble')">Connect B</UButton>
|
||||
<UButton color="red" @click="labelPrinter.disconnect">Disconnect</UButton>
|
||||
<UButton color="primary" @click="handlePrint" :disabled="!labelPrinter.connected">Print</UButton>
|
||||
</div>
|
||||
|
||||
{{labelPrinter.info}}
|
||||
|
||||
{{labelPrinter.printProgress}}
|
||||
|
||||
<UFormGroup label="Breite">
|
||||
<UInput v-model="labelWidth"><template #trailing>mm</template></UInput>
|
||||
</UFormGroup>
|
||||
<UFormGroup label="Höhe">
|
||||
<UInput v-model="labelHeight"><template #trailing>mm</template></UInput>
|
||||
</UFormGroup>
|
||||
<UFormGroup label="ZPL">
|
||||
<UTextarea v-model="zpl" rows="6" />
|
||||
</UFormGroup>
|
||||
</UCard>
|
||||
</template>
|
||||
Reference in New Issue
Block a user