✨ develop basic APIs / optimize database organization
This commit is contained in:
@@ -450,7 +450,12 @@ type (
|
||||
result string `json:"result"`
|
||||
}
|
||||
FaceDetailListRequest {
|
||||
FaceID int64 `json:"face_id"`
|
||||
FaceID int64 `json:"face_id"`
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
FaceDetailListResponse {
|
||||
records []AllImageDetail `json:"records"`
|
||||
}
|
||||
// 创建相册请求参数
|
||||
AlbumCreateRequest {
|
||||
@@ -478,7 +483,13 @@ type (
|
||||
}
|
||||
// 相册详情请求参数
|
||||
AlbumDetailListRequest {
|
||||
ID int64 `json:"id"`
|
||||
ID int64 `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
// 相册详情响应参数
|
||||
AlbumDetailListResponse {
|
||||
records []AllImageDetail `json:"records"`
|
||||
}
|
||||
// 重命名相册请求参数
|
||||
AlbumRenameRequest {
|
||||
@@ -522,42 +533,56 @@ type (
|
||||
records []AllImageDetail `json:"records"`
|
||||
}
|
||||
LocationMeta {
|
||||
ID int64 `json:"id"`
|
||||
City string `json:"city"`
|
||||
Total int64 `json:"total"`
|
||||
ID int64 `json:"id"`
|
||||
City string `json:"city"`
|
||||
Total int64 `json:"total"`
|
||||
CoverImage string `json:"cover_image"`
|
||||
}
|
||||
LocationListData {
|
||||
location string `json:"location"` // 中国 新疆维吾尔自治区
|
||||
list []LocationMeta `json:"list"` // 图片列表
|
||||
}
|
||||
LocationListRequest {
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
// 地点相册列表响应参数
|
||||
LocationListResponse {
|
||||
records []LocationListData `json:"records"`
|
||||
}
|
||||
// 地点详情列表请求参数
|
||||
LocationDetailListRequest {
|
||||
ID int64 `json:"id"`
|
||||
ID int64 `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
// 地点详情列表响应参数
|
||||
LocationDetailListResponse {
|
||||
records []AllImageDetail `json:"records"`
|
||||
}
|
||||
ThingMeta {
|
||||
TagName string `json:"tag_name"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
TagCount int64 `json:"tag_count"`
|
||||
TagName string `json:"tag_name"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
TagCount int64 `json:"tag_count"`
|
||||
CoverImage string `json:"cover_image"`
|
||||
}
|
||||
ThingListData {
|
||||
Category string `json:"category"` // 分类
|
||||
list []ThingMeta `json:"list"` // 图片列表
|
||||
}
|
||||
ThingListRequest {
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
// 事物相册列表响应参数
|
||||
ThingListResponse {
|
||||
records []ThingListData `json:"records"`
|
||||
}
|
||||
// 事物详情列表请求参数
|
||||
ThingDetailListRequest {
|
||||
ID int64 `json:"id"`
|
||||
TagName string `json:"tag_name"`
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
// 事物详情列表响应参数
|
||||
ThingDetailListResponse {
|
||||
@@ -598,9 +623,9 @@ service auth {
|
||||
@handler modifyFaceLibraryType
|
||||
post /face/sample/modify/type (ModifyFaceTypeRequest) returns (ModifyFaceTypeResponse)
|
||||
|
||||
// 获取人脸详情列表 (暂定)
|
||||
// 获取人脸详情列表
|
||||
@handler getFaceDetailList
|
||||
post /face/detail/list (FaceDetailListRequest) returns (string)
|
||||
post /face/detail/list (FaceDetailListRequest) returns (FaceDetailListResponse)
|
||||
|
||||
// 创建相册
|
||||
@handler createAlbum
|
||||
@@ -610,9 +635,9 @@ service auth {
|
||||
@handler getAlbumList
|
||||
post /album/list (AlbumListRequest) returns (AlbumListResponse)
|
||||
|
||||
// 获取相册详情(暂定)
|
||||
// 获取相册详情
|
||||
@handler getAlbumDetail
|
||||
post /album/detail/list (AlbumDetailListRequest) returns (string)
|
||||
post /album/detail/list (AlbumDetailListRequest) returns (AlbumDetailListResponse)
|
||||
|
||||
// 重命名相册
|
||||
@handler renameAlbum
|
||||
@@ -632,7 +657,7 @@ service auth {
|
||||
|
||||
// 获取地点相册列表
|
||||
@handler queryLocationImageList
|
||||
post /image/location/list returns (LocationListResponse)
|
||||
post /image/location/list (LocationListRequest) returns (LocationListResponse)
|
||||
|
||||
// 获取地点详情列表
|
||||
@handler queryLocationDetailList
|
||||
@@ -640,7 +665,7 @@ service auth {
|
||||
|
||||
// 获取事物相册列表
|
||||
@handler queryThingImageList
|
||||
post /image/thing/list returns (ThingListResponse)
|
||||
post /image/thing/list (ThingListRequest) returns (ThingListResponse)
|
||||
|
||||
// 获取事物详情列表
|
||||
@handler queryThingDetailList
|
||||
|
@@ -17,7 +17,6 @@ func GetAlbumDetailHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := storage.NewGetAlbumDetailLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetAlbumDetail(&req)
|
||||
if err != nil {
|
||||
|
@@ -3,15 +3,23 @@ package storage
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/storage"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func QueryLocationImageListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.LocationListRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := storage.NewQueryLocationImageListLogic(r.Context(), svcCtx)
|
||||
resp, err := l.QueryLocationImageList()
|
||||
resp, err := l.QueryLocationImageList(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
|
@@ -3,15 +3,23 @@ package storage
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/storage"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func QueryThingImageListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ThingListRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := storage.NewQueryThingImageListLogic(r.Context(), svcCtx)
|
||||
resp, err := l.QueryThingImageList()
|
||||
resp, err := l.QueryThingImageList(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
|
@@ -2,6 +2,18 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"math/rand"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/query"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"schisandra-album-cloud-microservices/common/encrypt"
|
||||
storageConfig "schisandra-album-cloud-microservices/common/storage/config"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
@@ -23,8 +35,172 @@ func NewGetAlbumDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAlbumDetailLogic) GetAlbumDetail(req *types.AlbumDetailListRequest) (resp string, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
func (l *GetAlbumDetailLogic) GetAlbumDetail(req *types.AlbumDetailListRequest) (resp *types.AlbumDetailListResponse, err error) {
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found")
|
||||
}
|
||||
// 缓存获取数据 v1.0.0
|
||||
cacheKey := fmt.Sprintf("%s%s:%s:%s:%v", constant.ImageListPrefix, uid, req.Provider, req.Bucket, req.ID)
|
||||
// 尝试从缓存获取
|
||||
cachedResult, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err == nil {
|
||||
var cachedResponse types.AlbumDetailListResponse
|
||||
if err := json.Unmarshal([]byte(cachedResult), &cachedResponse); err == nil {
|
||||
return &cachedResponse, nil
|
||||
}
|
||||
logx.Error("Failed to unmarshal cached image list:", err)
|
||||
return nil, errors.New("get cached image list failed")
|
||||
} else if !errors.Is(err, redis.Nil) {
|
||||
logx.Error("Redis error:", err)
|
||||
return nil, errors.New("get cached image list failed")
|
||||
}
|
||||
|
||||
return
|
||||
// 缓存未命中,从数据库中查询
|
||||
storageInfo := l.svcCtx.DB.ScaStorageInfo
|
||||
// 数据库查询文件信息列表
|
||||
var storageInfoQuery query.IScaStorageInfoDo
|
||||
|
||||
storageInfoQuery = storageInfo.Where(
|
||||
storageInfo.UserID.Eq(uid),
|
||||
storageInfo.Provider.Eq(req.Provider),
|
||||
storageInfo.Bucket.Eq(req.Bucket),
|
||||
storageInfo.AlbumID.Eq(req.ID)).
|
||||
Order(storageInfo.CreatedAt.Desc())
|
||||
storageInfoList, err := storageInfoQuery.Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(storageInfoList) == 0 {
|
||||
return &types.AlbumDetailListResponse{}, nil
|
||||
}
|
||||
|
||||
// 加载用户oss配置信息
|
||||
cacheOssConfigKey := constant.UserOssConfigPrefix + uid + ":" + req.Provider
|
||||
ossConfig, err := l.getOssConfigFromCacheOrDb(cacheOssConfigKey, uid, req.Provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
service, err := l.svcCtx.StorageManager.GetStorage(uid, ossConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("get storage failed")
|
||||
}
|
||||
|
||||
// 按日期进行分组
|
||||
var wg sync.WaitGroup
|
||||
groupedImages := sync.Map{}
|
||||
|
||||
for _, dbFileInfo := range storageInfoList {
|
||||
wg.Add(1)
|
||||
go func(dbFileInfo *model.ScaStorageInfo) {
|
||||
defer wg.Done()
|
||||
weekday := WeekdayMap[dbFileInfo.CreatedAt.Weekday()]
|
||||
date := dbFileInfo.CreatedAt.Format("2006年1月2日 星期" + weekday)
|
||||
url, err := service.PresignedURL(l.ctx, ossConfig.BucketName, dbFileInfo.Path, time.Hour*24*7)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
}
|
||||
// 使用 Load 或 Store 确保原子操作
|
||||
value, _ := groupedImages.LoadOrStore(date, []types.ImageMeta{})
|
||||
images := value.([]types.ImageMeta)
|
||||
|
||||
images = append(images, types.ImageMeta{
|
||||
ID: dbFileInfo.ID,
|
||||
FileName: dbFileInfo.FileName,
|
||||
URL: url,
|
||||
Width: dbFileInfo.Width,
|
||||
Height: dbFileInfo.Height,
|
||||
CreatedAt: dbFileInfo.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
|
||||
// 重新存储更新后的图像列表
|
||||
groupedImages.Store(date, images)
|
||||
}(dbFileInfo)
|
||||
}
|
||||
wg.Wait()
|
||||
var imageList []types.AllImageDetail
|
||||
groupedImages.Range(func(key, value interface{}) bool {
|
||||
imageList = append(imageList, types.AllImageDetail{
|
||||
Date: key.(string),
|
||||
List: value.([]types.ImageMeta),
|
||||
})
|
||||
return true
|
||||
})
|
||||
resp = &types.AlbumDetailListResponse{
|
||||
Records: imageList,
|
||||
}
|
||||
|
||||
// 缓存结果
|
||||
if data, err := json.Marshal(resp); err == nil {
|
||||
expireTime := 7*24*time.Hour - time.Duration(rand.Intn(60))*time.Minute
|
||||
if err := l.svcCtx.RedisClient.Set(l.ctx, cacheKey, data, expireTime).Err(); err != nil {
|
||||
logx.Error("Failed to cache image list:", err)
|
||||
}
|
||||
} else {
|
||||
logx.Error("Failed to marshal image list for caching:", err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// 提取解密操作为函数
|
||||
func (l *GetAlbumDetailLogic) decryptConfig(config *model.ScaStorageConfig) (*storageConfig.StorageConfig, error) {
|
||||
accessKey, err := encrypt.Decrypt(config.AccessKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt access key failed")
|
||||
}
|
||||
secretKey, err := encrypt.Decrypt(config.SecretKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt secret key failed")
|
||||
}
|
||||
return &storageConfig.StorageConfig{
|
||||
Provider: config.Provider,
|
||||
Endpoint: config.Endpoint,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
BucketName: config.Bucket,
|
||||
Region: config.Region,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 从缓存或数据库中获取 OSS 配置
|
||||
func (l *GetAlbumDetailLogic) getOssConfigFromCacheOrDb(cacheKey, uid, provider string) (*storageConfig.StorageConfig, error) {
|
||||
result, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return nil, errors.New("get oss config failed")
|
||||
}
|
||||
|
||||
var ossConfig *storageConfig.StorageConfig
|
||||
if result != "" {
|
||||
var redisOssConfig model.ScaStorageConfig
|
||||
if err = json.Unmarshal([]byte(result), &redisOssConfig); err != nil {
|
||||
return nil, errors.New("unmarshal oss config failed")
|
||||
}
|
||||
return l.decryptConfig(&redisOssConfig)
|
||||
}
|
||||
|
||||
// 缓存未命中,从数据库中加载
|
||||
scaOssConfig := l.svcCtx.DB.ScaStorageConfig
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Provider.Eq(provider)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 缓存数据库配置
|
||||
ossConfig, err = l.decryptConfig(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
marshalData, err := json.Marshal(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("marshal oss config failed")
|
||||
}
|
||||
err = l.svcCtx.RedisClient.Set(l.ctx, cacheKey, marshalData, 0).Err()
|
||||
if err != nil {
|
||||
return nil, errors.New("set oss config failed")
|
||||
}
|
||||
|
||||
return ossConfig, nil
|
||||
}
|
||||
|
@@ -2,6 +2,18 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"math/rand"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/query"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"schisandra-album-cloud-microservices/common/encrypt"
|
||||
storageConfig "schisandra-album-cloud-microservices/common/storage/config"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
@@ -23,8 +35,172 @@ func NewGetFaceDetailListLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetFaceDetailListLogic) GetFaceDetailList(req *types.FaceDetailListRequest) (resp string, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
func (l *GetFaceDetailListLogic) GetFaceDetailList(req *types.FaceDetailListRequest) (resp *types.FaceDetailListResponse, err error) {
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found")
|
||||
}
|
||||
// 缓存获取数据 v1.0.0
|
||||
cacheKey := fmt.Sprintf("%s%s:%s:%s:%v", constant.ImageFaceListPrefix, uid, req.Provider, req.Bucket, req.FaceID)
|
||||
// 尝试从缓存获取
|
||||
cachedResult, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err == nil {
|
||||
var cachedResponse types.FaceDetailListResponse
|
||||
if err := json.Unmarshal([]byte(cachedResult), &cachedResponse); err == nil {
|
||||
return &cachedResponse, nil
|
||||
}
|
||||
logx.Error("Failed to unmarshal cached image list:", err)
|
||||
return nil, errors.New("get cached image list failed")
|
||||
} else if !errors.Is(err, redis.Nil) {
|
||||
logx.Error("Redis error:", err)
|
||||
return nil, errors.New("get cached image list failed")
|
||||
}
|
||||
|
||||
return
|
||||
// 缓存未命中,从数据库中查询
|
||||
storageInfo := l.svcCtx.DB.ScaStorageInfo
|
||||
// 数据库查询文件信息列表
|
||||
var storageInfoQuery query.IScaStorageInfoDo
|
||||
|
||||
storageInfoQuery = storageInfo.Where(
|
||||
storageInfo.UserID.Eq(uid),
|
||||
storageInfo.Provider.Eq(req.Provider),
|
||||
storageInfo.Bucket.Eq(req.Bucket),
|
||||
storageInfo.FaceID.Eq(req.FaceID)).
|
||||
Order(storageInfo.CreatedAt.Desc())
|
||||
storageInfoList, err := storageInfoQuery.Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(storageInfoList) == 0 {
|
||||
return &types.FaceDetailListResponse{}, nil
|
||||
}
|
||||
|
||||
// 加载用户oss配置信息
|
||||
cacheOssConfigKey := constant.UserOssConfigPrefix + uid + ":" + req.Provider
|
||||
ossConfig, err := l.getOssConfigFromCacheOrDb(cacheOssConfigKey, uid, req.Provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
service, err := l.svcCtx.StorageManager.GetStorage(uid, ossConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("get storage failed")
|
||||
}
|
||||
|
||||
// 按日期进行分组
|
||||
var wg sync.WaitGroup
|
||||
groupedImages := sync.Map{}
|
||||
|
||||
for _, dbFileInfo := range storageInfoList {
|
||||
wg.Add(1)
|
||||
go func(dbFileInfo *model.ScaStorageInfo) {
|
||||
defer wg.Done()
|
||||
weekday := WeekdayMap[dbFileInfo.CreatedAt.Weekday()]
|
||||
date := dbFileInfo.CreatedAt.Format("2006年1月2日 星期" + weekday)
|
||||
url, err := service.PresignedURL(l.ctx, ossConfig.BucketName, dbFileInfo.Path, time.Hour*24*7)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
}
|
||||
// 使用 Load 或 Store 确保原子操作
|
||||
value, _ := groupedImages.LoadOrStore(date, []types.ImageMeta{})
|
||||
images := value.([]types.ImageMeta)
|
||||
|
||||
images = append(images, types.ImageMeta{
|
||||
ID: dbFileInfo.ID,
|
||||
FileName: dbFileInfo.FileName,
|
||||
URL: url,
|
||||
Width: dbFileInfo.Width,
|
||||
Height: dbFileInfo.Height,
|
||||
CreatedAt: dbFileInfo.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
|
||||
// 重新存储更新后的图像列表
|
||||
groupedImages.Store(date, images)
|
||||
}(dbFileInfo)
|
||||
}
|
||||
wg.Wait()
|
||||
var imageList []types.AllImageDetail
|
||||
groupedImages.Range(func(key, value interface{}) bool {
|
||||
imageList = append(imageList, types.AllImageDetail{
|
||||
Date: key.(string),
|
||||
List: value.([]types.ImageMeta),
|
||||
})
|
||||
return true
|
||||
})
|
||||
resp = &types.FaceDetailListResponse{
|
||||
Records: imageList,
|
||||
}
|
||||
|
||||
// 缓存结果
|
||||
if data, err := json.Marshal(resp); err == nil {
|
||||
expireTime := 7*24*time.Hour - time.Duration(rand.Intn(60))*time.Minute
|
||||
if err := l.svcCtx.RedisClient.Set(l.ctx, cacheKey, data, expireTime).Err(); err != nil {
|
||||
logx.Error("Failed to cache image list:", err)
|
||||
}
|
||||
} else {
|
||||
logx.Error("Failed to marshal image list for caching:", err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// 提取解密操作为函数
|
||||
func (l *GetFaceDetailListLogic) decryptConfig(config *model.ScaStorageConfig) (*storageConfig.StorageConfig, error) {
|
||||
accessKey, err := encrypt.Decrypt(config.AccessKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt access key failed")
|
||||
}
|
||||
secretKey, err := encrypt.Decrypt(config.SecretKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt secret key failed")
|
||||
}
|
||||
return &storageConfig.StorageConfig{
|
||||
Provider: config.Provider,
|
||||
Endpoint: config.Endpoint,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
BucketName: config.Bucket,
|
||||
Region: config.Region,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 从缓存或数据库中获取 OSS 配置
|
||||
func (l *GetFaceDetailListLogic) getOssConfigFromCacheOrDb(cacheKey, uid, provider string) (*storageConfig.StorageConfig, error) {
|
||||
result, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return nil, errors.New("get oss config failed")
|
||||
}
|
||||
|
||||
var ossConfig *storageConfig.StorageConfig
|
||||
if result != "" {
|
||||
var redisOssConfig model.ScaStorageConfig
|
||||
if err = json.Unmarshal([]byte(result), &redisOssConfig); err != nil {
|
||||
return nil, errors.New("unmarshal oss config failed")
|
||||
}
|
||||
return l.decryptConfig(&redisOssConfig)
|
||||
}
|
||||
|
||||
// 缓存未命中,从数据库中加载
|
||||
scaOssConfig := l.svcCtx.DB.ScaStorageConfig
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Provider.Eq(provider)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 缓存数据库配置
|
||||
ossConfig, err = l.decryptConfig(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
marshalData, err := json.Marshal(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("marshal oss config failed")
|
||||
}
|
||||
err = l.svcCtx.RedisClient.Set(l.ctx, cacheKey, marshalData, 0).Err()
|
||||
if err != nil {
|
||||
return nil, errors.New("set oss config failed")
|
||||
}
|
||||
|
||||
return ossConfig, nil
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ func (l *ModifyFaceLibraryTypeLogic) ModifyFaceLibraryType(req *types.ModifyFace
|
||||
return nil, err
|
||||
}
|
||||
storageInfo := l.svcCtx.DB.ScaStorageInfo
|
||||
resultInfo, err := storageInfo.Where(storageInfo.FaceID.In(req.IDs...)).Update(storageInfo.ImgShow, req.FaceType)
|
||||
resultInfo, err := storageInfo.Where(storageInfo.FaceID.In(req.IDs...)).Update(storageInfo.IsDisplayed, req.FaceType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -173,7 +173,7 @@ func (l *QueryAllImageListLogic) decryptConfig(config *model.ScaStorageConfig) (
|
||||
return nil, errors.New("decrypt secret key failed")
|
||||
}
|
||||
return &storageConfig.StorageConfig{
|
||||
Provider: config.Type,
|
||||
Provider: config.Provider,
|
||||
Endpoint: config.Endpoint,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
@@ -200,7 +200,7 @@ func (l *QueryAllImageListLogic) getOssConfigFromCacheOrDb(cacheKey, uid, provid
|
||||
|
||||
// 缓存未命中,从数据库中加载
|
||||
scaOssConfig := l.svcCtx.DB.ScaStorageConfig
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Type.Eq(provider)).First()
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Provider.Eq(provider)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -2,6 +2,18 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"math/rand"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/query"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"schisandra-album-cloud-microservices/common/encrypt"
|
||||
storageConfig "schisandra-album-cloud-microservices/common/storage/config"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
@@ -24,7 +36,171 @@ func NewQueryLocationDetailListLogic(ctx context.Context, svcCtx *svc.ServiceCon
|
||||
}
|
||||
|
||||
func (l *QueryLocationDetailListLogic) QueryLocationDetailList(req *types.LocationDetailListRequest) (resp *types.LocationDetailListResponse, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found")
|
||||
}
|
||||
// 缓存获取数据 v1.0.0
|
||||
cacheKey := fmt.Sprintf("%s%s:%s:%s:%v", constant.ImageListPrefix, uid, req.Provider, req.Bucket, req.ID)
|
||||
// 尝试从缓存获取
|
||||
cachedResult, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err == nil {
|
||||
var cachedResponse types.LocationDetailListResponse
|
||||
if err := json.Unmarshal([]byte(cachedResult), &cachedResponse); err == nil {
|
||||
return &cachedResponse, nil
|
||||
}
|
||||
logx.Error("Failed to unmarshal cached image list:", err)
|
||||
return nil, errors.New("get cached image list failed")
|
||||
} else if !errors.Is(err, redis.Nil) {
|
||||
logx.Error("Redis error:", err)
|
||||
return nil, errors.New("get cached image list failed")
|
||||
}
|
||||
|
||||
return
|
||||
// 缓存未命中,从数据库中查询
|
||||
storageInfo := l.svcCtx.DB.ScaStorageInfo
|
||||
// 数据库查询文件信息列表
|
||||
var storageInfoQuery query.IScaStorageInfoDo
|
||||
|
||||
storageInfoQuery = storageInfo.Where(
|
||||
storageInfo.UserID.Eq(uid),
|
||||
storageInfo.Provider.Eq(req.Provider),
|
||||
storageInfo.Bucket.Eq(req.Bucket),
|
||||
storageInfo.LocationID.Eq(req.ID)).
|
||||
Order(storageInfo.CreatedAt.Desc())
|
||||
storageInfoList, err := storageInfoQuery.Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(storageInfoList) == 0 {
|
||||
return &types.LocationDetailListResponse{}, nil
|
||||
}
|
||||
|
||||
// 加载用户oss配置信息
|
||||
cacheOssConfigKey := constant.UserOssConfigPrefix + uid + ":" + req.Provider
|
||||
ossConfig, err := l.getOssConfigFromCacheOrDb(cacheOssConfigKey, uid, req.Provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
service, err := l.svcCtx.StorageManager.GetStorage(uid, ossConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("get storage failed")
|
||||
}
|
||||
|
||||
// 按日期进行分组
|
||||
var wg sync.WaitGroup
|
||||
groupedImages := sync.Map{}
|
||||
|
||||
for _, dbFileInfo := range storageInfoList {
|
||||
wg.Add(1)
|
||||
go func(dbFileInfo *model.ScaStorageInfo) {
|
||||
defer wg.Done()
|
||||
weekday := WeekdayMap[dbFileInfo.CreatedAt.Weekday()]
|
||||
date := dbFileInfo.CreatedAt.Format("2006年1月2日 星期" + weekday)
|
||||
url, err := service.PresignedURL(l.ctx, ossConfig.BucketName, dbFileInfo.Path, time.Hour*24*7)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
}
|
||||
// 使用 Load 或 Store 确保原子操作
|
||||
value, _ := groupedImages.LoadOrStore(date, []types.ImageMeta{})
|
||||
images := value.([]types.ImageMeta)
|
||||
|
||||
images = append(images, types.ImageMeta{
|
||||
ID: dbFileInfo.ID,
|
||||
FileName: dbFileInfo.FileName,
|
||||
URL: url,
|
||||
Width: dbFileInfo.Width,
|
||||
Height: dbFileInfo.Height,
|
||||
CreatedAt: dbFileInfo.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
|
||||
// 重新存储更新后的图像列表
|
||||
groupedImages.Store(date, images)
|
||||
}(dbFileInfo)
|
||||
}
|
||||
wg.Wait()
|
||||
var imageList []types.AllImageDetail
|
||||
groupedImages.Range(func(key, value interface{}) bool {
|
||||
imageList = append(imageList, types.AllImageDetail{
|
||||
Date: key.(string),
|
||||
List: value.([]types.ImageMeta),
|
||||
})
|
||||
return true
|
||||
})
|
||||
resp = &types.LocationDetailListResponse{
|
||||
Records: imageList,
|
||||
}
|
||||
|
||||
// 缓存结果
|
||||
if data, err := json.Marshal(resp); err == nil {
|
||||
expireTime := 7*24*time.Hour - time.Duration(rand.Intn(60))*time.Minute
|
||||
if err := l.svcCtx.RedisClient.Set(l.ctx, cacheKey, data, expireTime).Err(); err != nil {
|
||||
logx.Error("Failed to cache image list:", err)
|
||||
}
|
||||
} else {
|
||||
logx.Error("Failed to marshal image list for caching:", err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// 提取解密操作为函数
|
||||
func (l *QueryLocationDetailListLogic) decryptConfig(config *model.ScaStorageConfig) (*storageConfig.StorageConfig, error) {
|
||||
accessKey, err := encrypt.Decrypt(config.AccessKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt access key failed")
|
||||
}
|
||||
secretKey, err := encrypt.Decrypt(config.SecretKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt secret key failed")
|
||||
}
|
||||
return &storageConfig.StorageConfig{
|
||||
Provider: config.Provider,
|
||||
Endpoint: config.Endpoint,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
BucketName: config.Bucket,
|
||||
Region: config.Region,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 从缓存或数据库中获取 OSS 配置
|
||||
func (l *QueryLocationDetailListLogic) getOssConfigFromCacheOrDb(cacheKey, uid, provider string) (*storageConfig.StorageConfig, error) {
|
||||
result, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return nil, errors.New("get oss config failed")
|
||||
}
|
||||
|
||||
var ossConfig *storageConfig.StorageConfig
|
||||
if result != "" {
|
||||
var redisOssConfig model.ScaStorageConfig
|
||||
if err = json.Unmarshal([]byte(result), &redisOssConfig); err != nil {
|
||||
return nil, errors.New("unmarshal oss config failed")
|
||||
}
|
||||
return l.decryptConfig(&redisOssConfig)
|
||||
}
|
||||
|
||||
// 缓存未命中,从数据库中加载
|
||||
scaOssConfig := l.svcCtx.DB.ScaStorageConfig
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Provider.Eq(provider)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 缓存数据库配置
|
||||
ossConfig, err = l.decryptConfig(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
marshalData, err := json.Marshal(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("marshal oss config failed")
|
||||
}
|
||||
err = l.svcCtx.RedisClient.Set(l.ctx, cacheKey, marshalData, 0).Err()
|
||||
if err != nil {
|
||||
return nil, errors.New("set oss config failed")
|
||||
}
|
||||
|
||||
return ossConfig, nil
|
||||
}
|
||||
|
@@ -2,10 +2,17 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"schisandra-album-cloud-microservices/common/encrypt"
|
||||
storageConfig "schisandra-album-cloud-microservices/common/storage/config"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -24,7 +31,7 @@ func NewQueryLocationImageListLogic(ctx context.Context, svcCtx *svc.ServiceCont
|
||||
}
|
||||
}
|
||||
|
||||
func (l *QueryLocationImageListLogic) QueryLocationImageList() (resp *types.LocationListResponse, err error) {
|
||||
func (l *QueryLocationImageListLogic) QueryLocationImageList(req *types.LocationListRequest) (resp *types.LocationListResponse, err error) {
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found")
|
||||
@@ -36,11 +43,26 @@ func (l *QueryLocationImageListLogic) QueryLocationImageList() (resp *types.Loca
|
||||
storageLocation.Country,
|
||||
storageLocation.City,
|
||||
storageLocation.Province,
|
||||
storageLocation.Total).Where(storageLocation.UserID.Eq(uid)).
|
||||
storageLocation.CoverImage,
|
||||
storageLocation.Total).Where(storageLocation.UserID.Eq(uid),
|
||||
storageLocation.Provider.Eq(req.Provider),
|
||||
storageLocation.Bucket.Eq(req.Bucket)).
|
||||
Order(storageLocation.CreatedAt.Desc()).Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 加载用户oss配置信息
|
||||
cacheOssConfigKey := constant.UserOssConfigPrefix + uid + ":" + req.Provider
|
||||
ossConfig, err := l.getOssConfigFromCacheOrDb(cacheOssConfigKey, uid, req.Provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
service, err := l.svcCtx.StorageManager.GetStorage(uid, ossConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("get storage failed")
|
||||
}
|
||||
locationMap := make(map[string][]types.LocationMeta)
|
||||
|
||||
for _, loc := range locations {
|
||||
@@ -55,10 +77,15 @@ func (l *QueryLocationImageListLogic) QueryLocationImageList() (resp *types.Loca
|
||||
if city == "" {
|
||||
city = loc.Country
|
||||
}
|
||||
url, err := service.PresignedURL(l.ctx, req.Bucket, loc.CoverImage, 7*24*time.Hour)
|
||||
if err != nil {
|
||||
return nil, errors.New("get presigned url failed")
|
||||
}
|
||||
locationMeta := types.LocationMeta{
|
||||
ID: loc.ID,
|
||||
City: city,
|
||||
Total: loc.Total,
|
||||
ID: loc.ID,
|
||||
City: city,
|
||||
Total: loc.Total,
|
||||
CoverImage: url,
|
||||
}
|
||||
locationMap[locationKey] = append(locationMap[locationKey], locationMeta)
|
||||
}
|
||||
@@ -74,3 +101,63 @@ func (l *QueryLocationImageListLogic) QueryLocationImageList() (resp *types.Loca
|
||||
|
||||
return &types.LocationListResponse{Records: locationListData}, nil
|
||||
}
|
||||
|
||||
// 提取解密操作为函数
|
||||
func (l *QueryLocationImageListLogic) decryptConfig(config *model.ScaStorageConfig) (*storageConfig.StorageConfig, error) {
|
||||
accessKey, err := encrypt.Decrypt(config.AccessKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt access key failed")
|
||||
}
|
||||
secretKey, err := encrypt.Decrypt(config.SecretKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt secret key failed")
|
||||
}
|
||||
return &storageConfig.StorageConfig{
|
||||
Provider: config.Provider,
|
||||
Endpoint: config.Endpoint,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
BucketName: config.Bucket,
|
||||
Region: config.Region,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 从缓存或数据库中获取 OSS 配置
|
||||
func (l *QueryLocationImageListLogic) getOssConfigFromCacheOrDb(cacheKey, uid, provider string) (*storageConfig.StorageConfig, error) {
|
||||
result, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return nil, errors.New("get oss config failed")
|
||||
}
|
||||
|
||||
var ossConfig *storageConfig.StorageConfig
|
||||
if result != "" {
|
||||
var redisOssConfig model.ScaStorageConfig
|
||||
if err = json.Unmarshal([]byte(result), &redisOssConfig); err != nil {
|
||||
return nil, errors.New("unmarshal oss config failed")
|
||||
}
|
||||
return l.decryptConfig(&redisOssConfig)
|
||||
}
|
||||
|
||||
// 缓存未命中,从数据库中加载
|
||||
scaOssConfig := l.svcCtx.DB.ScaStorageConfig
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Provider.Eq(provider)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 缓存数据库配置
|
||||
ossConfig, err = l.decryptConfig(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
marshalData, err := json.Marshal(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("marshal oss config failed")
|
||||
}
|
||||
err = l.svcCtx.RedisClient.Set(l.ctx, cacheKey, marshalData, 0).Err()
|
||||
if err != nil {
|
||||
return nil, errors.New("set oss config failed")
|
||||
}
|
||||
|
||||
return ossConfig, nil
|
||||
}
|
||||
|
@@ -2,6 +2,18 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"math/rand"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/query"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"schisandra-album-cloud-microservices/common/encrypt"
|
||||
storageConfig "schisandra-album-cloud-microservices/common/storage/config"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
@@ -24,7 +36,171 @@ func NewQueryThingDetailListLogic(ctx context.Context, svcCtx *svc.ServiceContex
|
||||
}
|
||||
|
||||
func (l *QueryThingDetailListLogic) QueryThingDetailList(req *types.ThingDetailListRequest) (resp *types.ThingDetailListResponse, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found")
|
||||
}
|
||||
// 缓存获取数据 v1.0.0
|
||||
cacheKey := fmt.Sprintf("%s%s:%s:%s:%v", constant.ImageListPrefix, uid, req.Provider, req.Bucket, req.TagName)
|
||||
// 尝试从缓存获取
|
||||
cachedResult, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err == nil {
|
||||
var cachedResponse types.ThingDetailListResponse
|
||||
if err := json.Unmarshal([]byte(cachedResult), &cachedResponse); err == nil {
|
||||
return &cachedResponse, nil
|
||||
}
|
||||
logx.Error("Failed to unmarshal cached image list:", err)
|
||||
return nil, errors.New("get cached image list failed")
|
||||
} else if !errors.Is(err, redis.Nil) {
|
||||
logx.Error("Redis error:", err)
|
||||
return nil, errors.New("get cached image list failed")
|
||||
}
|
||||
|
||||
return
|
||||
// 缓存未命中,从数据库中查询
|
||||
storageInfo := l.svcCtx.DB.ScaStorageInfo
|
||||
// 数据库查询文件信息列表
|
||||
var storageInfoQuery query.IScaStorageInfoDo
|
||||
|
||||
storageInfoQuery = storageInfo.Where(
|
||||
storageInfo.UserID.Eq(uid),
|
||||
storageInfo.Provider.Eq(req.Provider),
|
||||
storageInfo.Bucket.Eq(req.Bucket),
|
||||
storageInfo.Tag.Eq(req.TagName)).
|
||||
Order(storageInfo.CreatedAt.Desc())
|
||||
storageInfoList, err := storageInfoQuery.Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(storageInfoList) == 0 {
|
||||
return &types.ThingDetailListResponse{}, nil
|
||||
}
|
||||
|
||||
// 加载用户oss配置信息
|
||||
cacheOssConfigKey := constant.UserOssConfigPrefix + uid + ":" + req.Provider
|
||||
ossConfig, err := l.getOssConfigFromCacheOrDb(cacheOssConfigKey, uid, req.Provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
service, err := l.svcCtx.StorageManager.GetStorage(uid, ossConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("get storage failed")
|
||||
}
|
||||
|
||||
// 按日期进行分组
|
||||
var wg sync.WaitGroup
|
||||
groupedImages := sync.Map{}
|
||||
|
||||
for _, dbFileInfo := range storageInfoList {
|
||||
wg.Add(1)
|
||||
go func(dbFileInfo *model.ScaStorageInfo) {
|
||||
defer wg.Done()
|
||||
weekday := WeekdayMap[dbFileInfo.CreatedAt.Weekday()]
|
||||
date := dbFileInfo.CreatedAt.Format("2006年1月2日 星期" + weekday)
|
||||
url, err := service.PresignedURL(l.ctx, ossConfig.BucketName, dbFileInfo.Path, time.Hour*24*7)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
}
|
||||
// 使用 Load 或 Store 确保原子操作
|
||||
value, _ := groupedImages.LoadOrStore(date, []types.ImageMeta{})
|
||||
images := value.([]types.ImageMeta)
|
||||
|
||||
images = append(images, types.ImageMeta{
|
||||
ID: dbFileInfo.ID,
|
||||
FileName: dbFileInfo.FileName,
|
||||
URL: url,
|
||||
Width: dbFileInfo.Width,
|
||||
Height: dbFileInfo.Height,
|
||||
CreatedAt: dbFileInfo.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
|
||||
// 重新存储更新后的图像列表
|
||||
groupedImages.Store(date, images)
|
||||
}(dbFileInfo)
|
||||
}
|
||||
wg.Wait()
|
||||
var imageList []types.AllImageDetail
|
||||
groupedImages.Range(func(key, value interface{}) bool {
|
||||
imageList = append(imageList, types.AllImageDetail{
|
||||
Date: key.(string),
|
||||
List: value.([]types.ImageMeta),
|
||||
})
|
||||
return true
|
||||
})
|
||||
resp = &types.ThingDetailListResponse{
|
||||
Records: imageList,
|
||||
}
|
||||
|
||||
// 缓存结果
|
||||
if data, err := json.Marshal(resp); err == nil {
|
||||
expireTime := 7*24*time.Hour - time.Duration(rand.Intn(60))*time.Minute
|
||||
if err := l.svcCtx.RedisClient.Set(l.ctx, cacheKey, data, expireTime).Err(); err != nil {
|
||||
logx.Error("Failed to cache image list:", err)
|
||||
}
|
||||
} else {
|
||||
logx.Error("Failed to marshal image list for caching:", err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// 提取解密操作为函数
|
||||
func (l *QueryThingDetailListLogic) decryptConfig(config *model.ScaStorageConfig) (*storageConfig.StorageConfig, error) {
|
||||
accessKey, err := encrypt.Decrypt(config.AccessKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt access key failed")
|
||||
}
|
||||
secretKey, err := encrypt.Decrypt(config.SecretKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt secret key failed")
|
||||
}
|
||||
return &storageConfig.StorageConfig{
|
||||
Provider: config.Provider,
|
||||
Endpoint: config.Endpoint,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
BucketName: config.Bucket,
|
||||
Region: config.Region,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 从缓存或数据库中获取 OSS 配置
|
||||
func (l *QueryThingDetailListLogic) getOssConfigFromCacheOrDb(cacheKey, uid, provider string) (*storageConfig.StorageConfig, error) {
|
||||
result, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return nil, errors.New("get oss config failed")
|
||||
}
|
||||
|
||||
var ossConfig *storageConfig.StorageConfig
|
||||
if result != "" {
|
||||
var redisOssConfig model.ScaStorageConfig
|
||||
if err = json.Unmarshal([]byte(result), &redisOssConfig); err != nil {
|
||||
return nil, errors.New("unmarshal oss config failed")
|
||||
}
|
||||
return l.decryptConfig(&redisOssConfig)
|
||||
}
|
||||
|
||||
// 缓存未命中,从数据库中加载
|
||||
scaOssConfig := l.svcCtx.DB.ScaStorageConfig
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Provider.Eq(provider)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 缓存数据库配置
|
||||
ossConfig, err = l.decryptConfig(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
marshalData, err := json.Marshal(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("marshal oss config failed")
|
||||
}
|
||||
err = l.svcCtx.RedisClient.Set(l.ctx, cacheKey, marshalData, 0).Err()
|
||||
if err != nil {
|
||||
return nil, errors.New("set oss config failed")
|
||||
}
|
||||
|
||||
return ossConfig, nil
|
||||
}
|
||||
|
@@ -2,8 +2,15 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"schisandra-album-cloud-microservices/common/encrypt"
|
||||
storageConfig "schisandra-album-cloud-microservices/common/storage/config"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
@@ -25,7 +32,7 @@ func NewQueryThingImageListLogic(ctx context.Context, svcCtx *svc.ServiceContext
|
||||
}
|
||||
}
|
||||
|
||||
func (l *QueryThingImageListLogic) QueryThingImageList() (resp *types.ThingListResponse, err error) {
|
||||
func (l *QueryThingImageListLogic) QueryThingImageList(req *types.ThingListRequest) (resp *types.ThingListResponse, err error) {
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found")
|
||||
@@ -34,33 +41,60 @@ func (l *QueryThingImageListLogic) QueryThingImageList() (resp *types.ThingListR
|
||||
storageInfos, err := storageInfo.Select(
|
||||
storageInfo.ID,
|
||||
storageInfo.Category,
|
||||
storageInfo.Tags,
|
||||
storageInfo.Tag,
|
||||
storageInfo.Path,
|
||||
storageInfo.CreatedAt).
|
||||
Where(storageInfo.UserID.Eq(uid),
|
||||
storageInfo.Provider.Eq(req.Provider),
|
||||
storageInfo.Bucket.Eq(req.Bucket),
|
||||
storageInfo.Category.IsNotNull(),
|
||||
storageInfo.Tags.IsNotNull()).
|
||||
storageInfo.Tag.IsNotNull(),
|
||||
storageInfo.Category.Length().Gt(0),
|
||||
storageInfo.Tag.Length().Gte(0)).
|
||||
Order(storageInfo.CreatedAt.Desc()).
|
||||
Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 加载用户oss配置信息
|
||||
cacheOssConfigKey := constant.UserOssConfigPrefix + uid + ":" + req.Provider
|
||||
ossConfig, err := l.getOssConfigFromCacheOrDb(cacheOssConfigKey, uid, req.Provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
service, err := l.svcCtx.StorageManager.GetStorage(uid, ossConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("get storage failed")
|
||||
}
|
||||
|
||||
categoryMap := sync.Map{}
|
||||
tagCountMap := sync.Map{}
|
||||
tagCoverMap := sync.Map{} // 用于存储每个 Tag 的封面图片路径
|
||||
|
||||
for _, info := range storageInfos {
|
||||
tagKey := info.Category + "::" + info.Tags
|
||||
tagKey := info.Category + "::" + info.Tag
|
||||
if _, exists := tagCountMap.Load(tagKey); !exists {
|
||||
tagCountMap.Store(tagKey, int64(0))
|
||||
categoryEntry, _ := categoryMap.LoadOrStore(info.Category, &sync.Map{})
|
||||
tagMap := categoryEntry.(*sync.Map)
|
||||
tagMap.Store(info.Tags, types.ThingMeta{
|
||||
TagName: info.Tags,
|
||||
tagMap.Store(info.Tag, types.ThingMeta{
|
||||
TagName: info.Tag,
|
||||
CreatedAt: info.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
tagCount, _ := tagCountMap.Load(tagKey)
|
||||
tagCountMap.Store(tagKey, tagCount.(int64)+1)
|
||||
|
||||
// 为每个 Tag 存储封面图片路径
|
||||
if _, exists := tagCoverMap.Load(tagKey); !exists {
|
||||
// 使用服务生成预签名 URL
|
||||
coverImageURL, err := service.PresignedURL(l.ctx, req.Bucket, info.Path, 7*24*time.Hour)
|
||||
if err == nil {
|
||||
tagCoverMap.Store(tagKey, coverImageURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var thingListData []types.ThingListData
|
||||
@@ -71,6 +105,11 @@ func (l *QueryThingImageListLogic) QueryThingImageList() (resp *types.ThingListR
|
||||
tagCount, _ := tagCountMap.Load(tagKey)
|
||||
meta := item.(types.ThingMeta)
|
||||
meta.TagCount = tagCount.(int64)
|
||||
|
||||
// 获取封面图片 URL
|
||||
if coverImageURL, ok := tagCoverMap.Load(tagKey); ok {
|
||||
meta.CoverImage = coverImageURL.(string)
|
||||
}
|
||||
metas = append(metas, meta)
|
||||
return true
|
||||
})
|
||||
@@ -83,3 +122,63 @@ func (l *QueryThingImageListLogic) QueryThingImageList() (resp *types.ThingListR
|
||||
|
||||
return &types.ThingListResponse{Records: thingListData}, nil
|
||||
}
|
||||
|
||||
// 提取解密操作为函数
|
||||
func (l *QueryThingImageListLogic) decryptConfig(config *model.ScaStorageConfig) (*storageConfig.StorageConfig, error) {
|
||||
accessKey, err := encrypt.Decrypt(config.AccessKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt access key failed")
|
||||
}
|
||||
secretKey, err := encrypt.Decrypt(config.SecretKey, l.svcCtx.Config.Encrypt.Key)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt secret key failed")
|
||||
}
|
||||
return &storageConfig.StorageConfig{
|
||||
Provider: config.Provider,
|
||||
Endpoint: config.Endpoint,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
BucketName: config.Bucket,
|
||||
Region: config.Region,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 从缓存或数据库中获取 OSS 配置
|
||||
func (l *QueryThingImageListLogic) getOssConfigFromCacheOrDb(cacheKey, uid, provider string) (*storageConfig.StorageConfig, error) {
|
||||
result, err := l.svcCtx.RedisClient.Get(l.ctx, cacheKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return nil, errors.New("get oss config failed")
|
||||
}
|
||||
|
||||
var ossConfig *storageConfig.StorageConfig
|
||||
if result != "" {
|
||||
var redisOssConfig model.ScaStorageConfig
|
||||
if err = json.Unmarshal([]byte(result), &redisOssConfig); err != nil {
|
||||
return nil, errors.New("unmarshal oss config failed")
|
||||
}
|
||||
return l.decryptConfig(&redisOssConfig)
|
||||
}
|
||||
|
||||
// 缓存未命中,从数据库中加载
|
||||
scaOssConfig := l.svcCtx.DB.ScaStorageConfig
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Provider.Eq(provider)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 缓存数据库配置
|
||||
ossConfig, err = l.decryptConfig(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
marshalData, err := json.Marshal(dbOssConfig)
|
||||
if err != nil {
|
||||
return nil, errors.New("marshal oss config failed")
|
||||
}
|
||||
err = l.svcCtx.RedisClient.Set(l.ctx, cacheKey, marshalData, 0).Err()
|
||||
if err != nil {
|
||||
return nil, errors.New("set oss config failed")
|
||||
}
|
||||
|
||||
return ossConfig, nil
|
||||
}
|
||||
|
@@ -40,7 +40,7 @@ func (l *SetStorageConfigLogic) SetStorageConfig(req *types.StorageConfigRequest
|
||||
}
|
||||
ossConfig := &model.ScaStorageConfig{
|
||||
UserID: uid,
|
||||
Type: req.Type,
|
||||
Provider: req.Type,
|
||||
Endpoint: req.Endpoint,
|
||||
Bucket: req.Bucket,
|
||||
AccessKey: accessKey,
|
||||
|
@@ -83,29 +83,8 @@ func (l *UploadFileLogic) UploadFile(r *http.Request) (resp string, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// 解析 EXIF 信息
|
||||
exif, err := l.parseExifData(result.Exif)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 提取拍摄时间
|
||||
originalDateTime, err := l.extractOriginalDateTime(exif)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 提取 GPS 信息
|
||||
latitude, longitude := l.extractGPSCoordinates(exif)
|
||||
|
||||
// 根据 GPS 信息获取地理位置信息
|
||||
country, province, city, err := l.getGeoLocation(latitude, longitude)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 将地址信息保存到数据库
|
||||
locationId, err := l.saveFileLocationInfoToDB(uid, latitude, longitude, country, province, city)
|
||||
country, province, city, err := l.getGeoLocation(result.Latitude, result.Longitude)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -120,8 +99,14 @@ func (l *UploadFileLogic) UploadFile(r *http.Request) (resp string, err error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 将地址信息保存到数据库
|
||||
locationId, err := l.saveFileLocationInfoToDB(uid, result.Provider, result.Bucket, result.Latitude, result.Longitude, country, province, city, filePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 将 EXIF 和文件信息存入数据库
|
||||
id, err := l.saveFileInfoToDB(uid, bucket, provider, header, result, originalDateTime, locationId, exif, faceId, filePath)
|
||||
id, err := l.saveFileInfoToDB(uid, bucket, provider, header, result, locationId, faceId, filePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -175,23 +160,6 @@ func (l *UploadFileLogic) parseAIRecognitionResult(r *http.Request) (types.File,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 解析 EXIF 数据
|
||||
func (l *UploadFileLogic) parseExifData(exifData interface{}) (map[string]interface{}, error) {
|
||||
if exifData == "" {
|
||||
return nil, nil
|
||||
}
|
||||
marshaledExif, err := json.Marshal(exifData)
|
||||
if err != nil {
|
||||
return nil, errors.New("invalid exif")
|
||||
}
|
||||
|
||||
var exif map[string]interface{}
|
||||
if err = json.Unmarshal(marshaledExif, &exif); err != nil {
|
||||
return nil, errors.New("invalid exif")
|
||||
}
|
||||
return exif, nil
|
||||
}
|
||||
|
||||
// 提取拍摄时间
|
||||
func (l *UploadFileLogic) extractOriginalDateTime(exif map[string]interface{}) (string, error) {
|
||||
if dateTimeOriginal, ok := exif["DateTimeOriginal"].(string); ok {
|
||||
@@ -203,18 +171,6 @@ func (l *UploadFileLogic) extractOriginalDateTime(exif map[string]interface{}) (
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// 提取 GPS 信息
|
||||
func (l *UploadFileLogic) extractGPSCoordinates(exif map[string]interface{}) (float64, float64) {
|
||||
var latitude, longitude float64
|
||||
if lat, ok := exif["latitude"].(float64); ok {
|
||||
latitude = lat
|
||||
}
|
||||
if long, ok := exif["longitude"].(float64); ok {
|
||||
longitude = long
|
||||
}
|
||||
return latitude, longitude
|
||||
}
|
||||
|
||||
// 根据 GPS 信息获取地理位置信息
|
||||
func (l *UploadFileLogic) getGeoLocation(latitude, longitude float64) (string, string, string, error) {
|
||||
if latitude == 0.000000 || longitude == 0.000000 {
|
||||
@@ -284,7 +240,7 @@ func (l *UploadFileLogic) uploadFileToOSS(uid string, header *multipart.FileHead
|
||||
return ossConfig.BucketName, ossConfig.Provider, objectKey, url, nil
|
||||
}
|
||||
|
||||
func (l *UploadFileLogic) saveFileLocationInfoToDB(uid string, latitude float64, longitude float64, country string, province string, city string) (int64, error) {
|
||||
func (l *UploadFileLogic) saveFileLocationInfoToDB(uid string, provider string, bucket string, latitude float64, longitude float64, country string, province string, city string, filePath string) (int64, error) {
|
||||
if latitude == 0.000000 || longitude == 0.000000 {
|
||||
return 0, nil
|
||||
}
|
||||
@@ -295,13 +251,16 @@ func (l *UploadFileLogic) saveFileLocationInfoToDB(uid string, latitude float64,
|
||||
}
|
||||
if storageLocations == nil {
|
||||
locationInfo := model.ScaStorageLocation{
|
||||
UserID: uid,
|
||||
Country: country,
|
||||
City: city,
|
||||
Province: province,
|
||||
Latitude: fmt.Sprintf("%f", latitude),
|
||||
Longitude: fmt.Sprintf("%f", longitude),
|
||||
Total: 1,
|
||||
Provider: provider,
|
||||
Bucket: bucket,
|
||||
UserID: uid,
|
||||
Country: country,
|
||||
City: city,
|
||||
Province: province,
|
||||
Latitude: fmt.Sprintf("%f", latitude),
|
||||
Longitude: fmt.Sprintf("%f", longitude),
|
||||
Total: 1,
|
||||
CoverImage: filePath,
|
||||
}
|
||||
err = locationDB.Create(&locationInfo)
|
||||
if err != nil {
|
||||
@@ -309,7 +268,7 @@ func (l *UploadFileLogic) saveFileLocationInfoToDB(uid string, latitude float64,
|
||||
}
|
||||
return locationInfo.ID, nil
|
||||
} else {
|
||||
info, err := locationDB.Where(locationDB.ID.Eq(storageLocations.ID), locationDB.UserID.Eq(uid)).Update(locationDB.Total, locationDB.Total.Add(1))
|
||||
info, err := locationDB.Where(locationDB.ID.Eq(storageLocations.ID), locationDB.UserID.Eq(uid)).UpdateColumnSimple(locationDB.Total.Add(1), locationDB.CoverImage.Value(filePath))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -321,35 +280,29 @@ func (l *UploadFileLogic) saveFileLocationInfoToDB(uid string, latitude float64,
|
||||
}
|
||||
|
||||
// 将 EXIF 和文件信息存入数据库
|
||||
func (l *UploadFileLogic) saveFileInfoToDB(uid, bucket, provider string, header *multipart.FileHeader, result types.File, originalDateTime string, locationId int64, exif map[string]interface{}, faceId int64, filePath string) (int64, error) {
|
||||
exifJSON, err := json.Marshal(exif)
|
||||
if err != nil {
|
||||
return 0, errors.New("marshal exif failed")
|
||||
}
|
||||
func (l *UploadFileLogic) saveFileInfoToDB(uid, bucket, provider string, header *multipart.FileHeader, result types.File, locationId, faceId int64, filePath string) (int64, error) {
|
||||
|
||||
typeName := l.classifyFile(result.FileType, result.IsScreenshot)
|
||||
scaStorageInfo := &model.ScaStorageInfo{
|
||||
UserID: uid,
|
||||
Provider: provider,
|
||||
Bucket: bucket,
|
||||
FileName: header.Filename,
|
||||
FileSize: strconv.FormatInt(header.Size, 10),
|
||||
FileType: result.FileType,
|
||||
Path: filePath,
|
||||
Landscape: result.Landscape,
|
||||
Tags: result.TagName,
|
||||
Anime: strconv.FormatBool(result.IsAnime),
|
||||
Category: result.TopCategory,
|
||||
Screenshot: strconv.FormatBool(result.IsScreenshot),
|
||||
OriginalTime: originalDateTime,
|
||||
LocationID: locationId,
|
||||
Exif: string(exifJSON),
|
||||
FaceID: faceId,
|
||||
Type: typeName,
|
||||
Width: result.Width,
|
||||
Height: result.Height,
|
||||
UserID: uid,
|
||||
Provider: provider,
|
||||
Bucket: bucket,
|
||||
FileName: header.Filename,
|
||||
FileSize: strconv.FormatInt(header.Size, 10),
|
||||
FileType: result.FileType,
|
||||
Path: filePath,
|
||||
Landscape: result.Landscape,
|
||||
Tag: result.TagName,
|
||||
IsAnime: strconv.FormatBool(result.IsAnime),
|
||||
Category: result.TopCategory,
|
||||
LocationID: locationId,
|
||||
FaceID: faceId,
|
||||
Type: typeName,
|
||||
Width: result.Width,
|
||||
Height: result.Height,
|
||||
}
|
||||
|
||||
err = l.svcCtx.DB.ScaStorageInfo.Create(scaStorageInfo)
|
||||
err := l.svcCtx.DB.ScaStorageInfo.Create(scaStorageInfo)
|
||||
if err != nil {
|
||||
return 0, errors.New("create storage info failed")
|
||||
}
|
||||
@@ -367,7 +320,7 @@ func (l *UploadFileLogic) decryptConfig(dbConfig *model.ScaStorageConfig) (*conf
|
||||
return nil, errors.New("decrypt secret key failed")
|
||||
}
|
||||
return &config.StorageConfig{
|
||||
Provider: dbConfig.Type,
|
||||
Provider: dbConfig.Provider,
|
||||
Endpoint: dbConfig.Endpoint,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
@@ -394,7 +347,7 @@ func (l *UploadFileLogic) getOssConfigFromCacheOrDb(cacheKey, uid, provider stri
|
||||
|
||||
// 缓存未命中,从数据库中加载
|
||||
scaOssConfig := l.svcCtx.DB.ScaStorageConfig
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Type.Eq(provider)).First()
|
||||
dbOssConfig, err := scaOssConfig.Where(scaOssConfig.UserID.Eq(uid), scaOssConfig.Provider.Eq(provider)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -10,7 +10,8 @@ type File struct {
|
||||
Landscape string `json:"landscape"`
|
||||
TopCategory string `json:"topCategory"`
|
||||
IsScreenshot bool `json:"isScreenshot"`
|
||||
Exif any `json:"exif"`
|
||||
Width float64 `json:"width"`
|
||||
Height float64 `json:"height"`
|
||||
Longitude float64 `json:"longitude"`
|
||||
Latitude float64 `json:"latitude"`
|
||||
}
|
||||
|
@@ -32,7 +32,13 @@ type AlbumDeleteRequest struct {
|
||||
}
|
||||
|
||||
type AlbumDetailListRequest struct {
|
||||
ID int64 `json:"id"`
|
||||
ID int64 `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
|
||||
type AlbumDetailListResponse struct {
|
||||
Records []AllImageDetail `json:"records"`
|
||||
}
|
||||
|
||||
type AlbumListRequest struct {
|
||||
@@ -142,7 +148,13 @@ type CommentResponse struct {
|
||||
}
|
||||
|
||||
type FaceDetailListRequest struct {
|
||||
FaceID int64 `json:"face_id"`
|
||||
FaceID int64 `json:"face_id"`
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
|
||||
type FaceDetailListResponse struct {
|
||||
Records []AllImageDetail `json:"records"`
|
||||
}
|
||||
|
||||
type FaceSampleLibrary struct {
|
||||
@@ -169,7 +181,9 @@ type ImageMeta struct {
|
||||
}
|
||||
|
||||
type LocationDetailListRequest struct {
|
||||
ID int64 `json:"id"`
|
||||
ID int64 `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
|
||||
type LocationDetailListResponse struct {
|
||||
@@ -181,14 +195,20 @@ type LocationListData struct {
|
||||
List []LocationMeta `json:"list"` // 图片列表
|
||||
}
|
||||
|
||||
type LocationListRequest struct {
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
|
||||
type LocationListResponse struct {
|
||||
Records []LocationListData `json:"records"`
|
||||
}
|
||||
|
||||
type LocationMeta struct {
|
||||
ID int64 `json:"id"`
|
||||
City string `json:"city"`
|
||||
Total int64 `json:"total"`
|
||||
ID int64 `json:"id"`
|
||||
City string `json:"city"`
|
||||
Total int64 `json:"total"`
|
||||
CoverImage string `json:"cover_image"`
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
@@ -311,7 +331,9 @@ type StorageConfigRequest struct {
|
||||
}
|
||||
|
||||
type ThingDetailListRequest struct {
|
||||
ID int64 `json:"id"`
|
||||
TagName string `json:"tag_name"`
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
|
||||
type ThingDetailListResponse struct {
|
||||
@@ -323,14 +345,20 @@ type ThingListData struct {
|
||||
List []ThingMeta `json:"list"` // 图片列表
|
||||
}
|
||||
|
||||
type ThingListRequest struct {
|
||||
Provider string `json:"provider"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
|
||||
type ThingListResponse struct {
|
||||
Records []ThingListData `json:"records"`
|
||||
}
|
||||
|
||||
type ThingMeta struct {
|
||||
TagName string `json:"tag_name"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
TagCount int64 `json:"tag_count"`
|
||||
TagName string `json:"tag_name"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
TagCount int64 `json:"tag_count"`
|
||||
CoverImage string `json:"cover_image"`
|
||||
}
|
||||
|
||||
type UploadRequest struct {
|
||||
|
@@ -16,7 +16,7 @@ const TableNameScaStorageConfig = "sca_storage_config"
|
||||
type ScaStorageConfig struct {
|
||||
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;autoIncrement:true;comment:主键;primary_key" json:"id,string"` // 主键
|
||||
UserID string `gorm:"column:user_id;type:varchar(50);not null;comment:用户ID" json:"user_id"` // 用户ID
|
||||
Type string `gorm:"column:type;type:varchar(50);comment:类型" json:"type"` // 类型
|
||||
Provider string `gorm:"column:provider;type:varchar(50);comment:供应商" json:"provider"` // 供应商
|
||||
Endpoint string `gorm:"column:endpoint;type:varchar(50);comment:地址" json:"endpoint"` // 地址
|
||||
AccessKey string `gorm:"column:access_key;type:varchar(100);comment:密钥key" json:"access_key"` // 密钥key
|
||||
SecretKey string `gorm:"column:secret_key;type:varchar(100);comment:密钥" json:"secret_key"` // 密钥
|
||||
|
@@ -14,32 +14,29 @@ const TableNameScaStorageInfo = "sca_storage_info"
|
||||
|
||||
// ScaStorageInfo mapped from table <sca_storage_info>
|
||||
type ScaStorageInfo struct {
|
||||
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;autoIncrement:true;comment:主键;primary_key" json:"id,string"` // 主键
|
||||
UserID string `gorm:"column:user_id;type:varchar(50);not null;comment:用户ID" json:"user_id"` // 用户ID
|
||||
Provider string `gorm:"column:provider;type:varchar(50);comment:供应商" json:"provider"` // 供应商
|
||||
Bucket string `gorm:"column:bucket;type:varchar(50);comment:存储桶" json:"bucket"` // 存储桶
|
||||
Path string `gorm:"column:path;type:text;comment:路径" json:"path"` // 路径
|
||||
FileName string `gorm:"column:file_name;type:varchar(100);comment:文件名称" json:"file_name"` // 文件名称
|
||||
FileSize string `gorm:"column:file_size;type:varchar(50);comment:文件大小" json:"file_size"` // 文件大小
|
||||
FileType string `gorm:"column:file_type;type:varchar(50);comment:文件类型" json:"file_type"` // 文件类型
|
||||
Width float64 `gorm:"column:width;type:double;comment:宽" json:"width"` // 宽
|
||||
Height float64 `gorm:"column:height;type:double;comment:高" json:"height"` // 高
|
||||
Category string `gorm:"column:category;type:varchar(50);comment:分类" json:"category"` // 分类
|
||||
Tags string `gorm:"column:tags;type:varchar(255);comment:标签" json:"tags"` // 标签
|
||||
Type string `gorm:"column:type;type:varchar(50);comment:类型" json:"type"` // 类型
|
||||
LocationID int64 `gorm:"column:location_id;type:bigint(20);comment:地址ID" json:"location_id"` // 地址ID
|
||||
Hash string `gorm:"column:hash;type:varchar(255);comment:哈希值" json:"hash"` // 哈希值
|
||||
Anime string `gorm:"column:anime;type:varchar(50);comment:是否是动漫图片" json:"anime"` // 是否是动漫图片
|
||||
FaceID int64 `gorm:"column:face_id;type:bigint(20);comment:人像ID" json:"face_id"` // 人像ID
|
||||
Landscape string `gorm:"column:landscape;type:varchar(50);comment:风景类型" json:"landscape"` // 风景类型
|
||||
OriginalTime string `gorm:"column:original_time;type:varchar(50);comment:拍摄时间" json:"original_time"` // 拍摄时间
|
||||
Screenshot string `gorm:"column:screenshot;type:varchar(50);comment:是否是截图" json:"screenshot"` // 是否是截图
|
||||
Exif string `gorm:"column:exif;type:json;comment:exif 信息" json:"exif"` // exif 信息
|
||||
ImgShow int64 `gorm:"column:img_show;type:tinyint(4);comment:是否隐藏(0 不隐藏 1 隐藏)" json:"img_show"` // 是否隐藏(0 不隐藏 1 隐藏)
|
||||
AlbumID int64 `gorm:"column:album_id;type:bigint(20);comment:相册ID" json:"album_id"` // 相册ID
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;autoCreateTime;comment:创建时间" json:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp;autoUpdateTime;comment:更新时间" json:"updated_at"` // 更新时间
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp;comment:删除时间" json:"deleted_at"` // 删除时间
|
||||
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;autoIncrement:true;comment:主键;primary_key" json:"id,string"` // 主键
|
||||
UserID string `gorm:"column:user_id;type:varchar(50);not null;comment:用户ID" json:"user_id"` // 用户ID
|
||||
Provider string `gorm:"column:provider;type:varchar(50);comment:供应商" json:"provider"` // 供应商
|
||||
Bucket string `gorm:"column:bucket;type:varchar(50);comment:存储桶" json:"bucket"` // 存储桶
|
||||
Path string `gorm:"column:path;type:text;comment:路径" json:"path"` // 路径
|
||||
FileName string `gorm:"column:file_name;type:varchar(100);comment:文件名称" json:"file_name"` // 文件名称
|
||||
FileSize string `gorm:"column:file_size;type:varchar(50);comment:文件大小" json:"file_size"` // 文件大小
|
||||
FileType string `gorm:"column:file_type;type:varchar(50);comment:文件类型" json:"file_type"` // 文件类型
|
||||
Width float64 `gorm:"column:width;type:double;comment:宽" json:"width"` // 宽
|
||||
Height float64 `gorm:"column:height;type:double;comment:高" json:"height"` // 高
|
||||
Category string `gorm:"column:category;type:varchar(50);comment:分类" json:"category"` // 分类
|
||||
Tag string `gorm:"column:tag;type:varchar(255);comment:标签" json:"tag"` // 标签
|
||||
Type string `gorm:"column:type;type:varchar(50);comment:类型" json:"type"` // 类型
|
||||
LocationID int64 `gorm:"column:location_id;type:bigint(20);comment:地址ID" json:"location_id"` // 地址ID
|
||||
Hash string `gorm:"column:hash;type:varchar(255);comment:哈希值" json:"hash"` // 哈希值
|
||||
IsAnime string `gorm:"column:is_anime;type:varchar(50);comment:是否是动漫图片" json:"is_anime"` // 是否是动漫图片
|
||||
FaceID int64 `gorm:"column:face_id;type:bigint(20);comment:人像ID" json:"face_id"` // 人像ID
|
||||
Landscape string `gorm:"column:landscape;type:varchar(50);comment:风景类型" json:"landscape"` // 风景类型
|
||||
IsDisplayed int64 `gorm:"column:is_displayed;type:tinyint(4);comment:是否隐藏(0 不隐藏 1 隐藏)" json:"is_displayed"` // 是否隐藏(0 不隐藏 1 隐藏)
|
||||
AlbumID int64 `gorm:"column:album_id;type:bigint(20);comment:相册ID" json:"album_id"` // 相册ID
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;autoCreateTime;comment:创建时间" json:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp;autoUpdateTime;comment:更新时间" json:"updated_at"` // 更新时间
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp;comment:删除时间" json:"deleted_at"` // 删除时间
|
||||
}
|
||||
|
||||
// TableName ScaStorageInfo's table name
|
||||
|
@@ -15,18 +15,21 @@ const TableNameScaStorageLocation = "sca_storage_location"
|
||||
|
||||
// ScaStorageLocation mapped from table <sca_storage_location>
|
||||
type ScaStorageLocation struct {
|
||||
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;autoIncrement:true;comment:主键;primary_key" json:"id,string"` // 主键
|
||||
UserID string `gorm:"column:user_id;type:varchar(50);comment:用户id" json:"user_id"` // 用户id
|
||||
Country string `gorm:"column:country;type:varchar(100);comment:国家" json:"country"` // 国家
|
||||
Province string `gorm:"column:province;type:varchar(100);comment:省" json:"province"` // 省
|
||||
City string `gorm:"column:city;type:varchar(100);comment:城市" json:"city"` // 城市
|
||||
Latitude string `gorm:"column:latitude;type:varchar(50);comment:纬度" json:"latitude"` // 纬度
|
||||
Longitude string `gorm:"column:longitude;type:varchar(50);comment:经度" json:"longitude"` // 经度
|
||||
Total int64 `gorm:"column:total;type:bigint(20);comment:数量" json:"total"` // 数量
|
||||
Version optimisticlock.Version `gorm:"column:version;type:bigint(20);comment:版本" json:"version"` // 版本
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;autoCreateTime;comment:创建时间" json:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp;autoUpdateTime;comment:更新时间" json:"updated_at"` // 更新时间
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp;comment:删除时间" json:"deleted_at"` // 删除时间
|
||||
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;autoIncrement:true;comment:主键;primary_key" json:"id,string"` // 主键
|
||||
UserID string `gorm:"column:user_id;type:varchar(50);comment:用户id" json:"user_id"` // 用户id
|
||||
Provider string `gorm:"column:provider;type:varchar(50);comment:供应商" json:"provider"` // 供应商
|
||||
Bucket string `gorm:"column:bucket;type:varchar(50);comment:存储桶" json:"bucket"` // 存储桶
|
||||
Country string `gorm:"column:country;type:varchar(100);comment:国家" json:"country"` // 国家
|
||||
Province string `gorm:"column:province;type:varchar(100);comment:省" json:"province"` // 省
|
||||
City string `gorm:"column:city;type:varchar(100);comment:城市" json:"city"` // 城市
|
||||
Latitude string `gorm:"column:latitude;type:varchar(50);comment:纬度" json:"latitude"` // 纬度
|
||||
Longitude string `gorm:"column:longitude;type:varchar(50);comment:经度" json:"longitude"` // 经度
|
||||
Total int64 `gorm:"column:total;type:bigint(20);comment:数量" json:"total"` // 数量
|
||||
CoverImage string `gorm:"column:cover_image;type:text;comment:封面图片" json:"cover_image"` // 封面图片
|
||||
Version optimisticlock.Version `gorm:"column:version;type:bigint(20);comment:版本" json:"version"` // 版本
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;autoCreateTime;comment:创建时间" json:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp;autoUpdateTime;comment:更新时间" json:"updated_at"` // 更新时间
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp;comment:删除时间" json:"deleted_at"` // 删除时间
|
||||
}
|
||||
|
||||
// TableName ScaStorageLocation's table name
|
||||
|
@@ -29,7 +29,7 @@ func newScaStorageConfig(db *gorm.DB, opts ...gen.DOOption) scaStorageConfig {
|
||||
_scaStorageConfig.ALL = field.NewAsterisk(tableName)
|
||||
_scaStorageConfig.ID = field.NewInt64(tableName, "id")
|
||||
_scaStorageConfig.UserID = field.NewString(tableName, "user_id")
|
||||
_scaStorageConfig.Type = field.NewString(tableName, "type")
|
||||
_scaStorageConfig.Provider = field.NewString(tableName, "provider")
|
||||
_scaStorageConfig.Endpoint = field.NewString(tableName, "endpoint")
|
||||
_scaStorageConfig.AccessKey = field.NewString(tableName, "access_key")
|
||||
_scaStorageConfig.SecretKey = field.NewString(tableName, "secret_key")
|
||||
@@ -50,7 +50,7 @@ type scaStorageConfig struct {
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // 主键
|
||||
UserID field.String // 用户ID
|
||||
Type field.String // 类型
|
||||
Provider field.String // 供应商
|
||||
Endpoint field.String // 地址
|
||||
AccessKey field.String // 密钥key
|
||||
SecretKey field.String // 密钥
|
||||
@@ -77,7 +77,7 @@ func (s *scaStorageConfig) updateTableName(table string) *scaStorageConfig {
|
||||
s.ALL = field.NewAsterisk(table)
|
||||
s.ID = field.NewInt64(table, "id")
|
||||
s.UserID = field.NewString(table, "user_id")
|
||||
s.Type = field.NewString(table, "type")
|
||||
s.Provider = field.NewString(table, "provider")
|
||||
s.Endpoint = field.NewString(table, "endpoint")
|
||||
s.AccessKey = field.NewString(table, "access_key")
|
||||
s.SecretKey = field.NewString(table, "secret_key")
|
||||
@@ -105,7 +105,7 @@ func (s *scaStorageConfig) fillFieldMap() {
|
||||
s.fieldMap = make(map[string]field.Expr, 11)
|
||||
s.fieldMap["id"] = s.ID
|
||||
s.fieldMap["user_id"] = s.UserID
|
||||
s.fieldMap["type"] = s.Type
|
||||
s.fieldMap["provider"] = s.Provider
|
||||
s.fieldMap["endpoint"] = s.Endpoint
|
||||
s.fieldMap["access_key"] = s.AccessKey
|
||||
s.fieldMap["secret_key"] = s.SecretKey
|
||||
|
@@ -38,17 +38,14 @@ func newScaStorageInfo(db *gorm.DB, opts ...gen.DOOption) scaStorageInfo {
|
||||
_scaStorageInfo.Width = field.NewFloat64(tableName, "width")
|
||||
_scaStorageInfo.Height = field.NewFloat64(tableName, "height")
|
||||
_scaStorageInfo.Category = field.NewString(tableName, "category")
|
||||
_scaStorageInfo.Tags = field.NewString(tableName, "tags")
|
||||
_scaStorageInfo.Tag = field.NewString(tableName, "tag")
|
||||
_scaStorageInfo.Type = field.NewString(tableName, "type")
|
||||
_scaStorageInfo.LocationID = field.NewInt64(tableName, "location_id")
|
||||
_scaStorageInfo.Hash = field.NewString(tableName, "hash")
|
||||
_scaStorageInfo.Anime = field.NewString(tableName, "anime")
|
||||
_scaStorageInfo.IsAnime = field.NewString(tableName, "is_anime")
|
||||
_scaStorageInfo.FaceID = field.NewInt64(tableName, "face_id")
|
||||
_scaStorageInfo.Landscape = field.NewString(tableName, "landscape")
|
||||
_scaStorageInfo.OriginalTime = field.NewString(tableName, "original_time")
|
||||
_scaStorageInfo.Screenshot = field.NewString(tableName, "screenshot")
|
||||
_scaStorageInfo.Exif = field.NewString(tableName, "exif")
|
||||
_scaStorageInfo.ImgShow = field.NewInt64(tableName, "img_show")
|
||||
_scaStorageInfo.IsDisplayed = field.NewInt64(tableName, "is_displayed")
|
||||
_scaStorageInfo.AlbumID = field.NewInt64(tableName, "album_id")
|
||||
_scaStorageInfo.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_scaStorageInfo.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
@@ -62,33 +59,30 @@ func newScaStorageInfo(db *gorm.DB, opts ...gen.DOOption) scaStorageInfo {
|
||||
type scaStorageInfo struct {
|
||||
scaStorageInfoDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // 主键
|
||||
UserID field.String // 用户ID
|
||||
Provider field.String // 供应商
|
||||
Bucket field.String // 存储桶
|
||||
Path field.String // 路径
|
||||
FileName field.String // 文件名称
|
||||
FileSize field.String // 文件大小
|
||||
FileType field.String // 文件类型
|
||||
Width field.Float64 // 宽
|
||||
Height field.Float64 // 高
|
||||
Category field.String // 分类
|
||||
Tags field.String // 标签
|
||||
Type field.String // 类型
|
||||
LocationID field.Int64 // 地址ID
|
||||
Hash field.String // 哈希值
|
||||
Anime field.String // 是否是动漫图片
|
||||
FaceID field.Int64 // 人像ID
|
||||
Landscape field.String // 风景类型
|
||||
OriginalTime field.String // 拍摄时间
|
||||
Screenshot field.String // 是否是截图
|
||||
Exif field.String // exif 信息
|
||||
ImgShow field.Int64 // 是否隐藏(0 不隐藏 1 隐藏)
|
||||
AlbumID field.Int64 // 相册ID
|
||||
CreatedAt field.Time // 创建时间
|
||||
UpdatedAt field.Time // 更新时间
|
||||
DeletedAt field.Field // 删除时间
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // 主键
|
||||
UserID field.String // 用户ID
|
||||
Provider field.String // 供应商
|
||||
Bucket field.String // 存储桶
|
||||
Path field.String // 路径
|
||||
FileName field.String // 文件名称
|
||||
FileSize field.String // 文件大小
|
||||
FileType field.String // 文件类型
|
||||
Width field.Float64 // 宽
|
||||
Height field.Float64 // 高
|
||||
Category field.String // 分类
|
||||
Tag field.String // 标签
|
||||
Type field.String // 类型
|
||||
LocationID field.Int64 // 地址ID
|
||||
Hash field.String // 哈希值
|
||||
IsAnime field.String // 是否是动漫图片
|
||||
FaceID field.Int64 // 人像ID
|
||||
Landscape field.String // 风景类型
|
||||
IsDisplayed field.Int64 // 是否隐藏(0 不隐藏 1 隐藏)
|
||||
AlbumID field.Int64 // 相册ID
|
||||
CreatedAt field.Time // 创建时间
|
||||
UpdatedAt field.Time // 更新时间
|
||||
DeletedAt field.Field // 删除时间
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@@ -116,17 +110,14 @@ func (s *scaStorageInfo) updateTableName(table string) *scaStorageInfo {
|
||||
s.Width = field.NewFloat64(table, "width")
|
||||
s.Height = field.NewFloat64(table, "height")
|
||||
s.Category = field.NewString(table, "category")
|
||||
s.Tags = field.NewString(table, "tags")
|
||||
s.Tag = field.NewString(table, "tag")
|
||||
s.Type = field.NewString(table, "type")
|
||||
s.LocationID = field.NewInt64(table, "location_id")
|
||||
s.Hash = field.NewString(table, "hash")
|
||||
s.Anime = field.NewString(table, "anime")
|
||||
s.IsAnime = field.NewString(table, "is_anime")
|
||||
s.FaceID = field.NewInt64(table, "face_id")
|
||||
s.Landscape = field.NewString(table, "landscape")
|
||||
s.OriginalTime = field.NewString(table, "original_time")
|
||||
s.Screenshot = field.NewString(table, "screenshot")
|
||||
s.Exif = field.NewString(table, "exif")
|
||||
s.ImgShow = field.NewInt64(table, "img_show")
|
||||
s.IsDisplayed = field.NewInt64(table, "is_displayed")
|
||||
s.AlbumID = field.NewInt64(table, "album_id")
|
||||
s.CreatedAt = field.NewTime(table, "created_at")
|
||||
s.UpdatedAt = field.NewTime(table, "updated_at")
|
||||
@@ -147,7 +138,7 @@ func (s *scaStorageInfo) GetFieldByName(fieldName string) (field.OrderExpr, bool
|
||||
}
|
||||
|
||||
func (s *scaStorageInfo) fillFieldMap() {
|
||||
s.fieldMap = make(map[string]field.Expr, 26)
|
||||
s.fieldMap = make(map[string]field.Expr, 23)
|
||||
s.fieldMap["id"] = s.ID
|
||||
s.fieldMap["user_id"] = s.UserID
|
||||
s.fieldMap["provider"] = s.Provider
|
||||
@@ -159,17 +150,14 @@ func (s *scaStorageInfo) fillFieldMap() {
|
||||
s.fieldMap["width"] = s.Width
|
||||
s.fieldMap["height"] = s.Height
|
||||
s.fieldMap["category"] = s.Category
|
||||
s.fieldMap["tags"] = s.Tags
|
||||
s.fieldMap["tag"] = s.Tag
|
||||
s.fieldMap["type"] = s.Type
|
||||
s.fieldMap["location_id"] = s.LocationID
|
||||
s.fieldMap["hash"] = s.Hash
|
||||
s.fieldMap["anime"] = s.Anime
|
||||
s.fieldMap["is_anime"] = s.IsAnime
|
||||
s.fieldMap["face_id"] = s.FaceID
|
||||
s.fieldMap["landscape"] = s.Landscape
|
||||
s.fieldMap["original_time"] = s.OriginalTime
|
||||
s.fieldMap["screenshot"] = s.Screenshot
|
||||
s.fieldMap["exif"] = s.Exif
|
||||
s.fieldMap["img_show"] = s.ImgShow
|
||||
s.fieldMap["is_displayed"] = s.IsDisplayed
|
||||
s.fieldMap["album_id"] = s.AlbumID
|
||||
s.fieldMap["created_at"] = s.CreatedAt
|
||||
s.fieldMap["updated_at"] = s.UpdatedAt
|
||||
|
@@ -29,12 +29,15 @@ func newScaStorageLocation(db *gorm.DB, opts ...gen.DOOption) scaStorageLocation
|
||||
_scaStorageLocation.ALL = field.NewAsterisk(tableName)
|
||||
_scaStorageLocation.ID = field.NewInt64(tableName, "id")
|
||||
_scaStorageLocation.UserID = field.NewString(tableName, "user_id")
|
||||
_scaStorageLocation.Provider = field.NewString(tableName, "provider")
|
||||
_scaStorageLocation.Bucket = field.NewString(tableName, "bucket")
|
||||
_scaStorageLocation.Country = field.NewString(tableName, "country")
|
||||
_scaStorageLocation.Province = field.NewString(tableName, "province")
|
||||
_scaStorageLocation.City = field.NewString(tableName, "city")
|
||||
_scaStorageLocation.Latitude = field.NewString(tableName, "latitude")
|
||||
_scaStorageLocation.Longitude = field.NewString(tableName, "longitude")
|
||||
_scaStorageLocation.Total = field.NewInt64(tableName, "total")
|
||||
_scaStorageLocation.CoverImage = field.NewString(tableName, "cover_image")
|
||||
_scaStorageLocation.Version = field.NewField(tableName, "version")
|
||||
_scaStorageLocation.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_scaStorageLocation.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
@@ -48,19 +51,22 @@ func newScaStorageLocation(db *gorm.DB, opts ...gen.DOOption) scaStorageLocation
|
||||
type scaStorageLocation struct {
|
||||
scaStorageLocationDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // 主键
|
||||
UserID field.String // 用户id
|
||||
Country field.String // 国家
|
||||
Province field.String // 省
|
||||
City field.String // 城市
|
||||
Latitude field.String // 纬度
|
||||
Longitude field.String // 经度
|
||||
Total field.Int64 // 数量
|
||||
Version field.Field // 版本
|
||||
CreatedAt field.Time // 创建时间
|
||||
UpdatedAt field.Time // 更新时间
|
||||
DeletedAt field.Field // 删除时间
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // 主键
|
||||
UserID field.String // 用户id
|
||||
Provider field.String // 供应商
|
||||
Bucket field.String // 存储桶
|
||||
Country field.String // 国家
|
||||
Province field.String // 省
|
||||
City field.String // 城市
|
||||
Latitude field.String // 纬度
|
||||
Longitude field.String // 经度
|
||||
Total field.Int64 // 数量
|
||||
CoverImage field.String // 封面图片
|
||||
Version field.Field // 版本
|
||||
CreatedAt field.Time // 创建时间
|
||||
UpdatedAt field.Time // 更新时间
|
||||
DeletedAt field.Field // 删除时间
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@@ -79,12 +85,15 @@ func (s *scaStorageLocation) updateTableName(table string) *scaStorageLocation {
|
||||
s.ALL = field.NewAsterisk(table)
|
||||
s.ID = field.NewInt64(table, "id")
|
||||
s.UserID = field.NewString(table, "user_id")
|
||||
s.Provider = field.NewString(table, "provider")
|
||||
s.Bucket = field.NewString(table, "bucket")
|
||||
s.Country = field.NewString(table, "country")
|
||||
s.Province = field.NewString(table, "province")
|
||||
s.City = field.NewString(table, "city")
|
||||
s.Latitude = field.NewString(table, "latitude")
|
||||
s.Longitude = field.NewString(table, "longitude")
|
||||
s.Total = field.NewInt64(table, "total")
|
||||
s.CoverImage = field.NewString(table, "cover_image")
|
||||
s.Version = field.NewField(table, "version")
|
||||
s.CreatedAt = field.NewTime(table, "created_at")
|
||||
s.UpdatedAt = field.NewTime(table, "updated_at")
|
||||
@@ -105,15 +114,18 @@ func (s *scaStorageLocation) GetFieldByName(fieldName string) (field.OrderExpr,
|
||||
}
|
||||
|
||||
func (s *scaStorageLocation) fillFieldMap() {
|
||||
s.fieldMap = make(map[string]field.Expr, 12)
|
||||
s.fieldMap = make(map[string]field.Expr, 15)
|
||||
s.fieldMap["id"] = s.ID
|
||||
s.fieldMap["user_id"] = s.UserID
|
||||
s.fieldMap["provider"] = s.Provider
|
||||
s.fieldMap["bucket"] = s.Bucket
|
||||
s.fieldMap["country"] = s.Country
|
||||
s.fieldMap["province"] = s.Province
|
||||
s.fieldMap["city"] = s.City
|
||||
s.fieldMap["latitude"] = s.Latitude
|
||||
s.fieldMap["longitude"] = s.Longitude
|
||||
s.fieldMap["total"] = s.Total
|
||||
s.fieldMap["cover_image"] = s.CoverImage
|
||||
s.fieldMap["version"] = s.Version
|
||||
s.fieldMap["created_at"] = s.CreatedAt
|
||||
s.fieldMap["updated_at"] = s.UpdatedAt
|
||||
|
@@ -24,4 +24,5 @@ const (
|
||||
ImageListPrefix = "image:list:"
|
||||
ImageListMetaPrefix = "image:meta:"
|
||||
ImageRecentPrefix = "image:recent:"
|
||||
ImageFaceListPrefix = "image:face:list:"
|
||||
)
|
||||
|
Reference in New Issue
Block a user