fix(c2c-bot): 安装中文字体解决水单图片乱码问题

Alpine Linux 容器没有中文字体,sharp 渲染 SVG 时中文显示为方块。
- Dockerfile: 安装 fontconfig + font-noto-cjk 并刷新字体缓存
- SVG 模板: font-family 改为 Noto Sans CJK SC

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-02 18:56:55 -08:00
parent 21f51c5d84
commit 2de4baf0af
2 changed files with 15 additions and 15 deletions

View File

@ -22,7 +22,7 @@ FROM node:20-alpine AS runner
RUN addgroup --system --gid 1001 nodejs && \ RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 -G nodejs nestjs adduser --system --uid 1001 -G nodejs nestjs
RUN apk add --no-cache curl tzdata openssl su-exec RUN apk add --no-cache curl tzdata openssl su-exec fontconfig font-noto-cjk && fc-cache -f
RUN mkdir -p /app && chown nestjs:nodejs /app RUN mkdir -p /app && chown nestjs:nodejs /app
WORKDIR /app WORKDIR /app

View File

@ -60,39 +60,39 @@ export class PaymentProofService {
<!-- Header --> <!-- Header -->
<rect x="20" y="20" width="560" height="70" rx="12" fill="#1e40af"/> <rect x="20" y="20" width="560" height="70" rx="12" fill="#1e40af"/>
<rect x="20" y="60" width="560" height="30" fill="#1e40af"/> <rect x="20" y="60" width="560" height="30" fill="#1e40af"/>
<text x="300" y="62" text-anchor="middle" font-family="Arial,sans-serif" font-size="22" font-weight="bold" fill="white">C2C Bot </text> <text x="300" y="62" text-anchor="middle" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="22" font-weight="bold" fill="white">C2C Bot </text>
<!-- Stamp --> <!-- Stamp -->
<circle cx="510" cy="160" r="40" fill="none" stroke="#16a34a" stroke-width="2.5" opacity="0.5"/> <circle cx="510" cy="160" r="40" fill="none" stroke="#16a34a" stroke-width="2.5" opacity="0.5"/>
<text x="510" y="155" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" font-weight="bold" fill="#16a34a" opacity="0.5"></text> <text x="510" y="155" text-anchor="middle" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="13" font-weight="bold" fill="#16a34a" opacity="0.5"></text>
<text x="510" y="172" text-anchor="middle" font-family="Arial,sans-serif" font-size="10" fill="#16a34a" opacity="0.5">COMPLETED</text> <text x="510" y="172" text-anchor="middle" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="10" fill="#16a34a" opacity="0.5">COMPLETED</text>
<!-- Fields --> <!-- Fields -->
<text x="60" y="135" font-family="Arial,sans-serif" font-size="13" fill="#64748b"></text> <text x="60" y="135" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="13" fill="#64748b"></text>
<text x="60" y="158" font-family="Arial,sans-serif" font-size="16" font-weight="bold" fill="#1e293b">${this.esc(data.orderNo)}</text> <text x="60" y="158" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="16" font-weight="bold" fill="#1e293b">${this.esc(data.orderNo)}</text>
<line x1="60" y1="175" x2="540" y2="175" stroke="#e2e8f0" stroke-width="1"/> <line x1="60" y1="175" x2="540" y2="175" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="200" font-family="Arial,sans-serif" font-size="13" fill="#64748b"> (dUSDT)</text> <text x="60" y="200" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="13" fill="#64748b"> (dUSDT)</text>
<text x="60" y="228" font-family="Arial,sans-serif" font-size="26" font-weight="bold" fill="#1e40af">${this.esc(data.amount)}</text> <text x="60" y="228" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="26" font-weight="bold" fill="#1e40af">${this.esc(data.amount)}</text>
<line x1="60" y1="248" x2="540" y2="248" stroke="#e2e8f0" stroke-width="1"/> <line x1="60" y1="248" x2="540" y2="248" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="275" font-family="Arial,sans-serif" font-size="13" fill="#64748b"></text> <text x="60" y="275" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="13" fill="#64748b"></text>
<text x="60" y="298" font-family="monospace,Arial" font-size="14" fill="#1e293b">${this.esc(shortTx)}</text> <text x="60" y="298" font-family="monospace,Noto Sans CJK SC,sans-serif" font-size="14" fill="#1e293b">${this.esc(shortTx)}</text>
<line x1="60" y1="315" x2="540" y2="315" stroke="#e2e8f0" stroke-width="1"/> <line x1="60" y1="315" x2="540" y2="315" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="340" font-family="Arial,sans-serif" font-size="13" fill="#64748b"></text> <text x="60" y="340" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="13" fill="#64748b"></text>
<text x="60" y="363" font-family="monospace,Arial" font-size="14" fill="#1e293b">${this.esc(shortAddr)}</text> <text x="60" y="363" font-family="monospace,Noto Sans CJK SC,sans-serif" font-size="14" fill="#1e293b">${this.esc(shortAddr)}</text>
<line x1="60" y1="380" x2="540" y2="380" stroke="#e2e8f0" stroke-width="1"/> <line x1="60" y1="380" x2="540" y2="380" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="405" font-family="Arial,sans-serif" font-size="13" fill="#64748b"></text> <text x="60" y="405" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="13" fill="#64748b"></text>
<text x="60" y="428" font-family="Arial,sans-serif" font-size="15" fill="#1e293b">${this.esc(time)}</text> <text x="60" y="428" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="15" fill="#1e293b">${this.esc(time)}</text>
<!-- Footer --> <!-- Footer -->
<text x="300" y="458" text-anchor="middle" font-family="Arial,sans-serif" font-size="11" fill="#94a3b8"> · RWAdurian C2C Bot</text> <text x="300" y="458" text-anchor="middle" font-family="Noto Sans CJK SC,Noto Sans SC,sans-serif" font-size="11" fill="#94a3b8"> · RWAdurian C2C Bot</text>
</svg>`; </svg>`;
} }