|
6 | 6 | "io"
|
7 | 7 | "mime/multipart"
|
8 | 8 | "path/filepath"
|
| 9 | + "sync" |
9 | 10 |
|
10 | 11 | "github.com/gin-gonic/gin"
|
11 | 12 | uuid "github.com/satori/go.uuid"
|
@@ -44,71 +45,79 @@ func BatchUploadFiles(c *gin.Context) {
|
44 | 45 | return
|
45 | 46 | }
|
46 | 47 |
|
47 |
| - results := make([]uploadFileRespElement, 0) |
48 |
| - for _, fileHeader := range data.Files { |
49 |
| - element := uploadFileRespElement{ |
50 |
| - Filename: fileHeader.Filename, |
51 |
| - } |
| 48 | + var mutex sync.Mutex |
| 49 | + var wg sync.WaitGroup |
| 50 | + results := make([]uploadFileRespElement, 0, len(data.Files)) |
| 51 | + for _, f := range data.Files { |
| 52 | + wg.Add(1) |
| 53 | + go func(fileHeader *multipart.FileHeader) { |
| 54 | + defer wg.Done() |
| 55 | + |
| 56 | + res := handleSingleUpload(fileHeader, &data, bucket, c.ClientIP()) |
| 57 | + mutex.Lock() |
| 58 | + results = append(results, res) |
| 59 | + mutex.Unlock() |
| 60 | + }(f) |
| 61 | + } |
52 | 62 |
|
53 |
| - fileSize := fileHeader.Size |
54 |
| - if fileSize > objectService.SizeLimit { |
55 |
| - element.Error = apiException.FileSizeExceedError.Error() |
56 |
| - results = append(results, element) |
57 |
| - continue |
58 |
| - } |
| 63 | + wg.Wait() |
| 64 | + response.JsonSuccessResp(c, gin.H{ |
| 65 | + "results": results, |
| 66 | + }) |
| 67 | +} |
59 | 68 |
|
60 |
| - filename := fileHeader.Filename |
61 |
| - ext := filepath.Ext(filename) // 获取文件扩展名 |
62 |
| - name := filename[:len(filename)-len(ext)] // 获取去掉扩展名的文件名 |
| 69 | +func handleSingleUpload( |
| 70 | + fileHeader *multipart.FileHeader, data *batchUploadFileData, bucket oss.StorageProvider, ip string, |
| 71 | +) uploadFileRespElement { |
| 72 | + element := uploadFileRespElement{ |
| 73 | + Filename: fileHeader.Filename, |
| 74 | + } |
63 | 75 |
|
64 |
| - // 若使用 UUID 作为文件名 |
65 |
| - if data.UseUUID { |
66 |
| - name = uuid.NewV1().String() |
67 |
| - } |
| 76 | + if fileHeader.Size > objectService.SizeLimit { |
| 77 | + element.Error = apiException.FileSizeExceedError.Error() |
| 78 | + return element |
| 79 | + } |
68 | 80 |
|
69 |
| - file, err := fileHeader.Open() |
70 |
| - if err != nil { |
71 |
| - element.Error = apiException.UploadFileError.Error() |
72 |
| - results = append(results, element) |
73 |
| - continue |
74 |
| - } |
| 81 | + filename := fileHeader.Filename |
| 82 | + ext := filepath.Ext(filename) // 获取文件扩展名 |
| 83 | + name := filename[:len(filename)-len(ext)] // 获取去掉扩展名的文件名 |
75 | 84 |
|
76 |
| - // 转换到 WebP |
77 |
| - var reader io.ReadSeeker = file |
78 |
| - if data.ConvertWebP { |
79 |
| - reader, err = objectService.ConvertToWebP(file) |
80 |
| - ext = ".webp" |
81 |
| - if errors.Is(err, image.ErrFormat) { |
82 |
| - element.Error = apiException.FileNotImageError.Error() |
83 |
| - results = append(results, element) |
84 |
| - continue |
85 |
| - } |
86 |
| - if err != nil { |
87 |
| - element.Error = apiException.ServerError.Error() |
88 |
| - results = append(results, element) |
89 |
| - continue |
90 |
| - } |
91 |
| - } |
| 85 | + // 若使用 UUID 作为文件名 |
| 86 | + if data.UseUUID { |
| 87 | + name = uuid.NewV1().String() |
| 88 | + } |
92 | 89 |
|
93 |
| - // 上传文件 |
94 |
| - objectKey := objectService.GenerateObjectKey(data.Location, name, ext) |
95 |
| - err = bucket.SaveObject(reader, objectKey) |
| 90 | + file, err := fileHeader.Open() |
| 91 | + if err != nil { |
| 92 | + element.Error = apiException.UploadFileError.Error() |
| 93 | + return element |
| 94 | + } |
| 95 | + defer func() { _ = file.Close() }() |
| 96 | + |
| 97 | + // 转换到 WebP |
| 98 | + var reader io.ReadSeeker = file |
| 99 | + if data.ConvertWebP { |
| 100 | + reader, err = objectService.ConvertToWebP(file) |
| 101 | + ext = ".webp" |
| 102 | + if errors.Is(err, image.ErrFormat) { |
| 103 | + element.Error = apiException.FileNotImageError.Error() |
| 104 | + return element |
| 105 | + } |
96 | 106 | if err != nil {
|
97 | 107 | element.Error = apiException.ServerError.Error()
|
98 |
| - results = append(results, element) |
99 |
| - continue |
| 108 | + return element |
100 | 109 | }
|
| 110 | + } |
101 | 111 |
|
102 |
| - element.ObjectKey = objectKey |
103 |
| - results = append(results, element) |
104 |
| - |
105 |
| - zap.L().Info("上传文件成功", zap.String("bucket", data.Bucket), zap.String("objectKey", objectKey), zap.String("ip", c.ClientIP())) |
106 |
| - |
107 |
| - // 关闭文件 |
108 |
| - _ = file.Close() |
| 112 | + // 上传文件 |
| 113 | + objectKey := objectService.GenerateObjectKey(data.Location, name, ext) |
| 114 | + err = bucket.SaveObject(reader, objectKey) |
| 115 | + if err != nil { |
| 116 | + element.Error = apiException.ServerError.Error() |
| 117 | + return element |
109 | 118 | }
|
110 | 119 |
|
111 |
| - response.JsonSuccessResp(c, gin.H{ |
112 |
| - "results": results, |
113 |
| - }) |
| 120 | + element.ObjectKey = objectKey |
| 121 | + zap.L().Info("上传文件成功", zap.String("bucket", data.Bucket), zap.String("objectKey", objectKey), zap.String("ip", ip)) |
| 122 | + return element |
114 | 123 | }
|
0 commit comments