feat: 完善全栈 Dashboard 项目 - UI优化、Docker支持、账单系统等
This commit is contained in:
66
server/utils/font.ts
Normal file
66
server/utils/font.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const FONTS_DIR = path.join(__dirname, '..', 'fonts')
|
||||
const FONT_FILE = path.join(FONTS_DIR, 'NotoSansSC-Regular.otf')
|
||||
|
||||
const CDN_URLS = [
|
||||
'https://cdn.jsdelivr.net/gh/googlefonts/noto-cjk@main/Sans/SubsetOTF/SC/NotoSansSC-Regular.otf',
|
||||
'https://raw.githubusercontent.com/googlefonts/noto-cjk/main/Sans/SubsetOTF/SC/NotoSansSC-Regular.otf',
|
||||
]
|
||||
|
||||
let fontReady: string | null = null
|
||||
|
||||
export async function ensureChineseFont(): Promise<string> {
|
||||
if (fontReady) return fontReady
|
||||
|
||||
// Check if already downloaded
|
||||
if (fs.existsSync(FONT_FILE) && fs.statSync(FONT_FILE).size > 100000) {
|
||||
fontReady = FONT_FILE
|
||||
return FONT_FILE
|
||||
}
|
||||
|
||||
// Ensure directory exists
|
||||
if (!fs.existsSync(FONTS_DIR)) fs.mkdirSync(FONTS_DIR, { recursive: true })
|
||||
|
||||
// Try each CDN URL
|
||||
for (const url of CDN_URLS) {
|
||||
try {
|
||||
console.log(`Downloading Chinese font from ${url.split('/')[2]}...`)
|
||||
const res = await fetch(url, { signal: AbortSignal.timeout(60000) })
|
||||
if (!res.ok) continue
|
||||
const buf = Buffer.from(await res.arrayBuffer())
|
||||
if (buf.length < 100000) continue // too small, probably error page
|
||||
fs.writeFileSync(FONT_FILE, buf)
|
||||
console.log(`Chinese font downloaded (${(buf.length / 1024 / 1024).toFixed(1)} MB)`)
|
||||
fontReady = FONT_FILE
|
||||
return FONT_FILE
|
||||
} catch (e: any) {
|
||||
console.warn(`Font download failed from ${url.split('/')[2]}: ${e.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: try local system fonts
|
||||
const fallbacks = [
|
||||
'C:\\Windows\\Fonts\\simhei.ttf',
|
||||
'C:\\Windows\\Fonts\\msyh.ttf',
|
||||
'/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc',
|
||||
'/System/Library/Fonts/PingFang.ttc',
|
||||
]
|
||||
for (const f of fallbacks) {
|
||||
if (fs.existsSync(f)) {
|
||||
console.log(`Using fallback system font: ${f}`)
|
||||
fontReady = f
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('No Chinese font available. Set PDF_FONT_PATH env variable to a TTF/OTF font path.')
|
||||
}
|
||||
|
||||
export function getChineseFont(): string {
|
||||
if (!fontReady) throw new Error('Font not initialized. Call ensureChineseFont() first.')
|
||||
return fontReady
|
||||
}
|
||||
Reference in New Issue
Block a user