巴青农资商城

htmlContent.js 1.8KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { resolveFileUrl } from '@/utils/image'
  2. /**
  3. * 解码常见 HTML 实体(后台若存了 <p> 会原样显示标签)
  4. */
  5. export function decodeHtmlEntities(html) {
  6. if (!html || typeof html !== 'string') {
  7. return ''
  8. }
  9. let s = html
  10. if (!/&(?:lt|gt|amp|quot|nbsp|#)/i.test(s)) {
  11. return s
  12. }
  13. s = s.replace(/ /gi, '\u00A0')
  14. s = s.replace(/&lt;/gi, '<')
  15. s = s.replace(/&gt;/gi, '>')
  16. s = s.replace(/&amp;/gi, '&')
  17. s = s.replace(/&quot;/gi, '"')
  18. s = s.replace(/&#39;/g, "'")
  19. s = s.replace(/&#(\d+);/g, (_, code) => {
  20. const n = Number(code)
  21. return Number.isNaN(n) ? '' : String.fromCharCode(n)
  22. })
  23. s = s.replace(/&#x([0-9a-f]+);/gi, (_, hex) => {
  24. const n = parseInt(hex, 16)
  25. return Number.isNaN(n) ? '' : String.fromCharCode(n)
  26. })
  27. return s
  28. }
  29. /** 富文本 img 相对路径转完整 URL(Quill 常存 /dev-api/profile/...) */
  30. export function fixHtmlImageSrc(html) {
  31. if (!html) return ''
  32. return html.replace(/src=(["'])([^"']+)\1/gi, (match, quote, src) => {
  33. // 去掉代理前缀,再走 resolveFileUrl 拼成小程序/rich-text 可用的完整地址
  34. const path = String(src).trim().replace(/^\/(dev-api|prod-api|shop-api)/i, '')
  35. const full = resolveFileUrl(path)
  36. return full ? `src=${quote}${full}${quote}` : match
  37. })
  38. }
  39. /** 去掉 Quill 常见空段落,避免占高度 */
  40. export function trimEmptyParagraphs(html) {
  41. if (!html) return ''
  42. return html
  43. .replace(/<p>(\s|&nbsp;|<br\s*\/?>)*<\/p>/gi, '')
  44. .replace(/<p><\/p>/gi, '')
  45. }
  46. /**
  47. * 协议/商品详情等富文本统一预处理(供 rich-text :nodes 使用)
  48. */
  49. export function prepareRichHtml(html) {
  50. let s = (html || '').trim()
  51. if (!s) return ''
  52. s = decodeHtmlEntities(s)
  53. s = fixHtmlImageSrc(s)
  54. s = trimEmptyParagraphs(s)
  55. return s
  56. }