Files
oss/service/file_service.go

131 lines
3.8 KiB
Go

package service
import (
"context"
"fmt"
"oss/consts"
"oss/dao"
"oss/model/dto"
"oss/model/entity"
"time"
"github.com/gogf/gf/v2/os/glog"
"gitea.com/red-future/common/minio"
"gitea.com/red-future/common/redis"
"gitea.com/red-future/common/utils"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
type file struct{}
// File 存储文件服务
var File = new(file)
func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto.UploadFileRes, err error) {
fileSize := gconv.Int(req.File.Size)
totalFileSize := 0
// 获取租户id
user, err := utils.GetUserInfo(ctx)
if err != nil {
glog.Errorf(ctx, "获取用户信息失败: %v", err)
return
}
tenantId := user.TenantId
// 获取redis-租户存储容量总数key
tenantOssTotalKey := fmt.Sprintf(consts.TenantOssTotalKey, gconv.String(user.TenantId))
// 获取redis-租户存储-锁key
fileLockKey := fmt.Sprintf(consts.FileLockKey, gconv.String(user.TenantId))
success, err := utils.Lock(ctx, fileLockKey, gconv.Int64(time.Minute*1), func(ctx context.Context) error {
// 获取redis-租户存储容量总数
get, err := redis.RedisClient().Get(ctx, tenantOssTotalKey)
if err != nil {
glog.Errorf(ctx, "获取redis-租户存储容量总数失败: %v", err)
return err
}
tenantOssTotalEntity := &entity.TenantOssTotal{}
if g.IsEmpty(get) {
//查询数据库-获取租户存储容量总数
getByTenantIdReq := &dto.GetByTenantIdReq{
TenantId: user.TenantId,
}
tenantOssTotalRes, err := dao.TenantOssTotal.GetOneByTenantId(ctx, getByTenantIdReq)
if err != nil {
glog.Errorf(ctx, "查询数据库-获取租户存储容量总数失败: %v", err)
return err
}
if tenantOssTotalRes == nil || g.IsEmpty(tenantOssTotalRes.Id) {
// 数据库中没有该租户的记录,创建默认配置
tenantOssTotalEntity.TenantId = user.TenantId
tenantOssTotalEntity.UsedOssSize = 0
tenantOssTotalEntity.TotalOssSize = g.Cfg().MustGet(ctx, "oss.capacitySize").Int() * 1024 * 1024
} else {
tenantOssTotalEntity = tenantOssTotalRes
}
} else {
// 反序列化-redis获取租户存储容量总数
if err = gconv.Struct(get, tenantOssTotalEntity); err != nil {
glog.Errorf(ctx, "反序列化-redis获取租户存储容量总数失败: %v", err)
return err
}
}
tenantId = tenantOssTotalEntity.TenantId
fileSize = tenantOssTotalEntity.UsedOssSize + fileSize
totalFileSize = tenantOssTotalEntity.TotalOssSize
// 设置redis-租户存储容量总数
tenantOssTotalKeyMap := dto.UpdateUsedOssReq{
TenantId: tenantId,
UsedOssSize: fileSize,
TotalOssSize: totalFileSize,
Creator: user.UserName,
Updater: user.UserName,
}
// 修改redis-租户存储容量总数 超时时间10分钟
if err = redis.RedisClient().SetEX(ctx, tenantOssTotalKey, tenantOssTotalKeyMap, gconv.Int64(time.Minute*10)); err != nil {
glog.Errorf(ctx, "修改redis-租户存储容量总数 超时时间10分钟失败: %v", err)
return err
}
if fileSize > totalFileSize {
return gerror.New("存储服务内存不足")
}
return nil
})
if err != nil {
return nil, err
}
if !success {
return nil, gerror.New("存储服务内存不足")
}
// 上传图片
fileURL, fileName, fileFormat, err := minio.UploadFile(ctx, req.File)
if err != nil {
glog.Errorf(ctx, "上传图片失败: %v", err)
return nil, err
}
// 插入数据库
ossEntity := &dto.UploadFile{
TenantId: tenantId,
FileURL: fileURL,
FileSize: fileSize,
}
if _, err = dao.File.Insert(ctx, ossEntity); err != nil {
return nil, err
}
// 返回图片url
res = &dto.UploadFileRes{
FileURL: fileURL,
FileSize: fileSize,
FileName: fileName,
FileFormat: fileFormat,
}
url, err := utils.GetFileAddressPrefix(ctx)
if err != nil {
return
}
res.FileAddressPrefix = url
return
}