diff --git a/src/utils/zplGenerator.js b/src/utils/zplGenerator.js index df68758..7f1db20 100644 --- a/src/utils/zplGenerator.js +++ b/src/utils/zplGenerator.js @@ -101,6 +101,8 @@ export class ZPLGenerator { return this.generateHorizontalLineZPL(element, x, y) case 'vLine': return this.generateVerticalLineZPL(element, x, y) + case 'serialNumber': + return this.generateSerialNumberZPL(element, x, y) default: return '' } @@ -201,6 +203,24 @@ export class ZPLGenerator { return `^FO${x},${y}^GB1,${element.height},${element.width},B^FS` } } + + /** + * 生成流水号ZPL代码 + */ + generateSerialNumberZPL(element, x, y) { + const zpl = [] + const bold = element.bold || false // 加粗(可选) + const serialStr = '流水号' + const base = `^FO${x},${y}^FD${element.data}^FS` + zpl.push(base) + // 可选:加粗效果(重复打印) + if (bold) { + zpl.push(`^FO${x+1},${y}^FD${serialStr}^FS`) + zpl.push(`^FO${x},${y+1}^FD${serialStr}^FS`) + zpl.push(`^FO${x+1},${y+1}^FD${serialStr}^FS`) + } + return zpl.join('\n') + } } /** diff --git a/src/views/modules/labelSetting/LabelDesigner.vue b/src/views/modules/labelSetting/LabelDesigner.vue index 4a23925..0d54487 100644 --- a/src/views/modules/labelSetting/LabelDesigner.vue +++ b/src/views/modules/labelSetting/LabelDesigner.vue @@ -133,6 +133,7 @@ :visible="dataSourceVisible" :data-keys="dataKeys" :current-text="currentElementText" + :source-type="sourceType" @update:visible="dataSourceVisible = $event" @confirm="handleDataSourceConfirm" /> @@ -172,6 +173,7 @@ export default { }, data() { return { + sourceType: 'text', // 数据源类型,默认为文本 labelNo: '', showGrid: true, snapToGrid: true, @@ -440,6 +442,8 @@ export default { }, handleDrop(dropData) { + console.log('主设计器接收到拖拽数据:', dropData) // 调试信息 + if (!this.labelNo) { this.$alert('标签编号不可为空!', '错误', { confirmButtonText: '确定' @@ -448,10 +452,17 @@ export default { } const newElement = this.createNewElement(dropData) + console.log('创建的新元素:', newElement) // 调试信息 + this.elements.push(newElement) + + // 自动选中新添加的元素 + this.selectedIndex = this.elements.length - 1 }, createNewElement({ type, x, y }) { + console.log('创建新元素:', { type, x, y }) // 调试信息 + const baseElement = { type, x, @@ -461,24 +472,65 @@ export default { bold: false, newline: false, lineRows: 2, - lineWidth: 200 + lineWidth: 200, + digits: 6, + step: 1, } - // 根据类型设置默认尺寸 + // 根据类型设置默认尺寸和特殊属性 const sizeConfig = { - text: { width: 100, height: 30 }, - barcode: { width: 3, height: 50 }, - onecode: { width: 3, height: 50 }, - qrcode: { width: 10, height: 10 }, - pic: { width: 100, height: 100 }, - hLine: { width: 400, height: 3 }, - vLine: { width: 3, height: 400 } + text: { + width: 100, + height: 30, + data: '文本元素' + }, + barcode: { + width: 3, + height: 50, + data: '123456789' + }, + onecode: { + width: 3, + height: 50, + data: '123456789' + }, + qrcode: { + width: 10, + height: 10, + data: 'QR Code' + }, + pic: { + width: 100, + height: 100 + }, + hLine: { + width: 400, + height: 3 + }, + vLine: { + width: 3, + height: 400 + }, + serialNumber: { + width: 120, + height: 30, + digits: 6, + step: 1, + data: '流水号', // 默认显示值 + fontSize: 30 + } } - return { + const config = sizeConfig[type] || { width: 100, height: 30 } + + const newElement = { ...baseElement, - ...sizeConfig[type] + ...config } + + console.log('新元素配置:', newElement) // 调试信息 + + return newElement }, handleElementSelect(index) { @@ -639,7 +691,7 @@ export default { // 预览逻辑由PropertyPanel处理 }, - async handleDataSource(currentText) { + async handleDataSource(inData) { const response = await getViewFieldsByLabelType({ labelType: this.labelSettings.labelType, site: this.$store.state.user.site @@ -650,42 +702,18 @@ export default { ...field, fieldDescription: field.fieldDescription || '' })); - this.currentElementText = currentText || '' + this.currentElementText = inData.data || '' + this.sourceType = inData.type || 'text' this.dataSourceVisible = true } else { this.$message.error(response.data.msg || '获取字段信息失败'); } - - /* if (this.elements.length > 0) { - this.dataKeys = Object.keys(this.elements[0]) - this.currentElementText = currentText || '' - this.dataSourceVisible = true - }*/ - }, - - async loadViewFields() { - try { - const response = await getViewFieldsByLabelType({ - labelType: this.labelSettings.labelType, - site: this.$store.state.user.site - }); - - if (response.data && response.data.code === 200) { - this.viewFields = response.data.data.map(field => ({ - ...field, - fieldDescription: field.fieldDescription || '' - })); - } else { - this.$message.error(response.data.msg || '获取字段信息失败'); - } - } catch (error) { - console.error('获取字段信息失败:', error); - } }, - handleDataSourceConfirm(selectedKeys) { + handleDataSourceConfirm(selectedKeys, sourceType) { if (this.selectedElement) { - this.selectedElement.data = selectedKeys.map(key => `#{${key}}`).join('') + this.selectedElement.data = sourceType==='serialNumber'?selectedKeys.map(key => `${key}`).join('+'): + selectedKeys.map(key => `#{${key}}`).join('') } }, diff --git a/src/views/modules/labelSetting/components/DataSourceDialog.vue b/src/views/modules/labelSetting/components/DataSourceDialog.vue index a7757a6..c8b4f0f 100644 --- a/src/views/modules/labelSetting/components/DataSourceDialog.vue +++ b/src/views/modules/labelSetting/components/DataSourceDialog.vue @@ -47,6 +47,10 @@ export default { currentText: { type: String, default: '' + }, + sourceType: { + type: String, + default: 'text' // 默认是文本类型 } }, emits: ['update:visible', 'confirm'], @@ -81,7 +85,17 @@ export default { foundKeys.push(key.fieldName) } }) + if (this.sourceType==='serialNumber'){ + this.dataKeys.forEach(key => { + // 构建字段匹配的正则,确保全字匹配 + const pattern = new RegExp(`\\b${key.fieldName}\\b`, 'g') + if (pattern.test(this.currentText)) { + foundKeys.push(key.fieldName) + } + }) + + } this.selectedKeys = foundKeys }, @@ -90,7 +104,7 @@ export default { }, handleConfirm() { - this.$emit('confirm', this.selectedKeys) + this.$emit('confirm', this.selectedKeys, this.sourceType) this.handleClose() } } diff --git a/src/views/modules/labelSetting/components/DesignCanvas.vue b/src/views/modules/labelSetting/components/DesignCanvas.vue index 99f8d71..fb7e1f9 100644 --- a/src/views/modules/labelSetting/components/DesignCanvas.vue +++ b/src/views/modules/labelSetting/components/DesignCanvas.vue @@ -3,7 +3,8 @@ class="design-canvas" :class="{ 'show-grid': showGrid }" :style="canvasStyle" - @dragover.prevent + @dragover="handleDragOver" + @dragenter="handleDragEnter" @drop="handleDrop" > @@ -134,14 +135,35 @@ export default { } }, methods: { + handleDragOver(e) { + e.preventDefault() + e.stopPropagation() + e.dataTransfer.dropEffect = 'copy' + }, + + handleDragEnter(e) { + e.preventDefault() + e.stopPropagation() + }, + handleDrop(e) { - const type = e.dataTransfer.getData('type') - if (!type) return + e.preventDefault() + e.stopPropagation() + + const type = e.dataTransfer.getData('type') || e.dataTransfer.getData('text/plain') + console.log('画布接收到拖拽类型:', type) // 调试信息 + + if (!type) { + console.warn('未获取到拖拽类型数据') + return + } const rect = e.currentTarget.getBoundingClientRect() const x = e.clientX - rect.left const y = e.clientY - rect.top + console.log('拖拽位置:', { x, y }) // 调试信息 + this.$emit('drop', { type, x, y }) }, @@ -335,6 +357,19 @@ export default { } } + // 对于流水号元素 + if (element.type === 'serialNumber') { + const fontSize = element.fontSize || 30 + const prefix = element.prefix || '' + const digits = parseInt(element.digits) || 6 + const estimatedWidth = Math.max((prefix.length + digits) * (fontSize * 0.6), 80) + + return { + width: Math.min(estimatedWidth + 16, 200), // 加上padding,限制最大宽度 + height: Math.max(fontSize + 8, 30) // 加上padding,最小高度30px + } + } + return baseSize } } diff --git a/src/views/modules/labelSetting/components/DesignElement.vue b/src/views/modules/labelSetting/components/DesignElement.vue index 0e572c6..2780235 100644 --- a/src/views/modules/labelSetting/components/DesignElement.vue +++ b/src/views/modules/labelSetting/components/DesignElement.vue @@ -78,6 +78,12 @@ }" > + + +