Browse Source

去掉条码;打勾;宽高转换

master
han\hanst 7 months ago
parent
commit
71a5e76478
  1. 38
      src/components/print/PrintService.vue
  2. 143
      src/utils/zplGenerator.js
  3. 56
      src/utils/zplUtil.js
  4. 59
      src/utils/zplUtil2.js
  5. 42
      src/views/modules/labelSetting/LabelDesigner.vue
  6. 6
      src/views/modules/labelSetting/components/DesignCanvas.vue
  7. 13
      src/views/modules/labelSetting/components/DesignElement.vue
  8. 7
      src/views/modules/labelSetting/components/HorizontalToolbar.vue
  9. 191
      src/views/modules/labelSetting/components/PropertyForm.vue
  10. 2
      src/views/modules/labelSetting/components/PropertyPanel.vue
  11. 2
      src/views/modules/labelSetting/components/ZPLPreview.vue
  12. 3
      src/views/modules/labelSetting/label_setting.vue

38
src/components/print/PrintService.vue

@ -77,12 +77,14 @@
<div class="form-item">
<label class="form-label">打印份数:</label>
<el-input
v-model.number="printCopies"
v-model="printCopies"
:min="1"
:max="1"
:max="10"
size="mini"
style="width: 100%;"
controls-position="right"
/>
<div class="form-hint">支持1-10份打印RFID标签将逐张处理</div>
</div>
</div>
@ -303,22 +305,6 @@ export default {
* 直接网络打印
*/
async printToNetworkPrinter(printerIP) {
/*this.printLoading = true
this.$emit('print-start')
try {
} catch (error) {
console.error('网络打印失败:', error)
this.$message.error(`网络打印失败: ${error.message}`)
this.$emit('print-error', error)
} finally {
this.printLoading = false
this.$emit('print-end')
}*/
//
//this.$emit('print-start')
await fetch(`http://${printerIP}:9100`, {
method: 'POST',
headers: {
@ -328,15 +314,6 @@ export default {
mode: 'no-cors'
})
this.$message.success(`打印任务已发送到 ${printerIP}`)
//this.$emit('print-success', { printerIP })
console.log('网络打印成功:', {
printerIP,
zplCode: this.zplCode,
paperSize: this.paperSize,
orientation: this.orientation,
dpi: this.dpi
})
//this.$emit('print-end')
}
}
}
@ -511,6 +488,13 @@ export default {
line-height: 1.4;
}
.form-hint {
margin-top: 6px;
font-size: 12px;
color: #909399;
line-height: 1.4;
}
/* 响应式设计 */
@media (max-width: 600px) {
.print-method {

143
src/utils/zplGenerator.js

@ -5,11 +5,12 @@ import { CoordinateTransformer } from './coordinateTransform.js'
* 统一处理不同打印方向的ZPL代码生成
*/
export class ZPLGenerator {
constructor(orientation = 'portrait', paperType = '60x40', customSize = null, paperId = null) {
constructor(orientation = 'portrait', paperType = '60x40', customSize = null, paperId = null, dpi = 300) {
this.orientation = orientation
this.paperType = paperType
this.customSize = customSize
this.paperId = paperId // 新增纸张ID支持
this.dpi = dpi // 新增DPI支持
this.transformer = new CoordinateTransformer(orientation, paperType, customSize, paperId)
this.config = this.getConfig()
}
@ -32,6 +33,13 @@ export class ZPLGenerator {
this.transformer.updatePaperId(paperId)
}
/**
* 更新DPI新增方法
*/
updateDPI(dpi) {
this.dpi = dpi
}
/**
* 获取配置参数
*/
@ -89,8 +97,6 @@ export class ZPLGenerator {
switch (element.type) {
case 'text':
return this.generateTextZPL(element, x, y)
case 'barcode':
return this.generateBarcodeZPL(element, x, y)
case 'onecode':
return this.generateOnecodeZPL(element, x, y)
case 'qrcode':
@ -113,10 +119,11 @@ export class ZPLGenerator {
*/
generateTextZPL(element, x, y) {
const zpl = []
// 设置中文字体
zpl.push(`^CI28 ^CWJ,E:MSYH.TTF ^CFJ,${element.fontSize}`)
if (element.isChecked) {
zpl.push(`^FO${x-60},${y}^GB45,45,2,B,0^FS ^FO${x-50},${y+10}^AJN,35,35^FD√^FS `)
}
// 基础文本
const textCommand = element.newline
? `^FO${x},${y}^FB${element.lineWidth},${element.lineRows},0^CFJ,${element.fontSize}^FD${element.data}^FS`
@ -127,13 +134,13 @@ export class ZPLGenerator {
// 加粗效果(通过偏移重复打印实现)
if (element.bold) {
const boldCommands = element.newline ? [
`^FO${x+1},${y}^FB${element.lineWidth},${element.lineRows},0^CFJ,${element.fontSize}^FD${element.data}^FS`,
`^FO${x},${y+1}^FB${element.lineWidth},${element.lineRows},0^CFJ,${element.fontSize}^FD${element.data}^FS`,
`^FO${x+1},${y+1}^FB${element.lineWidth},${element.lineRows},0^CFJ,${element.fontSize}^FD${element.data}^FS`
`^FO${x + 1},${y}^FB${element.lineWidth},${element.lineRows},0^CFJ,${element.fontSize}^FD${element.data}^FS`,
`^FO${x},${y + 1}^FB${element.lineWidth},${element.lineRows},0^CFJ,${element.fontSize}^FD${element.data}^FS`,
`^FO${x + 1},${y + 1}^FB${element.lineWidth},${element.lineRows},0^CFJ,${element.fontSize}^FD${element.data}^FS`
] : [
`^FO${x+1},${y}^FD${element.data}^FS`,
`^FO${x},${y+1}^FD${element.data}^FS`,
`^FO${x+1},${y+1}^FD${element.data}^FS`
`^FO${x + 1},${y}^FD${element.data}^FS`,
`^FO${x},${y + 1}^FD${element.data}^FS`,
`^FO${x + 1},${y + 1}^FD${element.data}^FS`
]
zpl.push(...boldCommands)
@ -142,24 +149,57 @@ export class ZPLGenerator {
return zpl.join('\n')
}
/**
* 生成条码ZPL代码
*/
generateBarcodeZPL(element, x, y) {
const orientation = this.config.barcodeOrientation
const additionalParams = orientation === 'B' ? ',Y,N,N' : ','
return `^FO${x},${y}^BY${element.width}^BC${orientation},${element.height}${additionalParams}^FD${element.data}^FS`
}
/**
* 生成一维码ZPL代码
*/
generateOnecodeZPL(element, x, y) {
const orientation = this.config.barcodeOrientation
const additionalParams = orientation === 'B' ? ',' : ','
const barcodeType = element.barcodeType || 'CODE128'
const showContent = element.showContent !== false // 默认显示内容
// 将毫米转换为ZPL单位
// 宽度:ZPL的^BY宽度参数控制窄条宽度倍数 (范围1-10)
// 根据ZPL规范,这个参数不是直接的物理尺寸,而是相对倍数
// 使用经验公式:倍数 ≈ 宽度(mm) * 1.5,确保在1-10范围内
const widthMM = parseFloat(element.width) || 2
const width = Math.max(1, Math.min(10, Math.round(widthMM * 1.5)))
// 高度:毫米转换为点数,使用精确的DPI转换公式
const height = Math.max(1, Math.round((element.height || 15) * this.dpi / 25.4))
// 根据条码类型选择ZPL指令
let zplCommand = ''
switch (barcodeType) {
case 'CODE128':
zplCommand = `^BC${orientation}`
break
case 'CODE39':
zplCommand = `^B3${orientation}`
break
case 'CODE93':
zplCommand = `^BA${orientation}`
break
case 'EAN13':
zplCommand = `^BE${orientation}`
break
case 'EAN8':
zplCommand = `^B8${orientation}`
break
case 'UPCA':
zplCommand = `^BU${orientation}`
break
case 'UPCE':
zplCommand = `^B9${orientation}`
break
default:
zplCommand = `^BC${orientation}` // 默认使用CODE128
}
return `^FO${x},${y}^BY${element.width}^BC${orientation},${element.height}${additionalParams}^FD${element.data}^FS`
// 构建完整的ZPL指令
const contentParam = showContent ? 'Y' : 'N'
const additionalParams = orientation === 'B' ? `,${contentParam},N,N` : `,${contentParam}`
return `^FO${x},${y}^BY${width}${zplCommand},${height}${additionalParams}^FD${element.data}^FS`
}
/**
@ -167,10 +207,37 @@ export class ZPLGenerator {
*/
generateQRCodeZPL(element, x, y) {
const orientation = this.config.qrcodeOrientation
const data = element.data || ''
// 将毫米转换为ZPL尺寸单位,使用精确的DPI转换公式
// 二维码的尺寸参数是模块大小,通常1-10
const sizeInDots = Math.max(1, Math.round((element.height || 10) * this.dpi / 25.4))
// 将点数转换为ZPL模块大小 (大约每20-30个点为1个模块)
let size = Math.max(1, Math.min(10, Math.round(sizeInDots / 25)))
// 根据数据长度自动调整最小尺寸,确保能容纳数据
if (data.length > 300) {
size = Math.max(size, 8) // 超长数据需要更大的尺寸
} else if (data.length > 200) {
size = Math.max(size, 6) // 长数据需要更大的尺寸
} else if (data.length > 100) {
size = Math.max(size, 4) // 中等数据需要中等尺寸
} else {
size = Math.max(size, 2) // 短数据使用较小尺寸
}
return `^FO${x},${y}^BQ${orientation},2,${element.height},^FDLA,${element.data}^FS`
// 尝试使用更明确的二维码格式
// 对于长数字内容,使用数字模式可能更有效
if (/^\d+$/.test(data)) {
// 纯数字内容,使用数字模式
return `^FO${x},${y}^BQ${orientation},2,${size}^FDMN,${data}^FS`
} else {
// 混合内容,使用自动模式
return `^FO${x},${y}^BQ${orientation},2,${size}^FDMA,${data}^FS`
}
}
/**
* 生成图片ZPL代码
*/
@ -209,15 +276,17 @@ export class ZPLGenerator {
*/
generateSerialNumberZPL(element, x, y) {
const zpl = []
// 设置中文字体
zpl.push(`^CI28 ^CWJ,E:MSYH.TTF ^CFJ,${element.fontSize}`)
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`)
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')
}
@ -229,20 +298,22 @@ export class ZPLGenerator {
* @param {string} paperType - 纸张类型兼容性
* @param {Object} customSize - 自定义尺寸兼容性
* @param {number} paperId - 纸张ID新增
* @param {number} dpi - DPI新增
* @returns {ZPLGenerator} 生成器实例
*/
export function createZPLGenerator(orientation, paperType = null, customSize = null, paperId = null) {
return new ZPLGenerator(orientation, paperType, customSize, paperId)
export function createZPLGenerator(orientation, paperType = null, customSize = null, paperId = null, dpi = 300) {
return new ZPLGenerator(orientation, paperType, customSize, paperId, dpi)
}
/**
* 根据纸张ID创建ZPL生成器实例新增方法
* @param {number} paperId - 纸张ID
* @param {string} orientation - 打印方向
* @param {number} dpi - DPI新增
* @returns {ZPLGenerator} 生成器实例
*/
export function createZPLGeneratorById(paperId, orientation = 'portrait') {
return new ZPLGenerator(orientation, null, null, paperId)
export function createZPLGeneratorById(paperId, orientation = 'portrait', dpi = 300) {
return new ZPLGenerator(orientation, null, null, paperId, dpi)
}
/**
@ -251,10 +322,11 @@ export function createZPLGeneratorById(paperId, orientation = 'portrait') {
* @param {string} orientation - 打印方向
* @param {string} paperType - 纸张类型兼容性
* @param {number} paperId - 纸张ID新增
* @param {number} dpi - DPI新增
* @returns {string} ZPL代码
*/
export function generateZPL(elements, orientation = 'portrait', paperType = null, paperId = null) {
const generator = new ZPLGenerator(orientation, paperType, null, paperId)
export function generateZPL(elements, orientation = 'portrait', paperType = null, paperId = null, dpi = 300) {
const generator = new ZPLGenerator(orientation, paperType, null, paperId, dpi)
return generator.generate(elements)
}
@ -263,10 +335,11 @@ export function generateZPL(elements, orientation = 'portrait', paperType = null
* @param {Array} elements - 设计元素
* @param {number} paperId - 纸张ID
* @param {string} orientation - 打印方向
* @param {number} dpi - DPI新增
* @returns {string} ZPL代码
*/
export function generateZPLById(elements, paperId, orientation = 'portrait') {
const generator = new ZPLGenerator(orientation, null, null, paperId)
export function generateZPLById(elements, paperId, orientation = 'portrait', dpi = 300) {
const generator = new ZPLGenerator(orientation, null, null, paperId, dpi)
return generator.generate(elements)
}

56
src/utils/zplUtil.js

@ -1,56 +0,0 @@
export function generateZPL(elements,zplHOrP) {
const zpl = ['^XA'];
zpl.push(zplHOrP)
elements.forEach(el => {
const x = Math.round(el.x);
const y = Math.round(el.y * 1.5); // 画布到 ZPL 像素转换
switch (el.type) {
case 'text':
zpl.push(`^CI28^LH0,^JUS^CWJ,E:SIMSUN.FNT^CFJ,${el.fontSize},${el.fontSize}`);
zpl.push(el.newline
? `^FO${x},${y}^FB${el.lineWidth},${el.lineRows},0^CFJ,${el.fontSize}^FD${el.data}^FS`
: `^FO${x},${y}^FD${el.data}^FS`);
if (el.bold) {
zpl.push(el.newline
? `^FO${x+1},${y}^FB${el.lineWidth},${el.lineRows},0^CFJ,${el.fontSize}^FD${el.data}^FS`
: `^FO${x+1},${y}^FD${el.data}^FS`);
zpl.push(el.newline
? `^FO${x},${y+1}^FB${el.lineWidth},${el.lineRows},0^CFJ,${el.fontSize}^FD${el.data}^FS`
: `^FO${x},${y+1}^FD${el.data}^FS`);
zpl.push(el.newline
? `^FO${x+1},${y+1}^FB${el.lineWidth},${el.lineRows},0^CFJ,${el.fontSize}^FD${el.data}^FS`
: `^FO${x+1},${y+1}^FD${el.data}^FS`);
}
break;
case 'barcode':
zpl.push(`^FO${x},${y}^BY${el.width}^BCN,${el.height},^FD${el.data}^FS`);
break;
case 'qrcode':
zpl.push(`^FO${x},${y}^BQN,2,${el.height},^FDLA,${el.data}^FS`);
break;
case 'onecode':
zpl.push(`^FO${x},${y}^BY${el.width}^BCN,${el.height},^FD${el.data}^FS`);
break;
case 'pic':
if (el.data) {
zpl.push(`^FO${x},${y}^GFA,${el.data}`);
}
break;
case 'hLine':
zpl.push(`^FO${x},${y}^GB${el.width},${el.height},3,B^FS`);
break;
case 'vLine':
zpl.push(`^FO${x},${y}^GB1,${el.height},${el.width},B^FS`);
break;
}
});
zpl.push('^XZ');
return zpl.join('\n');
}

59
src/utils/zplUtil2.js

@ -1,59 +0,0 @@
export function generateZPL(elements,zplHOrP) {
const zpl = ['^XA'];
//zpl.push('^POI');
zpl.push(zplHOrP)
elements.forEach(el => {
const x = Math.round(el.y * 1.3);
const y = Math.round((750-el.x) * 1.5); // 你之前的转换比例保持不变
switch (el.type) {
case 'text':
zpl.push(`^CI28^LH0,^JUS^CWJ,E:SIMSUN.FNT^CFJ,${el.fontSize},${el.fontSize}`);
zpl.push(el.newline
? `^FO${x},${y}^FB${el.lineWidth},${el.lineRows},0^CFJ,${el.fontSize}^FD${el.data}^FS`
: `^FO${x},${y}^FD${el.data}^FS`);
if (el.bold) {
zpl.push(el.newline
? `^FO${x+1},${y}^FB${el.lineWidth},${el.lineRows},0^CFJ,${el.fontSize}^FD${el.data}^FS`
: `^FO${x+1},${y}^FD${el.data}^FS`);
zpl.push(el.newline
? `^FO${x},${y+1}^FB${el.lineWidth},${el.lineRows},0^CFJ,${el.fontSize}^FD${el.data}^FS`
: `^FO${x},${y+1}^FD${el.data}^FS`);
zpl.push(el.newline
? `^FO${x+1},${y+1}^FB${el.lineWidth},${el.lineRows},0^CFJ,${el.fontSize}^FD${el.data}^FS`
: `^FO${x+1},${y+1}^FD${el.data}^FS`);
}
break;
case 'barcode':
zpl.push(`^FO${x},${y}^BY${el.width}^BCB,${el.height},Y,N,N^FD${el.data}^FS`);
break;
case 'qrcode':
zpl.push(`^FO${x},${y}^BQB,2,${el.height},^FDLA,${el.data}^FS`);
break;
case 'onecode':
zpl.push(`^FO${x},${y}^BY${el.width}^BCB,${el.height},^FD${el.data}^FS`);
break;
case 'pic':
if (el.data) {
zpl.push(`^FO${x},${y}^GFA,${el.data}`);
}
break;
case 'hLine':
const y1 = Math.round(1200-el.x)-el.width;
zpl.push(`^FO${x},${y1}^FWR^GB${el.height},${el.width},3,B^FS`);
break;
case 'vLine':
zpl.push(`^FO${x},${y}^FWR^GB${el.height},${el.width},3,B^FS`);
break;
}
});
zpl.push('^XZ');
return zpl.join('\n');
}

42
src/views/modules/labelSetting/LabelDesigner.vue

@ -286,8 +286,8 @@ export default {
return new CoordinateTransformer(this.orientation, null, null, this.selectedPaper)
},
zplGenerator() {
// 使IDZPL
return new ZPLGenerator(this.orientation, null, null, this.selectedPaper)
// 使IDDPIZPL
return new ZPLGenerator(this.orientation, null, null, this.selectedPaper, this.selectedDPI)
}
},
async created() {
@ -432,9 +432,19 @@ export default {
if (data.code === 200) {
//
const defaultElement = {
type: '', x: 0, y: 0, data: '', fontSize: 30, bold: false, newline: false, lineRows: 2, lineWidth: 200, digits: 6, step: 1, width: 100, height: 30, previewUrl: ''
type: '', x: 0, y: 0, data: '', fontSize: 30, bold: false, newline: false, lineRows: 2,
lineWidth: 200, digits: 6, step: 1, width: 100, height: 30, previewUrl: '', barcodeType: '', showContent: true,showPic:true,
showMainSeq:false,seqName:'',isChecked:false
};
this.elements = (data.data || []).map(item => Object.assign({}, defaultElement, item));
this.elements = (data.data || []).map(item => {
const element = Object.assign({}, defaultElement, item);
//
if (element.type === 'onecode') {
if (!element.barcodeType) element.barcodeType = 'CODE128';
if (element.showContent === undefined) element.showContent = true;
}
return element;
});
}
} catch (error) {
this.$message.error('加载标签元素失败')
@ -486,21 +496,19 @@ export default {
text: {
width: 100,
height: 30,
data: ''
},
barcode: {
width: 3,
height: 50,
data: ''
data: '',
isChecked:false,
},
onecode: {
width: 3,
height: 50,
data: ''
width: 2, // 2mm
height: 15, // 15mm
data: '',
barcodeType: 'CODE128', //
showContent: true //
},
qrcode: {
width: 10,
height: 10,
height: 10, // 10mm
data: ''
},
pic: {
@ -521,7 +529,8 @@ export default {
digits: 6,
step: 1,
data: '流水号', //
fontSize: 30
fontSize: 30,
showMainSeq: false,
}
}
@ -609,7 +618,7 @@ export default {
* 判断是否为严格模式元素
*/
isStrictElement(elementType) {
return ['barcode', 'onecode', 'qrcode'].includes(elementType)
return ['onecode', 'qrcode'].includes(elementType)
},
/**
@ -618,7 +627,6 @@ export default {
getElementTypeName(elementType) {
const nameMap = {
text: '文本',
barcode: '条形码',
onecode: '一维码',
qrcode: '二维码',
pic: '图片',

6
src/views/modules/labelSetting/components/DesignCanvas.vue

@ -240,7 +240,6 @@ export default {
getBoundaryStrategy(elementType) {
const strategyMap = {
text: 'flexible', //
barcode: 'strict', //
onecode: 'strict', //
qrcode: 'strict', //
pic: 'flexible', //
@ -295,7 +294,6 @@ export default {
//
const baseSizeMap = {
text: { width: 80, height: 24 }, //
barcode: { width: 70, height: 46 }, //
onecode: { width: 70, height: 46 }, //
qrcode: { width: 60, height: 60 }, //
pic: { width: 60, height: 60 }, //
@ -332,8 +330,8 @@ export default {
}
}
//
if (element.type === 'barcode' || element.type === 'onecode') {
//
if (element.type === 'onecode') {
return {
width: 70, //
height: 46 //

13
src/views/modules/labelSetting/components/DesignElement.vue

@ -12,15 +12,6 @@
{{ element.data || '文本元素' }}
</div>
<!-- 条码元素 -->
<div v-else-if="element.type === 'barcode'" class="barcode-element">
<svg width="100" height="60" viewBox="0 0 24 24" fill="none">
<path d="M2 4v16M4 4v16M6 4v16M8 4v16M10 4v16M12 4v16M14 4v16M16 4v16M18 4v16M20 4v16M22 4v16"
stroke="#333" stroke-width="1"/>
</svg>
<div class="element-label">条码</div>
</div>
<!-- 一维码元素 -->
<div v-else-if="element.type === 'onecode'" class="onecode-element">
<svg width="100" height="60" viewBox="0 0 24 24" fill="none">
@ -244,7 +235,6 @@ export default {
white-space: nowrap;
}
.barcode-element,
.onecode-element {
display: flex;
flex-direction: column;
@ -255,7 +245,6 @@ export default {
min-width: 60px;
}
.barcode-element svg,
.onecode-element svg {
width: 60px;
height: 36px;
@ -340,7 +329,6 @@ export default {
border-color: rgba(52, 152, 219, 0.3);
}
.design-element[data-type="barcode"],
.design-element[data-type="onecode"] {
border-color: rgba(255, 152, 0, 0.4);
}
@ -398,7 +386,6 @@ export default {
padding: 3px 6px;
}
.barcode-element svg,
.onecode-element svg {
width: 50px;
height: 30px;

7
src/views/modules/labelSetting/components/HorizontalToolbar.vue

@ -61,13 +61,6 @@ export default {
label: '文本',
color: '#409EFF'
},
{
type: 'barcode',
icon: 'el-icon-tickets',
label: '条码',
rotate: true,
color: '#67C23A'
},
{
type: 'qrcode',
icon: 'el-icon-menu',

191
src/views/modules/labelSetting/components/PropertyForm.vue

@ -26,6 +26,9 @@
<el-checkbox v-model="element.newline" size="small" class="inline-checkbox">自动换行</el-checkbox>
</div>
</el-form-item>
<el-form-item label="" class="form-item-half">
<el-checkbox v-model="element.isChecked" size="small" class="inline-checkbox">打勾</el-checkbox>
</el-form-item>
<template v-if="element.newline">
<div class="form-row">
@ -53,12 +56,12 @@
</el-form>
</div>
<!-- 条码/一维码属性 -->
<div v-else-if="['barcode', 'onecode'].includes(element.type)" class="form-section">
<!-- 一维码属性 -->
<div v-else-if="element.type === 'onecode'" class="form-section">
<el-form label-position="top" size="small">
<el-form-item label="数据内容">
<div class="input-with-button">
<el-input v-model="element.data" placeholder="请输入码数据" />
<el-input v-model="element.data" placeholder="请输入一维码数据" />
<el-button type="primary" size="mini" @click="$emit('data-source', element)">
数据源
</el-button>
@ -66,21 +69,38 @@
</el-form-item>
<div class="form-row">
<el-form-item label="宽度" class="form-item-half">
<el-form-item label="条码类型" class="form-item-half">
<el-select v-model="element.barcodeType" size="mini" style="width: 100%;">
<el-option label="CODE128" value="CODE128" />
<el-option label="CODE39" value="CODE39" />
<el-option label="CODE93" value="CODE93" />
<el-option label="EAN13" value="EAN13" />
<el-option label="EAN8" value="EAN8" />
<el-option label="UPCA" value="UPCA" />
<el-option label="UPCE" value="UPCE" />
</el-select>
</el-form-item>
<el-form-item label="显示内容" class="form-item-half">
<el-radio-group v-model="element.showContent" size="mini">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
</div>
<div class="form-row">
<el-form-item label="窄条宽(范围0.085-0.85mm)" class="form-item-half">
<el-input
v-model="element.width"
:min="1"
:max="10"
controls-position="right"
size="mini"
/>
</el-form-item>
<el-form-item label="高度" class="form-item-half">
<el-form-item label="高度(mm)" class="form-item-half">
<el-input
v-model="element.height"
:min="10"
:max="500"
controls-position="right"
size="mini"
/>
@ -94,23 +114,43 @@
<el-form label-position="top" size="small">
<el-form-item label="数据内容">
<div class="input-with-button">
<el-input v-model="element.data" placeholder="请输入二维码数据" />
<el-input
v-model="element.data"
placeholder="请输入二维码数据"
type="textarea"
:rows="2"
maxlength="1000"
show-word-limit
/>
<el-button type="primary" size="mini" @click="$emit('data-source', element)">
数据源
</el-button>
</div>
</el-form-item>
<el-form-item label="尺寸">
<el-form-item label="尺寸(mm)">
<el-input
v-model="element.height"
:min="1"
:max="10"
:min="3"
:max="50"
:step="0.5"
controls-position="right"
size="mini"
@change="validateQRSize"
/>
<div class="form-tip">二维码最大尺寸为10</div>
</el-form-item>
<div class="form-tip">
<div v-if="element.data && element.data.length > 200" class="tip-warning">
内容较长({{ element.data.length }}字符)建议尺寸15mm系统将自动优化
</div>
<div v-else-if="element.data && element.data.length > 100" class="tip-info">
内容中等({{ element.data.length }}字符)建议尺寸12mm系统将自动优化
</div>
<div v-else class="tip-normal">
内容较短({{ element.data ? element.data.length : 0 }}字符)当前尺寸足够
</div>
</div>
</el-form>
</div>
@ -126,11 +166,9 @@
@change="handleImageUpload"
style="display: none;"
/>
<el-button
type="primary"
<el-button type="primary"
icon="el-icon-upload"
@click="handleSelectImage"
>
@click="handleSelectImage">
选择图片
</el-button>
</div>
@ -139,6 +177,9 @@
<div v-if="element.previewUrl" class="image-preview">
<img :src="element.previewUrl" alt="预览" />
</div>
<el-form-item label="是否显示图片" class="form-item-half">
<el-input v-model="element.showPic" controls-position="right" size="mini"/>
</el-form-item>
</el-form>
</div>
@ -172,7 +213,18 @@
<!-- 流水号属性 -->
<div v-else-if="element.type === 'serialNumber'" class="form-section">
<el-form label-position="top" size="small">
<div class="form-row">
<div class="form-row">
<el-form-item label="名称" class="form-item-half">
<el-input v-model="element.seqName" controls-position="right" size="mini"/>
</el-form-item>
<el-form-item label="主标签流水码" class="form-item-half">
<el-radio-group v-model="element.showMainSeq" size="mini">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
</div>
<div class="form-row" v-if="!element.showMainSeq">
<el-form-item label="位数" class="form-item-half">
<el-input
v-model="element.digits"
@ -195,7 +247,7 @@
</el-form-item>
</div>
<div class="form-row">
<div class="form-row" v-if="!element.showMainSeq">
<el-form-item label="字体大小" class="form-item-half">
<el-input
v-model="element.fontSize"
@ -210,7 +262,7 @@
<el-checkbox v-model="element.bold" size="middle"></el-checkbox>
</el-form-item>
</div>
<div class="form-row">
<div class="form-row" v-if="!element.showMainSeq">
<el-form-item label="流水号规则" class="form-item-half">
<el-input v-model="element.data" placeholder="请输入流水号规则" @focus="$emit('data-source', element)"/>
</el-form-item>
@ -224,7 +276,7 @@
</el-form>
</div>
<!-- 标签内容流水号信息 -->
<comShowLabelSerialInfo ref="comShowLabelSerialInfo" @refreshCurrentPageTable="refreshCurrentPageTable" v-drag></comShowLabelSerialInfo>
<comShowLabelSerialInfo ref="comShowLabelSerialInfo" v-drag></comShowLabelSerialInfo>
</div>
</template>
@ -263,7 +315,7 @@ export default {
this.$refs.fileInput.click()
}
},
/*流水号信息的modal*/
serialInfoModal(row){
let rowData = {
@ -276,9 +328,21 @@ export default {
})
},
validateQRSize() {
if (this.element.height > 10) {
this.$message.warning('二维码最大尺寸为10')
this.element.height = 10
const dataLength = this.element.data ? this.element.data.length : 0
//
if (this.element.height > 50) {
this.$message.warning('二维码最大尺寸为50mm')
this.element.height = 50
} else if (this.element.height < 3) {
this.element.height = 3
}
//
if (dataLength > 200 && this.element.height < 15) {
this.$message.info('长内容建议使用15mm或以上尺寸,以确保扫描成功')
} else if (dataLength > 100 && this.element.height < 12) {
this.$message.info('中等长度内容建议使用12mm或以上尺寸')
}
},
@ -289,7 +353,7 @@ export default {
try {
const imageData = await this.processImage(file)
this.$emit('image-upload', imageData)
// change
event.target.value = ''
} catch (error) {
@ -431,17 +495,39 @@ export default {
border-left: 2px solid #409eff;
}
.form-tip .tip-warning {
color: #f56c6c;
font-weight: 500;
border-left: 2px solid #f56c6c;
padding-left: 6px;
}
.form-tip .tip-info {
color: #e6a23c;
font-weight: 500;
border-left: 2px solid #e6a23c;
padding-left: 6px;
}
.form-tip .tip-normal {
color: #67c23a;
font-weight: 500;
border-left: 2px solid #67c23a;
padding-left: 6px;
}
.image-upload {
margin-bottom: 8px;
}
.image-upload .el-button {
width: 100%;
height: 60px;
height: 30px;
border: 1px dashed #d9d9d9;
border-radius: 4px;
background: #fafafa;
font-size: 12px;
color: black;
}
.image-upload .el-button:hover {
@ -628,6 +714,55 @@ export default {
margin-bottom: 0 !important;
}
/* 单选按钮组样式 */
.form-item-half .el-radio-group {
display: flex !important;
gap: 8px !important;
align-items: center !important;
padding-top: 4px;
}
.form-item-half .el-radio {
margin-right: 0 !important;
font-size: 12px !important;
height: 20px !important;
line-height: 20px !important;
}
.form-item-half .el-radio__label {
font-size: 12px !important;
padding-left: 4px !important;
}
.form-item-half .el-radio__inner {
width: 12px !important;
height: 12px !important;
}
/* 下拉选择框样式 */
.form-item-half .el-select {
width: 100% !important;
}
.form-item-half .el-select .el-input__inner {
height: 32px !important;
font-size: 13px !important;
border: 1px solid #dcdfe6 !important;
border-radius: 6px !important;
padding: 0 30px 0 12px !important;
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) !important;
}
.form-item-half .el-select .el-input__inner:hover {
border-color: #c0c4cc !important;
}
.form-item-half .el-select .el-input__inner:focus {
border-color: #409eff !important;
outline: none !important;
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1) !important;
}
/* 复选框组样式 */
.checkbox-group {
position: relative;

2
src/views/modules/labelSetting/components/PropertyPanel.vue

@ -147,7 +147,7 @@ export default {
.property-form {
flex: 0 0 auto;
max-height: 200px;
max-height: 250px;
overflow-y: auto;
}

2
src/views/modules/labelSetting/components/ZPLPreview.vue

@ -122,7 +122,7 @@ export default {
zplGenerator() {
// 使IDZPL
if (typeof this.selectedPaper === 'number') {
return new ZPLGenerator(this.orientation, null, null, this.selectedPaper)
return new ZPLGenerator(this.orientation, null, null, this.selectedPaper, this.selectedDPI)
}
//

3
src/views/modules/labelSetting/label_setting.vue

@ -61,9 +61,10 @@
fixed="left"
header-align="center"
align="center"
width="160"
width="200"
:label=labels.operationLabel>
<template slot-scope="scope">
<a class="customer-a" v-if="!authEdit" @click="">一键复制</a>
<a class="customer-a" v-if="!authEdit" @click="editLabelSettingModal(scope.row)">{{ labels.editLabel }}</a>
<a class="customer-a" v-if="!authDelete" @click="deleteLabelSettingConfirm(scope.row)">{{ labels.deleteLabel }}</a>
<!-- <a class="customer-a" v-if="!authEdit" @click="labelParameterModal(scope.row)">{{ labels.printParameterLabel }}</a>

Loading…
Cancel
Save