feat:更改页面
This commit is contained in:
1 parent
b422df5b76
commit
44b2df144c
84 files changed
+11701
-2114
No files matched your search
@@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :title="dialogTitle" width="560px" draggable :close-on-click-modal="false">
|
||||
<el-form v-if="mode === 'bind'" ref="bindFormRef" :model="bindForm" label-width="120px">
|
||||
<el-form-item label="业务终端">
|
||||
<el-input :model-value="sourceName" disabled />
|
||||
</el-form-item>
|
||||
<el-alert class="mb-5" type="info" :closable="false" show-icon>
|
||||
<template #title
|
||||
>此处建立“业务终端 → 尔印 USB 打印机”的一对一关系。打印机没有独立屏幕、账号和心跳;绑定的食堂或超市终端负责发现 USB
|
||||
设备、接收任务、打印并回传结果。</template
|
||||
>
|
||||
</el-alert>
|
||||
<el-form-item label="尔印打印机" prop="printerHardId" :rules="[{ required: true, message: '请选择打印机' }]">
|
||||
<el-select
|
||||
v-model="bindForm.printerHardId"
|
||||
class="w-full"
|
||||
filterable
|
||||
:loading="loading"
|
||||
placeholder="请选择同商户同部门的空闲打印机"
|
||||
>
|
||||
<el-option
|
||||
v-for="printer in availablePrinters"
|
||||
:key="printer.id"
|
||||
:label="`${printer.name || '未命名打印机'}(ID:${printer.id})`"
|
||||
:value="String(printer.id)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<p v-if="!loading && availablePrinters.length === 0" class="text-sm text-[var(--el-text-color-secondary)]">
|
||||
当前部门没有可绑定的空闲尔印打印机资产,请先新增并分配商户部门。
|
||||
</p>
|
||||
</el-form>
|
||||
<el-form v-else ref="configFormRef" :model="configForm" :rules="configRules" label-width="150px">
|
||||
<el-alert class="mb-5" type="info" :closable="false" show-icon>
|
||||
<template #title
|
||||
>推荐在已绑定的食堂或超市终端打开“打印机信息”,点击“上报当前设备”自动回填型号、VID 和
|
||||
PID;管理端手填仅用于现场无法上报时。</template
|
||||
>
|
||||
</el-alert>
|
||||
<el-form-item prop="printerModel">
|
||||
<template #label>
|
||||
<span class="inline-flex items-center gap-1">
|
||||
打印机型号
|
||||
<el-tooltip
|
||||
content="用于运维人员识别实际 USB 打印机。优先由绑定的食堂或超市终端自动上报;手工填写示例:GEZHI / micro-printer。"
|
||||
placement="top"
|
||||
popper-class="max-w-[360px] leading-5"
|
||||
>
|
||||
<el-icon class="cursor-help text-[var(--el-text-color-secondary)]" tabindex="0" aria-label="打印机型号填写说明"
|
||||
><InfoFilled
|
||||
/></el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<el-input v-model="configForm.printerModel" placeholder="推荐由绑定的业务终端自动上报" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="usbVendorId">
|
||||
<template #label>
|
||||
<span class="inline-flex items-center gap-1">
|
||||
USB VID
|
||||
<el-tooltip
|
||||
content="USB 厂商编号,管理端填写十进制值,范围 0~65535。当前联调设备识别为 10473(十六进制 0x28E9);不确定时请勿猜测,使用终端自动上报。"
|
||||
placement="top"
|
||||
popper-class="max-w-[360px] leading-5"
|
||||
>
|
||||
<el-icon class="cursor-help text-[var(--el-text-color-secondary)]" tabindex="0" aria-label="USB VID 填写说明"
|
||||
><InfoFilled
|
||||
/></el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<el-input-number
|
||||
v-model="configForm.usbVendorId"
|
||||
:min="0"
|
||||
:max="65535"
|
||||
controls-position="right"
|
||||
class="w-full"
|
||||
placeholder="例如 10473"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="usbProductId">
|
||||
<template #label>
|
||||
<span class="inline-flex items-center gap-1">
|
||||
USB PID
|
||||
<el-tooltip
|
||||
content="USB 产品编号,管理端填写十进制值,必须与 VID 同时填写或同时留空。当前联调设备识别为 649(十六进制 0x0289);推荐使用终端自动上报。"
|
||||
placement="top"
|
||||
popper-class="max-w-[360px] leading-5"
|
||||
>
|
||||
<el-icon class="cursor-help text-[var(--el-text-color-secondary)]" tabindex="0" aria-label="USB PID 填写说明"
|
||||
><InfoFilled
|
||||
/></el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<el-input-number
|
||||
v-model="configForm.usbProductId"
|
||||
:min="0"
|
||||
:max="65535"
|
||||
controls-position="right"
|
||||
class="w-full"
|
||||
placeholder="例如 649"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="paperWidth">
|
||||
<template #label>
|
||||
<span class="inline-flex items-center gap-1">
|
||||
纸宽
|
||||
<el-tooltip
|
||||
content="首期只支持 80mm 热敏纸,对应后端图片宽度 576px。此项固定为 80,无需修改。"
|
||||
placement="top"
|
||||
popper-class="max-w-[360px] leading-5"
|
||||
>
|
||||
<el-icon class="cursor-help text-[var(--el-text-color-secondary)]" tabindex="0" aria-label="纸宽配置说明"
|
||||
><InfoFilled
|
||||
/></el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<el-input-number v-model="configForm.paperWidth" :min="80" :max="80" controls-position="right" class="w-full" />
|
||||
<span class="ml-2">mm(首期固定)</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<span class="inline-flex items-center gap-1">
|
||||
自动切刀
|
||||
<el-tooltip
|
||||
content="打印完成后发送切纸命令。打印机带自动切刀时保持开启;若型号没有切刀,或测试打印在切纸阶段报错,再关闭此项。"
|
||||
placement="top"
|
||||
popper-class="max-w-[360px] leading-5"
|
||||
>
|
||||
<el-icon class="cursor-help text-[var(--el-text-color-secondary)]" tabindex="0" aria-label="自动切刀配置说明"
|
||||
><InfoFilled
|
||||
/></el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<el-switch v-model="configForm.autoCut" active-value="1" inactive-value="0" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<span class="inline-flex items-center gap-1">
|
||||
图片指令模式
|
||||
<el-tooltip
|
||||
content="控制 PNG 图片转换成哪种 ESC/POS 指令。优先使用 GS v 0;只有真机测试出现白纸、缺行或图片不完整时,才切换 ESC * 兼容模式并重新测试。"
|
||||
placement="top"
|
||||
popper-class="max-w-[360px] leading-5"
|
||||
>
|
||||
<el-icon class="cursor-help text-[var(--el-text-color-secondary)]" tabindex="0" aria-label="图片指令模式说明"
|
||||
><InfoFilled
|
||||
/></el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<el-radio-group v-model="configForm.imageMode"
|
||||
><el-radio label="GS_V0">GS v 0(默认)</el-radio><el-radio label="ESC_STAR">ESC *(兼容回退)</el-radio></el-radio-group
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" :disabled="mode === 'bind' && availablePrinters.length === 0" @click="submit"
|
||||
>保存</el-button
|
||||
>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="HardPrinterDialog">
|
||||
import { InfoFilled } from "@element-plus/icons-vue"
|
||||
import * as printerApi from "/@/api/hard/hard-printer"
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
|
||||
const emit = defineEmits(["refresh"])
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const mode = ref<"bind" | "config">("bind")
|
||||
const sourceName = ref("")
|
||||
/** 来源业务终端雪花 ID,始终按字符串传递以保留完整精度。 */
|
||||
const sourceHardId = ref<printerApi.HardwareId | null>(null)
|
||||
/** 目标打印机资产雪花 ID,始终按字符串传递以保留完整精度。 */
|
||||
const printerHardId = ref<printerApi.HardwareId | null>(null)
|
||||
const availablePrinters = ref<any[]>([])
|
||||
const bindFormRef = ref()
|
||||
const configFormRef = ref()
|
||||
/** 当前待提交的一对一打印机绑定。 */
|
||||
const bindForm = reactive<{ printerHardId: printerApi.HardwareId | null }>({ printerHardId: null })
|
||||
const configForm = reactive<printerApi.HardPrinterConfig>({
|
||||
printerHardId: "",
|
||||
printerModel: "",
|
||||
usbVendorId: undefined,
|
||||
usbProductId: undefined,
|
||||
paperWidth: 80,
|
||||
autoCut: "1",
|
||||
imageMode: "GS_V0",
|
||||
})
|
||||
const validateUsbPair = (_rule: unknown, _value: unknown, callback: (error?: Error) => void) => {
|
||||
const hasVid = configForm.usbVendorId !== undefined && configForm.usbVendorId !== null
|
||||
const hasPid = configForm.usbProductId !== undefined && configForm.usbProductId !== null
|
||||
callback(hasVid === hasPid ? undefined : new Error("USB VID 和 PID 必须同时填写或同时留空"))
|
||||
}
|
||||
const configRules = {
|
||||
usbVendorId: [{ validator: validateUsbPair, trigger: "change" }],
|
||||
usbProductId: [{ validator: validateUsbPair, trigger: "change" }],
|
||||
paperWidth: [{ required: true, message: "纸宽必须为80mm", trigger: "change" }],
|
||||
}
|
||||
const dialogTitle = computed(() => (mode.value === "bind" ? "绑定尔印打印机" : "打印机配置"))
|
||||
|
||||
/** 恢复打印配置默认值,避免连续打开不同设备时残留上一台打印机的参数。 */
|
||||
const resetConfig = (hardId: printerApi.HardwareId) => {
|
||||
Object.assign(configForm, {
|
||||
id: undefined,
|
||||
printerHardId: hardId,
|
||||
printerModel: "",
|
||||
usbVendorId: undefined,
|
||||
usbProductId: undefined,
|
||||
paperWidth: 80,
|
||||
autoCut: "1",
|
||||
imageMode: "GS_V0",
|
||||
})
|
||||
}
|
||||
|
||||
/** 打开来源终端绑定弹窗,并使用未经过数值转换的雪花 ID 查询候选打印机。 */
|
||||
const openBind = async (row: any) => {
|
||||
mode.value = "bind"
|
||||
const hardId = String(row.id)
|
||||
sourceHardId.value = hardId
|
||||
sourceName.value = row.name || `设备 ${row.id}`
|
||||
bindForm.printerHardId = null
|
||||
visible.value = true
|
||||
loading.value = true
|
||||
try {
|
||||
const response: any = await printerApi.listAvailable(hardId)
|
||||
availablePrinters.value = response.data || []
|
||||
} catch (error: any) {
|
||||
availablePrinters.value = []
|
||||
useMessage().error(error?.msg || "读取可绑定打印机失败")
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 打开 EY_PRINT 参数弹窗,并保持目标设备雪花 ID 的字符串形态。 */
|
||||
const openConfig = async (row: any) => {
|
||||
mode.value = "config"
|
||||
const hardId = String(row.id)
|
||||
printerHardId.value = hardId
|
||||
resetConfig(hardId)
|
||||
visible.value = true
|
||||
loading.value = true
|
||||
try {
|
||||
const response: any = await printerApi.getConfig(hardId)
|
||||
Object.assign(configForm, response.data || {}, { printerHardId: hardId })
|
||||
} catch (error: any) {
|
||||
useMessage().error(error?.msg || "读取打印机配置失败")
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 校验并提交绑定或配置,设备主键保持字符串以便后端无损转换为 Long。 */
|
||||
const submit = async () => {
|
||||
const formRef = mode.value === "bind" ? bindFormRef.value : configFormRef.value
|
||||
const valid = await formRef?.validate?.().catch(() => false)
|
||||
if (valid === false) return
|
||||
loading.value = true
|
||||
try {
|
||||
if (mode.value === "bind") {
|
||||
if (!sourceHardId.value || !bindForm.printerHardId) {
|
||||
useMessage().warning("请选择尔印打印机")
|
||||
return
|
||||
}
|
||||
await printerApi.bind({ sourceHardId: sourceHardId.value, printerHardId: bindForm.printerHardId })
|
||||
useMessage().success("绑定成功,请在该业务终端的“打印机信息”页面刷新并上报 USB 设备")
|
||||
} else {
|
||||
await printerApi.saveConfig({ ...configForm, printerHardId: printerHardId.value || configForm.printerHardId })
|
||||
useMessage().success("配置保存成功")
|
||||
}
|
||||
visible.value = false
|
||||
emit("refresh")
|
||||
} catch (error: any) {
|
||||
useMessage().error(error?.msg || "保存失败")
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ openBind, openConfig })
|
||||
</script>
|
||||
Reference in new issue
Block a user