ai-c/utils/imageUrl.js
2026-02-02 18:21:32 +08:00

122 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 图片URL处理工具
* 统一处理相对路径和绝对路径的图片URL
*/
const config = require('../config/index')
function getImageBaseUrl() {
const apiBaseUrl = String(config?.API_BASE_URL || '').trim()
if (!apiBaseUrl) return 'https://ai-c.maimanji.com'
try {
const parsed = new URL(apiBaseUrl)
return parsed.origin
} catch (_) {
return apiBaseUrl.replace(/\/api\/?$/, '').replace(/\/+$/, '')
}
}
// 获取图片基础URL只保留 origin
const IMAGE_BASE_URL = getImageBaseUrl()
/**
* 转换图片URL为完整地址
* @param {string} url - 图片URL可能是相对路径或绝对路径
* @param {string} defaultImage - 默认图片路径(可选)
* @returns {string} 完整的图片URL
*/
function getFullImageUrl(url, defaultImage = '') {
// 如果没有URL返回默认图片
if (!url) {
return defaultImage || '/images/icon-empty.png'
}
if (url.startsWith('wxfile://')) {
return defaultImage || '/images/icon-empty.png'
}
if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('data:')) {
try {
const parsed = new URL(url)
if (parsed.pathname.startsWith('/uploads/')) {
parsed.pathname = `/api/uploads/${parsed.pathname.slice('/uploads/'.length)}`
return parsed.toString()
}
if (/^\/(avatars|characters|audio|documents|assets|interest-partners|exchange|products|temp)\//.test(parsed.pathname)) {
parsed.pathname = `/api/uploads${parsed.pathname}`
return parsed.toString()
}
return url
} catch (_) {
return url
}
}
// 如果是本地图片路径(/images/开头),直接返回
if (url.startsWith('/images/')) {
return url
}
let processedUrl = url
if (processedUrl.startsWith('/uploads/')) {
processedUrl = `/api/uploads/${processedUrl.slice('/uploads/'.length)}`
} else if (processedUrl.startsWith('uploads/')) {
processedUrl = `/api/uploads/${processedUrl.slice('uploads/'.length)}`
} else if (/^(\/)?(avatars|characters|audio|documents|assets|interest-partners|exchange|products|temp)\//.test(processedUrl)) {
processedUrl = processedUrl.startsWith('/') ? `/api/uploads${processedUrl}` : `/api/uploads/${processedUrl}`
}
// 其他相对路径,拼接服务器地址
// 确保URL以/开头
const normalizedUrl = processedUrl.startsWith('/') ? processedUrl : '/' + processedUrl
return IMAGE_BASE_URL + normalizedUrl
}
/**
* 批量转换图片URL数组
* @param {Array<string>} urls - 图片URL数组
* @returns {Array<string>} 完整的图片URL数组
*/
function getFullImageUrls(urls) {
if (!Array.isArray(urls)) {
return []
}
return urls.map(url => getFullImageUrl(url))
}
/**
* 处理用户头像URL
* @param {string} avatar - 头像URL
* @returns {string} 完整的头像URL
*/
function getAvatarUrl(avatar) {
return getFullImageUrl(avatar, '/images/default-avatar.svg')
}
/**
* 处理角色头像URL
* @param {string} avatar - 角色头像URL
* @returns {string} 完整的头像URL
*/
function getCharacterAvatarUrl(avatar) {
return getFullImageUrl(avatar, '/images/character-default.png')
}
/**
* 处理活动封面URL
* @param {string} cover - 封面URL
* @returns {string} 完整的封面URL
*/
function getActivityCoverUrl(cover) {
return getFullImageUrl(cover, '/images/activity-default.jpg')
}
module.exports = {
getFullImageUrl,
getFullImageUrls,
getAvatarUrl,
getCharacterAvatarUrl,
getActivityCoverUrl,
IMAGE_BASE_URL
}