巴青农资商城

image.js 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import { FILE_BASE, API_HOST } from '@/config'
  2. const PLACEHOLDER_PATHS = ['/static/logo.png']
  3. const API_PROXY_PREFIX = /^\/(dev-api|prod-api|shop-api)\//i
  4. /** 是否外链或 data URL */
  5. export function isExternalUrl(url) {
  6. if (!url) return false
  7. return /^(https?:|data:|\/\/)/i.test(String(url).trim())
  8. }
  9. /** 去掉 /dev-api、/shop-api 等代理前缀,得到后端真实路径 */
  10. function stripApiProxyPrefix(path) {
  11. return String(path).replace(/^\/(dev-api|prod-api|shop-api)/, '') || '/'
  12. }
  13. function isPlaceholderPath(path) {
  14. const raw = String(path || '').trim()
  15. return PLACEHOLDER_PATHS.includes(raw)
  16. }
  17. /**
  18. * 图片根地址
  19. * - H5 生产:自动取浏览器当前访问的 IP/域名(window.location.origin)
  20. * - H5 开发 / 小程序:用 .env 里的 VITE_APP_API_HOST
  21. */
  22. export function getFileBase() {
  23. // #ifdef H5
  24. if (import.meta.env.PROD && typeof window !== 'undefined') {
  25. const origin = window.location?.origin
  26. if (origin && origin !== 'null') {
  27. return origin.replace(/\/$/, '')
  28. }
  29. }
  30. // #endif
  31. return String(FILE_BASE).replace(/\/$/, '')
  32. }
  33. /** 拼接图片完整 URL */
  34. function joinFileUrlRuntime(path) {
  35. const base = getFileBase()
  36. if (!path) return base
  37. if (/^https?:\/\//i.test(path)) return path
  38. const p = path.startsWith('/') ? path : `/${path}`
  39. return base + p
  40. }
  41. /**
  42. * 是否已是可直接使用的图片地址(避免重复拼接)
  43. */
  44. export function isResolvedFileUrl(url) {
  45. if (!url) return false
  46. const raw = String(url).trim()
  47. if (isExternalUrl(raw)) return true
  48. if (raw.startsWith('/static/')) return true
  49. const fileBase = getFileBase()
  50. if (fileBase && (raw === fileBase || raw.startsWith(`${fileBase}/`))) return true
  51. if (API_PROXY_PREFIX.test(raw)) return true
  52. const apiHost = String(API_HOST).replace(/\/$/, '')
  53. return !!(apiHost && apiHost.startsWith('http') && (raw === apiHost || raw.startsWith(`${apiHost}/`)))
  54. }
  55. /**
  56. * 将后端返回的图片路径转为可展示的 URL(可重复调用)
  57. * - H5 生产:http://当前访问IP/profile/upload/xxx.jpg(自动)
  58. * - 开发:http://VITE_APP_API_HOST/profile/upload/xxx.jpg
  59. */
  60. export function resolveFileUrl(path) {
  61. if (path == null || path === '') {
  62. return ''
  63. }
  64. let raw = String(path).split(',')[0].trim()
  65. if (!raw || isPlaceholderPath(raw)) {
  66. return ''
  67. }
  68. if (isExternalUrl(raw) || raw.startsWith('/static/')) {
  69. return raw
  70. }
  71. const fileBase = getFileBase()
  72. if (fileBase && (raw === fileBase || raw.startsWith(`${fileBase}/`))) {
  73. return raw
  74. }
  75. if (API_PROXY_PREFIX.test(raw)) {
  76. return raw
  77. }
  78. const apiHost = String(API_HOST).replace(/\/$/, '')
  79. if (apiHost && apiHost.startsWith('http') && (raw === apiHost || raw.startsWith(`${apiHost}/`))) {
  80. return raw
  81. }
  82. if (API_PROXY_PREFIX.test(raw)) {
  83. raw = stripApiProxyPrefix(raw)
  84. }
  85. const normalized = raw.startsWith('/') ? raw : `/${raw}`
  86. return joinFileUrlRuntime(normalized)
  87. }
  88. /**
  89. * 将逗号分隔或数组形式的图片路径转为 URL 列表
  90. */
  91. export function resolveFileUrlList(pathOrList) {
  92. if (pathOrList == null || pathOrList === '') return []
  93. if (Array.isArray(pathOrList)) {
  94. return pathOrList.map((item) => resolveFileUrl(item)).filter(Boolean)
  95. }
  96. return String(pathOrList)
  97. .split(',')
  98. .map((s) => resolveFileUrl(s.trim()))
  99. .filter(Boolean)
  100. }