/** * ═══════════════════════════════════════════════════ * 小红书卡片模板 · 1080×1440 (3:4) * ═══════════════════════════════════════════════════ * * 支持: * - 单页卡片(封面/金句/干货) * - 多页轮播(长内容自动分页) */ import { STYLES } from '../config.js' const W = STYLES.sizes.xiaohongshu.width const H = STYLES.sizes.xiaohongshu.height /** * 生成小红书卡片 HTML * @param {object} data * @param {string} data.title - 标题 * @param {string} data.body - 正文(支持 \n 换行) * @param {string} data.subtitle - 副标题(可选) * @param {string} data.tag - 标签(可选,如「干货·教程」) * @param {string} data.quote - 金句/引用(可选) * @param {string} data.footer - 底部文字(可选,如账号名) * @param {string} data.layout - 布局: 'default' | 'quote' | 'list' | 'minimal' * @param {number} data.pageNum - 当前页码(多页时) * @param {number} data.totalPages - 总页数(多页时) */ export function xiaohongshuCard(data) { const { title = '', body = '', subtitle = '', tag = '', quote = '', footer = '', layout = 'default', pageNum = 1, totalPages = 1, } = data const C = STYLES.colors const F = STYLES.fonts const T = STYLES.typography // 正文按换行分段 const bodyLines = body.split('\n').filter(Boolean) const bodyHtml = bodyLines.map(line => { // 检测是否以 - 开头(列表项) if (line.trimStart().startsWith('- ')) { return `
  • ${line.trimStart().slice(2)}
  • ` } // 检测是否以 # 开头(小标题) if (line.trimStart().startsWith('#')) { return `

    ${line.trimStart().replace(/^#+\s*/, '')}

    ` } return `

    ${line}

    ` }).join('\n') const hasList = bodyLines.some(l => l.trimStart().startsWith('- ')) return `
    ${tag ? `
    ${tag}
    ` : ''} ${layout === 'quote' ? `
    "
    ${quote || title}
    ${subtitle ? `
    ${subtitle}
    ` : ''}
    ` : layout === 'minimal' ? `
    ${title}
    ${body ? `
    ${body}
    ` : ''}
    ` : `
    ${title}
    ${subtitle ? `
    ${subtitle}
    ` : ''}
    ${bodyHtml}
    `}
    ` } /** * 生成小红书轮播(多页) * @param {object} data - 同 xiaohongshuCard * @param {string[]} pages - 每页正文内容数组 * @returns {string[]} HTML 数组 */ export function xiaohongshuCarousel(data, pages) { return pages.map((body, i) => xiaohongshuCard({ ...data, body, pageNum: i + 1, totalPages: pages.length, })) }