# All files / services storage-example.ts

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

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
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166

     /**
     * 存储服务使用示例
     * 演示如何无缝切换 OSS 和本地存储
     */

    import { storageService, StorageType } from './storage.service';

    // ==================== 示例 1: 基本使用 ====================
    // 存储服务会根据 .env 中的 STORAGE_TYPE 自动选择存储方式

    // 上传音频
    async function uploadAudioExample() {
      const audioUrl = await storageService.uploadAudio(
        '/path/to/audio.mp3',
        'audio-uuid-123'
      );
      console.log('音频上传成功:', audioUrl);
      // OSS 模式: https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/audio-uuid-123/audio.mp3
      // 本地模式: /uploads/audio/audio-uuid-123/audio.mp3
    }

    // 上传视频
    async function uploadVideoExample() {
      const videoUrl = await storageService.uploadVideo(
        '/path/to/video.mp4',
        'video-uuid-456'
      );
      console.log('视频上传成功:', videoUrl);
    }

    // 上传封面
    async function uploadCoverExample() {
      const coverUrl = await storageService.uploadCover(
        '/path/to/cover.jpg',
        123  // bookId
      );
      console.log('封面上传成功:', coverUrl);
    }

    // ==================== 示例 2: 动态切换存储 ====================
    async function switchStorageExample() {
      // 查看当前存储类型
      const currentType = storageService.getStorageType();
      console.log('当前存储类型:', currentType);

      // 切换到 OSS
      storageService.setStorageType('oss');
      console.log('已切换到 OSS');

      // 切换到本地存储
      storageService.setStorageType('local');
      console.log('已切换到本地存储');
    }

    // ==================== 示例 3: 在控制器中使用 ====================
    // 在 TTS 控制器中
    async function ttsControllerExample(ctx: any) {
      try {
        const file = ctx.request.files?.audio;
        const audioId = ctx.params.id;

        // 统一调用，无需关心存储类型
        const audioUrl = await storageService.uploadAudio(file.path, audioId);

        ctx.body = {
          code: 0,
          message: '上传成功',
          data: { audioUrl },
        };
      } catch (error) {
        ctx.status = 500;
        ctx.body = { code: 500, message: '上传失败' };
      }
    }

    // ==================== 示例 4: 删除文件 ====================
    async function deleteFileExample() {
      const fileUrl = '/uploads/audio/123/audio.mp3';

      // 统一调用，自动根据存储类型删除
      await storageService.deleteFile(fileUrl);
      console.log('文件已删除');
    }

    // ==================== 示例 5: 删除整个目录 ====================
    async function deleteDirectoryExample() {
      // 删除某个音频的所有分段
      await storageService.deleteDirectory('audio', 'audio-uuid-123');
      console.log('目录已删除');
    }

    // ==================== 示例 6: 获取签名 URL ====================
    async function getSignedUrlExample() {
      const fileUrl = 'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/audio.mp3';

      // OSS 模式: 返回临时签名 URL（1小时有效）
      // 本地模式: 直接返回原 URL
      const signedUrl = await storageService.getSignedUrl(fileUrl, 3600);
      console.log('签名 URL:', signedUrl);
    }

    // ==================== 配置说明 ====================
    /*
    .env 配置示例:

    # 使用阿里云 OSS
    STORAGE_TYPE=oss
    OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com
    OSS_ACCESS_KEY_ID=your-key-id
    OSS_ACCESS_KEY_SECRET=your-key-secret
    OSS_BUCKET_NAME=your-bucket
    OSS_REGION=cn-hangzhou

    # 使用本地存储
    STORAGE_TYPE=local
    # 其他 OSS 配置可选（切换回 OSS 时使用）
    */

    // ==================== 切换存储模式 ====================
    /*
    方法 1: 修改 .env 文件（推荐）
    1. 编辑 .env 文件
    2. 修改 STORAGE_TYPE=oss 或 STORAGE_TYPE=local
    3. 重启服务

    方法 2: 运行时动态切换
    storageService.setStorageType('oss');  // 切换到 OSS
    storageService.setStorageType('local'); // 切换到本地

    注意：动态切换仅影响后续上传的文件，已上传的文件不会自动迁移
    */

    // ==================== 迁移已有文件 ====================
    /*
    如果需要从本地存储迁移到 OSS（或反向）：

    1. 编写迁移脚本
    2. 遍历 uploads 目录
    3. 上传到目标存储
    4. 更新数据库中的 URL

    示例迁移脚本伪代码:
    async function migrateFiles() {
      // 读取所有本地文件
      const files = getAllFiles('./uploads');

      for (const file of files) {
        // 上传到 OSS
        const ossUrl = await ossService.uploadFile(file.path, file.key);

        // 更新数据库
        await db.updateFileUrl(file.id, ossUrl);
      }
    }
    */

    export {
      uploadAudioExample,
      uploadVideoExample,
      uploadCoverExample,
      switchStorageExample,
      deleteFileExample,
      deleteDirectoryExample,
      getSignedUrlExample,
    };