diff --git a/src/utils/zplGenerator.js b/src/utils/zplGenerator.js index f476222..6b99058 100644 --- a/src/utils/zplGenerator.js +++ b/src/utils/zplGenerator.js @@ -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]) + } + /** * 生成字体命令 */