wangrong
2026-09-20 dc77841fcc93a5078469bf8dd5d6824d1c63f073
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
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import * as OSS from 'ali-oss';
import * as path from 'path';
import * as fs from 'fs';
 
@Provide()
@Scope(ScopeEnum.Singleton)
export class OssService {
  private client: OSS;
 
  constructor() {
    this.client = new OSS({
      region: 'cn-heyuan',
      accessKeyId: 'LTAI5t9gGLhifBTTBJ7JEq4h',
      accessKeySecret: 'JY3q0nioW6ATHr9N5EyI32OVmMMHk1',
      bucket: 'jskjwomps',
      endpoint: 'oss-cn-heyuan.aliyuncs.com',
      authorizationV4: true,
      timeout: '60s',
    });
  }
 
  /**
   * 上传本地文件
   * @param localPath 本地绝对路径
   * @param objectKey OSS 中的 key,如 images/capture/20260826/a.jpg
   * @returns 公网可访问 URL
   */
  async uploadLocalFile(localPath: string, objectKey: string): Promise<string> {
    if (!fs.existsSync(localPath)) {
      throw new Error(`本地文件不存在: ${localPath}`);
    }
    const ext = path.extname(localPath).toLowerCase();
    const contentType = this.getContentType(ext);
    const result = await this.client.put(objectKey, localPath, {
      headers: { 'Content-Type': contentType },
    });
    return result.url; // https://jskjwomps.oss-cn-heyuan.aliyuncs.com/images/...
  }
 
  /**
   * 上传 Buffer
   */
  async uploadBuffer(buf: Buffer, objectKey: string, contentType = 'image/jpeg') {
    const result = await this.client.put(objectKey, buf, {
      headers: { 'Content-Type': contentType },
    });
    return result.url;
  }
 
  /**
   * 批量上传某个目录下的图片
   */
  async uploadDir(localDir: string, prefix = 'images') {
    const files = fs.readdirSync(localDir).filter(f => /\.(jpg|jpeg|png|gif|webp)$/i.test(f));
    const urls: string[] = [];
    for (const f of files) {
      const key = `${prefix}/${Date.now()}_${f}`;
      const url = await this.uploadLocalFile(path.join(localDir, f), key);
      urls.push(url);
    }
    return urls;
  }
 
  private getContentType(ext: string) {
    return (
      {
        '.jpg': 'image/jpeg',
        '.jpeg': 'image/jpeg',
        '.png': 'image/png',
        '.gif': 'image/gif',
        '.webp': 'image/webp',
      }[ext] || 'application/octet-stream'
    );
  }
}