import type { WatermarkConfig, WatermarkPosition } from '#/api/x/dms/watermark';
|
|
export const CUSTOM_BARCODE_TEMPLATE = '{/CUSTOM_BARCODE_TEXT}';
|
|
export const WATERMARK_TYPE_LABELS = { BARCODE: '条码', IMAGE: '图片', TEXT: '文本' } as const;
|
export const VERSION_SCOPE_LABELS = { ALL: '所有版本', CURRENT: '现行版本' } as const;
|
export const SCENE_LABELS = { DOWNLOAD: '下载', PREVIEW: '预览', PRINT: '打印' } as const;
|
export const LAYOUT_LABELS = { POSITION: '按位置', TILED: '整页重复' } as const;
|
|
export const PAPER_SIZES = {
|
A4: { widthMm: 210, heightMm: 297 },
|
A3: { widthMm: 297, heightMm: 420 },
|
} as const;
|
|
export type PaperType = keyof typeof PAPER_SIZES;
|
|
export function defaultPosition(paperType: PaperType = 'A4', markWidthMm = 80, markHeightMm = 20): WatermarkPosition {
|
const { widthMm, heightMm } = PAPER_SIZES[paperType];
|
const center = (pageSize: number, markSize: number) => Math.max(0, Math.floor((pageSize - markSize) / 2));
|
return {
|
paperType,
|
paperWidthMm: widthMm,
|
paperHeightMm: heightMm,
|
portraitXMm: center(widthMm, markWidthMm),
|
portraitYMm: center(heightMm, markHeightMm),
|
landscapeXMm: center(heightMm, markWidthMm),
|
landscapeYMm: center(widthMm, markHeightMm),
|
};
|
}
|
|
export function validatePositionConfiguration(config: WatermarkConfig): string | undefined {
|
const markWidth = Number(config.markWidthMm);
|
const markHeight = Number(config.markHeightMm);
|
const angle = Number(config.rotationAngle);
|
if (![markWidth, markHeight, angle].every((value) => Number.isFinite(value)) || markWidth <= 0 || markHeight <= 0) {
|
return '请输入有效的水印宽度、高度和旋转角度';
|
}
|
|
const radians = (angle * Math.PI) / 180;
|
const drawnWidth = Math.abs(markWidth * Math.cos(radians)) + Math.abs(markHeight * Math.sin(radians));
|
const drawnHeight = Math.abs(markWidth * Math.sin(radians)) + Math.abs(markHeight * Math.cos(radians));
|
const paperTypes = new Set<string>();
|
|
for (const position of config.positions) {
|
const paperType = position.paperType?.trim().toUpperCase();
|
if (!paperType) return '请选择纸张类型';
|
if (paperTypes.has(paperType)) return `${paperType} 已配置,请勿重复添加`;
|
paperTypes.add(paperType);
|
|
const width = Number(position.paperWidthMm);
|
const height = Number(position.paperHeightMm);
|
if (![width, height].every((value) => Number.isFinite(value)) || width <= 0 || height <= 0) return `${paperType} 的纸张尺寸无效`;
|
|
const orientations = [
|
{ label: '纵向', pageWidth: width, pageHeight: height, x: Number(position.portraitXMm), y: Number(position.portraitYMm) },
|
{ label: '横向', pageWidth: height, pageHeight: width, x: Number(position.landscapeXMm), y: Number(position.landscapeYMm) },
|
];
|
for (const { label, pageWidth, pageHeight, x, y } of orientations) {
|
if (![x, y].every((value) => Number.isFinite(value)) || x < 0 || y < 0 || x > pageWidth || y > pageHeight) {
|
return `${paperType} ${label}位置的 X/Y 必须位于纸张范围内`;
|
}
|
if (config.layoutMode === 'TILED') {
|
if (x === pageWidth || y === pageHeight) return `${paperType} ${label}位置的重复起点必须位于纸张内`;
|
continue;
|
}
|
|
const drawnX = x - (drawnWidth - markWidth) / 2;
|
const drawnY = y - (drawnHeight - markHeight) / 2;
|
if (
|
x + markWidth > pageWidth + 0.01 ||
|
y + markHeight > pageHeight + 0.01 ||
|
drawnX < -0.01 ||
|
drawnY < -0.01 ||
|
drawnX + drawnWidth > pageWidth + 0.01 ||
|
drawnY + drawnHeight > pageHeight + 0.01
|
) {
|
return `${paperType} ${label}位置会使水印超出纸张,请调整坐标或水印尺寸`;
|
}
|
}
|
}
|
}
|
|
export function defaultWatermark(): WatermarkConfig {
|
return {
|
name: '',
|
watermarkType: 'TEXT',
|
versionScope: 'ALL',
|
loadScenes: ['DOWNLOAD'],
|
watermarkBusinessTypes: [],
|
enabled: true,
|
enterpriseName: '',
|
contentTemplate: '',
|
fontFamily: 'SimHei',
|
fontColor: '#666666',
|
fontSize: 24,
|
rotationAngle: 0,
|
opacity: 30,
|
layoutMode: 'POSITION',
|
markWidthMm: 80,
|
markHeightMm: 20,
|
horizontalAlign: 'LEFT',
|
verticalAlign: 'TOP',
|
repeatSpacingXMm: 20,
|
repeatSpacingYMm: 20,
|
showBarcodeText: false,
|
positions: [defaultPosition()],
|
};
|
}
|
|
export function sceneText(scenes: string[] = []) {
|
return scenes.map((item) => SCENE_LABELS[item as keyof typeof SCENE_LABELS] || item).join('、');
|
}
|