export type TextFormat = 'text' | 'number' | 'percent' | 'currency'; /** 数值格式下的显示部分:完整 / 仅整数 / 仅小数(含小数点) */ export type NumberPartDisplay = 'full' | 'integer' | 'fraction'; /** 文本变量值提取方式 */ export type TextExtractMode = 'none' | 'split' | 'prefix' | 'suffix'; export const TEXT_EXTRACT_MODE_LABELS: Record = { none: '无', split: '按分隔符', prefix: '前 N 位', suffix: '后 N 位', }; /** 变量/内容值提取配置(元素、表格单元格、显示条件等共用) */ export interface ValueExtractConfig { textExtractMode?: TextExtractMode; textSplitDelimiter?: string; textSplitIndex?: number; textExtractLength?: number; /** 反选:从原值中去掉「显示前缀 + 提取段 + 显示后缀」 */ textExtractInverse?: boolean; textDisplayPrefix?: string; textDisplaySuffix?: string; } export type ElementVisibilityMode = 'always' | 'conditional'; export type VisibilityOperator = | 'empty' | 'not_empty' | 'gt' | 'lt' | 'eq' | 'neq' | 'contains' | 'not_contains'; /** 显示条件判断对象:变量值 或 本元素解析后的内容值 */ export type VisibilityRuleTarget = 'variable' | 'content'; export interface VisibilityRule extends ValueExtractConfig { /** 条件对象,默认 variable */ target?: VisibilityRuleTarget; variable: string; operator: VisibilityOperator; /** gt / lt / eq / neq / contains / not_contains 时的比较目标值,支持 {变量名} */ value?: string; /** 为 false 时跳过该条件;默认启用 */ enabled?: boolean; } export const VISIBILITY_RULE_TARGET_LABELS: Record = { variable: '变量', content: '内容值', }; export const VISIBILITY_OPERATOR_LABELS: Record = { empty: '为空', not_empty: '不为空', gt: '大于', lt: '小于', eq: '等于', neq: '不等于', contains: '包含', not_contains: '不包含', }; export type ElementSide = 'top' | 'right' | 'bottom' | 'left'; export type ElementCorner = 'tl' | 'tr' | 'br' | 'bl'; /** 表格单元格数据;键为 `${row},${col}` */ export interface TableCellData { /** 被合并单元格指向主单元格坐标 */ mergeAnchor?: { row: number; col: number }; /** 主单元格合并行数,默认 1 */ rowSpan?: number; /** 主单元格合并列数,默认 1 */ colSpan?: number; content?: string; fontSize?: number; textAlign?: 'left' | 'center' | 'right'; verticalAlign?: 'top' | 'middle' | 'bottom'; fontWeight?: 'normal' | 'bold'; fontStyle?: 'normal' | 'italic'; textUnderline?: boolean; textLineThrough?: boolean; textScaleX?: number; textScaleY?: number; letterSpacing?: number; textWritingMode?: 'horizontal' | 'vertical'; textColor?: string; backgroundColor?: string; wordWrap?: boolean; /** 最大显示行数(横排为行、竖排为列);未设置或 0 表示不限制 */ textMaxLines?: number; /** 超出最大行数时末行/末列显示省略号 */ textEllipsis?: boolean; fontFamily?: 'sans' | 'serif' | 'mono'; textFormat?: TextFormat; decimalPlaces?: number; numberPartDisplay?: NumberPartDisplay; textExtractMode?: TextExtractMode; textSplitDelimiter?: string; textSplitIndex?: number; textExtractLength?: number; /** 反选:从原值中去掉「显示前缀 + 提取段 + 显示后缀」 */ textExtractInverse?: boolean; textDisplayPrefix?: string; textDisplaySuffix?: string; } export interface TemplateElement { id: string; type: 'text' | 'barcode' | 'qrcode' | 'image' | 'table'; name: string; /** 用户是否手动修改过图层名称;为 true 时不再根据内容自动同步名称 */ nameCustomized?: boolean; x: number; // in mm y: number; // in mm width: number; // in mm height: number; // in mm /** 旋转角度(度),顺时针,默认 0 */ rotation?: number; content: string; // static text or variable binding, e.g. "{货位}" or "格式化文本 {货位}" /** 显示控制:conditional 时按 visibilityRules 判断 */ visibilityMode?: ElementVisibilityMode; /** 显示控制条件;全部满足时才渲染(设计预览按变量默认值判断) */ visibilityRules?: VisibilityRule[]; /** @deprecated 使用 visibilityRules */ visibilityVariables?: string[]; /** @deprecated 使用 visibilityMode=conditional */ hideWhenNoData?: boolean; /** @deprecated 使用 visibilityRules */ visibilityVariable?: string; fontSize: number; // in pt textAlign: 'left' | 'center' | 'right'; /** 文本垂直对齐,仅 type=text */ verticalAlign?: 'top' | 'middle' | 'bottom'; /** 是否自动换行,仅 type=text,默认 true */ wordWrap?: boolean; /** 最大显示行数(横排为行、竖排为列);未设置或 0 表示不限制,仅 type=text */ textMaxLines?: number; /** 超出最大行数时显示省略号,仅 type=text */ textEllipsis?: boolean; /** 文本排列方向,仅 type=text,默认 horizontal */ textWritingMode?: 'horizontal' | 'vertical'; fontWeight: 'normal' | 'bold'; /** 斜体,仅 type=text */ fontStyle?: 'normal' | 'italic'; /** 下划线,仅 type=text */ textUnderline?: boolean; /** 删除线,仅 type=text */ textLineThrough?: boolean; /** 水平拉伸倍数,1 为默认,仅 type=text */ textScaleX?: number; /** 垂直拉伸倍数,1 为默认,仅 type=text */ textScaleY?: number; /** 字间距 (mm),仅 type=text */ letterSpacing?: number; barcodeFormat: 'CODE128' | 'CODE39' | 'EAN13' | 'ITF'; showText: boolean; // For barcode human-readable text below fontFamily: 'sans' | 'serif' | 'mono'; backgroundColor?: string; /** 背景不透明度 0–100,100 为完全不透明;0 或 backgroundColor 为 transparent 时不绘制背景 */ backgroundOpacity?: number; textColor?: string; /** 内边距 (mm),所有元素类型均有效 */ padding?: number; paddingTop?: number; paddingRight?: number; paddingBottom?: number; paddingLeft?: number; locked?: boolean; /** 图层是否隐藏;隐藏后在预览、导出、打印及画布中均不显示 */ hidden?: boolean; /** 图片缩放方式,仅 type=image 时有效 */ imageFit?: 'contain' | 'cover' | 'fill'; /** 默认图片 URL 或 data URI;主图加载失败时使用,仅 type=image 时有效 */ defaultImage?: string; /** 输出模式下内容值为空时仍渲染;条码/二维码/图片有效,默认 false */ showWhenContentEmpty?: boolean; /** 文本显示格式,仅 type=text 时有效 */ textFormat?: TextFormat; /** 数值/百分比/货币的小数位数,默认 2 */ decimalPlaces?: number; /** 数值格式下显示整数或小数部分,仅 type=text 且 textFormat≠text */ numberPartDisplay?: NumberPartDisplay; /** 变量值提取方式(文本/条码/二维码/图片内容均有效) */ textExtractMode?: TextExtractMode; /** 按分隔符拆分时使用的分隔符 */ textSplitDelimiter?: string; /** 分隔后显示第几位(从 1 开始),段数不足时显示为空 */ textSplitIndex?: number; /** 前 N / 后 N 位提取时的位数 */ textExtractLength?: number; /** 反选:从原值中去掉「显示前缀 + 提取段 + 显示后缀」 */ textExtractInverse?: boolean; /** 提取后在显示文本前追加的前缀字符,仅 type=text;不参与内容值条件 */ textDisplayPrefix?: string; /** 提取后在显示文本后追加的后缀字符,仅 type=text;不参与内容值条件 */ textDisplaySuffix?: string; /** 边框宽度 (mm),0 为无边框;各边留空时沿用此值 */ borderWidth?: number; borderColor?: string; borderWidthTop?: number; borderWidthRight?: number; borderWidthBottom?: number; borderWidthLeft?: number; borderColorTop?: string; borderColorRight?: string; borderColorBottom?: string; borderColorLeft?: string; /** @deprecated 使用各边 borderWidth*(0 为不显示) */ borderSides?: Partial>; /** 圆角半径 (mm),可被各角覆盖 */ borderRadius?: number; /** 指定哪些角应用圆角,默认四角 */ borderRadiusCorners?: Partial>; borderRadiusTL?: number; borderRadiusTR?: number; borderRadiusBR?: number; borderRadiusBL?: number; /** 表格行数,仅 type=table */ tableRows?: number; /** 表格列数,仅 type=table */ tableCols?: number; /** 各行高度 (mm),仅 type=table */ tableRowHeights?: number[]; /** 各列宽度 (mm),仅 type=table */ tableColWidths?: number[]; /** 单元格数据,键 `${row},${col}`,仅 type=table */ tableCells?: Record; /** 单元格网格线宽 (mm),仅 type=table,默认 0.2 */ tableBorderWidth?: number; /** 单元格网格线颜色,仅 type=table */ tableBorderColor?: string; /** 图层蒙版;在预览与导出时裁剪元素可见区域 */ mask?: ElementMaskConfig; } export type ElementMaskShape = 'rect' | 'image'; export interface ElementMaskConfig { /** 是否启用蒙版 */ enabled?: boolean; /** 蒙版形状:矩形矢量区域或图片 alpha */ type?: ElementMaskShape; /** 相对元素左上角的 X 偏移 (mm) */ x?: number; /** 相对元素左上角的 Y 偏移 (mm) */ y?: number; /** 蒙版区域宽度 (mm),默认与元素同宽 */ width?: number; /** 蒙版区域高度 (mm),默认与元素同高 */ height?: number; /** 圆角半径 (mm) */ borderRadius?: number; borderRadiusTL?: number; borderRadiusTR?: number; borderRadiusBR?: number; borderRadiusBL?: number; /** 图片蒙版(data URI / URL),type=image 时使用 */ image?: string; /** 图片蒙版在区域内的适应方式 */ imageFit?: 'contain' | 'cover' | 'fill'; /** include=保留蒙版区域内,exclude=保留区域外;默认 include */ mode?: 'include' | 'exclude'; } export interface DataSourceMeta { fileName: string; sheets: string[]; currentSheet: string; columns: string[]; rowCount: number; } export type CutLineStyle = 'dashed' | 'solid'; export interface CutLineConfig { enabled: boolean; style: CutLineStyle; /** 线宽 (mm) */ width: number; color: string; } export type ExportRangeMode = 'all' | 'odd' | 'even' | 'custom'; export interface ExportRangeConfig { mode: ExportRangeMode; /** 自定义范围:1-based 序号,如 "1,3,5-10"(排版过滤,不写入模板) */ custom?: string; } export interface LabelTemplate { id?: string; name?: string; width: number; // in mm height: number; // in mm elements: TemplateElement[]; /** 模板声明的变量名(统一管理;内容/显示控制从此选取) */ variableList?: string[]; /** 设计预览用:变量名 → 默认展示值 */ variableDefaults?: Record; /** 数据过滤条件(写入模板);全部满足的数据行才参与排版/导出 */ dataFilterRules?: VisibilityRule[]; /** 整页排版配置(每模板独立) */ paper?: PaperConfig; /** PDF 裁切参考线配置 */ cutLine?: CutLineConfig; /** 设计画布预览参考背景(URL / data URI) */ previewReferenceBackground?: string; /** 预览参考背景不透明度 0–100,默认 100 */ previewReferenceBackgroundOpacity?: number; /** 预览参考背景适应方式,默认 cover */ previewReferenceBackgroundFit?: 'contain' | 'cover' | 'fill'; /** 设计预览(画布、模板列表缩略图)是否显示参考背景,默认 true */ enablePreviewReferenceBackground?: boolean; /** 生成 PDF / 打印 / 排版预览输出时是否绘制参考背景,默认 false */ includeReferenceBackgroundInOutput?: boolean; /** 排版整页背景图(URL / data URI) */ layoutPageBackground?: string; /** 排版整页背景不透明度 0–100,默认 100 */ layoutPageBackgroundOpacity?: number; /** 排版整页背景适应方式,默认 cover */ layoutPageBackgroundFit?: 'contain' | 'cover' | 'fill'; /** 排版预览是否显示整页背景,默认 true */ enableLayoutPageBackground?: boolean; /** PDF / 打印输出时是否绘制整页背景,默认 false */ includeLayoutPageBackgroundInOutput?: boolean; /** 批量导出图片时的文件名模板,支持 {#SEQ}、{#INDEX}、{变量名};留空则按序号补零命名 */ exportImageFileNamePattern?: string; /** 批量导出图片:all=全部导出,conditional=按条件过滤 */ exportImageFilterMode?: ElementVisibilityMode; /** 批量导出图片过滤条件;全部满足时才导出该枚标签 */ exportImageFilterRules?: VisibilityRule[]; } export type PaperType = 'A4' | 'A5' | 'A6' | 'custom'; /** 排版/印刷输出色彩模式 */ export type PrintColorMode = 'rgb' | 'grayscale' | 'cmyk'; export const PRINT_COLOR_MODE_LABELS: Record = { rgb: '标准(轻度印刷补偿)', grayscale: '黑白(灰度)', cmyk: 'CMYK 印刷模拟(推荐)', }; export interface PaperConfig { type: PaperType; width: number; // in mm height: number; // in mm orientation: 'portrait' | 'landscape'; marginTop: number; // in mm marginRight: number; // in mm marginBottom: number; // in mm marginLeft: number; // in mm columnGap: number; // in mm (horizontal spacing between labels) rowGap: number; // in mm (vertical spacing between labels) flow: 'top-bottom-left-right' | 'left-right-top-bottom'; // how cells flow /** 排版预览与导出时的色彩模式,默认 rgb */ printColorMode?: PrintColorMode; } export interface RecordRow { [key: string]: string; } export interface ImportData { fileName: string; sheets: string[]; currentSheet: string; columns: string[]; rows: RecordRow[]; }