刘光辉
7 小时以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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('、');
}