feat: rbac完善,file接入完成
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
)
|
||||
|
||||
type CreateStorageConfigLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 创建存储配置
|
||||
func NewCreateStorageConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateStorageConfigLogic {
|
||||
return &CreateStorageConfigLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *CreateStorageConfigLogic) CreateStorageConfig(req *types.CreateStorageConfigReq) error {
|
||||
_, err := l.svcCtx.FileRpc.CreateStorageConfig(l.ctx, &fileservice.CreateStorageConfigReq{
|
||||
Type: req.Type,
|
||||
Name: req.Name,
|
||||
Endpoint: req.Endpoint,
|
||||
AccessKeyId: req.AccessKeyId,
|
||||
AccessKeySecret: req.AccessKeySecret,
|
||||
BucketName: req.BucketName,
|
||||
BucketUrl: req.BucketUrl,
|
||||
Region: req.Region,
|
||||
Status: int32(req.Status),
|
||||
Remark: req.Remark,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -6,10 +6,11 @@ package file
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/api/internal/oss_core"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
)
|
||||
|
||||
type DeleteFileLogic struct {
|
||||
@@ -28,7 +29,33 @@ func NewDeleteFileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Delete
|
||||
}
|
||||
|
||||
func (l *DeleteFileLogic) DeleteFile(req *types.IdsReq) error {
|
||||
// todo: add your logic here and delete this line
|
||||
if len(req.Ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
// 1. 查询文件记录获取OSS Key
|
||||
resp, err := l.svcCtx.FileRpc.GetFilesByIds(l.ctx, &fileservice.GetFilesByIdsReq{
|
||||
Ids: req.Ids,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. 从OSS物理删除
|
||||
factory := oss_core.NewOSSFactory(l.svcCtx.FileRpc)
|
||||
uploader, err := factory.GetActiveUploader(l.ctx)
|
||||
if err == nil && uploader != nil {
|
||||
for _, file := range resp.Files {
|
||||
if file.Key != "" {
|
||||
_ = uploader.DeleteFile(l.ctx, file.Key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 从数据库删除
|
||||
_, err = l.svcCtx.FileRpc.DeleteFiles(l.ctx, &fileservice.DeleteFilesReq{
|
||||
Ids: req.Ids,
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
)
|
||||
|
||||
type DeleteStorageConfigLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 删除存储配置
|
||||
func NewDeleteStorageConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteStorageConfigLogic {
|
||||
return &DeleteStorageConfigLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *DeleteStorageConfigLogic) DeleteStorageConfig(req *types.IdsReq) error {
|
||||
_, err := l.svcCtx.FileRpc.DeleteStorageConfig(l.ctx, &fileservice.DeleteFilesReq{
|
||||
Ids: req.Ids,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/api/internal/oss_core"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
)
|
||||
|
||||
type DownloadFileLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 下载文件
|
||||
func NewDownloadFileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DownloadFileLogic {
|
||||
return &DownloadFileLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *DownloadFileLogic) DownloadFile(w http.ResponseWriter, req *types.FileIdReq) error {
|
||||
// 1. 获取文件记录
|
||||
resp, err := l.svcCtx.FileRpc.GetFileById(l.ctx, &fileservice.GetFileByIdReq{
|
||||
Id: req.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. 获取具体底层client
|
||||
factory := oss_core.NewOSSFactory(l.svcCtx.FileRpc)
|
||||
uploader, err := factory.GetActiveUploader(l.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. 读取流
|
||||
reader, err := uploader.DownloadFile(l.ctx, resp.File.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
// 4. 返回文件流
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=\""+resp.File.Name+"\"")
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
_, err = io.Copy(w, reader)
|
||||
return err
|
||||
}
|
||||
@@ -6,10 +6,10 @@ package file
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
)
|
||||
|
||||
type GetFileByIdLogic struct {
|
||||
@@ -28,7 +28,20 @@ func NewGetFileByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetFi
|
||||
}
|
||||
|
||||
func (l *GetFileByIdLogic) GetFileById(req *types.FileIdReq) (resp *types.FileInfo, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
respRpc, err := l.svcCtx.FileRpc.GetFileById(l.ctx, &fileservice.GetFileByIdReq{
|
||||
Id: req.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
return &types.FileInfo{
|
||||
Id: respRpc.File.Id,
|
||||
Name: respRpc.File.Name,
|
||||
Url: respRpc.File.Url,
|
||||
Tag: respRpc.File.Tag,
|
||||
Key: respRpc.File.Key,
|
||||
Suffix: respRpc.File.Suffix,
|
||||
Md5: respRpc.File.Md5,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ package file
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
)
|
||||
|
||||
type GetFileListLogic struct {
|
||||
@@ -27,8 +27,31 @@ func NewGetFileListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetFi
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetFileListLogic) GetFileList(req *types.FileListReq) error {
|
||||
// todo: add your logic here and delete this line
|
||||
func (l *GetFileListLogic) GetFileList(req *types.FileListReq) (resp *types.FileListResp, err error) {
|
||||
respRpc, err := l.svcCtx.FileRpc.GetFileList(l.ctx, &fileservice.GetFileListReq{
|
||||
Current: int32(req.Current),
|
||||
PageSize: int32(req.PageSize),
|
||||
Name: req.Name,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil
|
||||
var list []types.FileInfo
|
||||
for _, item := range respRpc.List {
|
||||
list = append(list, types.FileInfo{
|
||||
Id: item.Id,
|
||||
Name: item.Name,
|
||||
Url: item.Url,
|
||||
Tag: item.Tag,
|
||||
Key: item.Key,
|
||||
Suffix: item.Suffix,
|
||||
Md5: item.Md5,
|
||||
})
|
||||
}
|
||||
|
||||
return &types.FileListResp{
|
||||
List: list,
|
||||
Total: respRpc.Total,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
)
|
||||
|
||||
type GetStorageConfigListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 获取存储配置列表
|
||||
func NewGetStorageConfigListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetStorageConfigListLogic {
|
||||
return &GetStorageConfigListLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetStorageConfigListLogic) GetStorageConfigList(req *types.StorageConfigListReq) (resp *types.StorageConfigListResp, err error) {
|
||||
respRpc, err := l.svcCtx.FileRpc.GetStorageConfigList(l.ctx, &fileservice.StorageConfigListReq{
|
||||
Current: int32(req.Current),
|
||||
PageSize: int32(req.PageSize),
|
||||
Type: req.Type,
|
||||
Name: req.Name,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var list []types.StorageConfigInfo
|
||||
for _, item := range respRpc.List {
|
||||
list = append(list, types.StorageConfigInfo{
|
||||
Id: item.Id,
|
||||
Type: item.Type,
|
||||
Name: item.Name,
|
||||
Endpoint: item.Endpoint,
|
||||
AccessKeyId: item.AccessKeyId,
|
||||
AccessKeySecret: item.AccessKeySecret,
|
||||
BucketName: item.BucketName,
|
||||
BucketUrl: item.BucketUrl,
|
||||
Region: item.Region,
|
||||
IsDefault: int(item.IsDefault),
|
||||
Status: int(item.Status),
|
||||
Remark: item.Remark,
|
||||
})
|
||||
}
|
||||
|
||||
return &types.StorageConfigListResp{
|
||||
List: list,
|
||||
Total: respRpc.Total,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
)
|
||||
|
||||
type SetDefaultStorageConfigLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 设置默认存储配置
|
||||
func NewSetDefaultStorageConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SetDefaultStorageConfigLogic {
|
||||
return &SetDefaultStorageConfigLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SetDefaultStorageConfigLogic) SetDefaultStorageConfig(req *types.SetDefaultStorageConfigReq) error {
|
||||
_, err := l.svcCtx.FileRpc.SetDefaultStorageConfig(l.ctx, &fileservice.SetDefaultStorageConfigReq{
|
||||
Id: req.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
)
|
||||
|
||||
type UpdateStorageConfigLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 更新存储配置
|
||||
func NewUpdateStorageConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateStorageConfigLogic {
|
||||
return &UpdateStorageConfigLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *UpdateStorageConfigLogic) UpdateStorageConfig(req *types.UpdateStorageConfigReq) error {
|
||||
_, err := l.svcCtx.FileRpc.UpdateStorageConfig(l.ctx, &fileservice.UpdateStorageConfigReq{
|
||||
Id: req.Id,
|
||||
Type: req.Type,
|
||||
Name: req.Name,
|
||||
Endpoint: req.Endpoint,
|
||||
AccessKeyId: req.AccessKeyId,
|
||||
AccessKeySecret: req.AccessKeySecret,
|
||||
BucketName: req.BucketName,
|
||||
BucketUrl: req.BucketUrl,
|
||||
Region: req.Region,
|
||||
Status: int32(req.Status),
|
||||
Remark: req.Remark,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -5,9 +5,17 @@ package file
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"sundynix-micro-go/app/file/api/internal/oss_core"
|
||||
"sundynix-micro-go/app/file/api/internal/svc"
|
||||
"sundynix-micro-go/app/file/api/internal/types"
|
||||
"sundynix-micro-go/app/file/rpc/fileservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -27,8 +35,84 @@ func NewUploadFileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Upload
|
||||
}
|
||||
}
|
||||
|
||||
func (l *UploadFileLogic) UploadFile() (resp *types.FileInfo, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
func (l *UploadFileLogic) UploadFile(r *http.Request) (resp *types.FileInfo, err error) {
|
||||
err = r.ParseMultipartForm(32 << 20) // 32MB max memory
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("解析表单失败: %v", err)
|
||||
}
|
||||
file, fileHeader, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取文件失败: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
return
|
||||
// 计算文件 MD5
|
||||
hash := md5.New()
|
||||
if _, err := io.Copy(hash, file); err != nil {
|
||||
return nil, fmt.Errorf("计算文件MD5失败: %v", err)
|
||||
}
|
||||
fileMd5 := hex.EncodeToString(hash.Sum(nil))
|
||||
|
||||
// 调用 RPC 检查文件是否已存在(秒传)
|
||||
checkResp, err := l.svcCtx.FileRpc.CheckFileByMd5(l.ctx, &fileservice.CheckFileByMd5Req{Md5: fileMd5})
|
||||
if err != nil {
|
||||
l.Logger.Errorf("调用FileRpc检查MD5失败: %v", err)
|
||||
return nil, fmt.Errorf("服务器内部异常")
|
||||
}
|
||||
if checkResp.Exists && checkResp.File != nil {
|
||||
l.Logger.Infof("文件已存在,触发秒传: %s", fileMd5)
|
||||
return &types.FileInfo{
|
||||
Id: checkResp.File.Id,
|
||||
Name: checkResp.File.Name,
|
||||
Url: checkResp.File.Url,
|
||||
Tag: checkResp.File.Tag,
|
||||
Key: checkResp.File.Key,
|
||||
Suffix: checkResp.File.Suffix,
|
||||
Md5: checkResp.File.Md5,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 此时需要真正上传,先将文件指针拨回开头
|
||||
if _, err := file.Seek(0, 0); err != nil {
|
||||
return nil, fmt.Errorf("读取文件流失败: %v", err)
|
||||
}
|
||||
|
||||
factory := oss_core.NewOSSFactory(l.svcCtx.FileRpc)
|
||||
uploader, err := factory.GetActiveUploader(l.ctx)
|
||||
if err != nil {
|
||||
l.Logger.Errorf("获取OSS客户端失败: %v", err)
|
||||
return nil, fmt.Errorf("存储服务未配置或不可用")
|
||||
}
|
||||
|
||||
url, key, err := uploader.UploadFile(l.ctx, file, fileHeader)
|
||||
if err != nil {
|
||||
l.Logger.Errorf("上传文件失败: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ext := filepath.Ext(fileHeader.Filename)
|
||||
|
||||
// 把记录存入数据库
|
||||
rpcResp, err := l.svcCtx.FileRpc.CreateFile(l.ctx, &fileservice.CreateFileReq{
|
||||
Name: fileHeader.Filename,
|
||||
Url: url,
|
||||
Tag: "default",
|
||||
Key: key,
|
||||
Suffix: ext,
|
||||
Md5: fileMd5, // 保存计算出的MD5
|
||||
})
|
||||
if err != nil {
|
||||
l.Logger.Errorf("调用FileRpc创建文件记录失败: %v", err)
|
||||
return nil, fmt.Errorf("保存文件记录失败")
|
||||
}
|
||||
|
||||
return &types.FileInfo{
|
||||
Id: rpcResp.File.Id,
|
||||
Name: rpcResp.File.Name,
|
||||
Url: rpcResp.File.Url,
|
||||
Tag: rpcResp.File.Tag,
|
||||
Key: rpcResp.File.Key,
|
||||
Suffix: rpcResp.File.Suffix,
|
||||
Md5: rpcResp.File.Md5,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user