添加素材库接口

This commit is contained in:
lzh 2025-06-03 15:58:52 +08:00
parent 5ce9a70c97
commit 5a8bb4216c
8 changed files with 3740 additions and 3 deletions

2377
api/files/files.pb.go Normal file

File diff suppressed because it is too large Load Diff

193
api/files/files.proto Normal file
View File

@ -0,0 +1,193 @@
syntax = "proto3";
package files;
option go_package = "./;files";
service File{
rpc List(FileListReq) returns (FileListResp) {} //
rpc Info(FileInfoReq) returns (FileInfoResp) {} //
rpc Create(CreateReq) returns (CreateResp) {} //
rpc Delete(DeleteReq) returns (DeleteResp) {} //
rpc Search(searchReq) returns (searchResp) {} //
rpc Upload(UploadReq) returns (UploadResp) {} //
rpc TusCreate(TusCreateReq) returns (TusCreateResp) {} //
rpc TusUpload(TusUploadReq) returns (TusUploadResp) {} //
rpc ResumableTransfer(ResumableTransferReq) returns (ResumableTransferResp) {} // grpc实现
rpc Preview(PreviewReq) returns (PreviewResp) {} //
rpc Action(ActionReq) returns (ActionResp) {} //
rpc DirDownload(DirDownloadReq) returns (stream DirDownloadResp) {} //
}
message FileListReq{
string path = 1; //
string userSpacePath = 2; //
Sorting sorting = 3;
}
message Items {
string path = 1;
string name = 2;
int64 size = 3;
string extension = 4;
string modified = 5;
string mode = 6;
bool isDir = 7;
bool isSymlink = 8;
string type = 9;
}
message Sorting {
string by = 1;
bool asc = 2;
}
message FileListResp {
repeated Items items = 1;
int32 numDirs = 2;
int32 numFiles = 3;
Sorting sorting = 4;
string path = 5;
string name = 6;
int64 size = 7;
string extension = 8;
string modified = 9;
string mode = 10;
bool isDir = 11;
bool isSymlink = 12;
string type = 13;
}
message CreateReq{
string path = 1;
string userSpacePath = 2;
}
message CreateResp{
}
message DeleteReq{
string path = 1;
string userSpacePath = 2;
}
message DeleteResp{
}
message UploadReq{
string path = 1;
string userSpacePath = 2;
bytes content =3;
}
message UploadResp{
}
message searchReq{
string path = 1;
string userSpacePath = 2;
string query = 3;
}
message searchResp{
message Nested {
bool dir = 1;
string path = 2;
}
repeated Nested items = 1;
}
message TusCreateReq{
string path = 1;
string userSpacePath = 2;
bool override =3 ;
}
message TusCreateResp{
int64 uploadLength = 1;
int64 uploadOffset = 2;
}
message TusUploadReq{
string path = 1;
string userSpacePath = 2;
int64 uploadOffset = 3;
bytes content = 4;
}
message TusUploadResp{
int64 uploadOffset = 1;
}
message ResumableTransferReq{
string path = 1;
string userSpacePath = 2;
int64 offset = 3;
int64 length = 4;
}
message ResumableTransferResp{
bytes content = 1;
}
message FileInfoReq{
string path = 1;
string userSpacePath = 2;
}
message FileInfoResp{
string path = 1;
string name = 2;
int64 size = 3;
string extension = 4;
string modified = 5;
string mode = 6;
bool isDir = 7;
bool isSymlink = 8;
string type = 9;
}
message PreviewReq{
string path = 1;
string userSpacePath = 2;
uint32 size = 3; // 0256x256, 1:1080x1080
}
message PreviewResp{
bytes content = 1;
string fileName = 2;
int64 modTime = 3;
}
message ActionReq{
string path = 1;
string userSpacePath = 2;
string action = 3;
string destination = 4;
bool override = 5;
bool rename = 6;
}
message ActionResp{
}
message DirDownloadReq {
string path = 1;
string userSpacePath = 2;
repeated string files =3;
string algo = 4;
}
message DirDownloadResp {
bytes content = 1;
}

View File

@ -0,0 +1,122 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: files.proto
package files
import (
fmt "fmt"
math "math"
proto "github.com/golang/protobuf/proto"
github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
func (this *FileListReq) Validate() error {
if this.Sorting != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Sorting); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Sorting", err)
}
}
return nil
}
func (this *Items) Validate() error {
return nil
}
func (this *Sorting) Validate() error {
return nil
}
func (this *FileListResp) Validate() error {
for _, item := range this.Items {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Items", err)
}
}
}
if this.Sorting != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Sorting); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Sorting", err)
}
}
return nil
}
func (this *CreateReq) Validate() error {
return nil
}
func (this *CreateResp) Validate() error {
return nil
}
func (this *DeleteReq) Validate() error {
return nil
}
func (this *DeleteResp) Validate() error {
return nil
}
func (this *UploadReq) Validate() error {
return nil
}
func (this *UploadResp) Validate() error {
return nil
}
func (this *SearchReq) Validate() error {
return nil
}
func (this *SearchResp) Validate() error {
for _, item := range this.Items {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Items", err)
}
}
}
return nil
}
func (this *SearchResp_Nested) Validate() error {
return nil
}
func (this *TusCreateReq) Validate() error {
return nil
}
func (this *TusCreateResp) Validate() error {
return nil
}
func (this *TusUploadReq) Validate() error {
return nil
}
func (this *TusUploadResp) Validate() error {
return nil
}
func (this *ResumableTransferReq) Validate() error {
return nil
}
func (this *ResumableTransferResp) Validate() error {
return nil
}
func (this *FileInfoReq) Validate() error {
return nil
}
func (this *FileInfoResp) Validate() error {
return nil
}
func (this *PreviewReq) Validate() error {
return nil
}
func (this *PreviewResp) Validate() error {
return nil
}
func (this *ActionReq) Validate() error {
return nil
}
func (this *ActionResp) Validate() error {
return nil
}
func (this *DirDownloadReq) Validate() error {
return nil
}
func (this *DirDownloadResp) Validate() error {
return nil
}

View File

@ -0,0 +1,678 @@
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
// versions:
// - protoc-gen-go-triple v1.0.8
// - protoc v3.20.3
// source: files.proto
package files
import (
context "context"
constant1 "dubbo.apache.org/dubbo-go/v3/common/constant"
protocol "dubbo.apache.org/dubbo-go/v3/protocol"
dubbo3 "dubbo.apache.org/dubbo-go/v3/protocol/dubbo3"
invocation "dubbo.apache.org/dubbo-go/v3/protocol/invocation"
fmt "fmt"
grpc_go "github.com/dubbogo/grpc-go"
codes "github.com/dubbogo/grpc-go/codes"
metadata "github.com/dubbogo/grpc-go/metadata"
status "github.com/dubbogo/grpc-go/status"
common "github.com/dubbogo/triple/pkg/common"
constant "github.com/dubbogo/triple/pkg/common/constant"
triple "github.com/dubbogo/triple/pkg/triple"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc_go.SupportPackageIsVersion7
// FileClient is the client API for File service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type FileClient interface {
List(ctx context.Context, in *FileListReq, opts ...grpc_go.CallOption) (*FileListResp, common.ErrorWithAttachment)
Info(ctx context.Context, in *FileInfoReq, opts ...grpc_go.CallOption) (*FileInfoResp, common.ErrorWithAttachment)
Create(ctx context.Context, in *CreateReq, opts ...grpc_go.CallOption) (*CreateResp, common.ErrorWithAttachment)
Delete(ctx context.Context, in *DeleteReq, opts ...grpc_go.CallOption) (*DeleteResp, common.ErrorWithAttachment)
Search(ctx context.Context, in *SearchReq, opts ...grpc_go.CallOption) (*SearchResp, common.ErrorWithAttachment)
Upload(ctx context.Context, in *UploadReq, opts ...grpc_go.CallOption) (*UploadResp, common.ErrorWithAttachment)
TusCreate(ctx context.Context, in *TusCreateReq, opts ...grpc_go.CallOption) (*TusCreateResp, common.ErrorWithAttachment)
TusUpload(ctx context.Context, in *TusUploadReq, opts ...grpc_go.CallOption) (*TusUploadResp, common.ErrorWithAttachment)
ResumableTransfer(ctx context.Context, in *ResumableTransferReq, opts ...grpc_go.CallOption) (*ResumableTransferResp, common.ErrorWithAttachment)
Preview(ctx context.Context, in *PreviewReq, opts ...grpc_go.CallOption) (*PreviewResp, common.ErrorWithAttachment)
Action(ctx context.Context, in *ActionReq, opts ...grpc_go.CallOption) (*ActionResp, common.ErrorWithAttachment)
DirDownload(ctx context.Context, in *DirDownloadReq, opts ...grpc_go.CallOption) (File_DirDownloadClient, error)
}
type fileClient struct {
cc *triple.TripleConn
}
type FileClientImpl struct {
List func(ctx context.Context, in *FileListReq) (*FileListResp, error)
Info func(ctx context.Context, in *FileInfoReq) (*FileInfoResp, error)
Create func(ctx context.Context, in *CreateReq) (*CreateResp, error)
Delete func(ctx context.Context, in *DeleteReq) (*DeleteResp, error)
Search func(ctx context.Context, in *SearchReq) (*SearchResp, error)
Upload func(ctx context.Context, in *UploadReq) (*UploadResp, error)
TusCreate func(ctx context.Context, in *TusCreateReq) (*TusCreateResp, error)
TusUpload func(ctx context.Context, in *TusUploadReq) (*TusUploadResp, error)
ResumableTransfer func(ctx context.Context, in *ResumableTransferReq) (*ResumableTransferResp, error)
Preview func(ctx context.Context, in *PreviewReq) (*PreviewResp, error)
Action func(ctx context.Context, in *ActionReq) (*ActionResp, error)
DirDownload func(ctx context.Context, in *DirDownloadReq) (File_DirDownloadClient, error)
}
func (c *FileClientImpl) GetDubboStub(cc *triple.TripleConn) FileClient {
return NewFileClient(cc)
}
func (c *FileClientImpl) XXX_InterfaceName() string {
return "files.File"
}
func NewFileClient(cc *triple.TripleConn) FileClient {
return &fileClient{cc}
}
func (c *fileClient) List(ctx context.Context, in *FileListReq, opts ...grpc_go.CallOption) (*FileListResp, common.ErrorWithAttachment) {
out := new(FileListResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/List", in, out)
}
func (c *fileClient) Info(ctx context.Context, in *FileInfoReq, opts ...grpc_go.CallOption) (*FileInfoResp, common.ErrorWithAttachment) {
out := new(FileInfoResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Info", in, out)
}
func (c *fileClient) Create(ctx context.Context, in *CreateReq, opts ...grpc_go.CallOption) (*CreateResp, common.ErrorWithAttachment) {
out := new(CreateResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Create", in, out)
}
func (c *fileClient) Delete(ctx context.Context, in *DeleteReq, opts ...grpc_go.CallOption) (*DeleteResp, common.ErrorWithAttachment) {
out := new(DeleteResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Delete", in, out)
}
func (c *fileClient) Search(ctx context.Context, in *SearchReq, opts ...grpc_go.CallOption) (*SearchResp, common.ErrorWithAttachment) {
out := new(SearchResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Search", in, out)
}
func (c *fileClient) Upload(ctx context.Context, in *UploadReq, opts ...grpc_go.CallOption) (*UploadResp, common.ErrorWithAttachment) {
out := new(UploadResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Upload", in, out)
}
func (c *fileClient) TusCreate(ctx context.Context, in *TusCreateReq, opts ...grpc_go.CallOption) (*TusCreateResp, common.ErrorWithAttachment) {
out := new(TusCreateResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/TusCreate", in, out)
}
func (c *fileClient) TusUpload(ctx context.Context, in *TusUploadReq, opts ...grpc_go.CallOption) (*TusUploadResp, common.ErrorWithAttachment) {
out := new(TusUploadResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/TusUpload", in, out)
}
func (c *fileClient) ResumableTransfer(ctx context.Context, in *ResumableTransferReq, opts ...grpc_go.CallOption) (*ResumableTransferResp, common.ErrorWithAttachment) {
out := new(ResumableTransferResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/ResumableTransfer", in, out)
}
func (c *fileClient) Preview(ctx context.Context, in *PreviewReq, opts ...grpc_go.CallOption) (*PreviewResp, common.ErrorWithAttachment) {
out := new(PreviewResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Preview", in, out)
}
func (c *fileClient) Action(ctx context.Context, in *ActionReq, opts ...grpc_go.CallOption) (*ActionResp, common.ErrorWithAttachment) {
out := new(ActionResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Action", in, out)
}
func (c *fileClient) DirDownload(ctx context.Context, in *DirDownloadReq, opts ...grpc_go.CallOption) (File_DirDownloadClient, error) {
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
stream, err := c.cc.NewStream(ctx, "/"+interfaceKey+"/DirDownload", opts...)
if err != nil {
return nil, err
}
x := &fileDirDownloadClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type File_DirDownloadClient interface {
Recv() (*DirDownloadResp, error)
grpc_go.ClientStream
}
type fileDirDownloadClient struct {
grpc_go.ClientStream
}
func (x *fileDirDownloadClient) Recv() (*DirDownloadResp, error) {
m := new(DirDownloadResp)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// FileServer is the server API for File service.
// All implementations must embed UnimplementedFileServer
// for forward compatibility
type FileServer interface {
List(context.Context, *FileListReq) (*FileListResp, error)
Info(context.Context, *FileInfoReq) (*FileInfoResp, error)
Create(context.Context, *CreateReq) (*CreateResp, error)
Delete(context.Context, *DeleteReq) (*DeleteResp, error)
Search(context.Context, *SearchReq) (*SearchResp, error)
Upload(context.Context, *UploadReq) (*UploadResp, error)
TusCreate(context.Context, *TusCreateReq) (*TusCreateResp, error)
TusUpload(context.Context, *TusUploadReq) (*TusUploadResp, error)
ResumableTransfer(context.Context, *ResumableTransferReq) (*ResumableTransferResp, error)
Preview(context.Context, *PreviewReq) (*PreviewResp, error)
Action(context.Context, *ActionReq) (*ActionResp, error)
DirDownload(*DirDownloadReq, File_DirDownloadServer) error
mustEmbedUnimplementedFileServer()
}
// UnimplementedFileServer must be embedded to have forward compatible implementations.
type UnimplementedFileServer struct {
proxyImpl protocol.Invoker
}
func (UnimplementedFileServer) List(context.Context, *FileListReq) (*FileListResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method List not implemented")
}
func (UnimplementedFileServer) Info(context.Context, *FileInfoReq) (*FileInfoResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method Info not implemented")
}
func (UnimplementedFileServer) Create(context.Context, *CreateReq) (*CreateResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method Create not implemented")
}
func (UnimplementedFileServer) Delete(context.Context, *DeleteReq) (*DeleteResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented")
}
func (UnimplementedFileServer) Search(context.Context, *SearchReq) (*SearchResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method Search not implemented")
}
func (UnimplementedFileServer) Upload(context.Context, *UploadReq) (*UploadResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method Upload not implemented")
}
func (UnimplementedFileServer) TusCreate(context.Context, *TusCreateReq) (*TusCreateResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method TusCreate not implemented")
}
func (UnimplementedFileServer) TusUpload(context.Context, *TusUploadReq) (*TusUploadResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method TusUpload not implemented")
}
func (UnimplementedFileServer) ResumableTransfer(context.Context, *ResumableTransferReq) (*ResumableTransferResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method ResumableTransfer not implemented")
}
func (UnimplementedFileServer) Preview(context.Context, *PreviewReq) (*PreviewResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method Preview not implemented")
}
func (UnimplementedFileServer) Action(context.Context, *ActionReq) (*ActionResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method Action not implemented")
}
func (UnimplementedFileServer) DirDownload(*DirDownloadReq, File_DirDownloadServer) error {
return status.Errorf(codes.Unimplemented, "method DirDownload not implemented")
}
func (s *UnimplementedFileServer) XXX_SetProxyImpl(impl protocol.Invoker) {
s.proxyImpl = impl
}
func (s *UnimplementedFileServer) XXX_GetProxyImpl() protocol.Invoker {
return s.proxyImpl
}
func (s *UnimplementedFileServer) XXX_ServiceDesc() *grpc_go.ServiceDesc {
return &File_ServiceDesc
}
func (s *UnimplementedFileServer) XXX_InterfaceName() string {
return "files.File"
}
func (UnimplementedFileServer) mustEmbedUnimplementedFileServer() {}
// UnsafeFileServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to FileServer will
// result in compilation errors.
type UnsafeFileServer interface {
mustEmbedUnimplementedFileServer()
}
func RegisterFileServer(s grpc_go.ServiceRegistrar, srv FileServer) {
s.RegisterService(&File_ServiceDesc, srv)
}
func _File_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(FileListReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("List", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(FileInfoReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("Info", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("Create", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("Delete", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_Search_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(SearchReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("Search", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_Upload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(UploadReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("Upload", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_TusCreate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(TusCreateReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("TusCreate", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_TusUpload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(TusUploadReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("TusUpload", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_ResumableTransfer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(ResumableTransferReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("ResumableTransfer", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_Preview_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(PreviewReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("Preview", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_Action_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(ActionReq)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("Action", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _File_DirDownload_Handler(srv interface{}, stream grpc_go.ServerStream) error {
_, ok := srv.(dubbo3.Dubbo3GrpcService)
ctx := stream.Context()
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
stream.(grpc_go.CtxSetterStream).SetContext(context.WithValue(ctx, constant1.AttachmentKey, invAttachment))
invo := invocation.NewRPCInvocation("DirDownload", nil, nil)
if !ok {
fmt.Println(invo)
return nil
}
m := new(DirDownloadReq)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(FileServer).DirDownload(m, &fileDirDownloadServer{stream})
}
type File_DirDownloadServer interface {
Send(*DirDownloadResp) error
grpc_go.ServerStream
}
type fileDirDownloadServer struct {
grpc_go.ServerStream
}
func (x *fileDirDownloadServer) Send(m *DirDownloadResp) error {
return x.ServerStream.SendMsg(m)
}
// File_ServiceDesc is the grpc_go.ServiceDesc for File service.
// It's only intended for direct use with grpc_go.RegisterService,
// and not to be introspected or modified (even as a copy)
var File_ServiceDesc = grpc_go.ServiceDesc{
ServiceName: "files.File",
HandlerType: (*FileServer)(nil),
Methods: []grpc_go.MethodDesc{
{
MethodName: "List",
Handler: _File_List_Handler,
},
{
MethodName: "Info",
Handler: _File_Info_Handler,
},
{
MethodName: "Create",
Handler: _File_Create_Handler,
},
{
MethodName: "Delete",
Handler: _File_Delete_Handler,
},
{
MethodName: "Search",
Handler: _File_Search_Handler,
},
{
MethodName: "Upload",
Handler: _File_Upload_Handler,
},
{
MethodName: "TusCreate",
Handler: _File_TusCreate_Handler,
},
{
MethodName: "TusUpload",
Handler: _File_TusUpload_Handler,
},
{
MethodName: "ResumableTransfer",
Handler: _File_ResumableTransfer_Handler,
},
{
MethodName: "Preview",
Handler: _File_Preview_Handler,
},
{
MethodName: "Action",
Handler: _File_Action_Handler,
},
},
Streams: []grpc_go.StreamDesc{
{
StreamName: "DirDownload",
Handler: _File_DirDownload_Handler,
ServerStreams: true,
},
},
Metadata: "files.proto",
}

View File

@ -5,6 +5,7 @@ import (
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/account"
"fonchain-fiee/pkg/service/auth"
"fonchain-fiee/pkg/service/file"
"fonchain-fiee/pkg/service/lang"
"fonchain-fiee/pkg/service/qr"
"fonchain-fiee/pkg/service/redirect"
@ -102,6 +103,23 @@ func NewRouter() *gin.Engine {
redirectRoute.POST("sdk/down/v3", auth.DownImgV3)
}
{
// 素材库
resourceRoute := v1.Group("/resource")
resourceRoute.GET("", file.Info)
resourceRoute.DELETE("", file.Delete)
resourceRoute.PUT("", file.Action)
resourceRoute.POST("", file.Create)
resourceRoute.GET("/search", file.Search)
resourceRoute.POST("/upload", file.Upload)
resourceRoute.POST("/tus/create", file.TusCreate)
resourceRoute.POST("/tus/upload", file.TusUpload)
resourceRoute.GET("/raw", file.Raw)
resourceRoute.GET("/raw/dir", file.DirDownload)
resourceRoute.GET("/preview", file.Preview)
resourceRoute.GET("/list", file.Info)
}
//静态文件
r.StaticFS("/api/static", http.Dir("./runtime"))
r.NoRoute(func(c *gin.Context) {

254
pkg/service/file/file.go Normal file
View File

@ -0,0 +1,254 @@
package file
import (
"bytes"
"errors"
"fmt"
"fonchain-fiee/api/files"
"fonchain-fiee/pkg/model/login"
"fonchain-fiee/pkg/service"
"io"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
)
func Raw(ctx *gin.Context) {
r := ctx.Request
w := ctx.Writer
w.Header().Add("Content-Security-Policy", `script-src 'none';`)
w.Header().Set("Cache-Control", "private")
rs, err := newGrpcReaderSeeker(getUserSpacePath(ctx), ctx.Query("path"))
if err != nil {
service.Error(ctx, err)
return
}
if r.URL.Query().Get("inline") == "true" {
w.Header().Set("Content-Disposition", "inline")
} else {
// As per RFC6266 section 4.3
w.Header().Set("Content-Disposition", "attachment; filename*=utf-8''"+rs.FileName)
}
http.ServeContent(ctx.Writer, r, rs.FileName, time.Now(), rs)
}
func List(ctx *gin.Context) {
path := ctx.DefaultQuery("path", "/")
sortBy := ctx.DefaultQuery("sortBy", "name")
sortAsc, _ := strconv.ParseBool(ctx.DefaultQuery("sortAsc", "true"))
resp, err := service.FilesProvider.List(ctx, &files.FileListReq{
Path: path,
UserSpacePath: getUserSpacePath(ctx),
Sorting: &files.Sorting{
By: sortBy,
Asc: sortAsc,
},
})
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
}
func Info(ctx *gin.Context) {
resp, err := service.FilesProvider.Info(ctx, &files.FileInfoReq{
Path: ctx.DefaultQuery("path", "/"),
UserSpacePath: getUserSpacePath(ctx),
})
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
}
func Create(ctx *gin.Context) {
var req files.CreateReq
if err := ctx.ShouldBindJSON(&req); err != nil {
service.Error(ctx, err)
return
}
req.UserSpacePath = getUserSpacePath(ctx)
resp, err := service.FilesProvider.Create(ctx, &req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
}
func Delete(ctx *gin.Context) {
resp, err := service.FilesProvider.Delete(ctx, &files.DeleteReq{
Path: ctx.DefaultQuery("path", "/"),
UserSpacePath: getUserSpacePath(ctx),
})
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
}
func Search(ctx *gin.Context) {
resp, err := service.FilesProvider.Search(ctx, &files.SearchReq{
UserSpacePath: getUserSpacePath(ctx),
Path: ctx.Query("path"),
Query: ctx.Query("query"),
})
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
}
func Upload(ctx *gin.Context) {
path, ok := ctx.GetQuery("path")
if !ok {
service.Error(ctx, errors.New("缺失参数路径"))
return
}
b, err := io.ReadAll(ctx.Request.Body)
if !ok {
service.Error(ctx, err)
return
}
resp, err := service.FilesProvider.Upload(ctx, &files.UploadReq{
Path: path,
UserSpacePath: getUserSpacePath(ctx),
Content: b,
})
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
}
func TusCreate(ctx *gin.Context) {
var req files.TusCreateReq
if err := ctx.ShouldBindJSON(&req); err != nil {
service.Error(ctx, err)
return
}
req.UserSpacePath = getUserSpacePath(ctx)
resp, err := service.FilesProvider.TusCreate(ctx, &req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
}
func TusUpload(ctx *gin.Context) {
path, ok := ctx.GetQuery("path")
if !ok {
service.Error(ctx, errors.New("文件路径缺失"))
return
}
uploadOffset, err := getUploadOffset(ctx.Request)
if err != nil {
service.Error(ctx, fmt.Errorf("invalid upload offset: %w", err))
return
}
b, err := io.ReadAll(ctx.Request.Body)
if !ok {
service.Error(ctx, err)
return
}
resp, err := service.FilesProvider.TusUpload(ctx, &files.TusUploadReq{
Path: path,
UploadOffset: uploadOffset,
Content: b,
UserSpacePath: getUserSpacePath(ctx),
})
if err != nil {
service.Error(ctx, err)
return
}
ctx.Writer.Header().Set("Upload-Offset", strconv.FormatInt(resp.UploadOffset, 10))
service.Success(ctx, nil)
}
func Preview(ctx *gin.Context) {
var size int
size, err := strconv.Atoi(ctx.Query("size"))
if err != nil {
size = 1
}
resp, err := service.FilesProvider.Preview(ctx, &files.PreviewReq{
Path: ctx.Query("path"),
UserSpacePath: getUserSpacePath(ctx),
Size: uint32(size),
})
if err != nil {
service.Error(ctx, err)
return
}
ctx.Writer.Header().Set("Cache-Control", "private")
http.ServeContent(ctx.Writer, ctx.Request, resp.FileName, time.UnixMilli(resp.ModTime), bytes.NewReader(resp.Content))
}
func Action(ctx *gin.Context) {
var req files.ActionReq
if err := ctx.ShouldBindJSON(&req); err != nil {
service.Error(ctx, err)
return
}
req.UserSpacePath = getUserSpacePath(ctx)
resp, err := service.FilesProvider.Action(ctx, &req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
}
func DirDownload(ctx *gin.Context) {
path := ctx.Query("path")
fileList := strings.Split(ctx.Query("files"), ",")
algo := ctx.Query("algo")
stream, err := service.FilesProvider.DirDownload(ctx, &files.DirDownloadReq{
Algo: algo,
Files: fileList,
Path: path,
UserSpacePath: getUserSpacePath(ctx),
})
if err != nil {
service.Error(ctx, err)
return
}
header, err := stream.Header()
if err != nil {
service.Error(ctx, err)
return
}
ctx.Writer.Header().Set("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(header.Get("filename")[0]))
for {
recvMsg, err := stream.Recv()
if err != nil {
break
}
ctx.Writer.Write(recvMsg.Content)
}
}
func getUploadOffset(r *http.Request) (int64, error) {
uploadOffset, err := strconv.ParseInt(r.Header.Get("Upload-Offset"), 10, 64)
if err != nil {
return 0, fmt.Errorf("invalid upload offset: %w", err)
}
return uploadOffset, nil
}
func getUserSpacePath(ctx *gin.Context) string {
user := login.GetUserInfoFromC(ctx)
return strconv.Itoa(int(user.ID))
}

View File

@ -0,0 +1,91 @@
package file
import (
"context"
"errors"
"fonchain-fiee/api/files"
"fonchain-fiee/pkg/service"
"io"
)
type grpcReaderSeeker struct {
io.Reader
io.Seeker
path string
userSpacePath string
cursor int64
length int64
FileName string
}
func (g *grpcReaderSeeker) Seek(offset int64, whence int) (int64, error) {
var abs int64
switch whence {
case io.SeekStart:
abs = offset
case io.SeekCurrent:
abs = g.cursor + offset
case io.SeekEnd:
abs = g.length + offset
default:
return 0, errors.New("grpc.Reader.Seek: invalid whence")
}
if abs < 0 {
return 0, errors.New("grpc.Reader.Seek: negative position")
}
g.cursor = abs
return abs, nil
}
func (g *grpcReaderSeeker) Read(b []byte) (n int, err error) {
if g.cursor >= g.length {
return 0, io.EOF
}
data, err := g.getBytesData(len(b))
if err != nil {
return 0, err
}
n = copy(b, data)
g.cursor += int64(n)
return
}
// 通过grpc获取到bytes数据
func (g *grpcReaderSeeker) getBytesData(len int) ([]byte, error) {
resp, err := service.FilesProvider.ResumableTransfer(context.TODO(), &files.ResumableTransferReq{
UserSpacePath: g.userSpacePath,
Path: g.path,
Offset: g.cursor,
Length: int64(len),
})
if err != nil {
return nil, err
}
return resp.Content, nil
}
// grpc 获取到文件信息
func (g *grpcReaderSeeker) initInfo() error {
resp, err := service.FilesProvider.Info(context.TODO(), &files.FileInfoReq{
UserSpacePath: g.userSpacePath,
Path: g.path,
})
if err != nil {
return nil
}
g.FileName = resp.Name
g.length = resp.Size
return err
}
func newGrpcReaderSeeker(userSpacePath string, path string) (*grpcReaderSeeker, error) {
g := new(grpcReaderSeeker)
g.userSpacePath = userSpacePath
g.path = path
err := g.initInfo()
if err != nil {
return nil, err
}
return g, nil
}

View File

@ -1,16 +1,18 @@
package service
import (
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/config"
_ "dubbo.apache.org/dubbo-go/v3/imports"
"fmt"
"fonchain-fiee/api/account"
"fonchain-fiee/api/bundle"
"fonchain-fiee/api/files"
"fonchain-fiee/api/order"
"fonchain-fiee/api/payment"
pkConfig "fonchain-fiee/pkg/config"
"os"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/config"
_ "dubbo.apache.org/dubbo-go/v3/imports"
)
var AccountProvider = new(account.AccountClientImpl)
@ -18,12 +20,14 @@ var AccountProvider = new(account.AccountClientImpl)
var BundleProvider = new(bundle.BundleClientImpl)
var OrderProvider = new(order.OrderClientImpl)
var PaymentProvider = new(payment.PaymentClientImpl)
var FilesProvider = new(files.FileClientImpl)
func init() {
config.SetConsumerService(BundleProvider)
config.SetConsumerService(OrderProvider)
config.SetConsumerService(AccountProvider)
config.SetConsumerService(PaymentProvider)
config.SetConsumerService(FilesProvider)
if err := config.Load(); err != nil {
panic(err)