120 lines
3.7 KiB
Go
120 lines
3.7 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/gogf/gf/v2/os/glog"
|
|
"oss/consts"
|
|
"oss/dao"
|
|
"oss/model/dto"
|
|
"oss/model/entity"
|
|
"time"
|
|
|
|
"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 := redis.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 := TenantOssTotal.GetOneByTenantId(ctx, getByTenantIdReq)
|
|
if err != nil {
|
|
glog.Errorf(ctx, "查询数据库-获取租户存储容量总数失败: %v", err)
|
|
return err
|
|
}
|
|
if tenantOssTotalRes == nil || tenantOssTotalRes.TenantOssTotal == nil || g.IsEmpty(tenantOssTotalRes.Id) || tenantOssTotalRes.Id.IsZero() {
|
|
// 数据库中没有该租户的记录,创建默认配置
|
|
tenantOssTotalEntity.TenantId = user.TenantId
|
|
tenantOssTotalEntity.UsedOssSize = 0
|
|
tenantOssTotalEntity.TotalOssSize = g.Cfg().MustGet(ctx, "oss.capacitySize").Int() * 1024 * 1024
|
|
} else {
|
|
tenantOssTotalEntity = tenantOssTotalRes.TenantOssTotal
|
|
}
|
|
} 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.TenantOssTotal{
|
|
TenantId: tenantId,
|
|
UsedOssSize: fileSize,
|
|
TotalOssSize: totalFileSize,
|
|
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, err := minio.UploadFile(ctx, req.File)
|
|
if err != nil {
|
|
glog.Errorf(ctx, "上传图片失败: %v", err)
|
|
return nil, err
|
|
}
|
|
// 插入数据库
|
|
ossEntity := &entity.File{
|
|
FileURL: fileURL,
|
|
FileSize: fileSize,
|
|
}
|
|
if err = dao.File.Insert(ctx, ossEntity); err != nil {
|
|
return nil, err
|
|
}
|
|
// 返回图片url
|
|
return &dto.UploadFileRes{
|
|
FileURL: fileURL,
|
|
FileAddressPrefix: minio.GetFileAddressPrefix(ctx),
|
|
}, err
|
|
}
|