You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
besure_web/src/views/mes/printconfig/ConfigForm.vue

266 lines
8.7 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="120px"
v-loading="formLoading"
>
<el-form-item :label="t('TemplateManagement.PrintConfig.hostName')" prop="hostName">
<el-input v-model="formData.hostName" :disabled="true" :placeholder="t('TemplateManagement.PrintConfig.placeholderHostName')" />
</el-form-item>
<el-form-item :label="t('TemplateManagement.PrintConfig.systemPrinterName')" prop="systemPrinterName">
<!-- <el-input v-model="formData.systemPrinterName" :placeholder="t('TemplateManagement.PrintConfig.placeholderSystemPrinterName')" />-->
<el-select
v-model="formData.systemPrinterName"
clearable
filterable
:placeholder="t('TemplateManagement.PrintConfig.placeholderSystemPrinterName')"
class="hiprint-printer-select"
>
<el-option
v-for="printer in printerList"
:key="printer.name"
:label="printer.name"
:value="printer.name"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('TemplateManagement.PrintConfig.defaultStatus')" prop="isDefault">
<el-switch v-model="formData.isDefault" />
</el-form-item>
<el-form-item :label="t('TemplateManagement.PrintConfig.isEnable')" prop="isEnabled">
<el-switch v-model="formData.isEnable" />
</el-form-item>
<el-form-item :label="t('TemplateManagement.PrintConfig.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="t('TemplateManagement.PrintConfig.placeholderRemark')" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleClientPrint" type="primary" plain :disabled="formLoading">{{ t('TemplateManagement.PrintConfig.testPrint') }}</el-button>
<el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('common.ok') }}</el-button>
<el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ConfigApi, ConfigVO } from '@/api/mes/printconfig/index'
import {
autoConnect,
defaultElementTypeProvider,
hiwebSocket,
hiprint
} from 'vue-plugin-hiprint'
/** 打印机配置 表单 */
defineOptions({ name: 'ConfigForm' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const printerList = ref<Array<{ name: string; [key: string]: any }>>([])
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref({
id: undefined,
hostName: undefined,
systemPrinterName: undefined,
isDefault: undefined,
isEnabled: undefined,
remark: undefined,
createdAt: undefined,
updatedAt: undefined,
})
const formRules = reactive({
hostName: [{ required: false, message: '主机名如PACKING-PC-01不可修改不能为空', trigger: 'blur' }],
systemPrinterName: [{ required: true, message: '系统打印机名称,关联下拉选项不能为空', trigger: 'blur' }],
isDefault: [{ required: false, message: '是否默认0-否1-是不能为空', trigger: 'blur' }],
isEnabled: [{ required: false, message: '是否启用0-禁用1-启用不能为空', trigger: 'blur' }],
createdAt: [{ required: false, message: '创建时间不能为空', trigger: 'blur' }],
updatedAt: [{ required: false, message: '更新时间不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
let hiprintTemplate: any
const selectedPrinter = ref('')
const clientConnected = ref(false)
const clientPrinting = ref(false)
let hiprintInited = false
let printEventBound = false
let autoConnectTried = false
const clientConnecting = ref(false)
const clientHostStorageKey = 'hiprint-client-host'
const defaultClientHost = 'http://192.168.2.58:17521'
let item = localStorage.getItem(clientHostStorageKey);
const clientHost = ref(localStorage.getItem(clientHostStorageKey) || defaultClientHost)
const getHiwebSocket = () => {
return ((hiwebSocket as any) || (window as any).hiwebSocket) as any
}
const syncClientState = (printersFromCallback?: Array<{ name: string; [key: string]: any }>) => {
const socket = getHiwebSocket()
clientConnected.value = !!socket?.opened
const printers = printersFromCallback || hiprintTemplate?.getPrinterList?.() || socket?.printerList || []
printerList.value = Array.isArray(printers) ? printers : []
if (selectedPrinter.value && !printerList.value.some((printer) => printer.name === selectedPrinter.value)) {
selectedPrinter.value = ''
}
}
/** 打开弹窗 */
const open = async (type: string, host: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
formData.value.hostName = host
syncClientState()
// 修改时,设置数据
if (id) {
formLoading.value = true
try {
formData.value = await ConfigApi.getConfig(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
await formRef.value.validate()
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as ConfigVO
if (formType.value === 'create') {
await ConfigApi.createConfig(data)
message.success(t('common.createSuccess'))
} else {
await ConfigApi.updateConfig(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
// 发送操作成功的事件
emit('success')
} finally {
formLoading.value = false
}
}
const printData = ref({
orderNo: 'TEST-20231125-001',
customerName: '测试客户',
amount: 199.99,
address: '北京市朝阳区测试街道123号'
});
const handleClientPrint = () => {
if (!hiprintTemplate) {
return
}
syncClientState()
if (!clientConnected.value) {
connectClient()
message.warning('正在连接本地打印客户端,请连接成功后重试')
return
}
clientPrinting.value = true
try {
hiprintTemplate.print2(printData.value, {
printer: selectedPrinter.value,
title: dialogTitle.value
})
} catch (error: any) {
clientPrinting.value = false
message.error(error?.message || '本地客户端打印失败')
}
}
const applyClientHost = () => {
const socket = getHiwebSocket()
let host = normalizeClientHost()
clientHost.value = host
localStorage.setItem(clientHostStorageKey, host)
if (!socket) {
return false
}
if (socket?.host !== host) {
socket?.stop?.()
socket.host = host
}
return true
}
const normalizeClientHost = () => {
const host = clientHost.value.trim()
if (!host) {
return defaultClientHost
}
if (/^https?:\/\//i.test(host)) {
return host
}
return `http://${host}`
}
const refreshPrinterList = () => {
let item = localStorage.getItem(clientHostStorageKey);
message.success('本地打印客户端已连接'+item)
if (!clientConnected.value) {
applyClientHost()
message.warning('请先连接本地打印客户端')
return
}
const socket = getHiwebSocket()
if (typeof socket?.refreshPrinterList === 'function') {
socket.refreshPrinterList()
window.setTimeout(syncClientState, 500)
return
}
syncClientState()
}
const connectClient = () => {
ensureInit()
if (!applyClientHost()) {
message.warning('打印客户端连接对象未初始化,请刷新页面后重试')
return
}
clientConnecting.value = true
autoConnect((status: boolean, msg?: string) => {
clientConnecting.value = false
clientConnected.value = !!status
syncClientState()
if (status) {
message.success('本地打印客户端已连接')
refreshPrinterList()
return
}
message.warning(msg || '未连接到本地打印客户端,请确认 electron-hiprint 已启动')
})
}
const ensureInit = () => {
if (hiprintInited) {
return
}
hiprint.init({
host: normalizeClientHost(),
providers: [defaultElementTypeProvider()]
})
hiprintInited = true
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
hostName: undefined,
systemPrinterName: undefined,
isDefault: undefined,
isEnabled: undefined,
remark: undefined,
createdAt: undefined,
updatedAt: undefined,
}
formRef.value?.resetFields()
}
</script>