|
|
|
@ -119,6 +119,7 @@ export class ZPLGenerator { |
|
|
|
*/ |
|
|
|
generateTextZPL(element, x, y) { |
|
|
|
const zpl = [] |
|
|
|
const textData = this.resolveTextData(element) |
|
|
|
|
|
|
|
// 生成字体命令
|
|
|
|
const fontCommand = this.generateFontCommand(element) |
|
|
|
@ -135,21 +136,21 @@ export class ZPLGenerator { |
|
|
|
|
|
|
|
// 基础文本
|
|
|
|
const textCommand = element.newline |
|
|
|
? `^FO${x},${y}^FB${lineWidth},${element.lineRows},0,${alignmentParam}^CFJ,${element.fontSize}^FD${element.data}^FS` |
|
|
|
: `^FO${x},${y}^FD${element.data}^FS` |
|
|
|
? `^FO${x},${y}^FB${lineWidth},${element.lineRows},0,${alignmentParam}^CFJ,${element.fontSize}^FD${textData}^FS` |
|
|
|
: `^FO${x},${y}^FD${textData}^FS` |
|
|
|
|
|
|
|
zpl.push(textCommand) |
|
|
|
|
|
|
|
// 加粗效果(通过偏移重复打印实现)
|
|
|
|
if (element.bold) { |
|
|
|
const boldCommands = element.newline ? [ |
|
|
|
`^FO${x + 1},${y}^FB${lineWidth},${element.lineRows},0,${alignmentParam}^CFJ,${element.fontSize}^FD${element.data}^FS`, |
|
|
|
`^FO${x},${y + 1}^FB${lineWidth},${element.lineRows},0,${alignmentParam}^CFJ,${element.fontSize}^FD${element.data}^FS`, |
|
|
|
`^FO${x + 1},${y + 1}^FB${lineWidth},${element.lineRows},0,${alignmentParam}^CFJ,${element.fontSize}^FD${element.data}^FS` |
|
|
|
`^FO${x + 1},${y}^FB${lineWidth},${element.lineRows},0,${alignmentParam}^CFJ,${element.fontSize}^FD${textData}^FS`, |
|
|
|
`^FO${x},${y + 1}^FB${lineWidth},${element.lineRows},0,${alignmentParam}^CFJ,${element.fontSize}^FD${textData}^FS`, |
|
|
|
`^FO${x + 1},${y + 1}^FB${lineWidth},${element.lineRows},0,${alignmentParam}^CFJ,${element.fontSize}^FD${textData}^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${textData}^FS`, |
|
|
|
`^FO${x},${y + 1}^FD${textData}^FS`, |
|
|
|
`^FO${x + 1},${y + 1}^FD${textData}^FS` |
|
|
|
] |
|
|
|
|
|
|
|
zpl.push(...boldCommands) |
|
|
|
@ -157,7 +158,7 @@ export class ZPLGenerator { |
|
|
|
|
|
|
|
// 下划线效果(通过线条实现)
|
|
|
|
if (element.fontUnderline) { |
|
|
|
const textWidth = this.estimateTextWidth(element.data, element.fontSize) |
|
|
|
const textWidth = this.estimateTextWidth(textData, element.fontSize) |
|
|
|
const underlineY = y + element.fontSize + 2 |
|
|
|
zpl.push(`^FO${x},${underlineY}^GB${textWidth},2,2,B^FS`) |
|
|
|
} |
|
|
|
@ -165,6 +166,107 @@ export class ZPLGenerator { |
|
|
|
return zpl.join('\n') |
|
|
|
} |
|
|
|
|
|
|
|
resolveTextData(element) { |
|
|
|
const rawData = element.data || '' |
|
|
|
if (element.type !== 'text' || element.dataType !== 'date') { |
|
|
|
return rawData |
|
|
|
} |
|
|
|
|
|
|
|
const hasCurrentDateToken = |
|
|
|
rawData.includes('#{CURRENT_DATE_YYYY-MM-DD}') || rawData.includes('#{CURRENT_DATE_YYYYMMDD}') |
|
|
|
if (!hasCurrentDateToken) { |
|
|
|
return rawData |
|
|
|
} |
|
|
|
|
|
|
|
const formattedDate = this.formatCurrentDateBySettings(element) |
|
|
|
return rawData |
|
|
|
.replaceAll('#{CURRENT_DATE_YYYY-MM-DD}', formattedDate) |
|
|
|
.replaceAll('#{CURRENT_DATE_YYYYMMDD}', formattedDate) |
|
|
|
} |
|
|
|
|
|
|
|
formatCurrentDateBySettings(element) { |
|
|
|
const now = new Date() |
|
|
|
const date = new Date(now.getFullYear(), now.getMonth(), now.getDate()) |
|
|
|
const offsetDays = Number(element.dateOffsetDays || 0) |
|
|
|
if (!Number.isNaN(offsetDays) && offsetDays !== 0) { |
|
|
|
date.setDate(date.getDate() + offsetDays) |
|
|
|
} |
|
|
|
|
|
|
|
const extractType = element.dateExtractType || 'full' |
|
|
|
switch (extractType) { |
|
|
|
case 'year': |
|
|
|
return String(date.getFullYear()) |
|
|
|
case 'month': |
|
|
|
return String(date.getMonth() + 1) |
|
|
|
case 'day': |
|
|
|
return String(date.getDate()) |
|
|
|
case 'week': |
|
|
|
return this.calculateWeekNumber(date, element.firstWeekDate) |
|
|
|
case 'weekday': |
|
|
|
return this.calculateWeekday(date, element.firstDayOfWeek) |
|
|
|
case 'full': |
|
|
|
default: |
|
|
|
return this.formatFullDate(date, element) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
calculateWeekNumber(date, firstWeekDateStr) { |
|
|
|
let firstWeekDate = new Date(date.getFullYear(), 0, 1) |
|
|
|
if (firstWeekDateStr) { |
|
|
|
const parsed = this.parseDateString(firstWeekDateStr) |
|
|
|
if (parsed) { |
|
|
|
firstWeekDate = parsed |
|
|
|
} |
|
|
|
} |
|
|
|
const diffMs = date.getTime() - firstWeekDate.getTime() |
|
|
|
const diffDays = Math.floor(diffMs / 86400000) |
|
|
|
const weekNo = Math.floor(diffDays / 7) + 1 |
|
|
|
return String(Math.max(1, weekNo)) |
|
|
|
} |
|
|
|
|
|
|
|
calculateWeekday(date, firstDayOfWeekStr) { |
|
|
|
const firstDayOfWeek = Number(firstDayOfWeekStr || 1) |
|
|
|
const dayOfWeek = date.getDay() === 0 ? 7 : date.getDay() |
|
|
|
const adjustedDay = ((dayOfWeek - firstDayOfWeek + 7) % 7) + 1 |
|
|
|
return String(adjustedDay) |
|
|
|
} |
|
|
|
|
|
|
|
formatFullDate(date, element) { |
|
|
|
const dateFormat = element.dateFormat || 'ymd' |
|
|
|
const separator = element.dateSeparator !== undefined && element.dateSeparator !== null ? element.dateSeparator : '-' |
|
|
|
const yearDigits = element.yearDigits || '4' |
|
|
|
const monthDayDigits = element.monthDayDigits || '2' |
|
|
|
|
|
|
|
const year = yearDigits === '2' |
|
|
|
? String(date.getFullYear() % 100).padStart(2, '0') |
|
|
|
: String(date.getFullYear()).padStart(4, '0') |
|
|
|
const month = monthDayDigits === '1' |
|
|
|
? String(date.getMonth() + 1) |
|
|
|
: String(date.getMonth() + 1).padStart(2, '0') |
|
|
|
const day = monthDayDigits === '1' |
|
|
|
? String(date.getDate()) |
|
|
|
: String(date.getDate()).padStart(2, '0') |
|
|
|
|
|
|
|
if (dateFormat === 'dmy') { |
|
|
|
return `${day}${separator}${month}${separator}${year}` |
|
|
|
} |
|
|
|
if (dateFormat === 'mdy') { |
|
|
|
return `${month}${separator}${day}${separator}${year}` |
|
|
|
} |
|
|
|
return `${year}${separator}${month}${separator}${day}` |
|
|
|
} |
|
|
|
|
|
|
|
parseDateString(dateStr) { |
|
|
|
if (!dateStr || typeof dateStr !== 'string') { |
|
|
|
return null |
|
|
|
} |
|
|
|
const parts = dateStr.split('-').map(item => Number(item)) |
|
|
|
if (parts.length !== 3 || parts.some(num => Number.isNaN(num))) { |
|
|
|
return null |
|
|
|
} |
|
|
|
return new Date(parts[0], parts[1] - 1, parts[2]) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 生成字体命令 |
|
|
|
*/ |
|
|
|
|