@@ -2,121 +2,56 @@ import { Injectable } from '@nestjs/common';
22import { ConfigService } from '@nestjs/config' ;
33import { InjectRepository } from '@nestjs/typeorm' ;
44import { Repository } from 'typeorm' ;
5- import * as qiniu from 'qiniu' ;
65import { Upload } from './entities/upload.entity' ;
7-
8- interface QiniuResponse {
9- hash : string ;
10- key : string ;
11- }
12-
13- interface QiniuCallbackInfo {
14- statusCode : number ;
15- }
6+ import * as fs from 'fs' ;
7+ import * as path from 'path' ;
8+ import * as crypto from 'crypto' ;
169
1710@Injectable ( )
1811export class UploadService {
19- private mac : qiniu . auth . digest . Mac ;
20- private config : qiniu . conf . Config ;
21- private bucketManager : qiniu . rs . BucketManager ;
22- private uploadToken : string ;
12+ private uploadDir : string ;
13+ private baseUrl : string ;
2314
2415 constructor (
2516 private configService : ConfigService ,
2617 @InjectRepository ( Upload )
2718 private uploadRepository : Repository < Upload > ,
2819 ) {
29- // 初始化七牛云配置
30- this . mac = new qiniu . auth . digest . Mac (
31- this . configService . get ( 'kodo.ACCESS_KEY' ) ,
32- this . configService . get ( 'kodo.SECRET_KEY' ) ,
33- ) ;
34- this . config = new qiniu . conf . Config ( ) ;
35- // 设置存储区域
36- this . config . zone = qiniu . zone . Zone_z0 ; // 根据你的空间所在的区域选择:华东(z0)、华北(z1)、华南(z2)、北美(na0)等
37- this . bucketManager = new qiniu . rs . BucketManager ( this . mac , this . config ) ;
38- const putPolicy = new qiniu . rs . PutPolicy ( {
39- scope : this . configService . get ( 'kodo.BUCKET' ) ,
40- } ) ;
41- this . uploadToken = putPolicy . uploadToken ( this . mac ) ;
20+ this . uploadDir = path . join ( process . cwd ( ) , 'uploads' ) ;
21+
22+ // 确保上传目录存在
23+ if ( ! fs . existsSync ( this . uploadDir ) ) {
24+ fs . mkdirSync ( this . uploadDir , { recursive : true } ) ;
25+ }
4226 }
4327
4428 async uploadFile ( file : Express . Multer . File ) : Promise < Upload > {
45- const formUploader = new qiniu . form_up . FormUploader ( this . config ) ;
46- const putExtra = new qiniu . form_up . PutExtra ( ) ;
47-
48- // 验证配置是否存在
49- const accessKey = this . configService . get < string > ( 'kodo.ACCESS_KEY' ) ;
50- const secretKey = this . configService . get < string > ( 'kodo.SECRET_KEY' ) ;
51- const bucket = this . configService . get < string > ( 'kodo.BUCKET' ) ;
52- const baseUrl = this . configService . get < string > ( 'kodo.BASE_URL' ) ;
29+ try {
30+ // 生成文件hash
31+ const hash = crypto . createHash ( 'sha256' )
32+ . update ( file . buffer )
33+ . digest ( 'hex' ) ;
5334
54- if ( ! accessKey || ! secretKey || ! bucket || ! baseUrl ) {
55- throw new Error (
56- 'Missing required Qiniu configuration. Please check your configuration file.' ,
57- ) ;
58- }
35+ // 生成文件名(使用原始文件扩展名)
36+ const ext = path . extname ( file . originalname ) ;
37+ const key = `${ hash } ${ ext } ` ;
38+ const filePath = path . join ( this . uploadDir , key ) ;
5939
60- return new Promise < Upload > ( ( resolve , reject ) => {
61- formUploader . put (
62- this . uploadToken ,
63- null , // 使用七牛云生成的文件名
64- file . buffer ,
65- putExtra ,
66- (
67- err : Error | undefined ,
68- body : QiniuResponse ,
69- info : QiniuCallbackInfo ,
70- ) => {
71- try {
72- // 检查是否有错误
73- if ( err ) {
74- console . error ( 'Upload error:' , err ) ;
75- return reject (
76- new Error ( 'File upload failed due to an internal error.' ) ,
77- ) ;
78- }
40+ // 保存文件
41+ await fs . promises . writeFile ( filePath , file . buffer ) ;
7942
80- // 检查 HTTP 状态码是否为成功
81- if ( info . statusCode !== 200 ) {
82- console . error ( 'Upload failed with status code:' , info . statusCode ) ;
83- return reject (
84- new Error (
85- `File upload failed with status code: ${ info . statusCode } ` ,
86- ) ,
87- ) ;
88- }
89- // 获取基础 URL 并构造上传对象
90- const baseUrl = this . configService . get < string > ( 'kodo.BASE_URL' ) ;
91- const upload = new Upload ( ) ;
92- upload . hash = body . hash ;
93- upload . key = body . key ;
94- upload . url = `${ baseUrl } /${ body . key } ` ;
43+ // 创建上传记录
44+ const upload = new Upload ( ) ;
45+ upload . hash = hash ;
46+ upload . key = key ;
47+ upload . url = `/uploads/${ key } ` ;
9548
96- // 将上传信息保存到数据库
97- try {
98- this . uploadRepository
99- . save ( upload )
100- . then ( ( savedUpload ) => resolve ( savedUpload ) )
101- . catch ( ( error ) =>
102- reject ( new Error ( `Failed to save upload: ${ error . message } ` ) ) ,
103- ) ; // 成功时返回保存的对象
104- } catch ( dbError ) {
105- console . error ( 'Database save error:' , dbError ) ;
106- reject (
107- new Error ( 'Failed to save upload information to the database.' ) ,
108- ) ;
109- }
110- } catch ( unexpectedError ) {
111- // 捕获任何意外错误
112- console . error ( 'Unexpected error during upload:' , unexpectedError ) ;
113- reject (
114- new Error ( 'An unexpected error occurred during file upload.' ) ,
115- ) ;
116- }
117- } ,
118- ) ;
119- } ) ;
49+ // 保存到数据库
50+ return await this . uploadRepository . save ( upload ) ;
51+ } catch ( error ) {
52+ console . error ( 'Upload error:' , error ) ;
53+ throw new Error ( 'File upload failed: ' + error . message ) ;
54+ }
12055 }
12156
12257 async getFiles ( page : number = 1 , limit : number = 10 ) {
0 commit comments