| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import { FILE_BASE, API_HOST } from '@/config'
- const PLACEHOLDER_PATHS = ['/static/logo.png']
- const API_PROXY_PREFIX = /^\/(dev-api|prod-api|shop-api)\//i
- /** 是否外链或 data URL */
- export function isExternalUrl(url) {
- if (!url) return false
- return /^(https?:|data:|\/\/)/i.test(String(url).trim())
- }
- /** 去掉 /dev-api、/shop-api 等代理前缀,得到后端真实路径 */
- function stripApiProxyPrefix(path) {
- return String(path).replace(/^\/(dev-api|prod-api|shop-api)/, '') || '/'
- }
- function isPlaceholderPath(path) {
- const raw = String(path || '').trim()
- return PLACEHOLDER_PATHS.includes(raw)
- }
- /**
- * 图片根地址
- * - H5 生产:自动取浏览器当前访问的 IP/域名(window.location.origin)
- * - H5 开发 / 小程序:用 .env 里的 VITE_APP_API_HOST
- */
- export function getFileBase() {
- // #ifdef H5
- if (import.meta.env.PROD && typeof window !== 'undefined') {
- const origin = window.location?.origin
- if (origin && origin !== 'null') {
- return origin.replace(/\/$/, '')
- }
- }
- // #endif
- return String(FILE_BASE).replace(/\/$/, '')
- }
- /** 拼接图片完整 URL */
- function joinFileUrlRuntime(path) {
- const base = getFileBase()
- if (!path) return base
- if (/^https?:\/\//i.test(path)) return path
- const p = path.startsWith('/') ? path : `/${path}`
- return base + p
- }
- /**
- * 是否已是可直接使用的图片地址(避免重复拼接)
- */
- export function isResolvedFileUrl(url) {
- if (!url) return false
- const raw = String(url).trim()
- if (isExternalUrl(raw)) return true
- if (raw.startsWith('/static/')) return true
- const fileBase = getFileBase()
- if (fileBase && (raw === fileBase || raw.startsWith(`${fileBase}/`))) return true
- if (API_PROXY_PREFIX.test(raw)) return true
- const apiHost = String(API_HOST).replace(/\/$/, '')
- return !!(apiHost && apiHost.startsWith('http') && (raw === apiHost || raw.startsWith(`${apiHost}/`)))
- }
- /**
- * 将后端返回的图片路径转为可展示的 URL(可重复调用)
- * - H5 生产:http://当前访问IP/profile/upload/xxx.jpg(自动)
- * - 开发:http://VITE_APP_API_HOST/profile/upload/xxx.jpg
- */
- export function resolveFileUrl(path) {
- if (path == null || path === '') {
- return ''
- }
- let raw = String(path).split(',')[0].trim()
- if (!raw || isPlaceholderPath(raw)) {
- return ''
- }
- if (isExternalUrl(raw) || raw.startsWith('/static/')) {
- return raw
- }
- const fileBase = getFileBase()
- if (fileBase && (raw === fileBase || raw.startsWith(`${fileBase}/`))) {
- return raw
- }
- if (API_PROXY_PREFIX.test(raw)) {
- return raw
- }
- const apiHost = String(API_HOST).replace(/\/$/, '')
- if (apiHost && apiHost.startsWith('http') && (raw === apiHost || raw.startsWith(`${apiHost}/`))) {
- return raw
- }
- if (API_PROXY_PREFIX.test(raw)) {
- raw = stripApiProxyPrefix(raw)
- }
- const normalized = raw.startsWith('/') ? raw : `/${raw}`
- return joinFileUrlRuntime(normalized)
- }
- /**
- * 将逗号分隔或数组形式的图片路径转为 URL 列表
- */
- export function resolveFileUrlList(pathOrList) {
- if (pathOrList == null || pathOrList === '') return []
- if (Array.isArray(pathOrList)) {
- return pathOrList.map((item) => resolveFileUrl(item)).filter(Boolean)
- }
- return String(pathOrList)
- .split(',')
- .map((s) => resolveFileUrl(s.trim()))
- .filter(Boolean)
- }
|