All files / modules/share share.service.ts

0% Statements 0/52
0% Branches 0/1
0% Functions 0/1
0% Lines 0/52

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91                                                                                                                                                                                     
import { v4 as uuidv4 } from 'uuid';
import { prisma } from '../../models';
 
/**
 * 分享服务
 * 生成分享链接和二维码
 */
export class ShareService {
  private baseUrl: string;
 
  constructor() {
    // 从环境变量获取基础 URL,默认使用当前域名
    this.baseUrl = process.env.APP_URL || 'http://localhost:3000';
  }
 
  /**
   * 生成书籍章节分享链接
   * @param chapterId 章节 ID
   */
  generateShareLink(chapterId: string): string {
    return `${this.baseUrl}/#/pages/player/index?id=${chapterId}`;
  }
 
  /**
   * 生成分享卡片数据
   * @param chapterId 章节 ID
   */
  async generateShareCard(chapterId: string) {
    const chapter = await prisma.bookChapter.findUnique({
      where: { id: parseInt(chapterId) },
      include: { book: true },
    });
 
    if (!chapter) {
      throw new Error('章节不存在');
    }
 
    // 生成更完整的描述
    let description = '';
    if (chapter.summary) {
      description = chapter.summary;
    } else if (chapter.content && chapter.content.length > 100) {
      description = chapter.content.slice(0, 100) + '...';
    } else if (chapter.content) {
      description = chapter.content;
    } else {
      description = 'AI 有声书精彩内容';
    }
 
    return {
      title: `${chapter.book?.title || 'AI 有声书'} - 第${chapter.number}章 ${chapter.title}`,
      description: description,
      imageUrl: this.generateCoverImage(chapter),
      link: this.generateShareLink(chapterId),
      chapterId: chapter.id,
      wordCount: chapter.wordCount,
      audioDuration: chapter.audioDuration,
    };
  }
 
  /**
   * 生成封面图片
   */
  private generateCoverImage(chapter: any) {
    // 实际项目中可以生成真实的图片
    return {
      type: 'gradient',
      colors: ['#4f46e5', '#818cf8'],
      icon: '🎵',
    };
  }
 
  /**
   * 生成二维码数据
   * @param chapterId 章节 ID
   */
  generateQRCodeData(chapterId: string): string {
    return this.generateShareLink(chapterId);
  }
 
  /**
   * 记录分享行为
   */
  async trackShare(chapterId: string, userId: string, platform: string) {
    console.log(`📤 用户 ${userId} 分享了章节 ${chapterId} 到 ${platform}`);
  }
}
 
// 导出单例
export const shareService = new ShareService();