This commit is contained in:
iqudoo
2026-06-14 03:59:45 +08:00
parent 833eda5621
commit 1e03b7750a
23 changed files with 1499 additions and 153 deletions

View File

@@ -1,6 +1,6 @@
import JsBarcode from 'jsbarcode';
import QRCode from 'qrcode';
import { TemplateElement, RecordRow } from './types';
import { TemplateElement, RecordRow, LabelTemplate } from './types';
import {
resolveElementValue,
isGraphicContentEmpty,
@@ -568,6 +568,10 @@ export interface RenderLabelOptions {
transparentBackground?: boolean;
variableDefaults?: Record<string, string> | null;
mode?: ContentResolveMode;
/** 输出参考背景(生成/打印),绘制在元素下层 */
referenceBackground?: string;
referenceBackgroundOpacity?: number;
referenceBackgroundFit?: 'contain' | 'cover' | 'fill';
/** 渲染倍率,默认 16PDF 导出可用较低倍率以减轻内存与耗时 */
scale?: number;
/** 输出格式,默认 png */
@@ -577,6 +581,47 @@ export interface RenderLabelOptions {
clipToCanvas?: boolean;
}
export type ReferenceBackgroundRenderOptions = Pick<
RenderLabelOptions,
'referenceBackground' | 'referenceBackgroundOpacity' | 'referenceBackgroundFit'
>;
type ReferenceBackgroundTemplate = Pick<
LabelTemplate,
'previewReferenceBackground' | 'previewReferenceBackgroundOpacity' | 'previewReferenceBackgroundFit'
>;
function buildReferenceBackgroundRenderOptions(
template: ReferenceBackgroundTemplate
): ReferenceBackgroundRenderOptions {
if (!template.previewReferenceBackground) {
return {};
}
return {
referenceBackground: template.previewReferenceBackground,
referenceBackgroundOpacity: template.previewReferenceBackgroundOpacity ?? 100,
referenceBackgroundFit: template.previewReferenceBackgroundFit ?? 'cover',
};
}
/** 模板列表 / 设计预览等:有参考图即绘制 */
export function resolveReferenceBackgroundForPreview(
template: ReferenceBackgroundTemplate
): ReferenceBackgroundRenderOptions {
return buildReferenceBackgroundRenderOptions(template);
}
/** 模板开启「输出参考背景」时,供 PDF / 打印 / 排版预览使用的渲染参数 */
export function resolveReferenceBackgroundForOutput(
template: ReferenceBackgroundTemplate &
Pick<LabelTemplate, 'includeReferenceBackgroundInOutput'>
): ReferenceBackgroundRenderOptions {
if (!template.includeReferenceBackgroundInOutput) {
return {};
}
return buildReferenceBackgroundRenderOptions(template);
}
/** 离屏渲染标签为 PNG data URL */
export async function renderLabelToDataUrl(options: RenderLabelOptions): Promise<string> {
const {
@@ -589,6 +634,9 @@ export async function renderLabelToDataUrl(options: RenderLabelOptions): Promise
transparentBackground = false,
variableDefaults = null,
mode = 'design',
referenceBackground,
referenceBackgroundOpacity = 100,
referenceBackgroundFit = 'cover',
scale: scaleOption = 16,
imageFormat = 'png',
jpegQuality = 0.92,
@@ -618,6 +666,16 @@ export async function renderLabelToDataUrl(options: RenderLabelOptions): Promise
ctx.setLineDash([]);
}
if (referenceBackground) {
const refImg = await loadImageOrNull(referenceBackground);
if (refImg) {
ctx.save();
ctx.globalAlpha = Math.min(1, Math.max(0, referenceBackgroundOpacity / 100));
drawImageWithFit(ctx, refImg, 0, 0, canvas.width, canvas.height, referenceBackgroundFit);
ctx.restore();
}
}
ctx.save();
if (clipToCanvas) {
ctx.beginPath();