123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- import fs from 'fs'
- import path from 'path'
- import { localizeImage } from './image-localizer'
-
- /**
- * 从JSON文件提取图片URL并下载到本地
- * @param jsonFilePath JSON文件路径
- * @param imageFields 包含图片URL的字段名称数组
- */
- async function extractAndDownloadImages(
- jsonFilePath: string,
- imageFields = ['image', 'imageUrl', 'thumbnail', 'cover', 'avatar', 'photo', 'src']
- ) {
- // 检查文件是否存在
- if (!fs.existsSync(jsonFilePath)) {
- console.error(`文件不存在: ${jsonFilePath}`)
- return
- }
-
- try {
- // 读取JSON文件
- const jsonData = JSON.parse(fs.readFileSync(jsonFilePath, 'utf-8'))
-
- // 递归查找所有图片URL
- const imageUrls = new Set<string>()
-
- // 递归函数查找所有图片URL
- function findImageUrls(obj: any) {
- if (!obj) return
-
- if (Array.isArray(obj)) {
- obj.forEach(item => findImageUrls(item))
- return
- }
-
- if (typeof obj === 'object') {
- for (const [key, value] of Object.entries(obj)) {
- if (imageFields.includes(key) && typeof value === 'string' && value.startsWith('http')) {
- imageUrls.add(value)
- } else if (typeof value === 'object' && value !== null) {
- findImageUrls(value)
- }
- }
- }
- }
-
- findImageUrls(jsonData)
-
- // 下载所有图片
- console.log(`在 ${jsonFilePath} 中找到 ${imageUrls.size} 个图片URL`)
-
- let downloadedCount = 0
- for (const url of imageUrls) {
- try {
- const localUrl = await localizeImage(url)
- if (localUrl !== url) {
- downloadedCount++
- console.log(`已下载: ${url} -> ${localUrl}`)
- }
- } catch (error) {
- console.error(`下载失败 ${url}:`, error)
- }
- }
-
- console.log(`成功下载 ${downloadedCount}/${imageUrls.size} 个图片`)
-
- // 将本地化的图片URL写回到JSON文件
- try {
- const localizedData = await localizeImages(jsonData)
- fs.writeFileSync(jsonFilePath, JSON.stringify(localizedData, null, 2))
- console.log(`已更新图片URL至本地路径: ${jsonFilePath}`)
- } catch (error) {
- console.error(`无法更新JSON文件 ${jsonFilePath}:`, error)
- }
- } catch (error) {
- console.error(`处理文件 ${jsonFilePath} 时出错:`, error)
- }
- }
-
- /**
- * 递归处理对象中的所有图片URL
- * 此函数是image-localizer.ts中同名函数的复制,以避免在命令行运行时的循环依赖问题
- */
- async function localizeImages(
- data: any,
- imageFields = ['image', 'imageUrl', 'thumbnail', 'cover', 'avatar', 'photo', 'src']
- ): Promise<any> {
- if (!data) return data
-
- // 处理数组
- if (Array.isArray(data)) {
- return Promise.all(data.map(item => localizeImages(item, imageFields)))
- }
-
- // 处理对象
- if (typeof data === 'object') {
- const result = { ...data }
-
- // 处理所有键
- for (const [key, value] of Object.entries(result)) {
- // 如果是图片字段且值是字符串,本地化图片
- if (imageFields.includes(key) && typeof value === 'string') {
- result[key] = await localizeImage(value)
- }
- // 递归处理嵌套对象或数组
- else if (typeof value === 'object' && value !== null) {
- result[key] = await localizeImages(value, imageFields)
- }
- }
-
- return result
- }
-
- return data
- }
-
- /**
- * 处理API响应文件中的图片
- * @param outputDir 输出目录路径(通常是.output目录)
- */
- export async function processApiResponseImages(outputDir = '.output') {
- console.log('开始处理API响应文件中的图片...')
-
- // 检查输出目录是否存在
- if (!fs.existsSync(outputDir)) {
- console.error(`输出目录不存在: ${outputDir}`)
- return
- }
-
- const serverDir = path.join(outputDir, 'server/api')
-
- if (!fs.existsSync(serverDir)) {
- console.error(`服务器API目录不存在: ${serverDir}`)
- return
- }
-
- console.log(`扫描API响应文件: ${serverDir}`)
-
- // 递归函数查找所有JSON文件
- async function processDirectory(dir: string) {
- const entries = fs.readdirSync(dir, { withFileTypes: true })
-
- for (const entry of entries) {
- const fullPath = path.join(dir, entry.name)
-
- if (entry.isDirectory()) {
- await processDirectory(fullPath)
- } else if (entry.name.endsWith('.json')) {
- console.log(`处理JSON文件: ${fullPath}`)
- await extractAndDownloadImages(fullPath)
- }
- }
- }
-
- await processDirectory(serverDir)
- console.log('所有API响应文件处理完成')
- }
-
- // 允许通过命令行直接运行
- // 兼容 ESM 和 CommonJS
- if (typeof require !== 'undefined' && require.main === module) {
- const outputDir = process.argv[2] || '.output'
- processApiResponseImages(outputDir)
- .then(() => console.log('图片本地化处理完成'))
- .catch(error => console.error('图片本地化处理失败:', error))
- }
-
- // 导出主函数,供脚本调用
- export default processApiResponseImages
|