| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- import { resolveFileUrl } from '@/utils/image'
- /**
- * 解码常见 HTML 实体(后台若存了 <p> 会原样显示标签)
- */
- export function decodeHtmlEntities(html) {
- if (!html || typeof html !== 'string') {
- return ''
- }
- let s = html
- if (!/&(?:lt|gt|amp|quot|nbsp|#)/i.test(s)) {
- return s
- }
- s = s.replace(/ /gi, '\u00A0')
- s = s.replace(/</gi, '<')
- s = s.replace(/>/gi, '>')
- s = s.replace(/&/gi, '&')
- s = s.replace(/"/gi, '"')
- s = s.replace(/'/g, "'")
- s = s.replace(/&#(\d+);/g, (_, code) => {
- const n = Number(code)
- return Number.isNaN(n) ? '' : String.fromCharCode(n)
- })
- s = s.replace(/&#x([0-9a-f]+);/gi, (_, hex) => {
- const n = parseInt(hex, 16)
- return Number.isNaN(n) ? '' : String.fromCharCode(n)
- })
- return s
- }
- /** 富文本 img 相对路径转完整 URL(Quill 常存 /dev-api/profile/...) */
- export function fixHtmlImageSrc(html) {
- if (!html) return ''
- return html.replace(/src=(["'])([^"']+)\1/gi, (match, quote, src) => {
- // 去掉代理前缀,再走 resolveFileUrl 拼成小程序/rich-text 可用的完整地址
- const path = String(src).trim().replace(/^\/(dev-api|prod-api|shop-api)/i, '')
- const full = resolveFileUrl(path)
- return full ? `src=${quote}${full}${quote}` : match
- })
- }
- /** 去掉 Quill 常见空段落,避免占高度 */
- export function trimEmptyParagraphs(html) {
- if (!html) return ''
- return html
- .replace(/<p>(\s| |<br\s*\/?>)*<\/p>/gi, '')
- .replace(/<p><\/p>/gi, '')
- }
- /**
- * 协议/商品详情等富文本统一预处理(供 rich-text :nodes 使用)
- */
- export function prepareRichHtml(html) {
- let s = (html || '').trim()
- if (!s) return ''
- s = decodeHtmlEntities(s)
- s = fixHtmlImageSrc(s)
- s = trimEmptyParagraphs(s)
- return s
- }
|