375 lines
14 KiB
TypeScript
375 lines
14 KiB
TypeScript
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<TextExtractMode, string> = {
|
||
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<VisibilityRuleTarget, string> = {
|
||
variable: '变量',
|
||
content: '内容值',
|
||
};
|
||
|
||
export const VISIBILITY_OPERATOR_LABELS: Record<VisibilityOperator, string> = {
|
||
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<Record<ElementSide, boolean>>;
|
||
/** 圆角半径 (mm),可被各角覆盖 */
|
||
borderRadius?: number;
|
||
/** 指定哪些角应用圆角,默认四角 */
|
||
borderRadiusCorners?: Partial<Record<ElementCorner, boolean>>;
|
||
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<string, TableCellData>;
|
||
/** 单元格网格线宽 (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<string, string>;
|
||
/** 数据过滤条件(写入模板);全部满足的数据行才参与排版/导出 */
|
||
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<PrintColorMode, string> = {
|
||
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[];
|
||
}
|