feat:打印模板管理-配置模板弹框添加图标组件

test
黄伟杰 2 weeks ago
parent 27d1afaa86
commit dfd2d7d829

@ -15,6 +15,16 @@ const props = defineProps({
clearable: {
require: false,
type: Boolean
},
persistent: {
require: false,
type: Boolean,
default: true
},
teleported: {
require: false,
type: Boolean,
default: true
}
})
const emit = defineEmits<{ (e: 'update:modelValue', v: string) }>()
@ -102,6 +112,10 @@ function clearIcon() {
visible.value = false
}
onBeforeUnmount(() => {
visible.value = false
})
watch(
() => {
return props.modelValue
@ -133,6 +147,8 @@ watch(
}"
:visible="visible"
:width="355"
:persistent="props.persistent"
:teleported="props.teleported"
popper-class="pure-popper"
trigger="click"
>

@ -78,6 +78,17 @@
</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>
@ -90,6 +101,7 @@
<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'
@ -101,6 +113,7 @@ 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: '横线' },
@ -109,6 +122,42 @@ const baseElements = [
{ 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[]>([])
@ -199,6 +248,45 @@ const qrcodeProvider = function () {
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)
@ -244,20 +332,111 @@ 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 ensureInit = () => {
if (hiprintInited) {
return
}
ensureIconRuntime()
hiprint.init({
providers: [new defaultElementTypeProvider(), qrcodeProvider(), barcodeProvider()]
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) {
@ -282,6 +461,7 @@ const buildDesigner = () => {
template,
settingContainer: `#${settingContainerId}`
})
bindIconCustomPanel(hiprintTemplate)
hiprintTemplate.design(`#${designerContainerId}`)
setPaper(curPaperType.value, { width: curPaper.value.width, height: curPaper.value.height })
hiprintTemplate.zoom(scaleValue.value)
@ -337,6 +517,7 @@ const clearPaper = () => {
if (!hiprintTemplate) return
try {
hiprintTemplate.clear()
setSelectedIconState(null)
} catch (error) {
message.error('清空失败')
}
@ -367,6 +548,7 @@ const handleSave = async () => {
const resetState = () => {
scaleValue.value = 1
setSelectedIconState(null)
curPaper.value = {
type: 'A4',
width: 210,
@ -393,6 +575,14 @@ const open = async (row: any) => {
const emit = defineEmits(['success'])
defineExpose({ open })
watch(selectedIconName, () => {
updateSelectedIconElement()
})
watch(selectedIconColor, () => {
updateSelectedIconElement()
})
</script>
<style scoped lang="scss">
@ -442,7 +632,7 @@ defineExpose({ open })
.hiprint-body {
height: 75vh;
display: grid;
grid-template-columns: 220px 1fr 300px;
grid-template-columns: 220px 1fr 400px;
gap: 12px;
}
@ -463,11 +653,21 @@ defineExpose({ open })
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));

Loading…
Cancel
Save