|
|
<template>
|
|
|
<Dialog v-model="dialogVisible" :title="dialogTitle" width="92%" :fullscreen="false" top="4vh">
|
|
|
<div class="hiprint-preview">
|
|
|
<div class="hiprint-toolbar">
|
|
|
<div class="hiprint-paper">
|
|
|
<el-button
|
|
|
v-for="(value, type) in paperTypes"
|
|
|
:key="type"
|
|
|
size="small"
|
|
|
:type="curPaperType === type ? 'primary' : 'default'"
|
|
|
@click="setPaper(type, value)"
|
|
|
>
|
|
|
{{ type }}
|
|
|
</el-button>
|
|
|
<el-popover placement="bottom-start" :width="260" trigger="click" v-model:visible="paperPopVisible">
|
|
|
<template #reference>
|
|
|
<el-button size="small" :type="curPaperType === 'other' ? 'primary' : 'default'">自定义纸张</el-button>
|
|
|
</template>
|
|
|
<div class="paper-pop">
|
|
|
<div class="paper-pop-title">设置纸张宽高(mm)</div>
|
|
|
<div class="paper-pop-form">
|
|
|
<el-input-number v-model="paperWidth" :precision="1" :min="1" controls-position="right" />
|
|
|
<span>x</span>
|
|
|
<el-input-number v-model="paperHeight" :precision="1" :min="1" controls-position="right" />
|
|
|
</div>
|
|
|
<el-button class="mt-8px" size="small" type="primary" @click="setPaperOther">确定</el-button>
|
|
|
</div>
|
|
|
</el-popover>
|
|
|
</div>
|
|
|
<div class="hiprint-zoom">
|
|
|
<el-button size="small" @click="changeScale(false)">
|
|
|
<Icon icon="ep:zoom-out" />
|
|
|
</el-button>
|
|
|
<div class="zoom-value">{{ (scaleValue * 100).toFixed(0) }}%</div>
|
|
|
<el-button size="small" @click="changeScale(true)">
|
|
|
<Icon icon="ep:zoom-in" />
|
|
|
</el-button>
|
|
|
</div>
|
|
|
<el-button size="small" @click="rotatePaper">
|
|
|
<Icon icon="ep:refresh-right" class="mr-4px" />
|
|
|
旋转
|
|
|
</el-button>
|
|
|
<el-button size="small" type="warning" @click="handlePreview">
|
|
|
<Icon icon="ep:view" class="mr-4px" />
|
|
|
预览
|
|
|
</el-button>
|
|
|
<el-popconfirm title="是否确认清空?" @confirm="clearPaper">
|
|
|
<template #reference>
|
|
|
<el-button size="small" type="danger">
|
|
|
<Icon icon="ep:delete" class="mr-4px" />
|
|
|
清空
|
|
|
</el-button>
|
|
|
</template>
|
|
|
</el-popconfirm>
|
|
|
<el-button type="primary" size="small" :loading="saveLoading" @click="handleSave">
|
|
|
<Icon icon="ep:check" class="mr-4px" />
|
|
|
{{ t('common.save') }}
|
|
|
</el-button>
|
|
|
</div>
|
|
|
|
|
|
<div class="hiprint-body">
|
|
|
<div class="hiprint-left">
|
|
|
<div class="hiprint-title">基础元素</div>
|
|
|
<div :id="dragContainerId" class="hiprint-drag-wrap">
|
|
|
<div v-for="item in baseElements" :key="item.tid" class="ep-draggable-item hiprint-item" :tid="item.tid">
|
|
|
<span>{{ item.label }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div v-if="barcodeElements.length" class="hiprint-title" style="margin-top: 8px">条码类型</div>
|
|
|
<div v-if="barcodeElements.length" :id="barcodeDragContainerId" class="hiprint-drag-wrap">
|
|
|
<div v-for="item in barcodeElements" :key="item.tid" class="ep-draggable-item hiprint-item" :tid="item.tid">
|
|
|
<span style="display: block; text-align: center;" v-html="item.label"></span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="hiprint-center">
|
|
|
<div :id="designerContainerId"></div>
|
|
|
</div>
|
|
|
<div class="hiprint-right">
|
|
|
<div :id="settingContainerId"></div>
|
|
|
<div v-if="selectedIconElement" class="hiprint-custom-setting">
|
|
|
<div class="hiprint-title hiprint-title-inline">图标属性</div>
|
|
|
<el-form label-position="top" size="small">
|
|
|
<el-form-item label="图标">
|
|
|
<IconSelect v-model="selectedIconName" :persistent="false" :teleported="false" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="颜色">
|
|
|
<el-color-picker v-model="selectedIconColor" show-alpha />
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<el-dialog v-model="previewVisible" title="打印预览" width="70%" top="2vh" append-to-body>
|
|
|
<div v-html="previewHtml" style="background: #fff;"></div>
|
|
|
</el-dialog>
|
|
|
</Dialog>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { defaultElementTypeProvider, hiprint } from 'vue-plugin-hiprint'
|
|
|
import Iconify from '@purge-icons/generated'
|
|
|
import { PrintTemplateApi } from '@/api/mes/printtemplate'
|
|
|
import { getSimpleDictDataList } from '@/api/system/dict/dict.data'
|
|
|
import qrCodeImg from '@/assets/imgs/qrCode.png'
|
|
|
|
|
|
const { t } = useI18n()
|
|
|
const message = useMessage()
|
|
|
|
|
|
const baseElements = [
|
|
|
{ tid: 'defaultModule.text', label: '文本' },
|
|
|
{ tid: 'defaultModule.image', label: '图片' },
|
|
|
{ tid: 'qrcodeModule.qrcode', label: '二维码' },
|
|
|
{ tid: 'iconModule.icon', label: '图标' },
|
|
|
{ tid: 'defaultModule.longText', label: '长文' },
|
|
|
{ tid: 'defaultModule.table', label: '表格' },
|
|
|
{ tid: 'defaultModule.hline', label: '横线' },
|
|
|
{ tid: 'defaultModule.vline', label: '竖线' },
|
|
|
{ tid: 'defaultModule.rect', label: '矩形' },
|
|
|
{ tid: 'defaultModule.oval', label: '圆形' }
|
|
|
]
|
|
|
|
|
|
const defaultIconName = 'ep:star-filled'
|
|
|
const defaultIconColor = '#409EFF'
|
|
|
|
|
|
const buildIconHtml = (iconName?: string, color?: string) => {
|
|
|
const finalIconName = iconName || defaultIconName
|
|
|
const finalColor = color || defaultIconColor
|
|
|
const svg = Iconify.renderSVG(finalIconName, {
|
|
|
height: '100%',
|
|
|
width: '100%'
|
|
|
})
|
|
|
if (svg) {
|
|
|
svg.setAttribute('color', finalColor)
|
|
|
svg.style.color = finalColor
|
|
|
svg.style.display = 'block'
|
|
|
svg.style.width = '100%'
|
|
|
svg.style.height = '100%'
|
|
|
return svg.outerHTML
|
|
|
}
|
|
|
return `<span class="iconify" data-icon="${finalIconName}" data-width="100%" data-height="100%" style="display:inline-block;width:100%;height:100%;color:${finalColor};"></span>`
|
|
|
}
|
|
|
|
|
|
const buildIconFormatter = () => {
|
|
|
return `function(value, options) {
|
|
|
const iconName = options.iconName || '${defaultIconName}';
|
|
|
const color = options.color || '${defaultIconColor}';
|
|
|
if (window.__hiprintBuildIconHtml) {
|
|
|
return window.__hiprintBuildIconHtml(iconName, color);
|
|
|
}
|
|
|
return '<span class="iconify" data-icon="' + iconName + '" data-width="100%" data-height="100%" style="display:inline-block;width:100%;height:100%;color:' + color + ';"></span>';
|
|
|
}`
|
|
|
}
|
|
|
|
|
|
const ensureIconRuntime = () => {
|
|
|
;(window as any).__hiprintBuildIconHtml = buildIconHtml
|
|
|
}
|
|
|
|
|
|
const barcodeElements = ref<{ tid: string; label: string }[]>([])
|
|
|
const barcodeDictData = ref<any[]>([])
|
|
|
|
|
|
const loadBarcodeDictData = async () => {
|
|
|
try {
|
|
|
const res = await getSimpleDictDataList()
|
|
|
const filtered = (res || []).filter((item: any) => item.dictType === 'print_template_type')
|
|
|
barcodeDictData.value = filtered
|
|
|
const elements: { tid: string; label: string }[] = []
|
|
|
filtered.forEach((item: any) => {
|
|
|
elements.push({ tid: `barcodeModule.${item.value}_qrcode`, label: `${item.label}<br/>二维码` })
|
|
|
elements.push({ tid: `barcodeModule.${item.value}_text`, label: `${item.label}<br/>文本` })
|
|
|
})
|
|
|
barcodeElements.value = elements
|
|
|
} catch (e) {
|
|
|
console.error('加载条码字典数据失败', e)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const barcodeProvider = function () {
|
|
|
const addElementTypes = function (context: any) {
|
|
|
context.removePrintElementTypes('barcodeModule')
|
|
|
if (!barcodeDictData.value.length) return
|
|
|
const groups: any[] = []
|
|
|
barcodeDictData.value.forEach((item: any) => {
|
|
|
const remark = item.remark || ''
|
|
|
const parts = remark.split(',').map((s: string) => s.trim())
|
|
|
const qrcodeField = parts[0] || ''
|
|
|
const textField = parts[1] || ''
|
|
|
groups.push(
|
|
|
new hiprint.PrintElementTypeGroup(item.label, [
|
|
|
{
|
|
|
tid: `barcodeModule.${item.value}_qrcode`,
|
|
|
title: `${item.label}`,
|
|
|
type: 'image',
|
|
|
options: {
|
|
|
field: qrcodeField,
|
|
|
src: qrCodeImg,
|
|
|
testData: qrCodeImg,
|
|
|
width: 80,
|
|
|
height: 80,
|
|
|
title: `${item.label}<br/>二维码`
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
tid: `barcodeModule.${item.value}_text`,
|
|
|
title: `${item.label}`,
|
|
|
type: 'text',
|
|
|
options: {
|
|
|
field: textField,
|
|
|
testData: '',
|
|
|
title: `${item.label}<br/>文本`,
|
|
|
fontSize: 10,
|
|
|
textAlign: 'center',
|
|
|
width: 80,
|
|
|
height: 16
|
|
|
}
|
|
|
}
|
|
|
])
|
|
|
)
|
|
|
})
|
|
|
context.addPrintElementTypes('barcodeModule', groups)
|
|
|
}
|
|
|
return { addElementTypes }
|
|
|
}
|
|
|
|
|
|
const qrcodeProvider = function () {
|
|
|
const addElementTypes = function (context: any) {
|
|
|
context.removePrintElementTypes('qrcodeModule')
|
|
|
context.addPrintElementTypes('qrcodeModule', [
|
|
|
new hiprint.PrintElementTypeGroup('二维码', [
|
|
|
{
|
|
|
tid: 'qrcodeModule.qrcode',
|
|
|
title: '二维码',
|
|
|
type: 'image',
|
|
|
options: {
|
|
|
field: '',
|
|
|
src: qrCodeImg,
|
|
|
testData: qrCodeImg,
|
|
|
width: 80,
|
|
|
height: 80,
|
|
|
title: '二维码'
|
|
|
}
|
|
|
}
|
|
|
])
|
|
|
])
|
|
|
}
|
|
|
return { addElementTypes }
|
|
|
}
|
|
|
|
|
|
const iconProvider = function () {
|
|
|
const addElementTypes = function (context: any) {
|
|
|
context.removePrintElementTypes('iconModule')
|
|
|
context.addPrintElementTypes('iconModule', [
|
|
|
new hiprint.PrintElementTypeGroup('图标', [
|
|
|
{
|
|
|
tid: 'iconModule.icon',
|
|
|
title: '图标',
|
|
|
type: 'html',
|
|
|
options: {
|
|
|
left: 12,
|
|
|
top: 12,
|
|
|
width: 28,
|
|
|
height: 28,
|
|
|
iconName: defaultIconName,
|
|
|
color: defaultIconColor,
|
|
|
formatter: buildIconFormatter()
|
|
|
},
|
|
|
onRendered: function (target: any) {
|
|
|
const iconify = (window as any).Iconify
|
|
|
if (iconify?.scan) {
|
|
|
iconify.scan(target?.[0] || target)
|
|
|
}
|
|
|
},
|
|
|
supportOptions: [
|
|
|
{ name: 'iconName' },
|
|
|
{ name: 'color' },
|
|
|
{ name: 'widthHeight' },
|
|
|
{ name: 'coordinate' },
|
|
|
{ name: 'transform' },
|
|
|
{ name: 'zIndex' }
|
|
|
]
|
|
|
}
|
|
|
])
|
|
|
])
|
|
|
}
|
|
|
return { addElementTypes }
|
|
|
}
|
|
|
|
|
|
const dialogVisible = ref(false)
|
|
|
const dialogTitle = ref('模板配置')
|
|
|
const saveLoading = ref(false)
|
|
|
const currentRow = ref<any>(null)
|
|
|
const currentTemplateJson = ref<Record<string, any> | undefined>(undefined)
|
|
|
|
|
|
const instanceId = `hiprint-designer-${Math.random().toString(36).slice(2)}`
|
|
|
const dragContainerId = `${instanceId}-drag`
|
|
|
const barcodeDragContainerId = `${instanceId}-barcode-drag`
|
|
|
const designerContainerId = `${instanceId}-designer`
|
|
|
const settingContainerId = `${instanceId}-setting`
|
|
|
|
|
|
const paperTypes = {
|
|
|
A3: { width: 420, height: 296.6 },
|
|
|
A4: { width: 210, height: 296.6 },
|
|
|
A5: { width: 210, height: 147.6 },
|
|
|
B3: { width: 500, height: 352.6 },
|
|
|
B4: { width: 250, height: 352.6 },
|
|
|
B5: { width: 250, height: 175.6 }
|
|
|
}
|
|
|
const defaultPaperConfig = {
|
|
|
type: 'A4',
|
|
|
width: 210,
|
|
|
height: 296.6
|
|
|
}
|
|
|
const curPaper = ref({
|
|
|
...defaultPaperConfig
|
|
|
})
|
|
|
const paperPopVisible = ref(false)
|
|
|
const paperWidth = ref(220)
|
|
|
const paperHeight = ref(80)
|
|
|
const curPaperType = computed(() => {
|
|
|
let type = 'other'
|
|
|
for (const [key, value] of Object.entries(paperTypes)) {
|
|
|
if (value.width === curPaper.value.width && value.height === curPaper.value.height) {
|
|
|
type = key
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
return type
|
|
|
})
|
|
|
|
|
|
const scaleValue = ref(1)
|
|
|
const scaleMax = 5
|
|
|
const scaleMin = 0.5
|
|
|
|
|
|
const previewVisible = ref(false)
|
|
|
const previewHtml = ref('')
|
|
|
const selectedIconElement = shallowRef<any>(null)
|
|
|
const selectedIconName = ref(defaultIconName)
|
|
|
const selectedIconColor = ref(defaultIconColor)
|
|
|
|
|
|
let hiprintInited = false
|
|
|
let hiprintTemplate: any
|
|
|
let iconSelectEventKey = ''
|
|
|
let iconSelectHandler: ((payload: any) => void) | undefined
|
|
|
let clearSettingHandler: (() => void) | undefined
|
|
|
|
|
|
const normalizePaperConfig = (value: any) => {
|
|
|
const width = Number(value?.width)
|
|
|
const height = Number(value?.height)
|
|
|
if (width <= 0 || height <= 0 || Number.isNaN(width) || Number.isNaN(height)) {
|
|
|
return { ...defaultPaperConfig }
|
|
|
}
|
|
|
return {
|
|
|
type: typeof value?.type === 'string' && value.type ? value.type : 'other',
|
|
|
width,
|
|
|
height
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const applyPaperConfig = (value: any) => {
|
|
|
const paper = normalizePaperConfig(value)
|
|
|
curPaper.value = paper
|
|
|
paperWidth.value = paper.width
|
|
|
paperHeight.value = paper.height
|
|
|
}
|
|
|
|
|
|
const getTemplatePaperConfig = (value: any) => {
|
|
|
const panel = Array.isArray(value?.panels) ? value.panels[0] : undefined
|
|
|
return panel
|
|
|
}
|
|
|
|
|
|
const ensureInit = () => {
|
|
|
if (hiprintInited) {
|
|
|
return
|
|
|
}
|
|
|
ensureIconRuntime()
|
|
|
hiprint.init({
|
|
|
providers: [new defaultElementTypeProvider(), qrcodeProvider(), barcodeProvider(), iconProvider()]
|
|
|
})
|
|
|
hiprintInited = true
|
|
|
}
|
|
|
|
|
|
const isIconPrintElement = (printElement: any) => {
|
|
|
if (!printElement) {
|
|
|
return false
|
|
|
}
|
|
|
if (printElement?.printElementType?.tid === 'iconModule.icon') {
|
|
|
return true
|
|
|
}
|
|
|
const formatter = String(printElement?.options?.formatter || printElement?.printElementType?.formatter || '')
|
|
|
return Boolean(
|
|
|
printElement?.printElementType?.type === 'html'
|
|
|
&& (
|
|
|
typeof printElement?.options?.iconName === 'string'
|
|
|
|| formatter.includes('__hiprintBuildIconHtml')
|
|
|
)
|
|
|
)
|
|
|
}
|
|
|
|
|
|
const normalizeIconPrintElement = (printElement: any) => {
|
|
|
if (!printElement?.options) {
|
|
|
return printElement
|
|
|
}
|
|
|
if (!printElement.options.iconName) {
|
|
|
printElement.options.iconName = defaultIconName
|
|
|
}
|
|
|
if (!printElement.options.color) {
|
|
|
printElement.options.color = defaultIconColor
|
|
|
}
|
|
|
if (!printElement.options.formatter) {
|
|
|
printElement.options.formatter = buildIconFormatter()
|
|
|
}
|
|
|
return printElement
|
|
|
}
|
|
|
|
|
|
const setSelectedIconState = (printElement: any | null) => {
|
|
|
const normalizedPrintElement = printElement ? normalizeIconPrintElement(printElement) : null
|
|
|
selectedIconElement.value = normalizedPrintElement
|
|
|
selectedIconName.value = normalizedPrintElement?.options?.iconName || defaultIconName
|
|
|
selectedIconColor.value = normalizedPrintElement?.options?.color || defaultIconColor
|
|
|
}
|
|
|
|
|
|
const updateSelectedIconElement = () => {
|
|
|
const printElement = selectedIconElement.value
|
|
|
if (!printElement) {
|
|
|
return
|
|
|
}
|
|
|
printElement.options.iconName = selectedIconName.value || defaultIconName
|
|
|
printElement.options.color = selectedIconColor.value || defaultIconColor
|
|
|
printElement.updateDesignViewFromOptions()
|
|
|
const iconify = (window as any).Iconify
|
|
|
if (iconify?.scan) {
|
|
|
iconify.scan(printElement.designTarget?.[0] || printElement.designTarget)
|
|
|
}
|
|
|
;(window as any).hinnn?.event?.trigger(`hiprintTemplateDataChanged_${printElement.templateId}`, '元素修改')
|
|
|
}
|
|
|
|
|
|
const bindIconCustomPanel = (template: any) => {
|
|
|
const event = (window as any).hinnn?.event
|
|
|
if (!event) {
|
|
|
return
|
|
|
}
|
|
|
if (iconSelectEventKey && iconSelectHandler) {
|
|
|
event.off(iconSelectEventKey, iconSelectHandler)
|
|
|
}
|
|
|
if (clearSettingHandler) {
|
|
|
event.off('clearSettingContainer', clearSettingHandler)
|
|
|
}
|
|
|
iconSelectEventKey = template?.getPrintElementSelectEventKey?.() || ''
|
|
|
iconSelectHandler = (payload: any) => {
|
|
|
const printElement = payload?.printElement
|
|
|
if (isIconPrintElement(printElement)) {
|
|
|
setSelectedIconState(printElement)
|
|
|
return
|
|
|
}
|
|
|
setSelectedIconState(null)
|
|
|
}
|
|
|
clearSettingHandler = () => {
|
|
|
setSelectedIconState(null)
|
|
|
}
|
|
|
if (iconSelectEventKey) {
|
|
|
event.on(iconSelectEventKey, iconSelectHandler)
|
|
|
}
|
|
|
event.on('clearSettingContainer', clearSettingHandler)
|
|
|
}
|
|
|
|
|
|
const buildLeftElement = () => {
|
|
|
const jquery = (window as any).$
|
|
|
if (!jquery) {
|
|
|
message.warning('未检测到 jQuery,无法加载拖拽元素')
|
|
|
return
|
|
|
}
|
|
|
hiprint.PrintElementTypeManager.buildByHtml(jquery(`#${dragContainerId} .ep-draggable-item`))
|
|
|
if (barcodeElements.value.length) {
|
|
|
hiprint.PrintElementTypeManager.buildByHtml(jquery(`#${barcodeDragContainerId} .ep-draggable-item`))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const buildDesigner = () => {
|
|
|
const jquery = (window as any).$
|
|
|
if (!jquery) {
|
|
|
message.warning('未检测到 jQuery,无法初始化打印设计器')
|
|
|
return
|
|
|
}
|
|
|
jquery(`#${designerContainerId}`).empty()
|
|
|
const template = currentTemplateJson.value || undefined
|
|
|
hiprintTemplate = new hiprint.PrintTemplate({
|
|
|
template,
|
|
|
settingContainer: `#${settingContainerId}`
|
|
|
})
|
|
|
bindIconCustomPanel(hiprintTemplate)
|
|
|
hiprintTemplate.design(`#${designerContainerId}`)
|
|
|
setPaper(curPaperType.value, { width: curPaper.value.width, height: curPaper.value.height })
|
|
|
hiprintTemplate.zoom(scaleValue.value)
|
|
|
}
|
|
|
|
|
|
const setPaper = (type: string, value: { width: number; height: number }) => {
|
|
|
if (!hiprintTemplate) {
|
|
|
return
|
|
|
}
|
|
|
const width = Number(value.width)
|
|
|
const height = Number(value.height)
|
|
|
curPaper.value = { type, width, height }
|
|
|
hiprintTemplate.setPaper(width, height)
|
|
|
}
|
|
|
|
|
|
const setPaperOther = () => {
|
|
|
paperPopVisible.value = false
|
|
|
setPaper('other', { width: Number(paperWidth.value), height: Number(paperHeight.value) })
|
|
|
}
|
|
|
|
|
|
const changeScale = (isZoomIn: boolean) => {
|
|
|
if (!hiprintTemplate) {
|
|
|
return
|
|
|
}
|
|
|
let nextScale = scaleValue.value
|
|
|
if (isZoomIn) {
|
|
|
nextScale += 0.1
|
|
|
if (nextScale > scaleMax) nextScale = scaleMax
|
|
|
} else {
|
|
|
nextScale -= 0.1
|
|
|
if (nextScale < scaleMin) nextScale = scaleMin
|
|
|
}
|
|
|
scaleValue.value = nextScale
|
|
|
hiprintTemplate.zoom(nextScale)
|
|
|
}
|
|
|
|
|
|
const rotatePaper = () => {
|
|
|
if (!hiprintTemplate) return
|
|
|
hiprintTemplate.rotatePaper()
|
|
|
}
|
|
|
|
|
|
const handlePreview = () => {
|
|
|
if (!hiprintTemplate) return
|
|
|
const jquery = (window as any).$
|
|
|
const htmlResult = hiprintTemplate.getHtml({})
|
|
|
if (htmlResult && jquery) {
|
|
|
previewHtml.value = jquery('<div>').append(htmlResult).html() || ''
|
|
|
}
|
|
|
previewVisible.value = true
|
|
|
}
|
|
|
|
|
|
const clearPaper = () => {
|
|
|
if (!hiprintTemplate) return
|
|
|
try {
|
|
|
hiprintTemplate.clear()
|
|
|
setSelectedIconState(null)
|
|
|
} catch (error) {
|
|
|
message.error('清空失败')
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const handleSave = async () => {
|
|
|
if (!hiprintTemplate) {
|
|
|
return
|
|
|
}
|
|
|
const templateJson = hiprintTemplate.getJson()
|
|
|
saveLoading.value = true
|
|
|
try {
|
|
|
await PrintTemplateApi.updatePrintTemplate({
|
|
|
id: currentRow.value.id,
|
|
|
templateCode: currentRow.value.templateCode,
|
|
|
templateName: currentRow.value.templateName,
|
|
|
templateType: currentRow.value.templateType,
|
|
|
templateBizType: currentRow.value.templateBizType ?? 1,
|
|
|
templateJson: JSON.stringify(templateJson),
|
|
|
} as any)
|
|
|
message.success(t('common.updateSuccess'))
|
|
|
dialogVisible.value = false
|
|
|
emit('success')
|
|
|
} finally {
|
|
|
saveLoading.value = false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const resetState = () => {
|
|
|
scaleValue.value = 1
|
|
|
setSelectedIconState(null)
|
|
|
applyPaperConfig(defaultPaperConfig)
|
|
|
paperPopVisible.value = false
|
|
|
}
|
|
|
|
|
|
const open = async (row: any) => {
|
|
|
currentRow.value = row
|
|
|
dialogTitle.value = `${t('TemplateManagement.PrintTemplate.designTitle')}${row.templateName ? ' - ' + row.templateName : ''}`
|
|
|
currentTemplateJson.value = row.templateJson ? (typeof row.templateJson === 'string' ? JSON.parse(row.templateJson) : row.templateJson) : undefined
|
|
|
resetState()
|
|
|
applyPaperConfig(getTemplatePaperConfig(currentTemplateJson.value))
|
|
|
await loadBarcodeDictData()
|
|
|
dialogVisible.value = true
|
|
|
await nextTick()
|
|
|
ensureInit()
|
|
|
buildLeftElement()
|
|
|
buildDesigner()
|
|
|
}
|
|
|
|
|
|
const emit = defineEmits(['success'])
|
|
|
|
|
|
defineExpose({ open })
|
|
|
|
|
|
watch(selectedIconName, () => {
|
|
|
updateSelectedIconElement()
|
|
|
})
|
|
|
|
|
|
watch(selectedIconColor, () => {
|
|
|
updateSelectedIconElement()
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
.hiprint-preview {
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
.hiprint-toolbar {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 12px;
|
|
|
margin-bottom: 12px;
|
|
|
}
|
|
|
|
|
|
.hiprint-paper {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 6px;
|
|
|
flex-wrap: wrap;
|
|
|
}
|
|
|
|
|
|
.hiprint-zoom {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 4px;
|
|
|
}
|
|
|
|
|
|
.zoom-value {
|
|
|
width: 56px;
|
|
|
text-align: center;
|
|
|
font-size: 13px;
|
|
|
color: var(--el-text-color-regular);
|
|
|
}
|
|
|
|
|
|
.paper-pop-title {
|
|
|
font-size: 14px;
|
|
|
font-weight: 600;
|
|
|
}
|
|
|
|
|
|
.paper-pop-form {
|
|
|
margin-top: 8px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 8px;
|
|
|
}
|
|
|
|
|
|
.hiprint-body {
|
|
|
height: 75vh;
|
|
|
display: grid;
|
|
|
grid-template-columns: 220px 1fr 400px;
|
|
|
gap: 12px;
|
|
|
}
|
|
|
|
|
|
.hiprint-left,
|
|
|
.hiprint-center,
|
|
|
.hiprint-right {
|
|
|
background: var(--el-bg-color);
|
|
|
border: 1px solid var(--el-border-color-light);
|
|
|
border-radius: 8px;
|
|
|
overflow: auto;
|
|
|
}
|
|
|
|
|
|
.hiprint-center {
|
|
|
padding: 16px;
|
|
|
}
|
|
|
|
|
|
.hiprint-right {
|
|
|
padding: 12px;
|
|
|
}
|
|
|
|
|
|
.hiprint-custom-setting {
|
|
|
margin-top: 12px;
|
|
|
border-top: 1px solid var(--el-border-color-light);
|
|
|
padding-top: 12px;
|
|
|
}
|
|
|
|
|
|
.hiprint-title {
|
|
|
padding: 10px 10px 0;
|
|
|
font-weight: 600;
|
|
|
}
|
|
|
|
|
|
.hiprint-title-inline {
|
|
|
padding: 0 0 12px;
|
|
|
}
|
|
|
|
|
|
.hiprint-drag-wrap {
|
|
|
display: grid;
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
gap: 10px;
|
|
|
padding: 10px;
|
|
|
}
|
|
|
|
|
|
.hiprint-item {
|
|
|
min-height: 56px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
border-radius: 6px;
|
|
|
border: 1px solid var(--el-border-color);
|
|
|
background: var(--el-fill-color-light);
|
|
|
color: var(--el-text-color-primary);
|
|
|
cursor: grab;
|
|
|
}
|
|
|
</style>
|