♻️ use minio instead of mongodb

This commit is contained in:
2025-02-05 18:08:29 +08:00
parent a3d4f2c8d1
commit d2b0d7b42e
53 changed files with 2446 additions and 702 deletions

View File

@@ -0,0 +1,6 @@
package constant
const (
FaceBucketName = "faces"
CommentImagesBucketName = "comments"
)

View File

@@ -1,5 +1,6 @@
package constant
const (
FaceTypeSample = "sample"
FaceTypePerson = iota
FaceTypeHidden
)

View File

@@ -15,5 +15,6 @@ const (
)
const (
FaceSamplePrefix = "face:sample:"
FaceSamplePrefix = "face:samples:"
FaceVectorPrefix = "face:vectors:"
)

View File

@@ -12,7 +12,7 @@ func CasbinMiddleware(w http.ResponseWriter, r *http.Request, casbin *casbin.Syn
userId := r.Header.Get(constant.UID_HEADER_KEY)
correct, err := casbin.Enforce(userId, r.URL.Path, r.Method)
if err != nil || !correct {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusForbidden, "forbidden"))
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusNotFound, "not found"))
return
}
}

17
common/miniox/minio.go Normal file
View File

@@ -0,0 +1,17 @@
package miniox
import (
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func NewMinio(endpoint, accessKeyID, secretAccessKey string, useSSL bool) *minio.Client {
client, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
Secure: useSSL,
})
if err != nil {
panic(err)
}
return client
}

View File

@@ -1,117 +1,23 @@
package utils
import (
"bytes"
"encoding/base64"
"errors"
"fmt"
"image"
_ "image/jpeg" // 引入 jpeg 解码器
_ "image/png" // 引入 png 解码器
"io"
"regexp"
"strings"
"sync"
)
var wg sync.WaitGroup
// GetMimeType 获取 MIME 类型
func GetMimeType(data []byte) string {
if len(data) < 4 {
return "application/octet-stream" // 默认类型
}
// 判断 JPEG
if data[0] == 0xFF && data[1] == 0xD8 {
return "image/jpeg"
}
// 判断 PNG
if len(data) >= 8 && data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47 &&
data[4] == 0x0D && data[5] == 0x0A && data[6] == 0x1A && data[7] == 0x0A {
return "image/png"
}
// 判断 GIF
if len(data) >= 6 && data[0] == 'G' && data[1] == 'I' && data[2] == 'F' {
return "image/gif"
}
// 判断 WEBP
if len(data) >= 12 && data[0] == 0x52 && data[1] == 0x49 && data[2] == 0x46 && data[3] == 0x46 &&
data[8] == 0x57 && data[9] == 0x45 && data[10] == 0x42 && data[11] == 0x50 {
return "image/webp"
}
// 判断svg
if len(data) >= 4 && data[0] == '<' && data[1] == '?' && data[2] == 'x' && data[3] == 'm' {
return "image/svg+xml"
}
// 判断JPG
if len(data) >= 3 && data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF {
return "image/jpeg"
}
return "application/octet-stream" // 默认类型
}
// ProcessImages 处理图片,将 base64 字符串转换为字节数组
func ProcessImages(images []string) ([][]byte, error) {
var imagesData [][]byte
dataChan := make(chan []byte, len(images))
re := regexp.MustCompile(`^data:image/\w+;base64,`)
for _, img := range images {
wg.Add(1)
go func(img string) {
defer wg.Done()
imgWithoutPrefix := re.ReplaceAllString(img, "")
data, err := Base64ToBytes(imgWithoutPrefix)
if err != nil {
return // 出错时直接返回
}
dataChan <- data
}(img)
}
wg.Wait()
close(dataChan)
for data := range dataChan {
imagesData = append(imagesData, data)
}
return imagesData, nil
}
// Base64ToBytes 将base64字符串转换为字节数组
func Base64ToBytes(base64Str string) ([]byte, error) {
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64Str))
re := regexp.MustCompile(`^data:image/\w+;base64,`)
imgWithoutPrefix := re.ReplaceAllString(base64Str, "")
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(imgWithoutPrefix))
data, err := io.ReadAll(reader)
if err != nil {
return nil, errors.New("failed to decode base64 string")
}
return data, nil
}
// Base64ToImage 将 Base64 字符串转换为 image.Image 格式
func Base64ToImage(base64Str string) (image.Image, error) {
// 使用正则表达式去除前缀
re := regexp.MustCompile(`^data:image/([a-zA-Z]*);base64,`)
// 去除前缀部分
base64Str = re.ReplaceAllString(base64Str, "")
// 解码 Base64 字符串
data, err := base64.StdEncoding.DecodeString(base64Str)
if err != nil {
return nil, fmt.Errorf("failed to decode base64 string: %v", err)
}
// 使用 image.Decode 解码字节数据
img, _, err := image.Decode(bytes.NewReader(data))
if err != nil {
return nil, fmt.Errorf("failed to decode image: %v", err)
}
return img, nil
}