43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
import './text-encoding-polyfill';
|
||
import QRCode from 'qrcode';
|
||
|
||
const QR_SIZE = 240;
|
||
const QR_OPTIONS = {
|
||
width: QR_SIZE * 2,
|
||
margin: 0,
|
||
color: { dark: '#1f1a17', light: '#ffffff' },
|
||
} as const;
|
||
|
||
/** 在 2d Canvas 上绘制二维码(小程序 / H5 通用) */
|
||
export function drawRedeemQrOnCanvas(
|
||
ctx: CanvasRenderingContext2D,
|
||
token: string,
|
||
sizePx = QR_SIZE,
|
||
) {
|
||
const qr = QRCode.create(token, { errorCorrectionLevel: 'M' });
|
||
const count = qr.modules.size;
|
||
const cell = sizePx / count;
|
||
|
||
ctx.fillStyle = '#ffffff';
|
||
ctx.fillRect(0, 0, sizePx, sizePx);
|
||
ctx.fillStyle = '#1f1a17';
|
||
for (let row = 0; row < count; row++) {
|
||
for (let col = 0; col < count; col++) {
|
||
if (qr.modules.get(row, col)) {
|
||
ctx.fillRect(col * cell, row * cell, cell, cell);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/** H5:Data URL;失败时回退到与 h5-user 相同的外部 QR 服务 */
|
||
export async function buildRedeemQrDataUrl(token: string): Promise<string> {
|
||
try {
|
||
return await QRCode.toDataURL(token, QR_OPTIONS);
|
||
} catch {
|
||
return `https://api.qrserver.com/v1/create-qr-code/?size=${QR_SIZE * 2}x${QR_SIZE * 2}&data=${encodeURIComponent(token)}`;
|
||
}
|
||
}
|
||
|
||
export const REDEEM_QR_DISPLAY_SIZE = QR_SIZE;
|