clip-normalize.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /** 将发现页视频列表接口数据规整为播放器可用结构 */
  2. function ensureArray(value) {
  3. if (Array.isArray(value)) return value
  4. if (typeof value === 'string' && value.trim()) {
  5. try {
  6. const parsed = JSON.parse(value)
  7. if (Array.isArray(parsed)) return parsed
  8. if (parsed && typeof parsed === 'object') {
  9. return Object.keys(parsed)
  10. .filter((k) => /^\d+$/.test(k))
  11. .sort((a, b) => Number(a) - Number(b))
  12. .map((k) => parsed[k])
  13. .filter(Boolean)
  14. }
  15. } catch (_) {}
  16. return value.split(',').map((s) => s.trim()).filter(Boolean)
  17. }
  18. if (value && typeof value === 'object') {
  19. return Object.keys(value)
  20. .filter((k) => /^\d+$/.test(k))
  21. .sort((a, b) => Number(a) - Number(b))
  22. .map((k) => value[k])
  23. .filter(Boolean)
  24. }
  25. return []
  26. }
  27. /** 兼容 wanlshop 分页接口多种 envelope */
  28. function unwrapFeedRows(payload) {
  29. if (!payload) return []
  30. if (Array.isArray(payload)) return payload
  31. if (typeof payload !== 'object') return []
  32. if (Array.isArray(payload.data)) return payload.data
  33. if (Array.isArray(payload.list)) return payload.list
  34. const inner = payload.data
  35. if (inner && typeof inner === 'object') {
  36. if (Array.isArray(inner.data)) return inner.data
  37. if (Array.isArray(inner.list)) return inner.list
  38. }
  39. return []
  40. }
  41. function unwrapFeedMeta(payload) {
  42. if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
  43. return { current_page: 1, last_page: 1 }
  44. }
  45. const inner = payload.data && typeof payload.data === 'object' && !Array.isArray(payload.data)
  46. ? payload.data
  47. : payload
  48. return {
  49. current_page: inner.current_page || payload.current_page || 1,
  50. last_page: inner.last_page || payload.last_page || inner.current_page || payload.current_page || 1
  51. }
  52. }
  53. export function extractFeedPage(payload) {
  54. const rows = unwrapFeedRows(payload)
  55. const meta = unwrapFeedMeta(payload)
  56. return {
  57. rows: rows.map(normalizeClip),
  58. currentPage: Number(meta.current_page || 1),
  59. lastPage: Number(meta.last_page || meta.current_page || 1)
  60. }
  61. }
  62. export function normalizeClip(raw = {}) {
  63. const video = raw.video || {}
  64. const seriesList = ensureArray(raw.series_list)
  65. return {
  66. ...raw,
  67. images: ensureArray(raw.images),
  68. goods: ensureArray(raw.goods),
  69. series_list: seriesList,
  70. series_id: raw.series_id != null ? raw.series_id : (raw.seriesId != null ? raw.seriesId : ''),
  71. play: false,
  72. initialTime: raw.initialTime ?? 0,
  73. video: {
  74. id: video.id || '',
  75. video_id: video.video_id || raw.video_id || '',
  76. url: video.url || '',
  77. cover_url: video.cover_url || '',
  78. width: video.width || 0,
  79. height: video.height || 0,
  80. fit: video.fit || 'cover',
  81. duration: video.duration,
  82. // 合辑付费:video.paid_money 或顶层 paid_money
  83. paid_money: video.paid_money != null ? video.paid_money : (raw.paid_money != null ? raw.paid_money : 0)
  84. }
  85. }
  86. }
  87. export function stripHtml(content) {
  88. if (!content) return ''
  89. return String(content)
  90. .replace(/<[^>]+>/g, '')
  91. .replace(/&nbsp;/g, ' ')
  92. .trim()
  93. }