From 2c62338e60ba31ffdd3383c887e45316451e1826 Mon Sep 17 00:00:00 2001 From: fangweiye Date: Sat, 8 Jun 2024 18:31:38 +0800 Subject: [PATCH] feat: update version --- api/errors/resource_error_reason.pb.go | 246 --- .../resource_error_reason.pb.validate.go | 36 - api/errors/resource_error_reason.proto | 37 - api/errors/resource_error_reason_errors.pb.go | 364 ---- api/export/resource_export.proto | 62 - api/export/resource_export_service.proto | 40 - api/export/v1/resource_export.pb.go | 929 ---------- api/export/v1/resource_export.pb.validate.go | 1385 -------------- api/export/v1/resource_export_service.pb.go | 113 -- .../v1/resource_export_service.pb.validate.go | 36 - .../v1/resource_export_service_grpc.pb.go | 221 --- .../v1/resource_export_service_http.pb.go | 190 -- api/file/resource_directory.proto | 41 - api/file/resource_file.proto | 96 - api/file/resource_file_service.proto | 81 - api/file/v1/resource_directory.pb.go | 573 ------ api/file/v1/resource_directory.pb.validate.go | 785 -------- api/file/v1/resource_file.pb.go | 1250 ------------- api/file/v1/resource_file_service.pb.go | 175 -- .../v1/resource_file_service.pb.validate.go | 36 - api/file/v1/resource_file_service_grpc.pb.go | 443 ----- api/file/v1/resource_file_service_http.pb.go | 422 ----- .../directory}/openapi.yaml | 0 .../directory/resource_directory.proto | 76 + .../resource_directory_service.proto | 52 + .../directory/v1/resource_directory.pb.go | 1004 +++++++++++ .../v1/resource_directory.pb.validate.go | 1448 +++++++++++++++ .../v1/resource_directory_service.pb.go | 151 ++ .../v1/resource_directory_service_grpc.pb.go | 267 +++ .../v1/resource_directory_service_http.pb.go | 230 +++ api/{export => resource/errors}/openapi.yaml | 0 .../errors/resource_error_reason.pb.go | 302 ++++ .../errors/resource_error_reason.proto | 42 + .../errors/resource_error_reason_errors.pb.go | 612 +++++++ api/resource/export/openapi.yaml | 208 +++ api/resource/export/resource_export.proto | 61 + .../export/resource_export_service.proto | 37 + api/resource/export/v1/resource_export.pb.go | 759 ++++++++ .../export/v1/resource_export.pb.validate.go | 971 ++++++++++ .../export/v1/resource_export_service.pb.go | 117 ++ .../v1/resource_export_service_grpc.pb.go | 189 ++ .../v1/resource_export_service_http.pb.go | 153 ++ api/{ => resource}/file/openapi.yaml | 0 api/resource/file/resource_file.proto | 126 ++ api/resource/file/resource_file_service.proto | 55 + api/resource/file/v1/resource_file.pb.go | 1586 +++++++++++++++++ .../file/v1/resource_file.pb.validate.go | 1123 ++++++++---- .../file/v1/resource_file_service.pb.go | 153 ++ .../file/v1/resource_file_service_grpc.pb.go | 306 ++++ .../file/v1/resource_file_service_http.pb.go | 230 +++ autocode/directory.json | 126 ++ autocode/export.json | 189 ++ autocode/file.json | 175 ++ cmd/resource/main.go | 19 +- deploy/data.sql | 94 - examples/export_test.go | 84 - go.mod | 34 +- go.sum | 61 +- internal/biz/directory/biz.go | 75 + internal/biz/directory/entity.go | 41 + internal/biz/directory/repo.go | 28 + internal/biz/directory/types.go | 10 + internal/biz/export/biz.go | 173 +- internal/biz/export/biz_test.go | 1 - internal/biz/export/entity.go | 30 +- internal/biz/export/factory.go | 11 - internal/biz/export/repo.go | 15 +- internal/biz/export/types.go | 32 +- internal/biz/file/biz.go | 439 ++--- internal/biz/file/biz_test.go | 1 - internal/biz/file/const.go | 6 + internal/biz/file/entity.go | 38 +- internal/biz/file/factory.go | 22 - internal/biz/file/repo.go | 60 +- internal/biz/file/types.go | 66 +- internal/conf/conf.go | 27 + .../{config/config.yaml => conf/conf.yaml} | 41 +- internal/config/config.go | 24 - internal/consts/consts.go | 13 - internal/data/directory.go | 174 ++ internal/data/export.go | 89 + internal/data/export/repo.go | 54 - internal/data/file.go | 284 +++ internal/data/file/repo.go | 146 -- internal/data/model/directory.go | 19 + internal/data/model/export.go | 19 + internal/data/model/file.go | 18 + internal/factory/factory.go | 362 ---- internal/pkg/image/image.go | 3 +- internal/pkg/store/aliyun/store.go | 64 +- internal/pkg/store/config.go | 22 +- internal/pkg/store/local/store.go | 98 +- internal/pkg/store/tencent/store.go | 64 +- internal/pkg/store/types.go | 28 +- internal/pkg/util/util.go | 19 + internal/router/router.go | 16 - internal/router/upload.go | 46 - internal/{router => service}/blob.go | 78 +- internal/service/directory.go | 132 ++ internal/service/entrance.go | 22 + internal/service/export.go | 88 + internal/service/exports.go | 99 - internal/service/file.go | 227 ++- internal/service/service.go | 23 - internal/service/upload.go | 44 + static/2a0786fe9127b8116bc30ed2ce9581e2.png | Bin 3055 -> 0 bytes static/36e2e87f7b73219343da52a28ba47eec.png | Bin 3006 -> 0 bytes static/385d37202ae8f08cd8ba429eb51b5422.png | Bin 0 -> 729 bytes static/6d06733ef579fbcef68b9f95745a3e99.png | Bin 3178 -> 0 bytes static/6dc607ee0b87559d8932377d46b9a3ea.png | Bin 0 -> 3740 bytes ...8801d43314f4df6ae9e886f572d2c0ed22a0b3.png | Bin 3178 -> 0 bytes static/b8dd9fe625169e3e199064bd5a8d56e4.pdf | Bin 610649 -> 0 bytes static/d19faa31f4a04b52f802a465edf50d18.png | Bin 0 -> 768 bytes .../1cd9127c5537dcde6b5934d6ad82d785.zip | Bin 8760 -> 0 bytes .../8826bc75ee8096309cb0b12fa6af7a7b.xlsx | Bin 10544 -> 0 bytes .../a4ac0516322a22ab537bc4c1f9ab858a.zip | Bin 8760 -> 0 bytes version.go | 4 - 117 files changed, 12242 insertions(+), 9754 deletions(-) delete mode 100644 api/errors/resource_error_reason.pb.go delete mode 100644 api/errors/resource_error_reason.pb.validate.go delete mode 100644 api/errors/resource_error_reason.proto delete mode 100644 api/errors/resource_error_reason_errors.pb.go delete mode 100644 api/export/resource_export.proto delete mode 100644 api/export/resource_export_service.proto delete mode 100644 api/export/v1/resource_export.pb.go delete mode 100644 api/export/v1/resource_export.pb.validate.go delete mode 100644 api/export/v1/resource_export_service.pb.go delete mode 100644 api/export/v1/resource_export_service.pb.validate.go delete mode 100644 api/export/v1/resource_export_service_grpc.pb.go delete mode 100644 api/export/v1/resource_export_service_http.pb.go delete mode 100644 api/file/resource_directory.proto delete mode 100644 api/file/resource_file.proto delete mode 100644 api/file/resource_file_service.proto delete mode 100644 api/file/v1/resource_directory.pb.go delete mode 100644 api/file/v1/resource_directory.pb.validate.go delete mode 100644 api/file/v1/resource_file.pb.go delete mode 100644 api/file/v1/resource_file_service.pb.go delete mode 100644 api/file/v1/resource_file_service.pb.validate.go delete mode 100644 api/file/v1/resource_file_service_grpc.pb.go delete mode 100644 api/file/v1/resource_file_service_http.pb.go rename api/{errors => resource/directory}/openapi.yaml (100%) create mode 100755 api/resource/directory/resource_directory.proto create mode 100755 api/resource/directory/resource_directory_service.proto create mode 100644 api/resource/directory/v1/resource_directory.pb.go create mode 100644 api/resource/directory/v1/resource_directory.pb.validate.go create mode 100644 api/resource/directory/v1/resource_directory_service.pb.go create mode 100644 api/resource/directory/v1/resource_directory_service_grpc.pb.go create mode 100644 api/resource/directory/v1/resource_directory_service_http.pb.go rename api/{export => resource/errors}/openapi.yaml (100%) create mode 100644 api/resource/errors/resource_error_reason.pb.go create mode 100755 api/resource/errors/resource_error_reason.proto create mode 100644 api/resource/errors/resource_error_reason_errors.pb.go create mode 100644 api/resource/export/openapi.yaml create mode 100755 api/resource/export/resource_export.proto create mode 100755 api/resource/export/resource_export_service.proto create mode 100644 api/resource/export/v1/resource_export.pb.go create mode 100644 api/resource/export/v1/resource_export.pb.validate.go create mode 100644 api/resource/export/v1/resource_export_service.pb.go create mode 100644 api/resource/export/v1/resource_export_service_grpc.pb.go create mode 100644 api/resource/export/v1/resource_export_service_http.pb.go rename api/{ => resource}/file/openapi.yaml (100%) create mode 100755 api/resource/file/resource_file.proto create mode 100755 api/resource/file/resource_file_service.proto create mode 100644 api/resource/file/v1/resource_file.pb.go rename api/{ => resource}/file/v1/resource_file.pb.validate.go (63%) create mode 100644 api/resource/file/v1/resource_file_service.pb.go create mode 100644 api/resource/file/v1/resource_file_service_grpc.pb.go create mode 100644 api/resource/file/v1/resource_file_service_http.pb.go create mode 100644 autocode/directory.json create mode 100644 autocode/export.json create mode 100644 autocode/file.json delete mode 100644 deploy/data.sql delete mode 100644 examples/export_test.go create mode 100755 internal/biz/directory/biz.go create mode 100755 internal/biz/directory/entity.go create mode 100755 internal/biz/directory/repo.go create mode 100755 internal/biz/directory/types.go mode change 100644 => 100755 internal/biz/export/biz.go delete mode 100644 internal/biz/export/biz_test.go mode change 100644 => 100755 internal/biz/export/entity.go delete mode 100644 internal/biz/export/factory.go mode change 100644 => 100755 internal/biz/export/repo.go mode change 100644 => 100755 internal/biz/export/types.go mode change 100644 => 100755 internal/biz/file/biz.go delete mode 100644 internal/biz/file/biz_test.go create mode 100644 internal/biz/file/const.go mode change 100644 => 100755 internal/biz/file/entity.go delete mode 100644 internal/biz/file/factory.go mode change 100644 => 100755 internal/biz/file/repo.go mode change 100644 => 100755 internal/biz/file/types.go create mode 100644 internal/conf/conf.go rename internal/{config/config.yaml => conf/conf.yaml} (61%) delete mode 100644 internal/config/config.go delete mode 100644 internal/consts/consts.go create mode 100755 internal/data/directory.go create mode 100755 internal/data/export.go delete mode 100644 internal/data/export/repo.go create mode 100755 internal/data/file.go delete mode 100644 internal/data/file/repo.go create mode 100755 internal/data/model/directory.go create mode 100755 internal/data/model/export.go create mode 100755 internal/data/model/file.go delete mode 100644 internal/factory/factory.go create mode 100644 internal/pkg/util/util.go delete mode 100644 internal/router/router.go delete mode 100644 internal/router/upload.go rename internal/{router => service}/blob.go (51%) create mode 100755 internal/service/directory.go create mode 100755 internal/service/entrance.go create mode 100755 internal/service/export.go delete mode 100644 internal/service/exports.go mode change 100644 => 100755 internal/service/file.go delete mode 100644 internal/service/service.go create mode 100644 internal/service/upload.go delete mode 100755 static/2a0786fe9127b8116bc30ed2ce9581e2.png delete mode 100755 static/36e2e87f7b73219343da52a28ba47eec.png create mode 100755 static/385d37202ae8f08cd8ba429eb51b5422.png delete mode 100755 static/6d06733ef579fbcef68b9f95745a3e99.png create mode 100755 static/6dc607ee0b87559d8932377d46b9a3ea.png delete mode 100755 static/b58901a5e27f2f3d7b2b2191608801d43314f4df6ae9e886f572d2c0ed22a0b3.png delete mode 100644 static/b8dd9fe625169e3e199064bd5a8d56e4.pdf create mode 100755 static/d19faa31f4a04b52f802a465edf50d18.png delete mode 100644 static/export/1cd9127c5537dcde6b5934d6ad82d785.zip delete mode 100755 static/export/8826bc75ee8096309cb0b12fa6af7a7b.xlsx delete mode 100644 static/export/a4ac0516322a22ab537bc4c1f9ab858a.zip delete mode 100644 version.go diff --git a/api/errors/resource_error_reason.pb.go b/api/errors/resource_error_reason.pb.go deleted file mode 100644 index 9ca0572..0000000 --- a/api/errors/resource_error_reason.pb.go +++ /dev/null @@ -1,246 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.32.0 -// protoc v4.24.4 -// source: resource_error_reason.proto - -package errors - -import ( - _ "github.com/go-kratos/kratos/v2/errors" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Reason int32 - -const ( - Reason_NotFound Reason = 0 - Reason_Transform Reason = 1 - Reason_NoSupportStore Reason = 2 - Reason_System Reason = 3 - Reason_ChunkUpload Reason = 4 - Reason_Database Reason = 5 - Reason_StatusProgress Reason = 6 - Reason_UploadFile Reason = 7 - Reason_InitStore Reason = 8 - Reason_FileFormat Reason = 9 - Reason_AddDirectory Reason = 10 - Reason_UpdateDirectory Reason = 11 - Reason_DeleteDirectory Reason = 12 - Reason_NotExistFile Reason = 13 - Reason_AlreadyExistFileName Reason = 14 - Reason_NotExistDirectory Reason = 15 - Reason_NotExistResource Reason = 16 - Reason_Params Reason = 17 - Reason_AccessResource Reason = 18 - Reason_ExportFileNameDup Reason = 19 - Reason_ExportTaskProcess Reason = 20 - Reason_ResourceServer Reason = 21 -) - -// Enum value maps for Reason. -var ( - Reason_name = map[int32]string{ - 0: "NotFound", - 1: "Transform", - 2: "NoSupportStore", - 3: "System", - 4: "ChunkUpload", - 5: "Database", - 6: "StatusProgress", - 7: "UploadFile", - 8: "InitStore", - 9: "FileFormat", - 10: "AddDirectory", - 11: "UpdateDirectory", - 12: "DeleteDirectory", - 13: "NotExistFile", - 14: "AlreadyExistFileName", - 15: "NotExistDirectory", - 16: "NotExistResource", - 17: "Params", - 18: "AccessResource", - 19: "ExportFileNameDup", - 20: "ExportTaskProcess", - 21: "ResourceServer", - } - Reason_value = map[string]int32{ - "NotFound": 0, - "Transform": 1, - "NoSupportStore": 2, - "System": 3, - "ChunkUpload": 4, - "Database": 5, - "StatusProgress": 6, - "UploadFile": 7, - "InitStore": 8, - "FileFormat": 9, - "AddDirectory": 10, - "UpdateDirectory": 11, - "DeleteDirectory": 12, - "NotExistFile": 13, - "AlreadyExistFileName": 14, - "NotExistDirectory": 15, - "NotExistResource": 16, - "Params": 17, - "AccessResource": 18, - "ExportFileNameDup": 19, - "ExportTaskProcess": 20, - "ResourceServer": 21, - } -) - -func (x Reason) Enum() *Reason { - p := new(Reason) - *p = x - return p -} - -func (x Reason) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Reason) Descriptor() protoreflect.EnumDescriptor { - return file_resource_error_reason_proto_enumTypes[0].Descriptor() -} - -func (Reason) Type() protoreflect.EnumType { - return &file_resource_error_reason_proto_enumTypes[0] -} - -func (x Reason) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Reason.Descriptor instead. -func (Reason) EnumDescriptor() ([]byte, []int) { - return file_resource_error_reason_proto_rawDescGZIP(), []int{0} -} - -var File_resource_error_reason_proto protoreflect.FileDescriptor - -var file_resource_error_reason_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x76, - 0x31, 0x1a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0xaa, 0x07, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x73, 0x6f, - 0x6e, 0x12, 0x20, 0x0a, 0x08, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x10, 0x00, 0x1a, - 0x12, 0xb2, 0x45, 0x0f, 0xe4, 0xb8, 0x8d, 0xe5, 0xad, 0x98, 0xe5, 0x9c, 0xa8, 0xe6, 0x95, 0xb0, - 0xe6, 0x8d, 0xae, 0x12, 0x24, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, - 0x10, 0x01, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe8, 0xbd, 0xac, - 0xe6, 0x8d, 0xa2, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x2f, 0x0a, 0x0e, 0x4e, 0x6f, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x10, 0x02, 0x1a, 0x1b, 0xb2, - 0x45, 0x18, 0xe4, 0xb8, 0x8d, 0xe6, 0x94, 0xaf, 0xe6, 0x8c, 0x81, 0xe7, 0x9a, 0x84, 0xe5, 0xad, - 0x98, 0xe5, 0x82, 0xa8, 0xe5, 0xbc, 0x95, 0xe6, 0x93, 0x8e, 0x12, 0x1b, 0x0a, 0x06, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x10, 0x03, 0x1a, 0x0f, 0xb2, 0x45, 0x0c, 0xe7, 0xb3, 0xbb, 0xe7, 0xbb, - 0x9f, 0xe9, 0x94, 0x99, 0xe8, 0xaf, 0xaf, 0x12, 0x26, 0x0a, 0x0b, 0x43, 0x68, 0x75, 0x6e, 0x6b, - 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x10, 0x04, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe5, 0x88, 0x86, - 0xe7, 0x89, 0x87, 0xe4, 0xb8, 0x8a, 0xe4, 0xbc, 0xa0, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, - 0x20, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x10, 0x05, 0x1a, 0x12, 0xb2, - 0x45, 0x0f, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xba, 0x93, 0xe9, 0x94, 0x99, 0xe8, 0xaf, - 0xaf, 0x12, 0x26, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x72, 0x6f, 0x67, 0x72, - 0x65, 0x73, 0x73, 0x10, 0x06, 0x1a, 0x12, 0xb2, 0x45, 0x0f, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, - 0xe4, 0xb8, 0x8a, 0xe4, 0xbc, 0xa0, 0xe4, 0xb8, 0xad, 0x12, 0x25, 0x0a, 0x0a, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x10, 0x07, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe6, 0x96, - 0x87, 0xe4, 0xbb, 0xb6, 0xe4, 0xb8, 0x8a, 0xe4, 0xbc, 0xa0, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, - 0x12, 0x2d, 0x0a, 0x09, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x10, 0x08, 0x1a, - 0x1e, 0xb2, 0x45, 0x1b, 0xe5, 0xad, 0x98, 0xe5, 0x82, 0xa8, 0xe5, 0xbc, 0x95, 0xe6, 0x93, 0x8e, - 0xe5, 0x88, 0x9d, 0xe5, 0xa7, 0x8b, 0xe5, 0x8c, 0x96, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, - 0x25, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x10, 0x09, 0x1a, - 0x15, 0xb2, 0x45, 0x12, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe6, 0xa0, 0xbc, 0xe5, 0xbc, 0x8f, - 0xe9, 0x94, 0x99, 0xe8, 0xaf, 0xaf, 0x12, 0x27, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x44, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x10, 0x0a, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe7, 0x9b, 0xae, - 0xe5, 0xbd, 0x95, 0xe5, 0x88, 0x9b, 0xe5, 0xbb, 0xba, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, - 0x2a, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x79, 0x10, 0x0b, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe7, 0x9b, 0xae, 0xe5, 0xbd, 0x95, 0xe6, - 0x9b, 0xb4, 0xe6, 0x96, 0xb0, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x2a, 0x0a, 0x0f, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x10, 0x0c, - 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe7, 0x9b, 0xae, 0xe5, 0xbd, 0x95, 0xe5, 0x88, 0xa0, 0xe9, 0x99, - 0xa4, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x24, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x45, 0x78, - 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x10, 0x0d, 0x1a, 0x12, 0xb2, 0x45, 0x0f, 0xe6, 0x96, - 0x87, 0xe4, 0xbb, 0xb6, 0xe4, 0xb8, 0x8d, 0xe5, 0xad, 0x98, 0xe5, 0x9c, 0xa8, 0x12, 0x2f, 0x0a, - 0x14, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x10, 0x0e, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe6, 0x96, 0x87, 0xe4, - 0xbb, 0xb6, 0xe5, 0x90, 0x8d, 0xe5, 0xb7, 0xb2, 0xe5, 0xad, 0x98, 0xe5, 0x9c, 0xa8, 0x12, 0x2c, - 0x0a, 0x11, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x79, 0x10, 0x0f, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, - 0xe5, 0xa4, 0xb9, 0xe4, 0xb8, 0x8d, 0xe5, 0xad, 0x98, 0xe5, 0x9c, 0xa8, 0x12, 0x28, 0x0a, 0x10, - 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x10, 0x10, 0x1a, 0x12, 0xb2, 0x45, 0x0f, 0xe8, 0xb5, 0x84, 0xe6, 0xba, 0x90, 0xe4, 0xb8, 0x8d, - 0xe5, 0xad, 0x98, 0xe5, 0x9c, 0xa8, 0x12, 0x1b, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x10, 0x11, 0x1a, 0x0f, 0xb2, 0x45, 0x0c, 0xe5, 0x8f, 0x82, 0xe6, 0x95, 0xb0, 0xe9, 0x94, 0x99, - 0xe8, 0xaf, 0xaf, 0x12, 0x2f, 0x0a, 0x0e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x10, 0x12, 0x1a, 0x1b, 0xb2, 0x45, 0x18, 0xe8, 0xae, 0xbf, 0xe9, - 0x97, 0xae, 0xe8, 0xb5, 0x84, 0xe6, 0xba, 0x90, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe5, 0xbc, - 0x82, 0xe5, 0xb8, 0xb8, 0x12, 0x35, 0x0a, 0x11, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x69, - 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x44, 0x75, 0x70, 0x10, 0x13, 0x1a, 0x1e, 0xb2, 0x45, 0x1b, - 0xe5, 0xaf, 0xbc, 0xe5, 0x87, 0xba, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe9, 0x87, 0x8d, 0xe5, - 0x91, 0xbd, 0xe5, 0x90, 0x8d, 0xe9, 0x87, 0x8d, 0xe5, 0xa4, 0x8d, 0x12, 0x35, 0x0a, 0x11, 0x45, - 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x10, 0x14, 0x1a, 0x1e, 0xb2, 0x45, 0x1b, 0xe5, 0xaf, 0xbc, 0xe5, 0x87, 0xba, 0xe4, 0xbb, 0xbb, - 0xe5, 0x8a, 0xa1, 0xe6, 0xad, 0xa3, 0xe5, 0x9c, 0xa8, 0xe8, 0xbf, 0x9b, 0xe8, 0xa1, 0x8c, 0xe4, - 0xb8, 0xad, 0x12, 0x29, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x10, 0x15, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe8, 0xb5, 0x84, 0xe6, 0xba, - 0x90, 0xe6, 0x9c, 0x8d, 0xe5, 0x8a, 0xa1, 0xe5, 0xbc, 0x82, 0xe5, 0xb8, 0xb8, 0x1a, 0x04, 0xa0, - 0x45, 0xf4, 0x03, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x3b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_resource_error_reason_proto_rawDescOnce sync.Once - file_resource_error_reason_proto_rawDescData = file_resource_error_reason_proto_rawDesc -) - -func file_resource_error_reason_proto_rawDescGZIP() []byte { - file_resource_error_reason_proto_rawDescOnce.Do(func() { - file_resource_error_reason_proto_rawDescData = protoimpl.X.CompressGZIP(file_resource_error_reason_proto_rawDescData) - }) - return file_resource_error_reason_proto_rawDescData -} - -var file_resource_error_reason_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_resource_error_reason_proto_goTypes = []interface{}{ - (Reason)(0), // 0: v1.Reason -} -var file_resource_error_reason_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_resource_error_reason_proto_init() } -func file_resource_error_reason_proto_init() { - if File_resource_error_reason_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_resource_error_reason_proto_rawDesc, - NumEnums: 1, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_resource_error_reason_proto_goTypes, - DependencyIndexes: file_resource_error_reason_proto_depIdxs, - EnumInfos: file_resource_error_reason_proto_enumTypes, - }.Build() - File_resource_error_reason_proto = out.File - file_resource_error_reason_proto_rawDesc = nil - file_resource_error_reason_proto_goTypes = nil - file_resource_error_reason_proto_depIdxs = nil -} diff --git a/api/errors/resource_error_reason.pb.validate.go b/api/errors/resource_error_reason.pb.validate.go deleted file mode 100644 index f182769..0000000 --- a/api/errors/resource_error_reason.pb.validate.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated by protoc-gen-validate. DO NOT EDIT. -// source: resource_error_reason.proto - -package errors - -import ( - "bytes" - "errors" - "fmt" - "net" - "net/mail" - "net/url" - "regexp" - "sort" - "strings" - "time" - "unicode/utf8" - - "google.golang.org/protobuf/types/known/anypb" -) - -// ensure the imports are used -var ( - _ = bytes.MinRead - _ = errors.New("") - _ = fmt.Print - _ = utf8.UTFMax - _ = (*regexp.Regexp)(nil) - _ = (*strings.Reader)(nil) - _ = net.IPv4len - _ = time.Duration(0) - _ = (*url.URL)(nil) - _ = (*mail.Address)(nil) - _ = anypb.Any{} - _ = sort.Sort -) diff --git a/api/errors/resource_error_reason.proto b/api/errors/resource_error_reason.proto deleted file mode 100644 index 382a8be..0000000 --- a/api/errors/resource_error_reason.proto +++ /dev/null @@ -1,37 +0,0 @@ -syntax = "proto3"; - -package v1; - -import "errors/errors.proto"; -option go_package = "./;errors"; - - -enum Reason { - // 设置缺省错误码 - option (errors.default_code) = 500; - NotFound = 0[(errors.message) = "不存在数据"]; - Transform = 1[(errors.message)="数据转换失败"]; - NoSupportStore = 2[(errors.message)="不支持的存储引擎"]; - System =3 [(errors.message)="系统错误"]; - ChunkUpload = 4[(errors.message)="分片上传失败"]; - Database = 5[(errors.message)="数据库错误"]; - StatusProgress = 6[(errors.message)="文件上传中"]; - UploadFile = 7[(errors.message)="文件上传失败"]; - InitStore = 8[(errors.message)="存储引擎初始化失败"]; - FileFormat = 9[(errors.message)="文件格式错误"]; - AddDirectory = 10[(errors.message)="目录创建失败"]; - UpdateDirectory = 11[(errors.message)="目录更新失败"]; - DeleteDirectory = 12[(errors.message)="目录删除失败"]; - NotExistFile = 13[(errors.message)="文件不存在"]; - AlreadyExistFileName = 14[(errors.message)="文件名已存在"]; - NotExistDirectory = 15[(errors.message)="文件夹不存在"]; - NotExistResource = 16[(errors.message)="资源不存在"]; - Params = 17[(errors.message)="参数错误"]; - AccessResource = 18[(errors.message)="访问资源文件异常"]; - ExportFileNameDup = 19[(errors.message)="导出文件重命名重复"]; - ExportTaskProcess = 20[(errors.message)="导出任务正在进行中"]; - ResourceServer = 21[(errors.message)="资源服务异常"]; -} - - - diff --git a/api/errors/resource_error_reason_errors.pb.go b/api/errors/resource_error_reason_errors.pb.go deleted file mode 100644 index d2a1abb..0000000 --- a/api/errors/resource_error_reason_errors.pb.go +++ /dev/null @@ -1,364 +0,0 @@ -// Code generated by protoc-gen-go-errors. DO NOT EDIT. - -package errors - -import ( - fmt "fmt" - errors "github.com/go-kratos/kratos/v2/errors" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the kratos package it is being compiled against. -const _ = errors.SupportPackageIsVersion1 - -func IsNotFound(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_NotFound.String() && e.Code == 500 -} - -func NotFoundFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_NotFound.String(), "不存在数据:"+fmt.Sprintf(format, args...)) -} - -func NotFound() *errors.Error { - return errors.New(500, Reason_NotFound.String(), "不存在数据") -} - -func IsTransform(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_Transform.String() && e.Code == 500 -} - -func TransformFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_Transform.String(), "数据转换失败:"+fmt.Sprintf(format, args...)) -} - -func Transform() *errors.Error { - return errors.New(500, Reason_Transform.String(), "数据转换失败") -} - -func IsNoSupportStore(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_NoSupportStore.String() && e.Code == 500 -} - -func NoSupportStoreFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_NoSupportStore.String(), "不支持的存储引擎:"+fmt.Sprintf(format, args...)) -} - -func NoSupportStore() *errors.Error { - return errors.New(500, Reason_NoSupportStore.String(), "不支持的存储引擎") -} - -func IsSystem(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_System.String() && e.Code == 500 -} - -func SystemFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_System.String(), "系统错误:"+fmt.Sprintf(format, args...)) -} - -func System() *errors.Error { - return errors.New(500, Reason_System.String(), "系统错误") -} - -func IsChunkUpload(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_ChunkUpload.String() && e.Code == 500 -} - -func ChunkUploadFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_ChunkUpload.String(), "分片上传失败:"+fmt.Sprintf(format, args...)) -} - -func ChunkUpload() *errors.Error { - return errors.New(500, Reason_ChunkUpload.String(), "分片上传失败") -} - -func IsDatabase(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_Database.String() && e.Code == 500 -} - -func DatabaseFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_Database.String(), "数据库错误:"+fmt.Sprintf(format, args...)) -} - -func Database() *errors.Error { - return errors.New(500, Reason_Database.String(), "数据库错误") -} - -func IsStatusProgress(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_StatusProgress.String() && e.Code == 500 -} - -func StatusProgressFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_StatusProgress.String(), "文件上传中:"+fmt.Sprintf(format, args...)) -} - -func StatusProgress() *errors.Error { - return errors.New(500, Reason_StatusProgress.String(), "文件上传中") -} - -func IsUploadFile(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_UploadFile.String() && e.Code == 500 -} - -func UploadFileFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_UploadFile.String(), "文件上传失败:"+fmt.Sprintf(format, args...)) -} - -func UploadFile() *errors.Error { - return errors.New(500, Reason_UploadFile.String(), "文件上传失败") -} - -func IsInitStore(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_InitStore.String() && e.Code == 500 -} - -func InitStoreFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_InitStore.String(), "存储引擎初始化失败:"+fmt.Sprintf(format, args...)) -} - -func InitStore() *errors.Error { - return errors.New(500, Reason_InitStore.String(), "存储引擎初始化失败") -} - -func IsFileFormat(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_FileFormat.String() && e.Code == 500 -} - -func FileFormatFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_FileFormat.String(), "文件格式错误:"+fmt.Sprintf(format, args...)) -} - -func FileFormat() *errors.Error { - return errors.New(500, Reason_FileFormat.String(), "文件格式错误") -} - -func IsAddDirectory(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_AddDirectory.String() && e.Code == 500 -} - -func AddDirectoryFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_AddDirectory.String(), "目录创建失败:"+fmt.Sprintf(format, args...)) -} - -func AddDirectory() *errors.Error { - return errors.New(500, Reason_AddDirectory.String(), "目录创建失败") -} - -func IsUpdateDirectory(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_UpdateDirectory.String() && e.Code == 500 -} - -func UpdateDirectoryFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_UpdateDirectory.String(), "目录更新失败:"+fmt.Sprintf(format, args...)) -} - -func UpdateDirectory() *errors.Error { - return errors.New(500, Reason_UpdateDirectory.String(), "目录更新失败") -} - -func IsDeleteDirectory(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_DeleteDirectory.String() && e.Code == 500 -} - -func DeleteDirectoryFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_DeleteDirectory.String(), "目录删除失败:"+fmt.Sprintf(format, args...)) -} - -func DeleteDirectory() *errors.Error { - return errors.New(500, Reason_DeleteDirectory.String(), "目录删除失败") -} - -func IsNotExistFile(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_NotExistFile.String() && e.Code == 500 -} - -func NotExistFileFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_NotExistFile.String(), "文件不存在:"+fmt.Sprintf(format, args...)) -} - -func NotExistFile() *errors.Error { - return errors.New(500, Reason_NotExistFile.String(), "文件不存在") -} - -func IsAlreadyExistFileName(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_AlreadyExistFileName.String() && e.Code == 500 -} - -func AlreadyExistFileNameFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_AlreadyExistFileName.String(), "文件名已存在:"+fmt.Sprintf(format, args...)) -} - -func AlreadyExistFileName() *errors.Error { - return errors.New(500, Reason_AlreadyExistFileName.String(), "文件名已存在") -} - -func IsNotExistDirectory(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_NotExistDirectory.String() && e.Code == 500 -} - -func NotExistDirectoryFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_NotExistDirectory.String(), "文件夹不存在:"+fmt.Sprintf(format, args...)) -} - -func NotExistDirectory() *errors.Error { - return errors.New(500, Reason_NotExistDirectory.String(), "文件夹不存在") -} - -func IsNotExistResource(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_NotExistResource.String() && e.Code == 500 -} - -func NotExistResourceFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_NotExistResource.String(), "资源不存在:"+fmt.Sprintf(format, args...)) -} - -func NotExistResource() *errors.Error { - return errors.New(500, Reason_NotExistResource.String(), "资源不存在") -} - -func IsParams(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_Params.String() && e.Code == 500 -} - -func ParamsFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_Params.String(), "参数错误:"+fmt.Sprintf(format, args...)) -} - -func Params() *errors.Error { - return errors.New(500, Reason_Params.String(), "参数错误") -} - -func IsAccessResource(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_AccessResource.String() && e.Code == 500 -} - -func AccessResourceFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_AccessResource.String(), "访问资源文件异常:"+fmt.Sprintf(format, args...)) -} - -func AccessResource() *errors.Error { - return errors.New(500, Reason_AccessResource.String(), "访问资源文件异常") -} - -func IsExportFileNameDup(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_ExportFileNameDup.String() && e.Code == 500 -} - -func ExportFileNameDupFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_ExportFileNameDup.String(), "导出文件重命名重复:"+fmt.Sprintf(format, args...)) -} - -func ExportFileNameDup() *errors.Error { - return errors.New(500, Reason_ExportFileNameDup.String(), "导出文件重命名重复") -} - -func IsExportTaskProcess(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_ExportTaskProcess.String() && e.Code == 500 -} - -func ExportTaskProcessFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_ExportTaskProcess.String(), "导出任务正在进行中:"+fmt.Sprintf(format, args...)) -} - -func ExportTaskProcess() *errors.Error { - return errors.New(500, Reason_ExportTaskProcess.String(), "导出任务正在进行中") -} - -func IsResourceServer(err error) bool { - if err == nil { - return false - } - e := errors.FromError(err) - return e.Reason == Reason_ResourceServer.String() && e.Code == 500 -} - -func ResourceServerFormat(format string, args ...any) *errors.Error { - return errors.New(500, Reason_ResourceServer.String(), "资源服务异常:"+fmt.Sprintf(format, args...)) -} - -func ResourceServer() *errors.Error { - return errors.New(500, Reason_ResourceServer.String(), "资源服务异常") -} diff --git a/api/export/resource_export.proto b/api/export/resource_export.proto deleted file mode 100644 index d1cc553..0000000 --- a/api/export/resource_export.proto +++ /dev/null @@ -1,62 +0,0 @@ -syntax = "proto3"; - -package export; -option go_package = "./v1;v1"; -import "google/api/annotations.proto"; -import "validate/validate.proto"; - -message Export{ - uint32 id = 1; - string name = 2; - uint32 size = 3; - string src = 4; - string version = 5; - string reason = 6; - string status = 7; - uint32 created_at = 8; - uint32 updated_at = 9; -} - -message PageExportRequest{ - uint32 page = 1[(validate.rules).uint32 = {gt:0}]; - uint32 page_size = 2[(validate.rules).uint32 = {gt:0,lte:100}]; -} - -message PageExportReply{ - repeated Export list = 1; - optional uint32 total = 2; -} - - -message AddExportRequest{ - message ExportFile{ - string sha = 1; - string rename = 2; - } - string name = 1[(validate.rules).string = {min_len:1}]; - repeated ExportFile files = 2; - repeated uint32 ids = 3; -} -message AddExportReply{ - uint32 id = 1; -} - -message AddExportExcelRequest{ - message Col{ - string type = 1[(validate.rules).string = {min_len:1}]; - string value = 2; - } - message Row{ - repeated Col cols = 1; - } - string name = 1[(validate.rules).string = {min_len:1}]; - repeated Row rows = 2[(validate.rules).repeated = {min_items:1}]; -} - -message AddExportExcelReply{ - uint32 id = 1; -} - -message DeleteExportRequest{ - uint32 id = 1; -} diff --git a/api/export/resource_export_service.proto b/api/export/resource_export_service.proto deleted file mode 100644 index cc64545..0000000 --- a/api/export/resource_export_service.proto +++ /dev/null @@ -1,40 +0,0 @@ -syntax = "proto3"; - -package export; -option go_package = "./v1;v1"; - -import "google/api/annotations.proto"; -import "google/protobuf/empty.proto"; - -import "resource_export.proto"; - -service Service { - - rpc PageExport (PageExportRequest) returns (PageExportReply) { - option (google.api.http) = { - get: "/resource/v1/exports" - }; - } - - rpc AddExport (AddExportRequest) returns (AddExportReply) { - option (google.api.http) = { - post: "/resource/v1/export", - body:"*" - }; - } - - rpc AddExportExcel (AddExportExcelRequest) returns (AddExportExcelReply) { - option (google.api.http) = { - post: "/resource/v1/export/excel", - body:"*" - }; - } - - rpc DeleteExport (DeleteExportRequest) returns (google.protobuf.Empty) { - option (google.api.http) = { - delete: "/resource/v1/export" - }; - } -} - - diff --git a/api/export/v1/resource_export.pb.go b/api/export/v1/resource_export.pb.go deleted file mode 100644 index 9280c01..0000000 --- a/api/export/v1/resource_export.pb.go +++ /dev/null @@ -1,929 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.32.0 -// protoc v4.24.4 -// source: resource_export.proto - -package v1 - -import ( - _ "github.com/envoyproxy/protoc-gen-validate/validate" - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Export struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Size uint32 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` - Src string `protobuf:"bytes,4,opt,name=src,proto3" json:"src,omitempty"` - Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"` - Reason string `protobuf:"bytes,6,opt,name=reason,proto3" json:"reason,omitempty"` - Status string `protobuf:"bytes,7,opt,name=status,proto3" json:"status,omitempty"` - CreatedAt uint32 `protobuf:"varint,8,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - UpdatedAt uint32 `protobuf:"varint,9,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` -} - -func (x *Export) Reset() { - *x = Export{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Export) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Export) ProtoMessage() {} - -func (x *Export) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Export.ProtoReflect.Descriptor instead. -func (*Export) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{0} -} - -func (x *Export) GetId() uint32 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *Export) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Export) GetSize() uint32 { - if x != nil { - return x.Size - } - return 0 -} - -func (x *Export) GetSrc() string { - if x != nil { - return x.Src - } - return "" -} - -func (x *Export) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *Export) GetReason() string { - if x != nil { - return x.Reason - } - return "" -} - -func (x *Export) GetStatus() string { - if x != nil { - return x.Status - } - return "" -} - -func (x *Export) GetCreatedAt() uint32 { - if x != nil { - return x.CreatedAt - } - return 0 -} - -func (x *Export) GetUpdatedAt() uint32 { - if x != nil { - return x.UpdatedAt - } - return 0 -} - -type PageExportRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Page uint32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` - PageSize uint32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` -} - -func (x *PageExportRequest) Reset() { - *x = PageExportRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PageExportRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PageExportRequest) ProtoMessage() {} - -func (x *PageExportRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PageExportRequest.ProtoReflect.Descriptor instead. -func (*PageExportRequest) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{1} -} - -func (x *PageExportRequest) GetPage() uint32 { - if x != nil { - return x.Page - } - return 0 -} - -func (x *PageExportRequest) GetPageSize() uint32 { - if x != nil { - return x.PageSize - } - return 0 -} - -type PageExportReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - List []*Export `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` - Total *uint32 `protobuf:"varint,2,opt,name=total,proto3,oneof" json:"total,omitempty"` -} - -func (x *PageExportReply) Reset() { - *x = PageExportReply{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PageExportReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PageExportReply) ProtoMessage() {} - -func (x *PageExportReply) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PageExportReply.ProtoReflect.Descriptor instead. -func (*PageExportReply) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{2} -} - -func (x *PageExportReply) GetList() []*Export { - if x != nil { - return x.List - } - return nil -} - -func (x *PageExportReply) GetTotal() uint32 { - if x != nil && x.Total != nil { - return *x.Total - } - return 0 -} - -type AddExportRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Files []*AddExportRequest_ExportFile `protobuf:"bytes,2,rep,name=files,proto3" json:"files,omitempty"` - Ids []uint32 `protobuf:"varint,3,rep,packed,name=ids,proto3" json:"ids,omitempty"` -} - -func (x *AddExportRequest) Reset() { - *x = AddExportRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddExportRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddExportRequest) ProtoMessage() {} - -func (x *AddExportRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddExportRequest.ProtoReflect.Descriptor instead. -func (*AddExportRequest) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{3} -} - -func (x *AddExportRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *AddExportRequest) GetFiles() []*AddExportRequest_ExportFile { - if x != nil { - return x.Files - } - return nil -} - -func (x *AddExportRequest) GetIds() []uint32 { - if x != nil { - return x.Ids - } - return nil -} - -type AddExportReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *AddExportReply) Reset() { - *x = AddExportReply{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddExportReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddExportReply) ProtoMessage() {} - -func (x *AddExportReply) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddExportReply.ProtoReflect.Descriptor instead. -func (*AddExportReply) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{4} -} - -func (x *AddExportReply) GetId() uint32 { - if x != nil { - return x.Id - } - return 0 -} - -type AddExportExcelRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Rows []*AddExportExcelRequest_Row `protobuf:"bytes,2,rep,name=rows,proto3" json:"rows,omitempty"` -} - -func (x *AddExportExcelRequest) Reset() { - *x = AddExportExcelRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddExportExcelRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddExportExcelRequest) ProtoMessage() {} - -func (x *AddExportExcelRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddExportExcelRequest.ProtoReflect.Descriptor instead. -func (*AddExportExcelRequest) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{5} -} - -func (x *AddExportExcelRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *AddExportExcelRequest) GetRows() []*AddExportExcelRequest_Row { - if x != nil { - return x.Rows - } - return nil -} - -type AddExportExcelReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *AddExportExcelReply) Reset() { - *x = AddExportExcelReply{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddExportExcelReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddExportExcelReply) ProtoMessage() {} - -func (x *AddExportExcelReply) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddExportExcelReply.ProtoReflect.Descriptor instead. -func (*AddExportExcelReply) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{6} -} - -func (x *AddExportExcelReply) GetId() uint32 { - if x != nil { - return x.Id - } - return 0 -} - -type DeleteExportRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *DeleteExportRequest) Reset() { - *x = DeleteExportRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteExportRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteExportRequest) ProtoMessage() {} - -func (x *DeleteExportRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteExportRequest.ProtoReflect.Descriptor instead. -func (*DeleteExportRequest) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{7} -} - -func (x *DeleteExportRequest) GetId() uint32 { - if x != nil { - return x.Id - } - return 0 -} - -type AddExportRequest_ExportFile struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Sha string `protobuf:"bytes,1,opt,name=sha,proto3" json:"sha,omitempty"` - Rename string `protobuf:"bytes,2,opt,name=rename,proto3" json:"rename,omitempty"` -} - -func (x *AddExportRequest_ExportFile) Reset() { - *x = AddExportRequest_ExportFile{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddExportRequest_ExportFile) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddExportRequest_ExportFile) ProtoMessage() {} - -func (x *AddExportRequest_ExportFile) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddExportRequest_ExportFile.ProtoReflect.Descriptor instead. -func (*AddExportRequest_ExportFile) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{3, 0} -} - -func (x *AddExportRequest_ExportFile) GetSha() string { - if x != nil { - return x.Sha - } - return "" -} - -func (x *AddExportRequest_ExportFile) GetRename() string { - if x != nil { - return x.Rename - } - return "" -} - -type AddExportExcelRequest_Col struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *AddExportExcelRequest_Col) Reset() { - *x = AddExportExcelRequest_Col{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddExportExcelRequest_Col) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddExportExcelRequest_Col) ProtoMessage() {} - -func (x *AddExportExcelRequest_Col) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddExportExcelRequest_Col.ProtoReflect.Descriptor instead. -func (*AddExportExcelRequest_Col) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{5, 0} -} - -func (x *AddExportExcelRequest_Col) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *AddExportExcelRequest_Col) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -type AddExportExcelRequest_Row struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Cols []*AddExportExcelRequest_Col `protobuf:"bytes,1,rep,name=cols,proto3" json:"cols,omitempty"` -} - -func (x *AddExportExcelRequest_Row) Reset() { - *x = AddExportExcelRequest_Row{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_export_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddExportExcelRequest_Row) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddExportExcelRequest_Row) ProtoMessage() {} - -func (x *AddExportExcelRequest_Row) ProtoReflect() protoreflect.Message { - mi := &file_resource_export_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddExportExcelRequest_Row.ProtoReflect.Descriptor instead. -func (*AddExportExcelRequest_Row) Descriptor() ([]byte, []int) { - return file_resource_export_proto_rawDescGZIP(), []int{5, 1} -} - -func (x *AddExportExcelRequest_Row) GetCols() []*AddExportExcelRequest_Col { - if x != nil { - return x.Cols - } - return nil -} - -var File_resource_export_proto protoreflect.FileDescriptor - -var file_resource_export_proto_rawDesc = []byte{ - 0x0a, 0x15, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x1a, - 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xda, 0x01, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x22, 0x58, 0x0a, 0x11, 0x50, 0x61, 0x67, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, - 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, - 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x18, - 0x64, 0x20, 0x00, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x5a, 0x0a, - 0x0f, 0x50, 0x61, 0x67, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x12, 0x22, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, - 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x04, - 0x6c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x42, - 0x08, 0x0a, 0x06, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0xb4, 0x01, 0x0a, 0x10, 0x41, 0x64, - 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, - 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x05, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x65, 0x78, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, - 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0d, 0x52, 0x03, 0x69, 0x64, 0x73, 0x1a, 0x36, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x68, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, - 0x22, 0x20, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, - 0x69, 0x64, 0x22, 0xed, 0x01, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x45, 0x78, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, - 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x04, 0x72, 0x6f, 0x77, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x63, 0x65, 0x6c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x6f, 0x77, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, - 0x01, 0x02, 0x08, 0x01, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x1a, 0x38, 0x0a, 0x03, 0x43, 0x6f, - 0x6c, 0x12, 0x1b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x3c, 0x0a, 0x03, 0x52, 0x6f, 0x77, 0x12, 0x35, 0x0a, 0x04, 0x63, - 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x63, 0x65, - 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6c, 0x52, 0x04, 0x63, 0x6f, - 0x6c, 0x73, 0x22, 0x25, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x45, - 0x78, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x22, 0x25, 0x0a, 0x13, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, - 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var ( - file_resource_export_proto_rawDescOnce sync.Once - file_resource_export_proto_rawDescData = file_resource_export_proto_rawDesc -) - -func file_resource_export_proto_rawDescGZIP() []byte { - file_resource_export_proto_rawDescOnce.Do(func() { - file_resource_export_proto_rawDescData = protoimpl.X.CompressGZIP(file_resource_export_proto_rawDescData) - }) - return file_resource_export_proto_rawDescData -} - -var file_resource_export_proto_msgTypes = make([]protoimpl.MessageInfo, 11) -var file_resource_export_proto_goTypes = []interface{}{ - (*Export)(nil), // 0: export.Export - (*PageExportRequest)(nil), // 1: export.PageExportRequest - (*PageExportReply)(nil), // 2: export.PageExportReply - (*AddExportRequest)(nil), // 3: export.AddExportRequest - (*AddExportReply)(nil), // 4: export.AddExportReply - (*AddExportExcelRequest)(nil), // 5: export.AddExportExcelRequest - (*AddExportExcelReply)(nil), // 6: export.AddExportExcelReply - (*DeleteExportRequest)(nil), // 7: export.DeleteExportRequest - (*AddExportRequest_ExportFile)(nil), // 8: export.AddExportRequest.ExportFile - (*AddExportExcelRequest_Col)(nil), // 9: export.AddExportExcelRequest.Col - (*AddExportExcelRequest_Row)(nil), // 10: export.AddExportExcelRequest.Row -} -var file_resource_export_proto_depIdxs = []int32{ - 0, // 0: export.PageExportReply.list:type_name -> export.Export - 8, // 1: export.AddExportRequest.files:type_name -> export.AddExportRequest.ExportFile - 10, // 2: export.AddExportExcelRequest.rows:type_name -> export.AddExportExcelRequest.Row - 9, // 3: export.AddExportExcelRequest.Row.cols:type_name -> export.AddExportExcelRequest.Col - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_resource_export_proto_init() } -func file_resource_export_proto_init() { - if File_resource_export_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_resource_export_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Export); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PageExportRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PageExportReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddExportRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddExportReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddExportExcelRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddExportExcelReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteExportRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddExportRequest_ExportFile); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddExportExcelRequest_Col); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_export_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddExportExcelRequest_Row); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_resource_export_proto_msgTypes[2].OneofWrappers = []interface{}{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_resource_export_proto_rawDesc, - NumEnums: 0, - NumMessages: 11, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_resource_export_proto_goTypes, - DependencyIndexes: file_resource_export_proto_depIdxs, - MessageInfos: file_resource_export_proto_msgTypes, - }.Build() - File_resource_export_proto = out.File - file_resource_export_proto_rawDesc = nil - file_resource_export_proto_goTypes = nil - file_resource_export_proto_depIdxs = nil -} diff --git a/api/export/v1/resource_export.pb.validate.go b/api/export/v1/resource_export.pb.validate.go deleted file mode 100644 index 82e3f1f..0000000 --- a/api/export/v1/resource_export.pb.validate.go +++ /dev/null @@ -1,1385 +0,0 @@ -// Code generated by protoc-gen-validate. DO NOT EDIT. -// source: resource_export.proto - -package v1 - -import ( - "bytes" - "errors" - "fmt" - "net" - "net/mail" - "net/url" - "regexp" - "sort" - "strings" - "time" - "unicode/utf8" - - "google.golang.org/protobuf/types/known/anypb" -) - -// ensure the imports are used -var ( - _ = bytes.MinRead - _ = errors.New("") - _ = fmt.Print - _ = utf8.UTFMax - _ = (*regexp.Regexp)(nil) - _ = (*strings.Reader)(nil) - _ = net.IPv4len - _ = time.Duration(0) - _ = (*url.URL)(nil) - _ = (*mail.Address)(nil) - _ = anypb.Any{} - _ = sort.Sort -) - -// Validate checks the field values on Export with the rules defined in the -// proto definition for this message. If any rules are violated, the first -// error encountered is returned, or nil if there are no violations. -func (m *Export) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on Export with the rules defined in the -// proto definition for this message. If any rules are violated, the result is -// a list of violation errors wrapped in ExportMultiError, or nil if none found. -func (m *Export) ValidateAll() error { - return m.validate(true) -} - -func (m *Export) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - // no validation rules for Id - - // no validation rules for Name - - // no validation rules for Size - - // no validation rules for Src - - // no validation rules for Version - - // no validation rules for Reason - - // no validation rules for Status - - // no validation rules for CreatedAt - - // no validation rules for UpdatedAt - - if len(errors) > 0 { - return ExportMultiError(errors) - } - - return nil -} - -// ExportMultiError is an error wrapping multiple validation errors returned by -// Export.ValidateAll() if the designated constraints aren't met. -type ExportMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m ExportMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m ExportMultiError) AllErrors() []error { return m } - -// ExportValidationError is the validation error returned by Export.Validate if -// the designated constraints aren't met. -type ExportValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e ExportValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e ExportValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e ExportValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e ExportValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e ExportValidationError) ErrorName() string { return "ExportValidationError" } - -// Error satisfies the builtin error interface -func (e ExportValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sExport.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = ExportValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = ExportValidationError{} - -// Validate checks the field values on PageExportRequest with the rules defined -// in the proto definition for this message. If any rules are violated, the -// first error encountered is returned, or nil if there are no violations. -func (m *PageExportRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on PageExportRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// PageExportRequestMultiError, or nil if none found. -func (m *PageExportRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *PageExportRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if m.GetPage() <= 0 { - err := PageExportRequestValidationError{ - field: "Page", - reason: "value must be greater than 0", - } - if !all { - return err - } - errors = append(errors, err) - } - - if val := m.GetPageSize(); val <= 0 || val > 100 { - err := PageExportRequestValidationError{ - field: "PageSize", - reason: "value must be inside range (0, 100]", - } - if !all { - return err - } - errors = append(errors, err) - } - - if len(errors) > 0 { - return PageExportRequestMultiError(errors) - } - - return nil -} - -// PageExportRequestMultiError is an error wrapping multiple validation errors -// returned by PageExportRequest.ValidateAll() if the designated constraints -// aren't met. -type PageExportRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m PageExportRequestMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m PageExportRequestMultiError) AllErrors() []error { return m } - -// PageExportRequestValidationError is the validation error returned by -// PageExportRequest.Validate if the designated constraints aren't met. -type PageExportRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e PageExportRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e PageExportRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e PageExportRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e PageExportRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e PageExportRequestValidationError) ErrorName() string { - return "PageExportRequestValidationError" -} - -// Error satisfies the builtin error interface -func (e PageExportRequestValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sPageExportRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = PageExportRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = PageExportRequestValidationError{} - -// Validate checks the field values on PageExportReply with the rules defined -// in the proto definition for this message. If any rules are violated, the -// first error encountered is returned, or nil if there are no violations. -func (m *PageExportReply) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on PageExportReply with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// PageExportReplyMultiError, or nil if none found. -func (m *PageExportReply) ValidateAll() error { - return m.validate(true) -} - -func (m *PageExportReply) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - for idx, item := range m.GetList() { - _, _ = idx, item - - if all { - switch v := interface{}(item).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, PageExportReplyValidationError{ - field: fmt.Sprintf("List[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, PageExportReplyValidationError{ - field: fmt.Sprintf("List[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return PageExportReplyValidationError{ - field: fmt.Sprintf("List[%v]", idx), - reason: "embedded message failed validation", - cause: err, - } - } - } - - } - - if m.Total != nil { - // no validation rules for Total - } - - if len(errors) > 0 { - return PageExportReplyMultiError(errors) - } - - return nil -} - -// PageExportReplyMultiError is an error wrapping multiple validation errors -// returned by PageExportReply.ValidateAll() if the designated constraints -// aren't met. -type PageExportReplyMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m PageExportReplyMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m PageExportReplyMultiError) AllErrors() []error { return m } - -// PageExportReplyValidationError is the validation error returned by -// PageExportReply.Validate if the designated constraints aren't met. -type PageExportReplyValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e PageExportReplyValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e PageExportReplyValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e PageExportReplyValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e PageExportReplyValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e PageExportReplyValidationError) ErrorName() string { return "PageExportReplyValidationError" } - -// Error satisfies the builtin error interface -func (e PageExportReplyValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sPageExportReply.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = PageExportReplyValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = PageExportReplyValidationError{} - -// Validate checks the field values on AddExportRequest with the rules defined -// in the proto definition for this message. If any rules are violated, the -// first error encountered is returned, or nil if there are no violations. -func (m *AddExportRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AddExportRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AddExportRequestMultiError, or nil if none found. -func (m *AddExportRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *AddExportRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if utf8.RuneCountInString(m.GetName()) < 1 { - err := AddExportRequestValidationError{ - field: "Name", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - for idx, item := range m.GetFiles() { - _, _ = idx, item - - if all { - switch v := interface{}(item).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, AddExportRequestValidationError{ - field: fmt.Sprintf("Files[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, AddExportRequestValidationError{ - field: fmt.Sprintf("Files[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return AddExportRequestValidationError{ - field: fmt.Sprintf("Files[%v]", idx), - reason: "embedded message failed validation", - cause: err, - } - } - } - - } - - if len(errors) > 0 { - return AddExportRequestMultiError(errors) - } - - return nil -} - -// AddExportRequestMultiError is an error wrapping multiple validation errors -// returned by AddExportRequest.ValidateAll() if the designated constraints -// aren't met. -type AddExportRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AddExportRequestMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AddExportRequestMultiError) AllErrors() []error { return m } - -// AddExportRequestValidationError is the validation error returned by -// AddExportRequest.Validate if the designated constraints aren't met. -type AddExportRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AddExportRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AddExportRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AddExportRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AddExportRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AddExportRequestValidationError) ErrorName() string { return "AddExportRequestValidationError" } - -// Error satisfies the builtin error interface -func (e AddExportRequestValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAddExportRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AddExportRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AddExportRequestValidationError{} - -// Validate checks the field values on AddExportReply with the rules defined in -// the proto definition for this message. If any rules are violated, the first -// error encountered is returned, or nil if there are no violations. -func (m *AddExportReply) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AddExportReply with the rules defined -// in the proto definition for this message. If any rules are violated, the -// result is a list of violation errors wrapped in AddExportReplyMultiError, -// or nil if none found. -func (m *AddExportReply) ValidateAll() error { - return m.validate(true) -} - -func (m *AddExportReply) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - // no validation rules for Id - - if len(errors) > 0 { - return AddExportReplyMultiError(errors) - } - - return nil -} - -// AddExportReplyMultiError is an error wrapping multiple validation errors -// returned by AddExportReply.ValidateAll() if the designated constraints -// aren't met. -type AddExportReplyMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AddExportReplyMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AddExportReplyMultiError) AllErrors() []error { return m } - -// AddExportReplyValidationError is the validation error returned by -// AddExportReply.Validate if the designated constraints aren't met. -type AddExportReplyValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AddExportReplyValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AddExportReplyValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AddExportReplyValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AddExportReplyValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AddExportReplyValidationError) ErrorName() string { return "AddExportReplyValidationError" } - -// Error satisfies the builtin error interface -func (e AddExportReplyValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAddExportReply.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AddExportReplyValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AddExportReplyValidationError{} - -// Validate checks the field values on AddExportExcelRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *AddExportExcelRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AddExportExcelRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AddExportExcelRequestMultiError, or nil if none found. -func (m *AddExportExcelRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *AddExportExcelRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if utf8.RuneCountInString(m.GetName()) < 1 { - err := AddExportExcelRequestValidationError{ - field: "Name", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if len(m.GetRows()) < 1 { - err := AddExportExcelRequestValidationError{ - field: "Rows", - reason: "value must contain at least 1 item(s)", - } - if !all { - return err - } - errors = append(errors, err) - } - - for idx, item := range m.GetRows() { - _, _ = idx, item - - if all { - switch v := interface{}(item).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, AddExportExcelRequestValidationError{ - field: fmt.Sprintf("Rows[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, AddExportExcelRequestValidationError{ - field: fmt.Sprintf("Rows[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return AddExportExcelRequestValidationError{ - field: fmt.Sprintf("Rows[%v]", idx), - reason: "embedded message failed validation", - cause: err, - } - } - } - - } - - if len(errors) > 0 { - return AddExportExcelRequestMultiError(errors) - } - - return nil -} - -// AddExportExcelRequestMultiError is an error wrapping multiple validation -// errors returned by AddExportExcelRequest.ValidateAll() if the designated -// constraints aren't met. -type AddExportExcelRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AddExportExcelRequestMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AddExportExcelRequestMultiError) AllErrors() []error { return m } - -// AddExportExcelRequestValidationError is the validation error returned by -// AddExportExcelRequest.Validate if the designated constraints aren't met. -type AddExportExcelRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AddExportExcelRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AddExportExcelRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AddExportExcelRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AddExportExcelRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AddExportExcelRequestValidationError) ErrorName() string { - return "AddExportExcelRequestValidationError" -} - -// Error satisfies the builtin error interface -func (e AddExportExcelRequestValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAddExportExcelRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AddExportExcelRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AddExportExcelRequestValidationError{} - -// Validate checks the field values on AddExportExcelReply with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *AddExportExcelReply) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AddExportExcelReply with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AddExportExcelReplyMultiError, or nil if none found. -func (m *AddExportExcelReply) ValidateAll() error { - return m.validate(true) -} - -func (m *AddExportExcelReply) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - // no validation rules for Id - - if len(errors) > 0 { - return AddExportExcelReplyMultiError(errors) - } - - return nil -} - -// AddExportExcelReplyMultiError is an error wrapping multiple validation -// errors returned by AddExportExcelReply.ValidateAll() if the designated -// constraints aren't met. -type AddExportExcelReplyMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AddExportExcelReplyMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AddExportExcelReplyMultiError) AllErrors() []error { return m } - -// AddExportExcelReplyValidationError is the validation error returned by -// AddExportExcelReply.Validate if the designated constraints aren't met. -type AddExportExcelReplyValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AddExportExcelReplyValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AddExportExcelReplyValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AddExportExcelReplyValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AddExportExcelReplyValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AddExportExcelReplyValidationError) ErrorName() string { - return "AddExportExcelReplyValidationError" -} - -// Error satisfies the builtin error interface -func (e AddExportExcelReplyValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAddExportExcelReply.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AddExportExcelReplyValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AddExportExcelReplyValidationError{} - -// Validate checks the field values on DeleteExportRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *DeleteExportRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on DeleteExportRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// DeleteExportRequestMultiError, or nil if none found. -func (m *DeleteExportRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *DeleteExportRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - // no validation rules for Id - - if len(errors) > 0 { - return DeleteExportRequestMultiError(errors) - } - - return nil -} - -// DeleteExportRequestMultiError is an error wrapping multiple validation -// errors returned by DeleteExportRequest.ValidateAll() if the designated -// constraints aren't met. -type DeleteExportRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m DeleteExportRequestMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m DeleteExportRequestMultiError) AllErrors() []error { return m } - -// DeleteExportRequestValidationError is the validation error returned by -// DeleteExportRequest.Validate if the designated constraints aren't met. -type DeleteExportRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e DeleteExportRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e DeleteExportRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e DeleteExportRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e DeleteExportRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e DeleteExportRequestValidationError) ErrorName() string { - return "DeleteExportRequestValidationError" -} - -// Error satisfies the builtin error interface -func (e DeleteExportRequestValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sDeleteExportRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = DeleteExportRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = DeleteExportRequestValidationError{} - -// Validate checks the field values on AddExportRequest_ExportFile with the -// rules defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *AddExportRequest_ExportFile) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AddExportRequest_ExportFile with the -// rules defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AddExportRequest_ExportFileMultiError, or nil if none found. -func (m *AddExportRequest_ExportFile) ValidateAll() error { - return m.validate(true) -} - -func (m *AddExportRequest_ExportFile) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - // no validation rules for Sha - - // no validation rules for Rename - - if len(errors) > 0 { - return AddExportRequest_ExportFileMultiError(errors) - } - - return nil -} - -// AddExportRequest_ExportFileMultiError is an error wrapping multiple -// validation errors returned by AddExportRequest_ExportFile.ValidateAll() if -// the designated constraints aren't met. -type AddExportRequest_ExportFileMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AddExportRequest_ExportFileMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AddExportRequest_ExportFileMultiError) AllErrors() []error { return m } - -// AddExportRequest_ExportFileValidationError is the validation error returned -// by AddExportRequest_ExportFile.Validate if the designated constraints -// aren't met. -type AddExportRequest_ExportFileValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AddExportRequest_ExportFileValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AddExportRequest_ExportFileValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AddExportRequest_ExportFileValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AddExportRequest_ExportFileValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AddExportRequest_ExportFileValidationError) ErrorName() string { - return "AddExportRequest_ExportFileValidationError" -} - -// Error satisfies the builtin error interface -func (e AddExportRequest_ExportFileValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAddExportRequest_ExportFile.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AddExportRequest_ExportFileValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AddExportRequest_ExportFileValidationError{} - -// Validate checks the field values on AddExportExcelRequest_Col with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *AddExportExcelRequest_Col) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AddExportExcelRequest_Col with the -// rules defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AddExportExcelRequest_ColMultiError, or nil if none found. -func (m *AddExportExcelRequest_Col) ValidateAll() error { - return m.validate(true) -} - -func (m *AddExportExcelRequest_Col) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if utf8.RuneCountInString(m.GetType()) < 1 { - err := AddExportExcelRequest_ColValidationError{ - field: "Type", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - // no validation rules for Value - - if len(errors) > 0 { - return AddExportExcelRequest_ColMultiError(errors) - } - - return nil -} - -// AddExportExcelRequest_ColMultiError is an error wrapping multiple validation -// errors returned by AddExportExcelRequest_Col.ValidateAll() if the -// designated constraints aren't met. -type AddExportExcelRequest_ColMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AddExportExcelRequest_ColMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AddExportExcelRequest_ColMultiError) AllErrors() []error { return m } - -// AddExportExcelRequest_ColValidationError is the validation error returned by -// AddExportExcelRequest_Col.Validate if the designated constraints aren't met. -type AddExportExcelRequest_ColValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AddExportExcelRequest_ColValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AddExportExcelRequest_ColValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AddExportExcelRequest_ColValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AddExportExcelRequest_ColValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AddExportExcelRequest_ColValidationError) ErrorName() string { - return "AddExportExcelRequest_ColValidationError" -} - -// Error satisfies the builtin error interface -func (e AddExportExcelRequest_ColValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAddExportExcelRequest_Col.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AddExportExcelRequest_ColValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AddExportExcelRequest_ColValidationError{} - -// Validate checks the field values on AddExportExcelRequest_Row with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *AddExportExcelRequest_Row) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AddExportExcelRequest_Row with the -// rules defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AddExportExcelRequest_RowMultiError, or nil if none found. -func (m *AddExportExcelRequest_Row) ValidateAll() error { - return m.validate(true) -} - -func (m *AddExportExcelRequest_Row) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - for idx, item := range m.GetCols() { - _, _ = idx, item - - if all { - switch v := interface{}(item).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, AddExportExcelRequest_RowValidationError{ - field: fmt.Sprintf("Cols[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, AddExportExcelRequest_RowValidationError{ - field: fmt.Sprintf("Cols[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return AddExportExcelRequest_RowValidationError{ - field: fmt.Sprintf("Cols[%v]", idx), - reason: "embedded message failed validation", - cause: err, - } - } - } - - } - - if len(errors) > 0 { - return AddExportExcelRequest_RowMultiError(errors) - } - - return nil -} - -// AddExportExcelRequest_RowMultiError is an error wrapping multiple validation -// errors returned by AddExportExcelRequest_Row.ValidateAll() if the -// designated constraints aren't met. -type AddExportExcelRequest_RowMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AddExportExcelRequest_RowMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AddExportExcelRequest_RowMultiError) AllErrors() []error { return m } - -// AddExportExcelRequest_RowValidationError is the validation error returned by -// AddExportExcelRequest_Row.Validate if the designated constraints aren't met. -type AddExportExcelRequest_RowValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AddExportExcelRequest_RowValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AddExportExcelRequest_RowValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AddExportExcelRequest_RowValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AddExportExcelRequest_RowValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AddExportExcelRequest_RowValidationError) ErrorName() string { - return "AddExportExcelRequest_RowValidationError" -} - -// Error satisfies the builtin error interface -func (e AddExportExcelRequest_RowValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAddExportExcelRequest_Row.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AddExportExcelRequest_RowValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AddExportExcelRequest_RowValidationError{} diff --git a/api/export/v1/resource_export_service.pb.go b/api/export/v1/resource_export_service.pb.go deleted file mode 100644 index 0daad5d..0000000 --- a/api/export/v1/resource_export_service.pb.go +++ /dev/null @@ -1,113 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.32.0 -// protoc v4.24.4 -// source: resource_export_service.proto - -package v1 - -import ( - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" - reflect "reflect" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -var File_resource_export_service_proto protoreflect.FileDescriptor - -var file_resource_export_service_proto_rawDesc = []byte{ - 0x0a, 0x1d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x15, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x65, 0x78, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x9e, 0x03, 0x0a, 0x07, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x0a, 0x50, 0x61, 0x67, 0x65, 0x45, 0x78, 0x70, - 0x6f, 0x72, 0x74, 0x12, 0x19, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x50, 0x61, 0x67, - 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, - 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x45, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, - 0x14, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x5d, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x12, 0x18, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x41, 0x64, 0x64, 0x45, - 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x65, - 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, - 0x13, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, - 0x70, 0x6f, 0x72, 0x74, 0x12, 0x72, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x45, 0x78, 0x63, 0x65, 0x6c, 0x12, 0x1d, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x41, 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x63, 0x65, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x41, - 0x64, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x2f, 0x65, 0x78, 0x63, 0x65, 0x6c, 0x12, 0x60, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x1b, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x2a, 0x13, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, - 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var file_resource_export_service_proto_goTypes = []interface{}{ - (*PageExportRequest)(nil), // 0: export.PageExportRequest - (*AddExportRequest)(nil), // 1: export.AddExportRequest - (*AddExportExcelRequest)(nil), // 2: export.AddExportExcelRequest - (*DeleteExportRequest)(nil), // 3: export.DeleteExportRequest - (*PageExportReply)(nil), // 4: export.PageExportReply - (*AddExportReply)(nil), // 5: export.AddExportReply - (*AddExportExcelReply)(nil), // 6: export.AddExportExcelReply - (*emptypb.Empty)(nil), // 7: google.protobuf.Empty -} -var file_resource_export_service_proto_depIdxs = []int32{ - 0, // 0: export.Service.PageExport:input_type -> export.PageExportRequest - 1, // 1: export.Service.AddExport:input_type -> export.AddExportRequest - 2, // 2: export.Service.AddExportExcel:input_type -> export.AddExportExcelRequest - 3, // 3: export.Service.DeleteExport:input_type -> export.DeleteExportRequest - 4, // 4: export.Service.PageExport:output_type -> export.PageExportReply - 5, // 5: export.Service.AddExport:output_type -> export.AddExportReply - 6, // 6: export.Service.AddExportExcel:output_type -> export.AddExportExcelReply - 7, // 7: export.Service.DeleteExport:output_type -> google.protobuf.Empty - 4, // [4:8] is the sub-list for method output_type - 0, // [0:4] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_resource_export_service_proto_init() } -func file_resource_export_service_proto_init() { - if File_resource_export_service_proto != nil { - return - } - file_resource_export_proto_init() - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_resource_export_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_resource_export_service_proto_goTypes, - DependencyIndexes: file_resource_export_service_proto_depIdxs, - }.Build() - File_resource_export_service_proto = out.File - file_resource_export_service_proto_rawDesc = nil - file_resource_export_service_proto_goTypes = nil - file_resource_export_service_proto_depIdxs = nil -} diff --git a/api/export/v1/resource_export_service.pb.validate.go b/api/export/v1/resource_export_service.pb.validate.go deleted file mode 100644 index 56fd243..0000000 --- a/api/export/v1/resource_export_service.pb.validate.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated by protoc-gen-validate. DO NOT EDIT. -// source: resource_export_service.proto - -package v1 - -import ( - "bytes" - "errors" - "fmt" - "net" - "net/mail" - "net/url" - "regexp" - "sort" - "strings" - "time" - "unicode/utf8" - - "google.golang.org/protobuf/types/known/anypb" -) - -// ensure the imports are used -var ( - _ = bytes.MinRead - _ = errors.New("") - _ = fmt.Print - _ = utf8.UTFMax - _ = (*regexp.Regexp)(nil) - _ = (*strings.Reader)(nil) - _ = net.IPv4len - _ = time.Duration(0) - _ = (*url.URL)(nil) - _ = (*mail.Address)(nil) - _ = anypb.Any{} - _ = sort.Sort -) diff --git a/api/export/v1/resource_export_service_grpc.pb.go b/api/export/v1/resource_export_service_grpc.pb.go deleted file mode 100644 index 2ada29a..0000000 --- a/api/export/v1/resource_export_service_grpc.pb.go +++ /dev/null @@ -1,221 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc v4.24.4 -// source: resource_export_service.proto - -package v1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -const ( - Service_PageExport_FullMethodName = "/export.Service/PageExport" - Service_AddExport_FullMethodName = "/export.Service/AddExport" - Service_AddExportExcel_FullMethodName = "/export.Service/AddExportExcel" - Service_DeleteExport_FullMethodName = "/export.Service/DeleteExport" -) - -// ServiceClient is the client API for Service 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 ServiceClient interface { - PageExport(ctx context.Context, in *PageExportRequest, opts ...grpc.CallOption) (*PageExportReply, error) - AddExport(ctx context.Context, in *AddExportRequest, opts ...grpc.CallOption) (*AddExportReply, error) - AddExportExcel(ctx context.Context, in *AddExportExcelRequest, opts ...grpc.CallOption) (*AddExportExcelReply, error) - DeleteExport(ctx context.Context, in *DeleteExportRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) -} - -type serviceClient struct { - cc grpc.ClientConnInterface -} - -func NewServiceClient(cc grpc.ClientConnInterface) ServiceClient { - return &serviceClient{cc} -} - -func (c *serviceClient) PageExport(ctx context.Context, in *PageExportRequest, opts ...grpc.CallOption) (*PageExportReply, error) { - out := new(PageExportReply) - err := c.cc.Invoke(ctx, Service_PageExport_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) AddExport(ctx context.Context, in *AddExportRequest, opts ...grpc.CallOption) (*AddExportReply, error) { - out := new(AddExportReply) - err := c.cc.Invoke(ctx, Service_AddExport_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) AddExportExcel(ctx context.Context, in *AddExportExcelRequest, opts ...grpc.CallOption) (*AddExportExcelReply, error) { - out := new(AddExportExcelReply) - err := c.cc.Invoke(ctx, Service_AddExportExcel_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) DeleteExport(ctx context.Context, in *DeleteExportRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Service_DeleteExport_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// ServiceServer is the server API for Service service. -// All implementations must embed UnimplementedServiceServer -// for forward compatibility -type ServiceServer interface { - PageExport(context.Context, *PageExportRequest) (*PageExportReply, error) - AddExport(context.Context, *AddExportRequest) (*AddExportReply, error) - AddExportExcel(context.Context, *AddExportExcelRequest) (*AddExportExcelReply, error) - DeleteExport(context.Context, *DeleteExportRequest) (*emptypb.Empty, error) - mustEmbedUnimplementedServiceServer() -} - -// UnimplementedServiceServer must be embedded to have forward compatible implementations. -type UnimplementedServiceServer struct { -} - -func (UnimplementedServiceServer) PageExport(context.Context, *PageExportRequest) (*PageExportReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method PageExport not implemented") -} -func (UnimplementedServiceServer) AddExport(context.Context, *AddExportRequest) (*AddExportReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddExport not implemented") -} -func (UnimplementedServiceServer) AddExportExcel(context.Context, *AddExportExcelRequest) (*AddExportExcelReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddExportExcel not implemented") -} -func (UnimplementedServiceServer) DeleteExport(context.Context, *DeleteExportRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteExport not implemented") -} -func (UnimplementedServiceServer) mustEmbedUnimplementedServiceServer() {} - -// UnsafeServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ServiceServer will -// result in compilation errors. -type UnsafeServiceServer interface { - mustEmbedUnimplementedServiceServer() -} - -func RegisterServiceServer(s grpc.ServiceRegistrar, srv ServiceServer) { - s.RegisterService(&Service_ServiceDesc, srv) -} - -func _Service_PageExport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PageExportRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).PageExport(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_PageExport_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).PageExport(ctx, req.(*PageExportRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_AddExport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddExportRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).AddExport(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_AddExport_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).AddExport(ctx, req.(*AddExportRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_AddExportExcel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddExportExcelRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).AddExportExcel(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_AddExportExcel_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).AddExportExcel(ctx, req.(*AddExportExcelRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_DeleteExport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteExportRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).DeleteExport(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_DeleteExport_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).DeleteExport(ctx, req.(*DeleteExportRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// Service_ServiceDesc is the grpc.ServiceDesc for Service service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Service_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "export.Service", - HandlerType: (*ServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "PageExport", - Handler: _Service_PageExport_Handler, - }, - { - MethodName: "AddExport", - Handler: _Service_AddExport_Handler, - }, - { - MethodName: "AddExportExcel", - Handler: _Service_AddExportExcel_Handler, - }, - { - MethodName: "DeleteExport", - Handler: _Service_DeleteExport_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "resource_export_service.proto", -} diff --git a/api/export/v1/resource_export_service_http.pb.go b/api/export/v1/resource_export_service_http.pb.go deleted file mode 100644 index 00d8248..0000000 --- a/api/export/v1/resource_export_service_http.pb.go +++ /dev/null @@ -1,190 +0,0 @@ -// Code generated by protoc-gen-go-http. DO NOT EDIT. -// versions: -// - protoc-gen-go-http v2.7.0 -// - protoc v4.24.4 -// source: resource_export_service.proto - -package v1 - -import ( - context "context" - http "github.com/go-kratos/kratos/v2/transport/http" - binding "github.com/go-kratos/kratos/v2/transport/http/binding" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the kratos package it is being compiled against. -var _ = new(context.Context) -var _ = binding.EncodeURL - -const _ = http.SupportPackageIsVersion1 - -const OperationServiceAddExport = "/export.Service/AddExport" -const OperationServiceAddExportExcel = "/export.Service/AddExportExcel" -const OperationServiceDeleteExport = "/export.Service/DeleteExport" -const OperationServicePageExport = "/export.Service/PageExport" - -type ServiceHTTPServer interface { - AddExport(context.Context, *AddExportRequest) (*AddExportReply, error) - AddExportExcel(context.Context, *AddExportExcelRequest) (*AddExportExcelReply, error) - DeleteExport(context.Context, *DeleteExportRequest) (*emptypb.Empty, error) - PageExport(context.Context, *PageExportRequest) (*PageExportReply, error) -} - -func RegisterServiceHTTPServer(s *http.Server, srv ServiceHTTPServer) { - r := s.Route("/") - r.GET("/resource/v1/exports", _Service_PageExport0_HTTP_Handler(srv)) - r.POST("/resource/v1/export", _Service_AddExport0_HTTP_Handler(srv)) - r.POST("/resource/v1/export/excel", _Service_AddExportExcel0_HTTP_Handler(srv)) - r.DELETE("/resource/v1/export", _Service_DeleteExport0_HTTP_Handler(srv)) -} - -func _Service_PageExport0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in PageExportRequest - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServicePageExport) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.PageExport(ctx, req.(*PageExportRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*PageExportReply) - return ctx.Result(200, reply) - } -} - -func _Service_AddExport0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in AddExportRequest - if err := ctx.Bind(&in); err != nil { - return err - } - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceAddExport) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.AddExport(ctx, req.(*AddExportRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*AddExportReply) - return ctx.Result(200, reply) - } -} - -func _Service_AddExportExcel0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in AddExportExcelRequest - if err := ctx.Bind(&in); err != nil { - return err - } - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceAddExportExcel) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.AddExportExcel(ctx, req.(*AddExportExcelRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*AddExportExcelReply) - return ctx.Result(200, reply) - } -} - -func _Service_DeleteExport0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in DeleteExportRequest - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceDeleteExport) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.DeleteExport(ctx, req.(*DeleteExportRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*emptypb.Empty) - return ctx.Result(200, reply) - } -} - -type ServiceHTTPClient interface { - AddExport(ctx context.Context, req *AddExportRequest, opts ...http.CallOption) (rsp *AddExportReply, err error) - AddExportExcel(ctx context.Context, req *AddExportExcelRequest, opts ...http.CallOption) (rsp *AddExportExcelReply, err error) - DeleteExport(ctx context.Context, req *DeleteExportRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) - PageExport(ctx context.Context, req *PageExportRequest, opts ...http.CallOption) (rsp *PageExportReply, err error) -} - -type ServiceHTTPClientImpl struct { - cc *http.Client -} - -func NewServiceHTTPClient(client *http.Client) ServiceHTTPClient { - return &ServiceHTTPClientImpl{client} -} - -func (c *ServiceHTTPClientImpl) AddExport(ctx context.Context, in *AddExportRequest, opts ...http.CallOption) (*AddExportReply, error) { - var out AddExportReply - pattern := "/resource/v1/export" - path := binding.EncodeURL(pattern, in, false) - opts = append(opts, http.Operation(OperationServiceAddExport)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) AddExportExcel(ctx context.Context, in *AddExportExcelRequest, opts ...http.CallOption) (*AddExportExcelReply, error) { - var out AddExportExcelReply - pattern := "/resource/v1/export/excel" - path := binding.EncodeURL(pattern, in, false) - opts = append(opts, http.Operation(OperationServiceAddExportExcel)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) DeleteExport(ctx context.Context, in *DeleteExportRequest, opts ...http.CallOption) (*emptypb.Empty, error) { - var out emptypb.Empty - pattern := "/resource/v1/export" - path := binding.EncodeURL(pattern, in, true) - opts = append(opts, http.Operation(OperationServiceDeleteExport)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) PageExport(ctx context.Context, in *PageExportRequest, opts ...http.CallOption) (*PageExportReply, error) { - var out PageExportReply - pattern := "/resource/v1/exports" - path := binding.EncodeURL(pattern, in, true) - opts = append(opts, http.Operation(OperationServicePageExport)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} diff --git a/api/file/resource_directory.proto b/api/file/resource_directory.proto deleted file mode 100644 index 379b6ea..0000000 --- a/api/file/resource_directory.proto +++ /dev/null @@ -1,41 +0,0 @@ -syntax = "proto3"; - -package file; -option go_package = "./v1;v1"; -import "google/api/annotations.proto"; -import "validate/validate.proto"; - -message Directory{ - uint32 id = 1; - optional uint32 parent_id = 2; - string app = 3; - string name = 4; - uint32 created_at = 5; - uint32 updated_at = 6; -} - -message AllDirectoryRequest{ - uint32 parent_id = 1; - string app = 2[(validate.rules).string = {min_len:0}]; -} - -message AllDirectoryReply{ - repeated Directory list = 1; -} - -message AddDirectoryRequest{ - uint32 parent_id = 1; - string name = 2[(validate.rules).string = {min_len:1}]; - string app = 3[(validate.rules).string = {min_len:1}]; -} - -message UpdateDirectoryRequest{ - uint32 id = 1[(validate.rules).uint32 = {gt:0}]; - string app = 2[(validate.rules).string = {min_len:1}]; - string name = 3[(validate.rules).string = {min_len:1}]; -} - -message DeleteDirectoryRequest{ - uint32 id = 1[(validate.rules).uint32 = {gt:0}]; - string app = 2[(validate.rules).string = {min_len:1}]; -} \ No newline at end of file diff --git a/api/file/resource_file.proto b/api/file/resource_file.proto deleted file mode 100644 index 3e3618e..0000000 --- a/api/file/resource_file.proto +++ /dev/null @@ -1,96 +0,0 @@ -syntax = "proto3"; - -package file; -option go_package = "./v1;v1"; -import "google/api/annotations.proto"; -import "validate/validate.proto"; - -message File{ - uint32 id = 11; - uint32 directory_id = 1; - string name = 2; - string type = 3; - uint32 size = 4; - string sha = 5; - string src = 6; - string storage = 9; - uint32 created_at = 10; -} - -message GetFileRequest{ - string src =1[(validate.rules).string = {min_len:1}]; - uint32 width =2; - uint32 height =3; - string mode = 4; - bool is_range = 5; - uint32 start = 6; - uint32 end = 7; - bool download = 8; - string save_name = 9; -} - -message GetFileReply{ - bytes data = 1; - string mime = 2; -} - -message GetFileByShaRequest{ - string sha = 5[(validate.rules).string = {min_len:1}]; -} - -message PrepareUploadFileRequest{ - uint32 directory_id = 1; - string directory_path = 2; - string app = 3[(validate.rules).string = {min_len:1}]; - string name = 4[(validate.rules).string = {min_len:1}]; - string sha = 5[(validate.rules).string = {min_len:1}]; - uint32 size = 6[(validate.rules).uint32 = {gt:0}]; -} - -message PrepareUploadFileReply{ - optional bool uploaded = 1; - optional string src = 2; - optional uint32 chunk_size = 3; - optional uint32 chunk_count = 4; - optional string upload_id = 5; - repeated uint32 upload_chunks = 6; - optional string sha = 7; -} - -message PageFileRequest{ - uint32 directory_id = 1[(validate.rules).uint32 = {gt:0}]; - string app = 2[(validate.rules).string = {min_len:1}]; - optional string name = 3; - uint32 page = 4[(validate.rules).uint32 = {gt:0}]; - uint32 page_size = 5[(validate.rules).uint32 = {gt:0,lte:100}]; -} - -message PageFileReply{ - repeated File list = 1; - optional uint32 total = 2; -} - - -message UpdateFileRequest{ - uint32 id = 1[(validate.rules).uint32 = {gt:0}]; - string app = 2[(validate.rules).string = {min_len:1}]; - string name = 3[(validate.rules).string = {min_len:1}]; - uint32 directory_id = 4[(validate.rules).uint32 = {gt:0}]; -} - -message DeleteFileRequest{ - repeated uint32 ids = 1[(validate.rules).repeated = {min_items:1}]; - string app = 2[(validate.rules).string = {min_len:1}]; - uint32 directory_id = 3[(validate.rules).uint32 = {gt:0}]; -} - -message UploadFileRequest{ - bytes data = 1[(validate.rules).bytes = {min_len:0}]; - string upload_id = 2[(validate.rules).string = {min_len:1}]; - uint32 index = 3[(validate.rules).uint32 = {gt:0}];; -} - -message UploadFileReply{ - string src = 1; - string sha = 2; -} diff --git a/api/file/resource_file_service.proto b/api/file/resource_file_service.proto deleted file mode 100644 index ae6c26f..0000000 --- a/api/file/resource_file_service.proto +++ /dev/null @@ -1,81 +0,0 @@ -syntax = "proto3"; - -package file; -option go_package = "./v1;v1"; - -import "google/api/annotations.proto"; -import "resource_file.proto"; -import "resource_directory.proto"; -import "google/protobuf/empty.proto"; - -service Service { - rpc AllDirectory (AllDirectoryRequest) returns (AllDirectoryReply) { - option (google.api.http) = { - get: "/resource/v1/directories", - }; - } - - rpc AddDirectory (AddDirectoryRequest) returns (Directory) { - option (google.api.http) = { - post: "/resource/v1/directory", - body:"*", - }; - } - - rpc UpdateDirectory (UpdateDirectoryRequest) returns (google.protobuf.Empty) { - option (google.api.http) = { - put: "/resource/v1/directory", - body:"*", - }; - } - - rpc DeleteDirectory (DeleteDirectoryRequest) returns (google.protobuf.Empty) { - option (google.api.http) = { - delete: "/resource/v1/directory", - }; - } - - rpc PrepareUploadFile (PrepareUploadFileRequest) returns (PrepareUploadFileReply) { - option (google.api.http) = { - post: "/resource/v1/upload/prepare", - body:"*", - additional_bindings:{ - post: "/resource/client/v1/upload/prepare", - body:"*", - } - }; - } - - rpc UploadFile(UploadFileRequest) returns (UploadFileReply){} - - rpc PageFile (PageFileRequest) returns (PageFileReply) { - option (google.api.http) = { - get: "/resource/v1/files" - }; - } - - rpc GetFileBySha (GetFileByShaRequest) returns (File) { - option (google.api.http) = { - get: "/resource/v1/file/sha", - additional_bindings:{ - get: "/resource/client/v1/file/sha", - } - }; - } - - rpc UpdateFile (UpdateFileRequest) returns (google.protobuf.Empty) { - option (google.api.http) = { - put: "/resource/v1/file", - body:"*" - }; - } - - rpc DeleteFile (DeleteFileRequest) returns (google.protobuf.Empty) { - option (google.api.http) = { - post: "/resource/v1/file", - body:"*" - }; - } -} - - diff --git a/api/file/v1/resource_directory.pb.go b/api/file/v1/resource_directory.pb.go deleted file mode 100644 index cb58806..0000000 --- a/api/file/v1/resource_directory.pb.go +++ /dev/null @@ -1,573 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.32.0 -// protoc v4.24.4 -// source: resource_directory.proto - -package v1 - -import ( - _ "github.com/envoyproxy/protoc-gen-validate/validate" - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Directory struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - ParentId *uint32 `protobuf:"varint,2,opt,name=parent_id,json=parentId,proto3,oneof" json:"parent_id,omitempty"` - App string `protobuf:"bytes,3,opt,name=app,proto3" json:"app,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - CreatedAt uint32 `protobuf:"varint,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - UpdatedAt uint32 `protobuf:"varint,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` -} - -func (x *Directory) Reset() { - *x = Directory{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_directory_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Directory) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Directory) ProtoMessage() {} - -func (x *Directory) ProtoReflect() protoreflect.Message { - mi := &file_resource_directory_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Directory.ProtoReflect.Descriptor instead. -func (*Directory) Descriptor() ([]byte, []int) { - return file_resource_directory_proto_rawDescGZIP(), []int{0} -} - -func (x *Directory) GetId() uint32 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *Directory) GetParentId() uint32 { - if x != nil && x.ParentId != nil { - return *x.ParentId - } - return 0 -} - -func (x *Directory) GetApp() string { - if x != nil { - return x.App - } - return "" -} - -func (x *Directory) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Directory) GetCreatedAt() uint32 { - if x != nil { - return x.CreatedAt - } - return 0 -} - -func (x *Directory) GetUpdatedAt() uint32 { - if x != nil { - return x.UpdatedAt - } - return 0 -} - -type AllDirectoryRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ParentId uint32 `protobuf:"varint,1,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"` - App string `protobuf:"bytes,2,opt,name=app,proto3" json:"app,omitempty"` -} - -func (x *AllDirectoryRequest) Reset() { - *x = AllDirectoryRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_directory_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AllDirectoryRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AllDirectoryRequest) ProtoMessage() {} - -func (x *AllDirectoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_directory_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AllDirectoryRequest.ProtoReflect.Descriptor instead. -func (*AllDirectoryRequest) Descriptor() ([]byte, []int) { - return file_resource_directory_proto_rawDescGZIP(), []int{1} -} - -func (x *AllDirectoryRequest) GetParentId() uint32 { - if x != nil { - return x.ParentId - } - return 0 -} - -func (x *AllDirectoryRequest) GetApp() string { - if x != nil { - return x.App - } - return "" -} - -type AllDirectoryReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - List []*Directory `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` -} - -func (x *AllDirectoryReply) Reset() { - *x = AllDirectoryReply{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_directory_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AllDirectoryReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AllDirectoryReply) ProtoMessage() {} - -func (x *AllDirectoryReply) ProtoReflect() protoreflect.Message { - mi := &file_resource_directory_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AllDirectoryReply.ProtoReflect.Descriptor instead. -func (*AllDirectoryReply) Descriptor() ([]byte, []int) { - return file_resource_directory_proto_rawDescGZIP(), []int{2} -} - -func (x *AllDirectoryReply) GetList() []*Directory { - if x != nil { - return x.List - } - return nil -} - -type AddDirectoryRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ParentId uint32 `protobuf:"varint,1,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - App string `protobuf:"bytes,3,opt,name=app,proto3" json:"app,omitempty"` -} - -func (x *AddDirectoryRequest) Reset() { - *x = AddDirectoryRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_directory_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddDirectoryRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddDirectoryRequest) ProtoMessage() {} - -func (x *AddDirectoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_directory_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddDirectoryRequest.ProtoReflect.Descriptor instead. -func (*AddDirectoryRequest) Descriptor() ([]byte, []int) { - return file_resource_directory_proto_rawDescGZIP(), []int{3} -} - -func (x *AddDirectoryRequest) GetParentId() uint32 { - if x != nil { - return x.ParentId - } - return 0 -} - -func (x *AddDirectoryRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *AddDirectoryRequest) GetApp() string { - if x != nil { - return x.App - } - return "" -} - -type UpdateDirectoryRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - App string `protobuf:"bytes,2,opt,name=app,proto3" json:"app,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *UpdateDirectoryRequest) Reset() { - *x = UpdateDirectoryRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_directory_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateDirectoryRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateDirectoryRequest) ProtoMessage() {} - -func (x *UpdateDirectoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_directory_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateDirectoryRequest.ProtoReflect.Descriptor instead. -func (*UpdateDirectoryRequest) Descriptor() ([]byte, []int) { - return file_resource_directory_proto_rawDescGZIP(), []int{4} -} - -func (x *UpdateDirectoryRequest) GetId() uint32 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *UpdateDirectoryRequest) GetApp() string { - if x != nil { - return x.App - } - return "" -} - -func (x *UpdateDirectoryRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type DeleteDirectoryRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - App string `protobuf:"bytes,2,opt,name=app,proto3" json:"app,omitempty"` -} - -func (x *DeleteDirectoryRequest) Reset() { - *x = DeleteDirectoryRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_directory_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteDirectoryRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteDirectoryRequest) ProtoMessage() {} - -func (x *DeleteDirectoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_directory_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteDirectoryRequest.ProtoReflect.Descriptor instead. -func (*DeleteDirectoryRequest) Descriptor() ([]byte, []int) { - return file_resource_directory_proto_rawDescGZIP(), []int{5} -} - -func (x *DeleteDirectoryRequest) GetId() uint32 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *DeleteDirectoryRequest) GetApp() string { - if x != nil { - return x.App - } - return "" -} - -var File_resource_directory_proto protoreflect.FileDescriptor - -var file_resource_directory_proto_rawDesc = []byte{ - 0x0a, 0x18, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x66, 0x69, 0x6c, 0x65, - 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaf, 0x01, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x70, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x4d, 0x0a, 0x13, 0x41, 0x6c, 0x6c, - 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, - 0x03, 0x61, 0x70, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, - 0x02, 0x10, 0x00, 0x52, 0x03, 0x61, 0x70, 0x70, 0x22, 0x38, 0x0a, 0x11, 0x41, 0x6c, 0x6c, 0x44, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x23, 0x0a, - 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x66, 0x69, - 0x6c, 0x65, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x04, 0x6c, 0x69, - 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x61, 0x70, 0x70, 0x22, 0x69, - 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x19, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x61, 0x70, 0x70, 0x12, 0x1b, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, - 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x4c, 0x0a, 0x16, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, - 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x03, - 0x61, 0x70, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, - 0x10, 0x01, 0x52, 0x03, 0x61, 0x70, 0x70, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x76, 0x31, 0x3b, - 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_resource_directory_proto_rawDescOnce sync.Once - file_resource_directory_proto_rawDescData = file_resource_directory_proto_rawDesc -) - -func file_resource_directory_proto_rawDescGZIP() []byte { - file_resource_directory_proto_rawDescOnce.Do(func() { - file_resource_directory_proto_rawDescData = protoimpl.X.CompressGZIP(file_resource_directory_proto_rawDescData) - }) - return file_resource_directory_proto_rawDescData -} - -var file_resource_directory_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_resource_directory_proto_goTypes = []interface{}{ - (*Directory)(nil), // 0: file.Directory - (*AllDirectoryRequest)(nil), // 1: file.AllDirectoryRequest - (*AllDirectoryReply)(nil), // 2: file.AllDirectoryReply - (*AddDirectoryRequest)(nil), // 3: file.AddDirectoryRequest - (*UpdateDirectoryRequest)(nil), // 4: file.UpdateDirectoryRequest - (*DeleteDirectoryRequest)(nil), // 5: file.DeleteDirectoryRequest -} -var file_resource_directory_proto_depIdxs = []int32{ - 0, // 0: file.AllDirectoryReply.list:type_name -> file.Directory - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_resource_directory_proto_init() } -func file_resource_directory_proto_init() { - if File_resource_directory_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_resource_directory_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Directory); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_directory_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AllDirectoryRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_directory_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AllDirectoryReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_directory_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddDirectoryRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_directory_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateDirectoryRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_directory_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteDirectoryRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_resource_directory_proto_msgTypes[0].OneofWrappers = []interface{}{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_resource_directory_proto_rawDesc, - NumEnums: 0, - NumMessages: 6, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_resource_directory_proto_goTypes, - DependencyIndexes: file_resource_directory_proto_depIdxs, - MessageInfos: file_resource_directory_proto_msgTypes, - }.Build() - File_resource_directory_proto = out.File - file_resource_directory_proto_rawDesc = nil - file_resource_directory_proto_goTypes = nil - file_resource_directory_proto_depIdxs = nil -} diff --git a/api/file/v1/resource_directory.pb.validate.go b/api/file/v1/resource_directory.pb.validate.go deleted file mode 100644 index a3572b6..0000000 --- a/api/file/v1/resource_directory.pb.validate.go +++ /dev/null @@ -1,785 +0,0 @@ -// Code generated by protoc-gen-validate. DO NOT EDIT. -// source: resource_directory.proto - -package v1 - -import ( - "bytes" - "errors" - "fmt" - "net" - "net/mail" - "net/url" - "regexp" - "sort" - "strings" - "time" - "unicode/utf8" - - "google.golang.org/protobuf/types/known/anypb" -) - -// ensure the imports are used -var ( - _ = bytes.MinRead - _ = errors.New("") - _ = fmt.Print - _ = utf8.UTFMax - _ = (*regexp.Regexp)(nil) - _ = (*strings.Reader)(nil) - _ = net.IPv4len - _ = time.Duration(0) - _ = (*url.URL)(nil) - _ = (*mail.Address)(nil) - _ = anypb.Any{} - _ = sort.Sort -) - -// Validate checks the field values on Directory with the rules defined in the -// proto definition for this message. If any rules are violated, the first -// error encountered is returned, or nil if there are no violations. -func (m *Directory) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on Directory with the rules defined in -// the proto definition for this message. If any rules are violated, the -// result is a list of violation errors wrapped in DirectoryMultiError, or nil -// if none found. -func (m *Directory) ValidateAll() error { - return m.validate(true) -} - -func (m *Directory) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - // no validation rules for Id - - // no validation rules for App - - // no validation rules for Name - - // no validation rules for CreatedAt - - // no validation rules for UpdatedAt - - if m.ParentId != nil { - // no validation rules for ParentId - } - - if len(errors) > 0 { - return DirectoryMultiError(errors) - } - - return nil -} - -// DirectoryMultiError is an error wrapping multiple validation errors returned -// by Directory.ValidateAll() if the designated constraints aren't met. -type DirectoryMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m DirectoryMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m DirectoryMultiError) AllErrors() []error { return m } - -// DirectoryValidationError is the validation error returned by -// Directory.Validate if the designated constraints aren't met. -type DirectoryValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e DirectoryValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e DirectoryValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e DirectoryValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e DirectoryValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e DirectoryValidationError) ErrorName() string { return "DirectoryValidationError" } - -// Error satisfies the builtin error interface -func (e DirectoryValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sDirectory.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = DirectoryValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = DirectoryValidationError{} - -// Validate checks the field values on AllDirectoryRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *AllDirectoryRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AllDirectoryRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AllDirectoryRequestMultiError, or nil if none found. -func (m *AllDirectoryRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *AllDirectoryRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - // no validation rules for ParentId - - if utf8.RuneCountInString(m.GetApp()) < 0 { - err := AllDirectoryRequestValidationError{ - field: "App", - reason: "value length must be at least 0 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if len(errors) > 0 { - return AllDirectoryRequestMultiError(errors) - } - - return nil -} - -// AllDirectoryRequestMultiError is an error wrapping multiple validation -// errors returned by AllDirectoryRequest.ValidateAll() if the designated -// constraints aren't met. -type AllDirectoryRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AllDirectoryRequestMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AllDirectoryRequestMultiError) AllErrors() []error { return m } - -// AllDirectoryRequestValidationError is the validation error returned by -// AllDirectoryRequest.Validate if the designated constraints aren't met. -type AllDirectoryRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AllDirectoryRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AllDirectoryRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AllDirectoryRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AllDirectoryRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AllDirectoryRequestValidationError) ErrorName() string { - return "AllDirectoryRequestValidationError" -} - -// Error satisfies the builtin error interface -func (e AllDirectoryRequestValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAllDirectoryRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AllDirectoryRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AllDirectoryRequestValidationError{} - -// Validate checks the field values on AllDirectoryReply with the rules defined -// in the proto definition for this message. If any rules are violated, the -// first error encountered is returned, or nil if there are no violations. -func (m *AllDirectoryReply) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AllDirectoryReply with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AllDirectoryReplyMultiError, or nil if none found. -func (m *AllDirectoryReply) ValidateAll() error { - return m.validate(true) -} - -func (m *AllDirectoryReply) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - for idx, item := range m.GetList() { - _, _ = idx, item - - if all { - switch v := interface{}(item).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, AllDirectoryReplyValidationError{ - field: fmt.Sprintf("List[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, AllDirectoryReplyValidationError{ - field: fmt.Sprintf("List[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return AllDirectoryReplyValidationError{ - field: fmt.Sprintf("List[%v]", idx), - reason: "embedded message failed validation", - cause: err, - } - } - } - - } - - if len(errors) > 0 { - return AllDirectoryReplyMultiError(errors) - } - - return nil -} - -// AllDirectoryReplyMultiError is an error wrapping multiple validation errors -// returned by AllDirectoryReply.ValidateAll() if the designated constraints -// aren't met. -type AllDirectoryReplyMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AllDirectoryReplyMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AllDirectoryReplyMultiError) AllErrors() []error { return m } - -// AllDirectoryReplyValidationError is the validation error returned by -// AllDirectoryReply.Validate if the designated constraints aren't met. -type AllDirectoryReplyValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AllDirectoryReplyValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AllDirectoryReplyValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AllDirectoryReplyValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AllDirectoryReplyValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AllDirectoryReplyValidationError) ErrorName() string { - return "AllDirectoryReplyValidationError" -} - -// Error satisfies the builtin error interface -func (e AllDirectoryReplyValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAllDirectoryReply.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AllDirectoryReplyValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AllDirectoryReplyValidationError{} - -// Validate checks the field values on AddDirectoryRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *AddDirectoryRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AddDirectoryRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AddDirectoryRequestMultiError, or nil if none found. -func (m *AddDirectoryRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *AddDirectoryRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - // no validation rules for ParentId - - if utf8.RuneCountInString(m.GetName()) < 1 { - err := AddDirectoryRequestValidationError{ - field: "Name", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if utf8.RuneCountInString(m.GetApp()) < 1 { - err := AddDirectoryRequestValidationError{ - field: "App", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if len(errors) > 0 { - return AddDirectoryRequestMultiError(errors) - } - - return nil -} - -// AddDirectoryRequestMultiError is an error wrapping multiple validation -// errors returned by AddDirectoryRequest.ValidateAll() if the designated -// constraints aren't met. -type AddDirectoryRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AddDirectoryRequestMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AddDirectoryRequestMultiError) AllErrors() []error { return m } - -// AddDirectoryRequestValidationError is the validation error returned by -// AddDirectoryRequest.Validate if the designated constraints aren't met. -type AddDirectoryRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AddDirectoryRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AddDirectoryRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AddDirectoryRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AddDirectoryRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AddDirectoryRequestValidationError) ErrorName() string { - return "AddDirectoryRequestValidationError" -} - -// Error satisfies the builtin error interface -func (e AddDirectoryRequestValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAddDirectoryRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AddDirectoryRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AddDirectoryRequestValidationError{} - -// Validate checks the field values on UpdateDirectoryRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *UpdateDirectoryRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on UpdateDirectoryRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// UpdateDirectoryRequestMultiError, or nil if none found. -func (m *UpdateDirectoryRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *UpdateDirectoryRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if m.GetId() <= 0 { - err := UpdateDirectoryRequestValidationError{ - field: "Id", - reason: "value must be greater than 0", - } - if !all { - return err - } - errors = append(errors, err) - } - - if utf8.RuneCountInString(m.GetApp()) < 1 { - err := UpdateDirectoryRequestValidationError{ - field: "App", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if utf8.RuneCountInString(m.GetName()) < 1 { - err := UpdateDirectoryRequestValidationError{ - field: "Name", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if len(errors) > 0 { - return UpdateDirectoryRequestMultiError(errors) - } - - return nil -} - -// UpdateDirectoryRequestMultiError is an error wrapping multiple validation -// errors returned by UpdateDirectoryRequest.ValidateAll() if the designated -// constraints aren't met. -type UpdateDirectoryRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m UpdateDirectoryRequestMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m UpdateDirectoryRequestMultiError) AllErrors() []error { return m } - -// UpdateDirectoryRequestValidationError is the validation error returned by -// UpdateDirectoryRequest.Validate if the designated constraints aren't met. -type UpdateDirectoryRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e UpdateDirectoryRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e UpdateDirectoryRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e UpdateDirectoryRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e UpdateDirectoryRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e UpdateDirectoryRequestValidationError) ErrorName() string { - return "UpdateDirectoryRequestValidationError" -} - -// Error satisfies the builtin error interface -func (e UpdateDirectoryRequestValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sUpdateDirectoryRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = UpdateDirectoryRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = UpdateDirectoryRequestValidationError{} - -// Validate checks the field values on DeleteDirectoryRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *DeleteDirectoryRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on DeleteDirectoryRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// DeleteDirectoryRequestMultiError, or nil if none found. -func (m *DeleteDirectoryRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *DeleteDirectoryRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if m.GetId() <= 0 { - err := DeleteDirectoryRequestValidationError{ - field: "Id", - reason: "value must be greater than 0", - } - if !all { - return err - } - errors = append(errors, err) - } - - if utf8.RuneCountInString(m.GetApp()) < 1 { - err := DeleteDirectoryRequestValidationError{ - field: "App", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if len(errors) > 0 { - return DeleteDirectoryRequestMultiError(errors) - } - - return nil -} - -// DeleteDirectoryRequestMultiError is an error wrapping multiple validation -// errors returned by DeleteDirectoryRequest.ValidateAll() if the designated -// constraints aren't met. -type DeleteDirectoryRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m DeleteDirectoryRequestMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m DeleteDirectoryRequestMultiError) AllErrors() []error { return m } - -// DeleteDirectoryRequestValidationError is the validation error returned by -// DeleteDirectoryRequest.Validate if the designated constraints aren't met. -type DeleteDirectoryRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e DeleteDirectoryRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e DeleteDirectoryRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e DeleteDirectoryRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e DeleteDirectoryRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e DeleteDirectoryRequestValidationError) ErrorName() string { - return "DeleteDirectoryRequestValidationError" -} - -// Error satisfies the builtin error interface -func (e DeleteDirectoryRequestValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sDeleteDirectoryRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = DeleteDirectoryRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = DeleteDirectoryRequestValidationError{} diff --git a/api/file/v1/resource_file.pb.go b/api/file/v1/resource_file.pb.go deleted file mode 100644 index d9c042d..0000000 --- a/api/file/v1/resource_file.pb.go +++ /dev/null @@ -1,1250 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.32.0 -// protoc v4.24.4 -// source: resource_file.proto - -package v1 - -import ( - _ "github.com/envoyproxy/protoc-gen-validate/validate" - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type File struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint32 `protobuf:"varint,11,opt,name=id,proto3" json:"id,omitempty"` - DirectoryId uint32 `protobuf:"varint,1,opt,name=directory_id,json=directoryId,proto3" json:"directory_id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` - Size uint32 `protobuf:"varint,4,opt,name=size,proto3" json:"size,omitempty"` - Sha string `protobuf:"bytes,5,opt,name=sha,proto3" json:"sha,omitempty"` - Src string `protobuf:"bytes,6,opt,name=src,proto3" json:"src,omitempty"` - Storage string `protobuf:"bytes,9,opt,name=storage,proto3" json:"storage,omitempty"` - CreatedAt uint32 `protobuf:"varint,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` -} - -func (x *File) Reset() { - *x = File{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *File) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*File) ProtoMessage() {} - -func (x *File) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use File.ProtoReflect.Descriptor instead. -func (*File) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{0} -} - -func (x *File) GetId() uint32 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *File) GetDirectoryId() uint32 { - if x != nil { - return x.DirectoryId - } - return 0 -} - -func (x *File) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *File) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *File) GetSize() uint32 { - if x != nil { - return x.Size - } - return 0 -} - -func (x *File) GetSha() string { - if x != nil { - return x.Sha - } - return "" -} - -func (x *File) GetSrc() string { - if x != nil { - return x.Src - } - return "" -} - -func (x *File) GetStorage() string { - if x != nil { - return x.Storage - } - return "" -} - -func (x *File) GetCreatedAt() uint32 { - if x != nil { - return x.CreatedAt - } - return 0 -} - -type GetFileRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Src string `protobuf:"bytes,1,opt,name=src,proto3" json:"src,omitempty"` - Width uint32 `protobuf:"varint,2,opt,name=width,proto3" json:"width,omitempty"` - Height uint32 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"` - Mode string `protobuf:"bytes,4,opt,name=mode,proto3" json:"mode,omitempty"` - IsRange bool `protobuf:"varint,5,opt,name=is_range,json=isRange,proto3" json:"is_range,omitempty"` - Start uint32 `protobuf:"varint,6,opt,name=start,proto3" json:"start,omitempty"` - End uint32 `protobuf:"varint,7,opt,name=end,proto3" json:"end,omitempty"` - Download bool `protobuf:"varint,8,opt,name=download,proto3" json:"download,omitempty"` - SaveName string `protobuf:"bytes,9,opt,name=save_name,json=saveName,proto3" json:"save_name,omitempty"` -} - -func (x *GetFileRequest) Reset() { - *x = GetFileRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetFileRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetFileRequest) ProtoMessage() {} - -func (x *GetFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetFileRequest.ProtoReflect.Descriptor instead. -func (*GetFileRequest) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{1} -} - -func (x *GetFileRequest) GetSrc() string { - if x != nil { - return x.Src - } - return "" -} - -func (x *GetFileRequest) GetWidth() uint32 { - if x != nil { - return x.Width - } - return 0 -} - -func (x *GetFileRequest) GetHeight() uint32 { - if x != nil { - return x.Height - } - return 0 -} - -func (x *GetFileRequest) GetMode() string { - if x != nil { - return x.Mode - } - return "" -} - -func (x *GetFileRequest) GetIsRange() bool { - if x != nil { - return x.IsRange - } - return false -} - -func (x *GetFileRequest) GetStart() uint32 { - if x != nil { - return x.Start - } - return 0 -} - -func (x *GetFileRequest) GetEnd() uint32 { - if x != nil { - return x.End - } - return 0 -} - -func (x *GetFileRequest) GetDownload() bool { - if x != nil { - return x.Download - } - return false -} - -func (x *GetFileRequest) GetSaveName() string { - if x != nil { - return x.SaveName - } - return "" -} - -type GetFileReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` - Mime string `protobuf:"bytes,2,opt,name=mime,proto3" json:"mime,omitempty"` -} - -func (x *GetFileReply) Reset() { - *x = GetFileReply{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetFileReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetFileReply) ProtoMessage() {} - -func (x *GetFileReply) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetFileReply.ProtoReflect.Descriptor instead. -func (*GetFileReply) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{2} -} - -func (x *GetFileReply) GetData() []byte { - if x != nil { - return x.Data - } - return nil -} - -func (x *GetFileReply) GetMime() string { - if x != nil { - return x.Mime - } - return "" -} - -type GetFileByShaRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Sha string `protobuf:"bytes,5,opt,name=sha,proto3" json:"sha,omitempty"` -} - -func (x *GetFileByShaRequest) Reset() { - *x = GetFileByShaRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetFileByShaRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetFileByShaRequest) ProtoMessage() {} - -func (x *GetFileByShaRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetFileByShaRequest.ProtoReflect.Descriptor instead. -func (*GetFileByShaRequest) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{3} -} - -func (x *GetFileByShaRequest) GetSha() string { - if x != nil { - return x.Sha - } - return "" -} - -type PrepareUploadFileRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DirectoryId uint32 `protobuf:"varint,1,opt,name=directory_id,json=directoryId,proto3" json:"directory_id,omitempty"` - DirectoryPath string `protobuf:"bytes,2,opt,name=directory_path,json=directoryPath,proto3" json:"directory_path,omitempty"` - App string `protobuf:"bytes,3,opt,name=app,proto3" json:"app,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - Sha string `protobuf:"bytes,5,opt,name=sha,proto3" json:"sha,omitempty"` - Size uint32 `protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"` -} - -func (x *PrepareUploadFileRequest) Reset() { - *x = PrepareUploadFileRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PrepareUploadFileRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PrepareUploadFileRequest) ProtoMessage() {} - -func (x *PrepareUploadFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PrepareUploadFileRequest.ProtoReflect.Descriptor instead. -func (*PrepareUploadFileRequest) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{4} -} - -func (x *PrepareUploadFileRequest) GetDirectoryId() uint32 { - if x != nil { - return x.DirectoryId - } - return 0 -} - -func (x *PrepareUploadFileRequest) GetDirectoryPath() string { - if x != nil { - return x.DirectoryPath - } - return "" -} - -func (x *PrepareUploadFileRequest) GetApp() string { - if x != nil { - return x.App - } - return "" -} - -func (x *PrepareUploadFileRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *PrepareUploadFileRequest) GetSha() string { - if x != nil { - return x.Sha - } - return "" -} - -func (x *PrepareUploadFileRequest) GetSize() uint32 { - if x != nil { - return x.Size - } - return 0 -} - -type PrepareUploadFileReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Uploaded *bool `protobuf:"varint,1,opt,name=uploaded,proto3,oneof" json:"uploaded,omitempty"` - Src *string `protobuf:"bytes,2,opt,name=src,proto3,oneof" json:"src,omitempty"` - ChunkSize *uint32 `protobuf:"varint,3,opt,name=chunk_size,json=chunkSize,proto3,oneof" json:"chunk_size,omitempty"` - ChunkCount *uint32 `protobuf:"varint,4,opt,name=chunk_count,json=chunkCount,proto3,oneof" json:"chunk_count,omitempty"` - UploadId *string `protobuf:"bytes,5,opt,name=upload_id,json=uploadId,proto3,oneof" json:"upload_id,omitempty"` - UploadChunks []uint32 `protobuf:"varint,6,rep,packed,name=upload_chunks,json=uploadChunks,proto3" json:"upload_chunks,omitempty"` - Sha *string `protobuf:"bytes,7,opt,name=sha,proto3,oneof" json:"sha,omitempty"` -} - -func (x *PrepareUploadFileReply) Reset() { - *x = PrepareUploadFileReply{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PrepareUploadFileReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PrepareUploadFileReply) ProtoMessage() {} - -func (x *PrepareUploadFileReply) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PrepareUploadFileReply.ProtoReflect.Descriptor instead. -func (*PrepareUploadFileReply) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{5} -} - -func (x *PrepareUploadFileReply) GetUploaded() bool { - if x != nil && x.Uploaded != nil { - return *x.Uploaded - } - return false -} - -func (x *PrepareUploadFileReply) GetSrc() string { - if x != nil && x.Src != nil { - return *x.Src - } - return "" -} - -func (x *PrepareUploadFileReply) GetChunkSize() uint32 { - if x != nil && x.ChunkSize != nil { - return *x.ChunkSize - } - return 0 -} - -func (x *PrepareUploadFileReply) GetChunkCount() uint32 { - if x != nil && x.ChunkCount != nil { - return *x.ChunkCount - } - return 0 -} - -func (x *PrepareUploadFileReply) GetUploadId() string { - if x != nil && x.UploadId != nil { - return *x.UploadId - } - return "" -} - -func (x *PrepareUploadFileReply) GetUploadChunks() []uint32 { - if x != nil { - return x.UploadChunks - } - return nil -} - -func (x *PrepareUploadFileReply) GetSha() string { - if x != nil && x.Sha != nil { - return *x.Sha - } - return "" -} - -type PageFileRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DirectoryId uint32 `protobuf:"varint,1,opt,name=directory_id,json=directoryId,proto3" json:"directory_id,omitempty"` - App string `protobuf:"bytes,2,opt,name=app,proto3" json:"app,omitempty"` - Name *string `protobuf:"bytes,3,opt,name=name,proto3,oneof" json:"name,omitempty"` - Page uint32 `protobuf:"varint,4,opt,name=page,proto3" json:"page,omitempty"` - PageSize uint32 `protobuf:"varint,5,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` -} - -func (x *PageFileRequest) Reset() { - *x = PageFileRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PageFileRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PageFileRequest) ProtoMessage() {} - -func (x *PageFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PageFileRequest.ProtoReflect.Descriptor instead. -func (*PageFileRequest) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{6} -} - -func (x *PageFileRequest) GetDirectoryId() uint32 { - if x != nil { - return x.DirectoryId - } - return 0 -} - -func (x *PageFileRequest) GetApp() string { - if x != nil { - return x.App - } - return "" -} - -func (x *PageFileRequest) GetName() string { - if x != nil && x.Name != nil { - return *x.Name - } - return "" -} - -func (x *PageFileRequest) GetPage() uint32 { - if x != nil { - return x.Page - } - return 0 -} - -func (x *PageFileRequest) GetPageSize() uint32 { - if x != nil { - return x.PageSize - } - return 0 -} - -type PageFileReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - List []*File `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` - Total *uint32 `protobuf:"varint,2,opt,name=total,proto3,oneof" json:"total,omitempty"` -} - -func (x *PageFileReply) Reset() { - *x = PageFileReply{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PageFileReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PageFileReply) ProtoMessage() {} - -func (x *PageFileReply) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PageFileReply.ProtoReflect.Descriptor instead. -func (*PageFileReply) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{7} -} - -func (x *PageFileReply) GetList() []*File { - if x != nil { - return x.List - } - return nil -} - -func (x *PageFileReply) GetTotal() uint32 { - if x != nil && x.Total != nil { - return *x.Total - } - return 0 -} - -type UpdateFileRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - App string `protobuf:"bytes,2,opt,name=app,proto3" json:"app,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - DirectoryId uint32 `protobuf:"varint,4,opt,name=directory_id,json=directoryId,proto3" json:"directory_id,omitempty"` -} - -func (x *UpdateFileRequest) Reset() { - *x = UpdateFileRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateFileRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateFileRequest) ProtoMessage() {} - -func (x *UpdateFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateFileRequest.ProtoReflect.Descriptor instead. -func (*UpdateFileRequest) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{8} -} - -func (x *UpdateFileRequest) GetId() uint32 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *UpdateFileRequest) GetApp() string { - if x != nil { - return x.App - } - return "" -} - -func (x *UpdateFileRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *UpdateFileRequest) GetDirectoryId() uint32 { - if x != nil { - return x.DirectoryId - } - return 0 -} - -type DeleteFileRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ids []uint32 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids,omitempty"` - App string `protobuf:"bytes,2,opt,name=app,proto3" json:"app,omitempty"` - DirectoryId uint32 `protobuf:"varint,3,opt,name=directory_id,json=directoryId,proto3" json:"directory_id,omitempty"` -} - -func (x *DeleteFileRequest) Reset() { - *x = DeleteFileRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteFileRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteFileRequest) ProtoMessage() {} - -func (x *DeleteFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteFileRequest.ProtoReflect.Descriptor instead. -func (*DeleteFileRequest) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{9} -} - -func (x *DeleteFileRequest) GetIds() []uint32 { - if x != nil { - return x.Ids - } - return nil -} - -func (x *DeleteFileRequest) GetApp() string { - if x != nil { - return x.App - } - return "" -} - -func (x *DeleteFileRequest) GetDirectoryId() uint32 { - if x != nil { - return x.DirectoryId - } - return 0 -} - -type UploadFileRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` - UploadId string `protobuf:"bytes,2,opt,name=upload_id,json=uploadId,proto3" json:"upload_id,omitempty"` - Index uint32 `protobuf:"varint,3,opt,name=index,proto3" json:"index,omitempty"` -} - -func (x *UploadFileRequest) Reset() { - *x = UploadFileRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UploadFileRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UploadFileRequest) ProtoMessage() {} - -func (x *UploadFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UploadFileRequest.ProtoReflect.Descriptor instead. -func (*UploadFileRequest) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{10} -} - -func (x *UploadFileRequest) GetData() []byte { - if x != nil { - return x.Data - } - return nil -} - -func (x *UploadFileRequest) GetUploadId() string { - if x != nil { - return x.UploadId - } - return "" -} - -func (x *UploadFileRequest) GetIndex() uint32 { - if x != nil { - return x.Index - } - return 0 -} - -type UploadFileReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Src string `protobuf:"bytes,1,opt,name=src,proto3" json:"src,omitempty"` - Sha string `protobuf:"bytes,2,opt,name=sha,proto3" json:"sha,omitempty"` -} - -func (x *UploadFileReply) Reset() { - *x = UploadFileReply{} - if protoimpl.UnsafeEnabled { - mi := &file_resource_file_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UploadFileReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UploadFileReply) ProtoMessage() {} - -func (x *UploadFileReply) ProtoReflect() protoreflect.Message { - mi := &file_resource_file_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UploadFileReply.ProtoReflect.Descriptor instead. -func (*UploadFileReply) Descriptor() ([]byte, []int) { - return file_resource_file_proto_rawDescGZIP(), []int{11} -} - -func (x *UploadFileReply) GetSrc() string { - if x != nil { - return x.Src - } - return "" -} - -func (x *UploadFileReply) GetSha() string { - if x != nil { - return x.Sha - } - return "" -} - -var File_resource_file_proto protoreflect.FileDescriptor - -var file_resource_file_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xd2, 0x01, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x68, - 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x68, 0x61, 0x12, 0x10, 0x0a, 0x03, - 0x73, 0x72, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xe9, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x46, - 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x03, 0x73, 0x72, - 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x72, 0x61, - 0x6e, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x52, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x6f, - 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x6f, - 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x61, 0x76, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x61, 0x76, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x22, 0x36, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x69, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x69, 0x6d, 0x65, 0x22, 0x30, 0x0a, 0x13, 0x47, - 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x19, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x73, 0x68, 0x61, 0x22, 0xd4, 0x01, - 0x0a, 0x18, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, - 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, - 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x25, 0x0a, - 0x0e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, - 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x61, 0x70, 0x70, 0x12, - 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, - 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x03, - 0x73, 0x68, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, - 0x10, 0x01, 0x52, 0x03, 0x73, 0x68, 0x61, 0x12, 0x1b, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x04, - 0x73, 0x69, 0x7a, 0x65, 0x22, 0xc2, 0x02, 0x0a, 0x16, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, - 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, - 0x1f, 0x0a, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x48, 0x00, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x88, 0x01, 0x01, - 0x12, 0x15, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, - 0x03, 0x73, 0x72, 0x63, 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x09, 0x63, - 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x24, 0x0a, 0x0b, 0x63, - 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, - 0x48, 0x03, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, - 0x01, 0x12, 0x20, 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, - 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x63, 0x68, - 0x75, 0x6e, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x12, 0x15, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x05, 0x52, 0x03, 0x73, 0x68, 0x61, 0x88, 0x01, 0x01, 0x42, - 0x0b, 0x0a, 0x09, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x42, 0x06, 0x0a, 0x04, - 0x5f, 0x73, 0x72, 0x63, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, - 0x64, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x73, 0x68, 0x61, 0x22, 0xbf, 0x01, 0x0a, 0x0f, 0x50, 0x61, - 0x67, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, - 0x0c, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x0b, 0x64, 0x69, - 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x03, 0x61, 0x70, 0x70, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, - 0x03, 0x61, 0x70, 0x70, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, - 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, - 0x2a, 0x02, 0x20, 0x00, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x09, 0x70, 0x61, - 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, - 0x42, 0x06, 0x2a, 0x04, 0x18, 0x64, 0x20, 0x00, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, - 0x7a, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x54, 0x0a, 0x0d, 0x50, - 0x61, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1e, 0x0a, 0x04, - 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x66, 0x69, 0x6c, - 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x05, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x05, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x22, 0x90, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x19, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, - 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x61, 0x70, 0x70, 0x12, 0x1b, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, - 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x0c, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, - 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x79, 0x49, 0x64, 0x22, 0x76, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x69, 0x64, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, - 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x19, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x61, 0x70, 0x70, - 0x12, 0x2a, 0x0a, 0x0c, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, - 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x22, 0x75, 0x0a, 0x11, - 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, - 0x07, 0xfa, 0x42, 0x04, 0x7a, 0x02, 0x10, 0x00, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, - 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x05, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x22, 0x35, 0x0a, 0x0f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, - 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x68, 0x61, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, - 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_resource_file_proto_rawDescOnce sync.Once - file_resource_file_proto_rawDescData = file_resource_file_proto_rawDesc -) - -func file_resource_file_proto_rawDescGZIP() []byte { - file_resource_file_proto_rawDescOnce.Do(func() { - file_resource_file_proto_rawDescData = protoimpl.X.CompressGZIP(file_resource_file_proto_rawDescData) - }) - return file_resource_file_proto_rawDescData -} - -var file_resource_file_proto_msgTypes = make([]protoimpl.MessageInfo, 12) -var file_resource_file_proto_goTypes = []interface{}{ - (*File)(nil), // 0: file.File - (*GetFileRequest)(nil), // 1: file.GetFileRequest - (*GetFileReply)(nil), // 2: file.GetFileReply - (*GetFileByShaRequest)(nil), // 3: file.GetFileByShaRequest - (*PrepareUploadFileRequest)(nil), // 4: file.PrepareUploadFileRequest - (*PrepareUploadFileReply)(nil), // 5: file.PrepareUploadFileReply - (*PageFileRequest)(nil), // 6: file.PageFileRequest - (*PageFileReply)(nil), // 7: file.PageFileReply - (*UpdateFileRequest)(nil), // 8: file.UpdateFileRequest - (*DeleteFileRequest)(nil), // 9: file.DeleteFileRequest - (*UploadFileRequest)(nil), // 10: file.UploadFileRequest - (*UploadFileReply)(nil), // 11: file.UploadFileReply -} -var file_resource_file_proto_depIdxs = []int32{ - 0, // 0: file.PageFileReply.list:type_name -> file.File - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_resource_file_proto_init() } -func file_resource_file_proto_init() { - if File_resource_file_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_resource_file_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*File); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetFileRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetFileReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetFileByShaRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PrepareUploadFileRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PrepareUploadFileReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PageFileRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PageFileReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateFileRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteFileRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadFileRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_resource_file_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadFileReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_resource_file_proto_msgTypes[5].OneofWrappers = []interface{}{} - file_resource_file_proto_msgTypes[6].OneofWrappers = []interface{}{} - file_resource_file_proto_msgTypes[7].OneofWrappers = []interface{}{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_resource_file_proto_rawDesc, - NumEnums: 0, - NumMessages: 12, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_resource_file_proto_goTypes, - DependencyIndexes: file_resource_file_proto_depIdxs, - MessageInfos: file_resource_file_proto_msgTypes, - }.Build() - File_resource_file_proto = out.File - file_resource_file_proto_rawDesc = nil - file_resource_file_proto_goTypes = nil - file_resource_file_proto_depIdxs = nil -} diff --git a/api/file/v1/resource_file_service.pb.go b/api/file/v1/resource_file_service.pb.go deleted file mode 100644 index a759056..0000000 --- a/api/file/v1/resource_file_service.pb.go +++ /dev/null @@ -1,175 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.32.0 -// protoc v4.24.4 -// source: resource_file_service.proto - -package v1 - -import ( - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" - reflect "reflect" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -var File_resource_file_service_proto protoreflect.FileDescriptor - -var file_resource_file_service_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x66, - 0x69, 0x6c, 0x65, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x8c, 0x08, - 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x64, 0x0a, 0x0c, 0x41, 0x6c, 0x6c, - 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x19, 0x2e, 0x66, 0x69, 0x6c, 0x65, - 0x2e, 0x41, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x44, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x20, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, - 0x5d, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, - 0x19, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x66, 0x69, 0x6c, - 0x65, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x21, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x6a, - 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1c, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, - 0x01, 0x2a, 0x1a, 0x16, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, - 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x67, 0x0a, 0x0f, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x2e, - 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0xa2, 0x01, 0x0a, 0x11, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1e, 0x2e, 0x66, 0x69, 0x6c, 0x65, - 0x2e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x66, 0x69, 0x6c, 0x65, - 0x2e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x4f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, 0x3a, - 0x01, 0x2a, 0x5a, 0x27, 0x3a, 0x01, 0x2a, 0x22, 0x22, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x2f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x22, 0x1b, 0x2f, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x2f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x3e, 0x0a, 0x0a, 0x55, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x17, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x15, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, - 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x08, 0x50, 0x61, 0x67, 0x65, - 0x46, 0x69, 0x6c, 0x65, 0x12, 0x15, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x50, 0x61, 0x67, 0x65, - 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x66, 0x69, - 0x6c, 0x65, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x74, 0x0a, 0x0c, - 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x12, 0x19, 0x2e, 0x66, - 0x69, 0x6c, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x46, - 0x69, 0x6c, 0x65, 0x22, 0x3d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x5a, 0x1e, 0x12, 0x1c, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x73, 0x68, 0x61, 0x12, 0x15, 0x2f, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x73, - 0x68, 0x61, 0x12, 0x5b, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, - 0x12, 0x17, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x1a, 0x11, 0x2f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x12, - 0x5b, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x17, 0x2e, - 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x1c, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x09, 0x5a, 0x07, - 0x2e, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var file_resource_file_service_proto_goTypes = []interface{}{ - (*AllDirectoryRequest)(nil), // 0: file.AllDirectoryRequest - (*AddDirectoryRequest)(nil), // 1: file.AddDirectoryRequest - (*UpdateDirectoryRequest)(nil), // 2: file.UpdateDirectoryRequest - (*DeleteDirectoryRequest)(nil), // 3: file.DeleteDirectoryRequest - (*PrepareUploadFileRequest)(nil), // 4: file.PrepareUploadFileRequest - (*UploadFileRequest)(nil), // 5: file.UploadFileRequest - (*PageFileRequest)(nil), // 6: file.PageFileRequest - (*GetFileByShaRequest)(nil), // 7: file.GetFileByShaRequest - (*UpdateFileRequest)(nil), // 8: file.UpdateFileRequest - (*DeleteFileRequest)(nil), // 9: file.DeleteFileRequest - (*AllDirectoryReply)(nil), // 10: file.AllDirectoryReply - (*Directory)(nil), // 11: file.Directory - (*emptypb.Empty)(nil), // 12: google.protobuf.Empty - (*PrepareUploadFileReply)(nil), // 13: file.PrepareUploadFileReply - (*UploadFileReply)(nil), // 14: file.UploadFileReply - (*PageFileReply)(nil), // 15: file.PageFileReply - (*File)(nil), // 16: file.File -} -var file_resource_file_service_proto_depIdxs = []int32{ - 0, // 0: file.Service.AllDirectory:input_type -> file.AllDirectoryRequest - 1, // 1: file.Service.AddDirectory:input_type -> file.AddDirectoryRequest - 2, // 2: file.Service.UpdateDirectory:input_type -> file.UpdateDirectoryRequest - 3, // 3: file.Service.DeleteDirectory:input_type -> file.DeleteDirectoryRequest - 4, // 4: file.Service.PrepareUploadFile:input_type -> file.PrepareUploadFileRequest - 5, // 5: file.Service.UploadFile:input_type -> file.UploadFileRequest - 6, // 6: file.Service.PageFile:input_type -> file.PageFileRequest - 7, // 7: file.Service.GetFileBySha:input_type -> file.GetFileByShaRequest - 8, // 8: file.Service.UpdateFile:input_type -> file.UpdateFileRequest - 9, // 9: file.Service.DeleteFile:input_type -> file.DeleteFileRequest - 10, // 10: file.Service.AllDirectory:output_type -> file.AllDirectoryReply - 11, // 11: file.Service.AddDirectory:output_type -> file.Directory - 12, // 12: file.Service.UpdateDirectory:output_type -> google.protobuf.Empty - 12, // 13: file.Service.DeleteDirectory:output_type -> google.protobuf.Empty - 13, // 14: file.Service.PrepareUploadFile:output_type -> file.PrepareUploadFileReply - 14, // 15: file.Service.UploadFile:output_type -> file.UploadFileReply - 15, // 16: file.Service.PageFile:output_type -> file.PageFileReply - 16, // 17: file.Service.GetFileBySha:output_type -> file.File - 12, // 18: file.Service.UpdateFile:output_type -> google.protobuf.Empty - 12, // 19: file.Service.DeleteFile:output_type -> google.protobuf.Empty - 10, // [10:20] is the sub-list for method output_type - 0, // [0:10] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_resource_file_service_proto_init() } -func file_resource_file_service_proto_init() { - if File_resource_file_service_proto != nil { - return - } - file_resource_file_proto_init() - file_resource_directory_proto_init() - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_resource_file_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_resource_file_service_proto_goTypes, - DependencyIndexes: file_resource_file_service_proto_depIdxs, - }.Build() - File_resource_file_service_proto = out.File - file_resource_file_service_proto_rawDesc = nil - file_resource_file_service_proto_goTypes = nil - file_resource_file_service_proto_depIdxs = nil -} diff --git a/api/file/v1/resource_file_service.pb.validate.go b/api/file/v1/resource_file_service.pb.validate.go deleted file mode 100644 index 74c9777..0000000 --- a/api/file/v1/resource_file_service.pb.validate.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated by protoc-gen-validate. DO NOT EDIT. -// source: resource_file_service.proto - -package v1 - -import ( - "bytes" - "errors" - "fmt" - "net" - "net/mail" - "net/url" - "regexp" - "sort" - "strings" - "time" - "unicode/utf8" - - "google.golang.org/protobuf/types/known/anypb" -) - -// ensure the imports are used -var ( - _ = bytes.MinRead - _ = errors.New("") - _ = fmt.Print - _ = utf8.UTFMax - _ = (*regexp.Regexp)(nil) - _ = (*strings.Reader)(nil) - _ = net.IPv4len - _ = time.Duration(0) - _ = (*url.URL)(nil) - _ = (*mail.Address)(nil) - _ = anypb.Any{} - _ = sort.Sort -) diff --git a/api/file/v1/resource_file_service_grpc.pb.go b/api/file/v1/resource_file_service_grpc.pb.go deleted file mode 100644 index 4b61b21..0000000 --- a/api/file/v1/resource_file_service_grpc.pb.go +++ /dev/null @@ -1,443 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc v4.24.4 -// source: resource_file_service.proto - -package v1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -const ( - Service_AllDirectory_FullMethodName = "/file.Service/AllDirectory" - Service_AddDirectory_FullMethodName = "/file.Service/AddDirectory" - Service_UpdateDirectory_FullMethodName = "/file.Service/UpdateDirectory" - Service_DeleteDirectory_FullMethodName = "/file.Service/DeleteDirectory" - Service_PrepareUploadFile_FullMethodName = "/file.Service/PrepareUploadFile" - Service_UploadFile_FullMethodName = "/file.Service/UploadFile" - Service_PageFile_FullMethodName = "/file.Service/PageFile" - Service_GetFileBySha_FullMethodName = "/file.Service/GetFileBySha" - Service_UpdateFile_FullMethodName = "/file.Service/UpdateFile" - Service_DeleteFile_FullMethodName = "/file.Service/DeleteFile" -) - -// ServiceClient is the client API for Service 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 ServiceClient interface { - AllDirectory(ctx context.Context, in *AllDirectoryRequest, opts ...grpc.CallOption) (*AllDirectoryReply, error) - AddDirectory(ctx context.Context, in *AddDirectoryRequest, opts ...grpc.CallOption) (*Directory, error) - UpdateDirectory(ctx context.Context, in *UpdateDirectoryRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - DeleteDirectory(ctx context.Context, in *DeleteDirectoryRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - PrepareUploadFile(ctx context.Context, in *PrepareUploadFileRequest, opts ...grpc.CallOption) (*PrepareUploadFileReply, error) - UploadFile(ctx context.Context, in *UploadFileRequest, opts ...grpc.CallOption) (*UploadFileReply, error) - PageFile(ctx context.Context, in *PageFileRequest, opts ...grpc.CallOption) (*PageFileReply, error) - GetFileBySha(ctx context.Context, in *GetFileByShaRequest, opts ...grpc.CallOption) (*File, error) - UpdateFile(ctx context.Context, in *UpdateFileRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - DeleteFile(ctx context.Context, in *DeleteFileRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) -} - -type serviceClient struct { - cc grpc.ClientConnInterface -} - -func NewServiceClient(cc grpc.ClientConnInterface) ServiceClient { - return &serviceClient{cc} -} - -func (c *serviceClient) AllDirectory(ctx context.Context, in *AllDirectoryRequest, opts ...grpc.CallOption) (*AllDirectoryReply, error) { - out := new(AllDirectoryReply) - err := c.cc.Invoke(ctx, Service_AllDirectory_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) AddDirectory(ctx context.Context, in *AddDirectoryRequest, opts ...grpc.CallOption) (*Directory, error) { - out := new(Directory) - err := c.cc.Invoke(ctx, Service_AddDirectory_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) UpdateDirectory(ctx context.Context, in *UpdateDirectoryRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Service_UpdateDirectory_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) DeleteDirectory(ctx context.Context, in *DeleteDirectoryRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Service_DeleteDirectory_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) PrepareUploadFile(ctx context.Context, in *PrepareUploadFileRequest, opts ...grpc.CallOption) (*PrepareUploadFileReply, error) { - out := new(PrepareUploadFileReply) - err := c.cc.Invoke(ctx, Service_PrepareUploadFile_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) UploadFile(ctx context.Context, in *UploadFileRequest, opts ...grpc.CallOption) (*UploadFileReply, error) { - out := new(UploadFileReply) - err := c.cc.Invoke(ctx, Service_UploadFile_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) PageFile(ctx context.Context, in *PageFileRequest, opts ...grpc.CallOption) (*PageFileReply, error) { - out := new(PageFileReply) - err := c.cc.Invoke(ctx, Service_PageFile_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) GetFileBySha(ctx context.Context, in *GetFileByShaRequest, opts ...grpc.CallOption) (*File, error) { - out := new(File) - err := c.cc.Invoke(ctx, Service_GetFileBySha_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) UpdateFile(ctx context.Context, in *UpdateFileRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Service_UpdateFile_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *serviceClient) DeleteFile(ctx context.Context, in *DeleteFileRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Service_DeleteFile_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// ServiceServer is the server API for Service service. -// All implementations must embed UnimplementedServiceServer -// for forward compatibility -type ServiceServer interface { - AllDirectory(context.Context, *AllDirectoryRequest) (*AllDirectoryReply, error) - AddDirectory(context.Context, *AddDirectoryRequest) (*Directory, error) - UpdateDirectory(context.Context, *UpdateDirectoryRequest) (*emptypb.Empty, error) - DeleteDirectory(context.Context, *DeleteDirectoryRequest) (*emptypb.Empty, error) - PrepareUploadFile(context.Context, *PrepareUploadFileRequest) (*PrepareUploadFileReply, error) - UploadFile(context.Context, *UploadFileRequest) (*UploadFileReply, error) - PageFile(context.Context, *PageFileRequest) (*PageFileReply, error) - GetFileBySha(context.Context, *GetFileByShaRequest) (*File, error) - UpdateFile(context.Context, *UpdateFileRequest) (*emptypb.Empty, error) - DeleteFile(context.Context, *DeleteFileRequest) (*emptypb.Empty, error) - mustEmbedUnimplementedServiceServer() -} - -// UnimplementedServiceServer must be embedded to have forward compatible implementations. -type UnimplementedServiceServer struct { -} - -func (UnimplementedServiceServer) AllDirectory(context.Context, *AllDirectoryRequest) (*AllDirectoryReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method AllDirectory not implemented") -} -func (UnimplementedServiceServer) AddDirectory(context.Context, *AddDirectoryRequest) (*Directory, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddDirectory not implemented") -} -func (UnimplementedServiceServer) UpdateDirectory(context.Context, *UpdateDirectoryRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateDirectory not implemented") -} -func (UnimplementedServiceServer) DeleteDirectory(context.Context, *DeleteDirectoryRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteDirectory not implemented") -} -func (UnimplementedServiceServer) PrepareUploadFile(context.Context, *PrepareUploadFileRequest) (*PrepareUploadFileReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method PrepareUploadFile not implemented") -} -func (UnimplementedServiceServer) UploadFile(context.Context, *UploadFileRequest) (*UploadFileReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method UploadFile not implemented") -} -func (UnimplementedServiceServer) PageFile(context.Context, *PageFileRequest) (*PageFileReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method PageFile not implemented") -} -func (UnimplementedServiceServer) GetFileBySha(context.Context, *GetFileByShaRequest) (*File, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetFileBySha not implemented") -} -func (UnimplementedServiceServer) UpdateFile(context.Context, *UpdateFileRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateFile not implemented") -} -func (UnimplementedServiceServer) DeleteFile(context.Context, *DeleteFileRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteFile not implemented") -} -func (UnimplementedServiceServer) mustEmbedUnimplementedServiceServer() {} - -// UnsafeServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ServiceServer will -// result in compilation errors. -type UnsafeServiceServer interface { - mustEmbedUnimplementedServiceServer() -} - -func RegisterServiceServer(s grpc.ServiceRegistrar, srv ServiceServer) { - s.RegisterService(&Service_ServiceDesc, srv) -} - -func _Service_AllDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AllDirectoryRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).AllDirectory(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_AllDirectory_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).AllDirectory(ctx, req.(*AllDirectoryRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_AddDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddDirectoryRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).AddDirectory(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_AddDirectory_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).AddDirectory(ctx, req.(*AddDirectoryRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_UpdateDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateDirectoryRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).UpdateDirectory(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_UpdateDirectory_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).UpdateDirectory(ctx, req.(*UpdateDirectoryRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_DeleteDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteDirectoryRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).DeleteDirectory(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_DeleteDirectory_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).DeleteDirectory(ctx, req.(*DeleteDirectoryRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_PrepareUploadFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PrepareUploadFileRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).PrepareUploadFile(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_PrepareUploadFile_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).PrepareUploadFile(ctx, req.(*PrepareUploadFileRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_UploadFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UploadFileRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).UploadFile(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_UploadFile_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).UploadFile(ctx, req.(*UploadFileRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_PageFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PageFileRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).PageFile(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_PageFile_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).PageFile(ctx, req.(*PageFileRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_GetFileBySha_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetFileByShaRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).GetFileBySha(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_GetFileBySha_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).GetFileBySha(ctx, req.(*GetFileByShaRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_UpdateFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateFileRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).UpdateFile(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_UpdateFile_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).UpdateFile(ctx, req.(*UpdateFileRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Service_DeleteFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteFileRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServiceServer).DeleteFile(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Service_DeleteFile_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).DeleteFile(ctx, req.(*DeleteFileRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// Service_ServiceDesc is the grpc.ServiceDesc for Service service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Service_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "file.Service", - HandlerType: (*ServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "AllDirectory", - Handler: _Service_AllDirectory_Handler, - }, - { - MethodName: "AddDirectory", - Handler: _Service_AddDirectory_Handler, - }, - { - MethodName: "UpdateDirectory", - Handler: _Service_UpdateDirectory_Handler, - }, - { - MethodName: "DeleteDirectory", - Handler: _Service_DeleteDirectory_Handler, - }, - { - MethodName: "PrepareUploadFile", - Handler: _Service_PrepareUploadFile_Handler, - }, - { - MethodName: "UploadFile", - Handler: _Service_UploadFile_Handler, - }, - { - MethodName: "PageFile", - Handler: _Service_PageFile_Handler, - }, - { - MethodName: "GetFileBySha", - Handler: _Service_GetFileBySha_Handler, - }, - { - MethodName: "UpdateFile", - Handler: _Service_UpdateFile_Handler, - }, - { - MethodName: "DeleteFile", - Handler: _Service_DeleteFile_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "resource_file_service.proto", -} diff --git a/api/file/v1/resource_file_service_http.pb.go b/api/file/v1/resource_file_service_http.pb.go deleted file mode 100644 index 3ef29cf..0000000 --- a/api/file/v1/resource_file_service_http.pb.go +++ /dev/null @@ -1,422 +0,0 @@ -// Code generated by protoc-gen-go-http. DO NOT EDIT. -// versions: -// - protoc-gen-go-http v2.7.0 -// - protoc v4.24.4 -// source: resource_file_service.proto - -package v1 - -import ( - context "context" - http "github.com/go-kratos/kratos/v2/transport/http" - binding "github.com/go-kratos/kratos/v2/transport/http/binding" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the kratos package it is being compiled against. -var _ = new(context.Context) -var _ = binding.EncodeURL - -const _ = http.SupportPackageIsVersion1 - -const OperationServiceAddDirectory = "/file.Service/AddDirectory" -const OperationServiceAllDirectory = "/file.Service/AllDirectory" -const OperationServiceDeleteDirectory = "/file.Service/DeleteDirectory" -const OperationServiceDeleteFile = "/file.Service/DeleteFile" -const OperationServiceGetFileBySha = "/file.Service/GetFileBySha" -const OperationServicePageFile = "/file.Service/PageFile" -const OperationServicePrepareUploadFile = "/file.Service/PrepareUploadFile" -const OperationServiceUpdateDirectory = "/file.Service/UpdateDirectory" -const OperationServiceUpdateFile = "/file.Service/UpdateFile" - -type ServiceHTTPServer interface { - AddDirectory(context.Context, *AddDirectoryRequest) (*Directory, error) - AllDirectory(context.Context, *AllDirectoryRequest) (*AllDirectoryReply, error) - DeleteDirectory(context.Context, *DeleteDirectoryRequest) (*emptypb.Empty, error) - DeleteFile(context.Context, *DeleteFileRequest) (*emptypb.Empty, error) - GetFileBySha(context.Context, *GetFileByShaRequest) (*File, error) - PageFile(context.Context, *PageFileRequest) (*PageFileReply, error) - PrepareUploadFile(context.Context, *PrepareUploadFileRequest) (*PrepareUploadFileReply, error) - UpdateDirectory(context.Context, *UpdateDirectoryRequest) (*emptypb.Empty, error) - UpdateFile(context.Context, *UpdateFileRequest) (*emptypb.Empty, error) -} - -func RegisterServiceHTTPServer(s *http.Server, srv ServiceHTTPServer) { - r := s.Route("/") - r.GET("/resource/v1/directories", _Service_AllDirectory0_HTTP_Handler(srv)) - r.POST("/resource/v1/directory", _Service_AddDirectory0_HTTP_Handler(srv)) - r.PUT("/resource/v1/directory", _Service_UpdateDirectory0_HTTP_Handler(srv)) - r.DELETE("/resource/v1/directory", _Service_DeleteDirectory0_HTTP_Handler(srv)) - r.POST("/resource/client/v1/upload/prepare", _Service_PrepareUploadFile0_HTTP_Handler(srv)) - r.POST("/resource/v1/upload/prepare", _Service_PrepareUploadFile1_HTTP_Handler(srv)) - r.GET("/resource/v1/files", _Service_PageFile0_HTTP_Handler(srv)) - r.GET("/resource/client/v1/file/sha", _Service_GetFileBySha0_HTTP_Handler(srv)) - r.GET("/resource/v1/file/sha", _Service_GetFileBySha1_HTTP_Handler(srv)) - r.PUT("/resource/v1/file", _Service_UpdateFile0_HTTP_Handler(srv)) - r.POST("/resource/v1/file", _Service_DeleteFile0_HTTP_Handler(srv)) -} - -func _Service_AllDirectory0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in AllDirectoryRequest - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceAllDirectory) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.AllDirectory(ctx, req.(*AllDirectoryRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*AllDirectoryReply) - return ctx.Result(200, reply) - } -} - -func _Service_AddDirectory0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in AddDirectoryRequest - if err := ctx.Bind(&in); err != nil { - return err - } - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceAddDirectory) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.AddDirectory(ctx, req.(*AddDirectoryRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*Directory) - return ctx.Result(200, reply) - } -} - -func _Service_UpdateDirectory0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in UpdateDirectoryRequest - if err := ctx.Bind(&in); err != nil { - return err - } - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceUpdateDirectory) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.UpdateDirectory(ctx, req.(*UpdateDirectoryRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*emptypb.Empty) - return ctx.Result(200, reply) - } -} - -func _Service_DeleteDirectory0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in DeleteDirectoryRequest - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceDeleteDirectory) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.DeleteDirectory(ctx, req.(*DeleteDirectoryRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*emptypb.Empty) - return ctx.Result(200, reply) - } -} - -func _Service_PrepareUploadFile0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in PrepareUploadFileRequest - if err := ctx.Bind(&in); err != nil { - return err - } - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServicePrepareUploadFile) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.PrepareUploadFile(ctx, req.(*PrepareUploadFileRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*PrepareUploadFileReply) - return ctx.Result(200, reply) - } -} - -func _Service_PrepareUploadFile1_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in PrepareUploadFileRequest - if err := ctx.Bind(&in); err != nil { - return err - } - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServicePrepareUploadFile) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.PrepareUploadFile(ctx, req.(*PrepareUploadFileRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*PrepareUploadFileReply) - return ctx.Result(200, reply) - } -} - -func _Service_PageFile0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in PageFileRequest - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServicePageFile) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.PageFile(ctx, req.(*PageFileRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*PageFileReply) - return ctx.Result(200, reply) - } -} - -func _Service_GetFileBySha0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in GetFileByShaRequest - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceGetFileBySha) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.GetFileBySha(ctx, req.(*GetFileByShaRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*File) - return ctx.Result(200, reply) - } -} - -func _Service_GetFileBySha1_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in GetFileByShaRequest - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceGetFileBySha) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.GetFileBySha(ctx, req.(*GetFileByShaRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*File) - return ctx.Result(200, reply) - } -} - -func _Service_UpdateFile0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in UpdateFileRequest - if err := ctx.Bind(&in); err != nil { - return err - } - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceUpdateFile) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.UpdateFile(ctx, req.(*UpdateFileRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*emptypb.Empty) - return ctx.Result(200, reply) - } -} - -func _Service_DeleteFile0_HTTP_Handler(srv ServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in DeleteFileRequest - if err := ctx.Bind(&in); err != nil { - return err - } - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationServiceDeleteFile) - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.DeleteFile(ctx, req.(*DeleteFileRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*emptypb.Empty) - return ctx.Result(200, reply) - } -} - -type ServiceHTTPClient interface { - AddDirectory(ctx context.Context, req *AddDirectoryRequest, opts ...http.CallOption) (rsp *Directory, err error) - AllDirectory(ctx context.Context, req *AllDirectoryRequest, opts ...http.CallOption) (rsp *AllDirectoryReply, err error) - DeleteDirectory(ctx context.Context, req *DeleteDirectoryRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) - DeleteFile(ctx context.Context, req *DeleteFileRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) - GetFileBySha(ctx context.Context, req *GetFileByShaRequest, opts ...http.CallOption) (rsp *File, err error) - PageFile(ctx context.Context, req *PageFileRequest, opts ...http.CallOption) (rsp *PageFileReply, err error) - PrepareUploadFile(ctx context.Context, req *PrepareUploadFileRequest, opts ...http.CallOption) (rsp *PrepareUploadFileReply, err error) - UpdateDirectory(ctx context.Context, req *UpdateDirectoryRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) - UpdateFile(ctx context.Context, req *UpdateFileRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) -} - -type ServiceHTTPClientImpl struct { - cc *http.Client -} - -func NewServiceHTTPClient(client *http.Client) ServiceHTTPClient { - return &ServiceHTTPClientImpl{client} -} - -func (c *ServiceHTTPClientImpl) AddDirectory(ctx context.Context, in *AddDirectoryRequest, opts ...http.CallOption) (*Directory, error) { - var out Directory - pattern := "/resource/v1/directory" - path := binding.EncodeURL(pattern, in, false) - opts = append(opts, http.Operation(OperationServiceAddDirectory)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) AllDirectory(ctx context.Context, in *AllDirectoryRequest, opts ...http.CallOption) (*AllDirectoryReply, error) { - var out AllDirectoryReply - pattern := "/resource/v1/directories" - path := binding.EncodeURL(pattern, in, true) - opts = append(opts, http.Operation(OperationServiceAllDirectory)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) DeleteDirectory(ctx context.Context, in *DeleteDirectoryRequest, opts ...http.CallOption) (*emptypb.Empty, error) { - var out emptypb.Empty - pattern := "/resource/v1/directory" - path := binding.EncodeURL(pattern, in, true) - opts = append(opts, http.Operation(OperationServiceDeleteDirectory)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) DeleteFile(ctx context.Context, in *DeleteFileRequest, opts ...http.CallOption) (*emptypb.Empty, error) { - var out emptypb.Empty - pattern := "/resource/v1/file" - path := binding.EncodeURL(pattern, in, false) - opts = append(opts, http.Operation(OperationServiceDeleteFile)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) GetFileBySha(ctx context.Context, in *GetFileByShaRequest, opts ...http.CallOption) (*File, error) { - var out File - pattern := "/resource/v1/file/sha" - path := binding.EncodeURL(pattern, in, true) - opts = append(opts, http.Operation(OperationServiceGetFileBySha)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) PageFile(ctx context.Context, in *PageFileRequest, opts ...http.CallOption) (*PageFileReply, error) { - var out PageFileReply - pattern := "/resource/v1/files" - path := binding.EncodeURL(pattern, in, true) - opts = append(opts, http.Operation(OperationServicePageFile)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) PrepareUploadFile(ctx context.Context, in *PrepareUploadFileRequest, opts ...http.CallOption) (*PrepareUploadFileReply, error) { - var out PrepareUploadFileReply - pattern := "/resource/v1/upload/prepare" - path := binding.EncodeURL(pattern, in, false) - opts = append(opts, http.Operation(OperationServicePrepareUploadFile)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) UpdateDirectory(ctx context.Context, in *UpdateDirectoryRequest, opts ...http.CallOption) (*emptypb.Empty, error) { - var out emptypb.Empty - pattern := "/resource/v1/directory" - path := binding.EncodeURL(pattern, in, false) - opts = append(opts, http.Operation(OperationServiceUpdateDirectory)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} - -func (c *ServiceHTTPClientImpl) UpdateFile(ctx context.Context, in *UpdateFileRequest, opts ...http.CallOption) (*emptypb.Empty, error) { - var out emptypb.Empty - pattern := "/resource/v1/file" - path := binding.EncodeURL(pattern, in, false) - opts = append(opts, http.Operation(OperationServiceUpdateFile)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} diff --git a/api/errors/openapi.yaml b/api/resource/directory/openapi.yaml similarity index 100% rename from api/errors/openapi.yaml rename to api/resource/directory/openapi.yaml diff --git a/api/resource/directory/resource_directory.proto b/api/resource/directory/resource_directory.proto new file mode 100755 index 0000000..5006984 --- /dev/null +++ b/api/resource/directory/resource_directory.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; + +package resource.api.resource.directory.v1; + +option go_package = "./v1;v1"; +option java_multiple_files = true; +option java_package = "resource.api.resource.directory.v1"; +option java_outer_classname = "DirectoryV1"; + +import "validate/validate.proto"; + +message GetDirectoryRequest { + optional uint32 id = 1[(validate.rules).uint32 = {gt: 0}]; +} + +message GetDirectoryReply { + uint32 id = 1; + uint32 parentId = 2; + string name = 3; + string accept = 4; + uint32 maxSize = 5; + uint32 createdAt = 6; + uint32 updatedAt = 7; +} + +message ListDirectoryRequest { + optional string order = 1[(validate.rules).string = {in: ["asc","desc"]}]; + optional string orderBy = 2[(validate.rules).string = {in: ["id","created_at","updated_at"]}]; +} + +message ListDirectoryReply { + message Directory { + uint32 id = 1; + uint32 parentId = 2; + string name = 3; + string accept = 4; + uint32 maxSize = 5; + uint32 createdAt = 6; + uint32 updatedAt = 7; + repeated Directory children = 8; + } + + uint32 total = 1; + repeated Directory list = 2; +} + +message CreateDirectoryRequest { + uint32 parentId = 1[(validate.rules).uint32 = {gt: 0}]; + string name = 2[(validate.rules).string = {min_len: 1}]; + string accept = 3[(validate.rules).string = {min_len: 1}]; + uint32 maxSize = 4[(validate.rules).uint32 = {gte: 1}]; +} + +message CreateDirectoryReply { + uint32 id = 1; +} + +message UpdateDirectoryRequest { + uint32 id = 1[(validate.rules).uint32 = {gt: 0}]; + uint32 parentId = 2[(validate.rules).uint32 = {gt: 0}]; + string name = 3[(validate.rules).string = {min_len: 1}]; + string accept = 4[(validate.rules).string = {min_len: 1}]; + uint32 maxSize = 5[(validate.rules).uint32 = {gte: 1}]; +} + +message UpdateDirectoryReply { +} + +message DeleteDirectoryRequest { + repeated uint32 ids = 1[(validate.rules).repeated = {min_items: 1, unique:true, max_items:50}]; +} + +message DeleteDirectoryReply { + uint32 total = 1; +} + diff --git a/api/resource/directory/resource_directory_service.proto b/api/resource/directory/resource_directory_service.proto new file mode 100755 index 0000000..47a9933 --- /dev/null +++ b/api/resource/directory/resource_directory_service.proto @@ -0,0 +1,52 @@ +syntax = "proto3"; + +package resource.api.resource.directory.v1; + +option go_package = "./v1;v1"; +option java_multiple_files = true; +option java_package = "resource.api.resource.directory.v1"; +option java_outer_classname = "DirectoryV1"; + +import "api/resource/directory/resource_directory.proto"; +import "google/api/annotations.proto"; + +service Directory{ + + // GetDirectory 获取指定的文件目录信息 + rpc GetDirectory (GetDirectoryRequest) returns (GetDirectoryReply) { + option (google.api.http) = { + get: "/resource/api/v1/directory", + }; + } + + // ListDirectory 获取文件目录信息列表 + rpc ListDirectory (ListDirectoryRequest) returns (ListDirectoryReply) { + option (google.api.http) = { + get: "/resource/api/v1/directories", + }; + } + + // CreateDirectory 创建文件目录信息 + rpc CreateDirectory (CreateDirectoryRequest) returns (CreateDirectoryReply) { + option (google.api.http) = { + post: "/resource/api/v1/directory", + body: "*" + }; + } + + // UpdateDirectory 更新文件目录信息 + rpc UpdateDirectory (UpdateDirectoryRequest) returns (UpdateDirectoryReply) { + option (google.api.http) = { + put: "/resource/api/v1/directory", + body: "*" + }; + } + + // DeleteDirectory 删除文件目录信息 + rpc DeleteDirectory (DeleteDirectoryRequest) returns (DeleteDirectoryReply) { + option (google.api.http) = { + delete: "/resource/api/v1/directory", + }; + } + +} \ No newline at end of file diff --git a/api/resource/directory/v1/resource_directory.pb.go b/api/resource/directory/v1/resource_directory.pb.go new file mode 100644 index 0000000..9d35b65 --- /dev/null +++ b/api/resource/directory/v1/resource_directory.pb.go @@ -0,0 +1,1004 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v4.24.4 +// source: api/resource/directory/resource_directory.proto + +package v1 + +import ( + _ "github.com/envoyproxy/protoc-gen-validate/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GetDirectoryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id *uint32 `protobuf:"varint,1,opt,name=id,proto3,oneof" json:"id,omitempty"` +} + +func (x *GetDirectoryRequest) Reset() { + *x = GetDirectoryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDirectoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDirectoryRequest) ProtoMessage() {} + +func (x *GetDirectoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDirectoryRequest.ProtoReflect.Descriptor instead. +func (*GetDirectoryRequest) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{0} +} + +func (x *GetDirectoryRequest) GetId() uint32 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +type GetDirectoryReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ParentId uint32 `protobuf:"varint,2,opt,name=parentId,proto3" json:"parentId,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Accept string `protobuf:"bytes,4,opt,name=accept,proto3" json:"accept,omitempty"` + MaxSize uint32 `protobuf:"varint,5,opt,name=maxSize,proto3" json:"maxSize,omitempty"` + CreatedAt uint32 `protobuf:"varint,6,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt uint32 `protobuf:"varint,7,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` +} + +func (x *GetDirectoryReply) Reset() { + *x = GetDirectoryReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDirectoryReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDirectoryReply) ProtoMessage() {} + +func (x *GetDirectoryReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDirectoryReply.ProtoReflect.Descriptor instead. +func (*GetDirectoryReply) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{1} +} + +func (x *GetDirectoryReply) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *GetDirectoryReply) GetParentId() uint32 { + if x != nil { + return x.ParentId + } + return 0 +} + +func (x *GetDirectoryReply) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetDirectoryReply) GetAccept() string { + if x != nil { + return x.Accept + } + return "" +} + +func (x *GetDirectoryReply) GetMaxSize() uint32 { + if x != nil { + return x.MaxSize + } + return 0 +} + +func (x *GetDirectoryReply) GetCreatedAt() uint32 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *GetDirectoryReply) GetUpdatedAt() uint32 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +type ListDirectoryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Order *string `protobuf:"bytes,1,opt,name=order,proto3,oneof" json:"order,omitempty"` + OrderBy *string `protobuf:"bytes,2,opt,name=orderBy,proto3,oneof" json:"orderBy,omitempty"` +} + +func (x *ListDirectoryRequest) Reset() { + *x = ListDirectoryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDirectoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDirectoryRequest) ProtoMessage() {} + +func (x *ListDirectoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDirectoryRequest.ProtoReflect.Descriptor instead. +func (*ListDirectoryRequest) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{2} +} + +func (x *ListDirectoryRequest) GetOrder() string { + if x != nil && x.Order != nil { + return *x.Order + } + return "" +} + +func (x *ListDirectoryRequest) GetOrderBy() string { + if x != nil && x.OrderBy != nil { + return *x.OrderBy + } + return "" +} + +type ListDirectoryReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*ListDirectoryReply_Directory `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +func (x *ListDirectoryReply) Reset() { + *x = ListDirectoryReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDirectoryReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDirectoryReply) ProtoMessage() {} + +func (x *ListDirectoryReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDirectoryReply.ProtoReflect.Descriptor instead. +func (*ListDirectoryReply) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{3} +} + +func (x *ListDirectoryReply) GetTotal() uint32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *ListDirectoryReply) GetList() []*ListDirectoryReply_Directory { + if x != nil { + return x.List + } + return nil +} + +type CreateDirectoryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ParentId uint32 `protobuf:"varint,1,opt,name=parentId,proto3" json:"parentId,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Accept string `protobuf:"bytes,3,opt,name=accept,proto3" json:"accept,omitempty"` + MaxSize uint32 `protobuf:"varint,4,opt,name=maxSize,proto3" json:"maxSize,omitempty"` +} + +func (x *CreateDirectoryRequest) Reset() { + *x = CreateDirectoryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateDirectoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDirectoryRequest) ProtoMessage() {} + +func (x *CreateDirectoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDirectoryRequest.ProtoReflect.Descriptor instead. +func (*CreateDirectoryRequest) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{4} +} + +func (x *CreateDirectoryRequest) GetParentId() uint32 { + if x != nil { + return x.ParentId + } + return 0 +} + +func (x *CreateDirectoryRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateDirectoryRequest) GetAccept() string { + if x != nil { + return x.Accept + } + return "" +} + +func (x *CreateDirectoryRequest) GetMaxSize() uint32 { + if x != nil { + return x.MaxSize + } + return 0 +} + +type CreateDirectoryReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *CreateDirectoryReply) Reset() { + *x = CreateDirectoryReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateDirectoryReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDirectoryReply) ProtoMessage() {} + +func (x *CreateDirectoryReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDirectoryReply.ProtoReflect.Descriptor instead. +func (*CreateDirectoryReply) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateDirectoryReply) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +type UpdateDirectoryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ParentId uint32 `protobuf:"varint,2,opt,name=parentId,proto3" json:"parentId,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Accept string `protobuf:"bytes,4,opt,name=accept,proto3" json:"accept,omitempty"` + MaxSize uint32 `protobuf:"varint,5,opt,name=maxSize,proto3" json:"maxSize,omitempty"` +} + +func (x *UpdateDirectoryRequest) Reset() { + *x = UpdateDirectoryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateDirectoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDirectoryRequest) ProtoMessage() {} + +func (x *UpdateDirectoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDirectoryRequest.ProtoReflect.Descriptor instead. +func (*UpdateDirectoryRequest) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{6} +} + +func (x *UpdateDirectoryRequest) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *UpdateDirectoryRequest) GetParentId() uint32 { + if x != nil { + return x.ParentId + } + return 0 +} + +func (x *UpdateDirectoryRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateDirectoryRequest) GetAccept() string { + if x != nil { + return x.Accept + } + return "" +} + +func (x *UpdateDirectoryRequest) GetMaxSize() uint32 { + if x != nil { + return x.MaxSize + } + return 0 +} + +type UpdateDirectoryReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpdateDirectoryReply) Reset() { + *x = UpdateDirectoryReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateDirectoryReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDirectoryReply) ProtoMessage() {} + +func (x *UpdateDirectoryReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDirectoryReply.ProtoReflect.Descriptor instead. +func (*UpdateDirectoryReply) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{7} +} + +type DeleteDirectoryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ids []uint32 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids,omitempty"` +} + +func (x *DeleteDirectoryRequest) Reset() { + *x = DeleteDirectoryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteDirectoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDirectoryRequest) ProtoMessage() {} + +func (x *DeleteDirectoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDirectoryRequest.ProtoReflect.Descriptor instead. +func (*DeleteDirectoryRequest) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{8} +} + +func (x *DeleteDirectoryRequest) GetIds() []uint32 { + if x != nil { + return x.Ids + } + return nil +} + +type DeleteDirectoryReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` +} + +func (x *DeleteDirectoryReply) Reset() { + *x = DeleteDirectoryReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteDirectoryReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDirectoryReply) ProtoMessage() {} + +func (x *DeleteDirectoryReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDirectoryReply.ProtoReflect.Descriptor instead. +func (*DeleteDirectoryReply) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{9} +} + +func (x *DeleteDirectoryReply) GetTotal() uint32 { + if x != nil { + return x.Total + } + return 0 +} + +type ListDirectoryReply_Directory struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ParentId uint32 `protobuf:"varint,2,opt,name=parentId,proto3" json:"parentId,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Accept string `protobuf:"bytes,4,opt,name=accept,proto3" json:"accept,omitempty"` + MaxSize uint32 `protobuf:"varint,5,opt,name=maxSize,proto3" json:"maxSize,omitempty"` + CreatedAt uint32 `protobuf:"varint,6,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt uint32 `protobuf:"varint,7,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` + Children []*ListDirectoryReply_Directory `protobuf:"bytes,8,rep,name=children,proto3" json:"children,omitempty"` +} + +func (x *ListDirectoryReply_Directory) Reset() { + *x = ListDirectoryReply_Directory{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDirectoryReply_Directory) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDirectoryReply_Directory) ProtoMessage() {} + +func (x *ListDirectoryReply_Directory) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_directory_resource_directory_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDirectoryReply_Directory.ProtoReflect.Descriptor instead. +func (*ListDirectoryReply_Directory) Descriptor() ([]byte, []int) { + return file_api_resource_directory_resource_directory_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *ListDirectoryReply_Directory) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *ListDirectoryReply_Directory) GetParentId() uint32 { + if x != nil { + return x.ParentId + } + return 0 +} + +func (x *ListDirectoryReply_Directory) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ListDirectoryReply_Directory) GetAccept() string { + if x != nil { + return x.Accept + } + return "" +} + +func (x *ListDirectoryReply_Directory) GetMaxSize() uint32 { + if x != nil { + return x.MaxSize + } + return 0 +} + +func (x *ListDirectoryReply_Directory) GetCreatedAt() uint32 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *ListDirectoryReply_Directory) GetUpdatedAt() uint32 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +func (x *ListDirectoryReply_Directory) GetChildren() []*ListDirectoryReply_Directory { + if x != nil { + return x.Children + } + return nil +} + +var File_api_resource_directory_resource_directory_proto protoreflect.FileDescriptor + +var file_api_resource_directory_resource_directory_proto_rawDesc = []byte{ + 0x0a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x22, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3a, + 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, + 0x88, 0x01, 0x01, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x22, 0xc1, 0x01, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x53, + 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x9b, + 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xfa, 0x42, 0x0d, 0x72, 0x0b, 0x52, 0x03, 0x61, + 0x73, 0x63, 0x52, 0x04, 0x64, 0x65, 0x73, 0x63, 0x48, 0x00, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xfa, 0x42, 0x1e, 0x72, 0x1c, 0x52, 0x02, 0x69, 0x64, + 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0a, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x48, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x42, 0x79, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0x9a, 0x03, 0x0a, + 0x12, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x54, 0x0a, 0x04, 0x6c, 0x69, 0x73, + 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x2e, + 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x1a, + 0x97, 0x02, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x5c, 0x0a, 0x08, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, + 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x9e, 0x01, 0x0a, 0x16, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, + 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, + 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x21, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, + 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x28, + 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x26, 0x0a, 0x14, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, + 0x69, 0x64, 0x22, 0xb7, 0x01, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, + 0x20, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, + 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, + 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x21, 0x0a, 0x07, 0x6d, 0x61, 0x78, + 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, + 0x02, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x16, 0x0a, 0x14, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x38, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, + 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x0c, 0xfa, 0x42, 0x09, + 0x92, 0x01, 0x06, 0x08, 0x01, 0x10, 0x32, 0x18, 0x01, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x2c, + 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x3c, 0x0a, 0x22, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, + 0x76, 0x31, 0x42, 0x0b, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x56, 0x31, 0x50, + 0x01, 0x5a, 0x07, 0x2e, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_api_resource_directory_resource_directory_proto_rawDescOnce sync.Once + file_api_resource_directory_resource_directory_proto_rawDescData = file_api_resource_directory_resource_directory_proto_rawDesc +) + +func file_api_resource_directory_resource_directory_proto_rawDescGZIP() []byte { + file_api_resource_directory_resource_directory_proto_rawDescOnce.Do(func() { + file_api_resource_directory_resource_directory_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_resource_directory_resource_directory_proto_rawDescData) + }) + return file_api_resource_directory_resource_directory_proto_rawDescData +} + +var file_api_resource_directory_resource_directory_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_api_resource_directory_resource_directory_proto_goTypes = []interface{}{ + (*GetDirectoryRequest)(nil), // 0: resource.api.resource.directory.v1.GetDirectoryRequest + (*GetDirectoryReply)(nil), // 1: resource.api.resource.directory.v1.GetDirectoryReply + (*ListDirectoryRequest)(nil), // 2: resource.api.resource.directory.v1.ListDirectoryRequest + (*ListDirectoryReply)(nil), // 3: resource.api.resource.directory.v1.ListDirectoryReply + (*CreateDirectoryRequest)(nil), // 4: resource.api.resource.directory.v1.CreateDirectoryRequest + (*CreateDirectoryReply)(nil), // 5: resource.api.resource.directory.v1.CreateDirectoryReply + (*UpdateDirectoryRequest)(nil), // 6: resource.api.resource.directory.v1.UpdateDirectoryRequest + (*UpdateDirectoryReply)(nil), // 7: resource.api.resource.directory.v1.UpdateDirectoryReply + (*DeleteDirectoryRequest)(nil), // 8: resource.api.resource.directory.v1.DeleteDirectoryRequest + (*DeleteDirectoryReply)(nil), // 9: resource.api.resource.directory.v1.DeleteDirectoryReply + (*ListDirectoryReply_Directory)(nil), // 10: resource.api.resource.directory.v1.ListDirectoryReply.Directory +} +var file_api_resource_directory_resource_directory_proto_depIdxs = []int32{ + 10, // 0: resource.api.resource.directory.v1.ListDirectoryReply.list:type_name -> resource.api.resource.directory.v1.ListDirectoryReply.Directory + 10, // 1: resource.api.resource.directory.v1.ListDirectoryReply.Directory.children:type_name -> resource.api.resource.directory.v1.ListDirectoryReply.Directory + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_api_resource_directory_resource_directory_proto_init() } +func file_api_resource_directory_resource_directory_proto_init() { + if File_api_resource_directory_resource_directory_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_resource_directory_resource_directory_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDirectoryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDirectoryReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListDirectoryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListDirectoryReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateDirectoryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateDirectoryReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateDirectoryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateDirectoryReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteDirectoryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteDirectoryReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListDirectoryReply_Directory); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_api_resource_directory_resource_directory_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_api_resource_directory_resource_directory_proto_msgTypes[2].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_resource_directory_resource_directory_proto_rawDesc, + NumEnums: 0, + NumMessages: 11, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_resource_directory_resource_directory_proto_goTypes, + DependencyIndexes: file_api_resource_directory_resource_directory_proto_depIdxs, + MessageInfos: file_api_resource_directory_resource_directory_proto_msgTypes, + }.Build() + File_api_resource_directory_resource_directory_proto = out.File + file_api_resource_directory_resource_directory_proto_rawDesc = nil + file_api_resource_directory_resource_directory_proto_goTypes = nil + file_api_resource_directory_resource_directory_proto_depIdxs = nil +} diff --git a/api/resource/directory/v1/resource_directory.pb.validate.go b/api/resource/directory/v1/resource_directory.pb.validate.go new file mode 100644 index 0000000..06b45d7 --- /dev/null +++ b/api/resource/directory/v1/resource_directory.pb.validate.go @@ -0,0 +1,1448 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: api/resource/directory/resource_directory.proto + +package v1 + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on GetDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetDirectoryRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetDirectoryRequestMultiError, or nil if none found. +func (m *GetDirectoryRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GetDirectoryRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.Id != nil { + + if m.GetId() <= 0 { + err := GetDirectoryRequestValidationError{ + field: "Id", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if len(errors) > 0 { + return GetDirectoryRequestMultiError(errors) + } + + return nil +} + +// GetDirectoryRequestMultiError is an error wrapping multiple validation +// errors returned by GetDirectoryRequest.ValidateAll() if the designated +// constraints aren't met. +type GetDirectoryRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetDirectoryRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetDirectoryRequestMultiError) AllErrors() []error { return m } + +// GetDirectoryRequestValidationError is the validation error returned by +// GetDirectoryRequest.Validate if the designated constraints aren't met. +type GetDirectoryRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetDirectoryRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetDirectoryRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetDirectoryRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetDirectoryRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetDirectoryRequestValidationError) ErrorName() string { + return "GetDirectoryRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e GetDirectoryRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetDirectoryRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetDirectoryRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetDirectoryRequestValidationError{} + +// Validate checks the field values on GetDirectoryReply with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *GetDirectoryReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetDirectoryReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetDirectoryReplyMultiError, or nil if none found. +func (m *GetDirectoryReply) ValidateAll() error { + return m.validate(true) +} + +func (m *GetDirectoryReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Id + + // no validation rules for ParentId + + // no validation rules for Name + + // no validation rules for Accept + + // no validation rules for MaxSize + + // no validation rules for CreatedAt + + // no validation rules for UpdatedAt + + if len(errors) > 0 { + return GetDirectoryReplyMultiError(errors) + } + + return nil +} + +// GetDirectoryReplyMultiError is an error wrapping multiple validation errors +// returned by GetDirectoryReply.ValidateAll() if the designated constraints +// aren't met. +type GetDirectoryReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetDirectoryReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetDirectoryReplyMultiError) AllErrors() []error { return m } + +// GetDirectoryReplyValidationError is the validation error returned by +// GetDirectoryReply.Validate if the designated constraints aren't met. +type GetDirectoryReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetDirectoryReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetDirectoryReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetDirectoryReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetDirectoryReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetDirectoryReplyValidationError) ErrorName() string { + return "GetDirectoryReplyValidationError" +} + +// Error satisfies the builtin error interface +func (e GetDirectoryReplyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetDirectoryReply.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetDirectoryReplyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetDirectoryReplyValidationError{} + +// Validate checks the field values on ListDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListDirectoryRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListDirectoryRequestMultiError, or nil if none found. +func (m *ListDirectoryRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ListDirectoryRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.Order != nil { + + if _, ok := _ListDirectoryRequest_Order_InLookup[m.GetOrder()]; !ok { + err := ListDirectoryRequestValidationError{ + field: "Order", + reason: "value must be in list [asc desc]", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if m.OrderBy != nil { + + if _, ok := _ListDirectoryRequest_OrderBy_InLookup[m.GetOrderBy()]; !ok { + err := ListDirectoryRequestValidationError{ + field: "OrderBy", + reason: "value must be in list [id created_at updated_at]", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if len(errors) > 0 { + return ListDirectoryRequestMultiError(errors) + } + + return nil +} + +// ListDirectoryRequestMultiError is an error wrapping multiple validation +// errors returned by ListDirectoryRequest.ValidateAll() if the designated +// constraints aren't met. +type ListDirectoryRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListDirectoryRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListDirectoryRequestMultiError) AllErrors() []error { return m } + +// ListDirectoryRequestValidationError is the validation error returned by +// ListDirectoryRequest.Validate if the designated constraints aren't met. +type ListDirectoryRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListDirectoryRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListDirectoryRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListDirectoryRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListDirectoryRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListDirectoryRequestValidationError) ErrorName() string { + return "ListDirectoryRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e ListDirectoryRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListDirectoryRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListDirectoryRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListDirectoryRequestValidationError{} + +var _ListDirectoryRequest_Order_InLookup = map[string]struct{}{ + "asc": {}, + "desc": {}, +} + +var _ListDirectoryRequest_OrderBy_InLookup = map[string]struct{}{ + "id": {}, + "created_at": {}, + "updated_at": {}, +} + +// Validate checks the field values on ListDirectoryReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListDirectoryReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListDirectoryReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListDirectoryReplyMultiError, or nil if none found. +func (m *ListDirectoryReply) ValidateAll() error { + return m.validate(true) +} + +func (m *ListDirectoryReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Total + + for idx, item := range m.GetList() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListDirectoryReplyValidationError{ + field: fmt.Sprintf("List[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListDirectoryReplyValidationError{ + field: fmt.Sprintf("List[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListDirectoryReplyValidationError{ + field: fmt.Sprintf("List[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ListDirectoryReplyMultiError(errors) + } + + return nil +} + +// ListDirectoryReplyMultiError is an error wrapping multiple validation errors +// returned by ListDirectoryReply.ValidateAll() if the designated constraints +// aren't met. +type ListDirectoryReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListDirectoryReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListDirectoryReplyMultiError) AllErrors() []error { return m } + +// ListDirectoryReplyValidationError is the validation error returned by +// ListDirectoryReply.Validate if the designated constraints aren't met. +type ListDirectoryReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListDirectoryReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListDirectoryReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListDirectoryReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListDirectoryReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListDirectoryReplyValidationError) ErrorName() string { + return "ListDirectoryReplyValidationError" +} + +// Error satisfies the builtin error interface +func (e ListDirectoryReplyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListDirectoryReply.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListDirectoryReplyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListDirectoryReplyValidationError{} + +// Validate checks the field values on CreateDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateDirectoryRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateDirectoryRequestMultiError, or nil if none found. +func (m *CreateDirectoryRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateDirectoryRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetParentId() <= 0 { + err := CreateDirectoryRequestValidationError{ + field: "ParentId", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetName()) < 1 { + err := CreateDirectoryRequestValidationError{ + field: "Name", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetAccept()) < 1 { + err := CreateDirectoryRequestValidationError{ + field: "Accept", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.GetMaxSize() < 1 { + err := CreateDirectoryRequestValidationError{ + field: "MaxSize", + reason: "value must be greater than or equal to 1", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return CreateDirectoryRequestMultiError(errors) + } + + return nil +} + +// CreateDirectoryRequestMultiError is an error wrapping multiple validation +// errors returned by CreateDirectoryRequest.ValidateAll() if the designated +// constraints aren't met. +type CreateDirectoryRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateDirectoryRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateDirectoryRequestMultiError) AllErrors() []error { return m } + +// CreateDirectoryRequestValidationError is the validation error returned by +// CreateDirectoryRequest.Validate if the designated constraints aren't met. +type CreateDirectoryRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateDirectoryRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateDirectoryRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateDirectoryRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateDirectoryRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateDirectoryRequestValidationError) ErrorName() string { + return "CreateDirectoryRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateDirectoryRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateDirectoryRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateDirectoryRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateDirectoryRequestValidationError{} + +// Validate checks the field values on CreateDirectoryReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateDirectoryReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateDirectoryReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateDirectoryReplyMultiError, or nil if none found. +func (m *CreateDirectoryReply) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateDirectoryReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Id + + if len(errors) > 0 { + return CreateDirectoryReplyMultiError(errors) + } + + return nil +} + +// CreateDirectoryReplyMultiError is an error wrapping multiple validation +// errors returned by CreateDirectoryReply.ValidateAll() if the designated +// constraints aren't met. +type CreateDirectoryReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateDirectoryReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateDirectoryReplyMultiError) AllErrors() []error { return m } + +// CreateDirectoryReplyValidationError is the validation error returned by +// CreateDirectoryReply.Validate if the designated constraints aren't met. +type CreateDirectoryReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateDirectoryReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateDirectoryReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateDirectoryReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateDirectoryReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateDirectoryReplyValidationError) ErrorName() string { + return "CreateDirectoryReplyValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateDirectoryReplyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateDirectoryReply.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateDirectoryReplyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateDirectoryReplyValidationError{} + +// Validate checks the field values on UpdateDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *UpdateDirectoryRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UpdateDirectoryRequestMultiError, or nil if none found. +func (m *UpdateDirectoryRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateDirectoryRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetId() <= 0 { + err := UpdateDirectoryRequestValidationError{ + field: "Id", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.GetParentId() <= 0 { + err := UpdateDirectoryRequestValidationError{ + field: "ParentId", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetName()) < 1 { + err := UpdateDirectoryRequestValidationError{ + field: "Name", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetAccept()) < 1 { + err := UpdateDirectoryRequestValidationError{ + field: "Accept", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.GetMaxSize() < 1 { + err := UpdateDirectoryRequestValidationError{ + field: "MaxSize", + reason: "value must be greater than or equal to 1", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return UpdateDirectoryRequestMultiError(errors) + } + + return nil +} + +// UpdateDirectoryRequestMultiError is an error wrapping multiple validation +// errors returned by UpdateDirectoryRequest.ValidateAll() if the designated +// constraints aren't met. +type UpdateDirectoryRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateDirectoryRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateDirectoryRequestMultiError) AllErrors() []error { return m } + +// UpdateDirectoryRequestValidationError is the validation error returned by +// UpdateDirectoryRequest.Validate if the designated constraints aren't met. +type UpdateDirectoryRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateDirectoryRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateDirectoryRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateDirectoryRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateDirectoryRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateDirectoryRequestValidationError) ErrorName() string { + return "UpdateDirectoryRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateDirectoryRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateDirectoryRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateDirectoryRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateDirectoryRequestValidationError{} + +// Validate checks the field values on UpdateDirectoryReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *UpdateDirectoryReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateDirectoryReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UpdateDirectoryReplyMultiError, or nil if none found. +func (m *UpdateDirectoryReply) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateDirectoryReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return UpdateDirectoryReplyMultiError(errors) + } + + return nil +} + +// UpdateDirectoryReplyMultiError is an error wrapping multiple validation +// errors returned by UpdateDirectoryReply.ValidateAll() if the designated +// constraints aren't met. +type UpdateDirectoryReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateDirectoryReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateDirectoryReplyMultiError) AllErrors() []error { return m } + +// UpdateDirectoryReplyValidationError is the validation error returned by +// UpdateDirectoryReply.Validate if the designated constraints aren't met. +type UpdateDirectoryReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateDirectoryReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateDirectoryReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateDirectoryReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateDirectoryReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateDirectoryReplyValidationError) ErrorName() string { + return "UpdateDirectoryReplyValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateDirectoryReplyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateDirectoryReply.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateDirectoryReplyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateDirectoryReplyValidationError{} + +// Validate checks the field values on DeleteDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteDirectoryRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteDirectoryRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteDirectoryRequestMultiError, or nil if none found. +func (m *DeleteDirectoryRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteDirectoryRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if l := len(m.GetIds()); l < 1 || l > 50 { + err := DeleteDirectoryRequestValidationError{ + field: "Ids", + reason: "value must contain between 1 and 50 items, inclusive", + } + if !all { + return err + } + errors = append(errors, err) + } + + _DeleteDirectoryRequest_Ids_Unique := make(map[uint32]struct{}, len(m.GetIds())) + + for idx, item := range m.GetIds() { + _, _ = idx, item + + if _, exists := _DeleteDirectoryRequest_Ids_Unique[item]; exists { + err := DeleteDirectoryRequestValidationError{ + field: fmt.Sprintf("Ids[%v]", idx), + reason: "repeated value must contain unique items", + } + if !all { + return err + } + errors = append(errors, err) + } else { + _DeleteDirectoryRequest_Ids_Unique[item] = struct{}{} + } + + // no validation rules for Ids[idx] + } + + if len(errors) > 0 { + return DeleteDirectoryRequestMultiError(errors) + } + + return nil +} + +// DeleteDirectoryRequestMultiError is an error wrapping multiple validation +// errors returned by DeleteDirectoryRequest.ValidateAll() if the designated +// constraints aren't met. +type DeleteDirectoryRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteDirectoryRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteDirectoryRequestMultiError) AllErrors() []error { return m } + +// DeleteDirectoryRequestValidationError is the validation error returned by +// DeleteDirectoryRequest.Validate if the designated constraints aren't met. +type DeleteDirectoryRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteDirectoryRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteDirectoryRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteDirectoryRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteDirectoryRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteDirectoryRequestValidationError) ErrorName() string { + return "DeleteDirectoryRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteDirectoryRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteDirectoryRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteDirectoryRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteDirectoryRequestValidationError{} + +// Validate checks the field values on DeleteDirectoryReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteDirectoryReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteDirectoryReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteDirectoryReplyMultiError, or nil if none found. +func (m *DeleteDirectoryReply) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteDirectoryReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Total + + if len(errors) > 0 { + return DeleteDirectoryReplyMultiError(errors) + } + + return nil +} + +// DeleteDirectoryReplyMultiError is an error wrapping multiple validation +// errors returned by DeleteDirectoryReply.ValidateAll() if the designated +// constraints aren't met. +type DeleteDirectoryReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteDirectoryReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteDirectoryReplyMultiError) AllErrors() []error { return m } + +// DeleteDirectoryReplyValidationError is the validation error returned by +// DeleteDirectoryReply.Validate if the designated constraints aren't met. +type DeleteDirectoryReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteDirectoryReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteDirectoryReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteDirectoryReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteDirectoryReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteDirectoryReplyValidationError) ErrorName() string { + return "DeleteDirectoryReplyValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteDirectoryReplyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteDirectoryReply.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteDirectoryReplyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteDirectoryReplyValidationError{} + +// Validate checks the field values on ListDirectoryReply_Directory with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListDirectoryReply_Directory) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListDirectoryReply_Directory with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListDirectoryReply_DirectoryMultiError, or nil if none found. +func (m *ListDirectoryReply_Directory) ValidateAll() error { + return m.validate(true) +} + +func (m *ListDirectoryReply_Directory) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Id + + // no validation rules for ParentId + + // no validation rules for Name + + // no validation rules for Accept + + // no validation rules for MaxSize + + // no validation rules for CreatedAt + + // no validation rules for UpdatedAt + + for idx, item := range m.GetChildren() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListDirectoryReply_DirectoryValidationError{ + field: fmt.Sprintf("Children[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListDirectoryReply_DirectoryValidationError{ + field: fmt.Sprintf("Children[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListDirectoryReply_DirectoryValidationError{ + field: fmt.Sprintf("Children[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ListDirectoryReply_DirectoryMultiError(errors) + } + + return nil +} + +// ListDirectoryReply_DirectoryMultiError is an error wrapping multiple +// validation errors returned by ListDirectoryReply_Directory.ValidateAll() if +// the designated constraints aren't met. +type ListDirectoryReply_DirectoryMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListDirectoryReply_DirectoryMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListDirectoryReply_DirectoryMultiError) AllErrors() []error { return m } + +// ListDirectoryReply_DirectoryValidationError is the validation error returned +// by ListDirectoryReply_Directory.Validate if the designated constraints +// aren't met. +type ListDirectoryReply_DirectoryValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListDirectoryReply_DirectoryValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListDirectoryReply_DirectoryValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListDirectoryReply_DirectoryValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListDirectoryReply_DirectoryValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListDirectoryReply_DirectoryValidationError) ErrorName() string { + return "ListDirectoryReply_DirectoryValidationError" +} + +// Error satisfies the builtin error interface +func (e ListDirectoryReply_DirectoryValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListDirectoryReply_Directory.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListDirectoryReply_DirectoryValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListDirectoryReply_DirectoryValidationError{} diff --git a/api/resource/directory/v1/resource_directory_service.pb.go b/api/resource/directory/v1/resource_directory_service.pb.go new file mode 100644 index 0000000..a501f70 --- /dev/null +++ b/api/resource/directory/v1/resource_directory_service.pb.go @@ -0,0 +1,151 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v4.24.4 +// source: api/resource/directory/resource_directory_service.proto + +package v1 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var File_api_resource_directory_resource_directory_service_proto protoreflect.FileDescriptor + +var file_api_resource_directory_resource_directory_service_proto_rawDesc = []byte{ + 0x0a, 0x37, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x22, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x1a, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xea, 0x06, 0x0a, + 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0xa2, 0x01, 0x0a, 0x0c, 0x47, + 0x65, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x37, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0xa7, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x38, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0xae, 0x01, 0x0a, 0x0f, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x3a, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, + 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, + 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0xae, 0x01, 0x0a, 0x0f, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x3a, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x1a, + 0x1a, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0xab, 0x01, 0x0a, 0x0f, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x3a, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x2a, 0x1a, 0x2f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x3c, 0x0a, 0x22, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x42, + 0x0b, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x56, 0x31, 0x50, 0x01, 0x5a, 0x07, + 0x2e, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_api_resource_directory_resource_directory_service_proto_goTypes = []interface{}{ + (*GetDirectoryRequest)(nil), // 0: resource.api.resource.directory.v1.GetDirectoryRequest + (*ListDirectoryRequest)(nil), // 1: resource.api.resource.directory.v1.ListDirectoryRequest + (*CreateDirectoryRequest)(nil), // 2: resource.api.resource.directory.v1.CreateDirectoryRequest + (*UpdateDirectoryRequest)(nil), // 3: resource.api.resource.directory.v1.UpdateDirectoryRequest + (*DeleteDirectoryRequest)(nil), // 4: resource.api.resource.directory.v1.DeleteDirectoryRequest + (*GetDirectoryReply)(nil), // 5: resource.api.resource.directory.v1.GetDirectoryReply + (*ListDirectoryReply)(nil), // 6: resource.api.resource.directory.v1.ListDirectoryReply + (*CreateDirectoryReply)(nil), // 7: resource.api.resource.directory.v1.CreateDirectoryReply + (*UpdateDirectoryReply)(nil), // 8: resource.api.resource.directory.v1.UpdateDirectoryReply + (*DeleteDirectoryReply)(nil), // 9: resource.api.resource.directory.v1.DeleteDirectoryReply +} +var file_api_resource_directory_resource_directory_service_proto_depIdxs = []int32{ + 0, // 0: resource.api.resource.directory.v1.Directory.GetDirectory:input_type -> resource.api.resource.directory.v1.GetDirectoryRequest + 1, // 1: resource.api.resource.directory.v1.Directory.ListDirectory:input_type -> resource.api.resource.directory.v1.ListDirectoryRequest + 2, // 2: resource.api.resource.directory.v1.Directory.CreateDirectory:input_type -> resource.api.resource.directory.v1.CreateDirectoryRequest + 3, // 3: resource.api.resource.directory.v1.Directory.UpdateDirectory:input_type -> resource.api.resource.directory.v1.UpdateDirectoryRequest + 4, // 4: resource.api.resource.directory.v1.Directory.DeleteDirectory:input_type -> resource.api.resource.directory.v1.DeleteDirectoryRequest + 5, // 5: resource.api.resource.directory.v1.Directory.GetDirectory:output_type -> resource.api.resource.directory.v1.GetDirectoryReply + 6, // 6: resource.api.resource.directory.v1.Directory.ListDirectory:output_type -> resource.api.resource.directory.v1.ListDirectoryReply + 7, // 7: resource.api.resource.directory.v1.Directory.CreateDirectory:output_type -> resource.api.resource.directory.v1.CreateDirectoryReply + 8, // 8: resource.api.resource.directory.v1.Directory.UpdateDirectory:output_type -> resource.api.resource.directory.v1.UpdateDirectoryReply + 9, // 9: resource.api.resource.directory.v1.Directory.DeleteDirectory:output_type -> resource.api.resource.directory.v1.DeleteDirectoryReply + 5, // [5:10] is the sub-list for method output_type + 0, // [0:5] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_api_resource_directory_resource_directory_service_proto_init() } +func file_api_resource_directory_resource_directory_service_proto_init() { + if File_api_resource_directory_resource_directory_service_proto != nil { + return + } + file_api_resource_directory_resource_directory_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_resource_directory_resource_directory_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_resource_directory_resource_directory_service_proto_goTypes, + DependencyIndexes: file_api_resource_directory_resource_directory_service_proto_depIdxs, + }.Build() + File_api_resource_directory_resource_directory_service_proto = out.File + file_api_resource_directory_resource_directory_service_proto_rawDesc = nil + file_api_resource_directory_resource_directory_service_proto_goTypes = nil + file_api_resource_directory_resource_directory_service_proto_depIdxs = nil +} diff --git a/api/resource/directory/v1/resource_directory_service_grpc.pb.go b/api/resource/directory/v1/resource_directory_service_grpc.pb.go new file mode 100644 index 0000000..f9594c4 --- /dev/null +++ b/api/resource/directory/v1/resource_directory_service_grpc.pb.go @@ -0,0 +1,267 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.24.4 +// source: api/resource/directory/resource_directory_service.proto + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + Directory_GetDirectory_FullMethodName = "/resource.api.resource.directory.v1.Directory/GetDirectory" + Directory_ListDirectory_FullMethodName = "/resource.api.resource.directory.v1.Directory/ListDirectory" + Directory_CreateDirectory_FullMethodName = "/resource.api.resource.directory.v1.Directory/CreateDirectory" + Directory_UpdateDirectory_FullMethodName = "/resource.api.resource.directory.v1.Directory/UpdateDirectory" + Directory_DeleteDirectory_FullMethodName = "/resource.api.resource.directory.v1.Directory/DeleteDirectory" +) + +// DirectoryClient is the client API for Directory 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 DirectoryClient interface { + // GetDirectory 获取指定的文件目录信息 + GetDirectory(ctx context.Context, in *GetDirectoryRequest, opts ...grpc.CallOption) (*GetDirectoryReply, error) + // ListDirectory 获取文件目录信息列表 + ListDirectory(ctx context.Context, in *ListDirectoryRequest, opts ...grpc.CallOption) (*ListDirectoryReply, error) + // CreateDirectory 创建文件目录信息 + CreateDirectory(ctx context.Context, in *CreateDirectoryRequest, opts ...grpc.CallOption) (*CreateDirectoryReply, error) + // UpdateDirectory 更新文件目录信息 + UpdateDirectory(ctx context.Context, in *UpdateDirectoryRequest, opts ...grpc.CallOption) (*UpdateDirectoryReply, error) + // DeleteDirectory 删除文件目录信息 + DeleteDirectory(ctx context.Context, in *DeleteDirectoryRequest, opts ...grpc.CallOption) (*DeleteDirectoryReply, error) +} + +type directoryClient struct { + cc grpc.ClientConnInterface +} + +func NewDirectoryClient(cc grpc.ClientConnInterface) DirectoryClient { + return &directoryClient{cc} +} + +func (c *directoryClient) GetDirectory(ctx context.Context, in *GetDirectoryRequest, opts ...grpc.CallOption) (*GetDirectoryReply, error) { + out := new(GetDirectoryReply) + err := c.cc.Invoke(ctx, Directory_GetDirectory_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *directoryClient) ListDirectory(ctx context.Context, in *ListDirectoryRequest, opts ...grpc.CallOption) (*ListDirectoryReply, error) { + out := new(ListDirectoryReply) + err := c.cc.Invoke(ctx, Directory_ListDirectory_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *directoryClient) CreateDirectory(ctx context.Context, in *CreateDirectoryRequest, opts ...grpc.CallOption) (*CreateDirectoryReply, error) { + out := new(CreateDirectoryReply) + err := c.cc.Invoke(ctx, Directory_CreateDirectory_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *directoryClient) UpdateDirectory(ctx context.Context, in *UpdateDirectoryRequest, opts ...grpc.CallOption) (*UpdateDirectoryReply, error) { + out := new(UpdateDirectoryReply) + err := c.cc.Invoke(ctx, Directory_UpdateDirectory_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *directoryClient) DeleteDirectory(ctx context.Context, in *DeleteDirectoryRequest, opts ...grpc.CallOption) (*DeleteDirectoryReply, error) { + out := new(DeleteDirectoryReply) + err := c.cc.Invoke(ctx, Directory_DeleteDirectory_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DirectoryServer is the server API for Directory service. +// All implementations must embed UnimplementedDirectoryServer +// for forward compatibility +type DirectoryServer interface { + // GetDirectory 获取指定的文件目录信息 + GetDirectory(context.Context, *GetDirectoryRequest) (*GetDirectoryReply, error) + // ListDirectory 获取文件目录信息列表 + ListDirectory(context.Context, *ListDirectoryRequest) (*ListDirectoryReply, error) + // CreateDirectory 创建文件目录信息 + CreateDirectory(context.Context, *CreateDirectoryRequest) (*CreateDirectoryReply, error) + // UpdateDirectory 更新文件目录信息 + UpdateDirectory(context.Context, *UpdateDirectoryRequest) (*UpdateDirectoryReply, error) + // DeleteDirectory 删除文件目录信息 + DeleteDirectory(context.Context, *DeleteDirectoryRequest) (*DeleteDirectoryReply, error) + mustEmbedUnimplementedDirectoryServer() +} + +// UnimplementedDirectoryServer must be embedded to have forward compatible implementations. +type UnimplementedDirectoryServer struct { +} + +func (UnimplementedDirectoryServer) GetDirectory(context.Context, *GetDirectoryRequest) (*GetDirectoryReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDirectory not implemented") +} +func (UnimplementedDirectoryServer) ListDirectory(context.Context, *ListDirectoryRequest) (*ListDirectoryReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListDirectory not implemented") +} +func (UnimplementedDirectoryServer) CreateDirectory(context.Context, *CreateDirectoryRequest) (*CreateDirectoryReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateDirectory not implemented") +} +func (UnimplementedDirectoryServer) UpdateDirectory(context.Context, *UpdateDirectoryRequest) (*UpdateDirectoryReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateDirectory not implemented") +} +func (UnimplementedDirectoryServer) DeleteDirectory(context.Context, *DeleteDirectoryRequest) (*DeleteDirectoryReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteDirectory not implemented") +} +func (UnimplementedDirectoryServer) mustEmbedUnimplementedDirectoryServer() {} + +// UnsafeDirectoryServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DirectoryServer will +// result in compilation errors. +type UnsafeDirectoryServer interface { + mustEmbedUnimplementedDirectoryServer() +} + +func RegisterDirectoryServer(s grpc.ServiceRegistrar, srv DirectoryServer) { + s.RegisterService(&Directory_ServiceDesc, srv) +} + +func _Directory_GetDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetDirectoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DirectoryServer).GetDirectory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Directory_GetDirectory_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DirectoryServer).GetDirectory(ctx, req.(*GetDirectoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Directory_ListDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListDirectoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DirectoryServer).ListDirectory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Directory_ListDirectory_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DirectoryServer).ListDirectory(ctx, req.(*ListDirectoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Directory_CreateDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateDirectoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DirectoryServer).CreateDirectory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Directory_CreateDirectory_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DirectoryServer).CreateDirectory(ctx, req.(*CreateDirectoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Directory_UpdateDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateDirectoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DirectoryServer).UpdateDirectory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Directory_UpdateDirectory_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DirectoryServer).UpdateDirectory(ctx, req.(*UpdateDirectoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Directory_DeleteDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteDirectoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DirectoryServer).DeleteDirectory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Directory_DeleteDirectory_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DirectoryServer).DeleteDirectory(ctx, req.(*DeleteDirectoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Directory_ServiceDesc is the grpc.ServiceDesc for Directory service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Directory_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "resource.api.resource.directory.v1.Directory", + HandlerType: (*DirectoryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetDirectory", + Handler: _Directory_GetDirectory_Handler, + }, + { + MethodName: "ListDirectory", + Handler: _Directory_ListDirectory_Handler, + }, + { + MethodName: "CreateDirectory", + Handler: _Directory_CreateDirectory_Handler, + }, + { + MethodName: "UpdateDirectory", + Handler: _Directory_UpdateDirectory_Handler, + }, + { + MethodName: "DeleteDirectory", + Handler: _Directory_DeleteDirectory_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/resource/directory/resource_directory_service.proto", +} diff --git a/api/resource/directory/v1/resource_directory_service_http.pb.go b/api/resource/directory/v1/resource_directory_service_http.pb.go new file mode 100644 index 0000000..4732f8c --- /dev/null +++ b/api/resource/directory/v1/resource_directory_service_http.pb.go @@ -0,0 +1,230 @@ +// Code generated by protoc-gen-go-http. DO NOT EDIT. +// versions: +// - protoc-gen-go-http v2.7.3 +// - protoc v4.24.4 +// source: api/resource/directory/resource_directory_service.proto + +package v1 + +import ( + context "context" + http "github.com/go-kratos/kratos/v2/transport/http" + binding "github.com/go-kratos/kratos/v2/transport/http/binding" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the kratos package it is being compiled against. +var _ = new(context.Context) +var _ = binding.EncodeURL + +const _ = http.SupportPackageIsVersion1 + +const OperationDirectoryCreateDirectory = "/resource.api.resource.directory.v1.Directory/CreateDirectory" +const OperationDirectoryDeleteDirectory = "/resource.api.resource.directory.v1.Directory/DeleteDirectory" +const OperationDirectoryGetDirectory = "/resource.api.resource.directory.v1.Directory/GetDirectory" +const OperationDirectoryListDirectory = "/resource.api.resource.directory.v1.Directory/ListDirectory" +const OperationDirectoryUpdateDirectory = "/resource.api.resource.directory.v1.Directory/UpdateDirectory" + +type DirectoryHTTPServer interface { + // CreateDirectory CreateDirectory 创建文件目录信息 + CreateDirectory(context.Context, *CreateDirectoryRequest) (*CreateDirectoryReply, error) + // DeleteDirectory DeleteDirectory 删除文件目录信息 + DeleteDirectory(context.Context, *DeleteDirectoryRequest) (*DeleteDirectoryReply, error) + // GetDirectory GetDirectory 获取指定的文件目录信息 + GetDirectory(context.Context, *GetDirectoryRequest) (*GetDirectoryReply, error) + // ListDirectory ListDirectory 获取文件目录信息列表 + ListDirectory(context.Context, *ListDirectoryRequest) (*ListDirectoryReply, error) + // UpdateDirectory UpdateDirectory 更新文件目录信息 + UpdateDirectory(context.Context, *UpdateDirectoryRequest) (*UpdateDirectoryReply, error) +} + +func RegisterDirectoryHTTPServer(s *http.Server, srv DirectoryHTTPServer) { + r := s.Route("/") + r.GET("/resource/api/v1/directory", _Directory_GetDirectory0_HTTP_Handler(srv)) + r.GET("/resource/api/v1/directories", _Directory_ListDirectory0_HTTP_Handler(srv)) + r.POST("/resource/api/v1/directory", _Directory_CreateDirectory0_HTTP_Handler(srv)) + r.PUT("/resource/api/v1/directory", _Directory_UpdateDirectory0_HTTP_Handler(srv)) + r.DELETE("/resource/api/v1/directory", _Directory_DeleteDirectory0_HTTP_Handler(srv)) +} + +func _Directory_GetDirectory0_HTTP_Handler(srv DirectoryHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in GetDirectoryRequest + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationDirectoryGetDirectory) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.GetDirectory(ctx, req.(*GetDirectoryRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*GetDirectoryReply) + return ctx.Result(200, reply) + } +} + +func _Directory_ListDirectory0_HTTP_Handler(srv DirectoryHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in ListDirectoryRequest + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationDirectoryListDirectory) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.ListDirectory(ctx, req.(*ListDirectoryRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*ListDirectoryReply) + return ctx.Result(200, reply) + } +} + +func _Directory_CreateDirectory0_HTTP_Handler(srv DirectoryHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in CreateDirectoryRequest + if err := ctx.Bind(&in); err != nil { + return err + } + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationDirectoryCreateDirectory) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.CreateDirectory(ctx, req.(*CreateDirectoryRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*CreateDirectoryReply) + return ctx.Result(200, reply) + } +} + +func _Directory_UpdateDirectory0_HTTP_Handler(srv DirectoryHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in UpdateDirectoryRequest + if err := ctx.Bind(&in); err != nil { + return err + } + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationDirectoryUpdateDirectory) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.UpdateDirectory(ctx, req.(*UpdateDirectoryRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*UpdateDirectoryReply) + return ctx.Result(200, reply) + } +} + +func _Directory_DeleteDirectory0_HTTP_Handler(srv DirectoryHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in DeleteDirectoryRequest + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationDirectoryDeleteDirectory) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.DeleteDirectory(ctx, req.(*DeleteDirectoryRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*DeleteDirectoryReply) + return ctx.Result(200, reply) + } +} + +type DirectoryHTTPClient interface { + CreateDirectory(ctx context.Context, req *CreateDirectoryRequest, opts ...http.CallOption) (rsp *CreateDirectoryReply, err error) + DeleteDirectory(ctx context.Context, req *DeleteDirectoryRequest, opts ...http.CallOption) (rsp *DeleteDirectoryReply, err error) + GetDirectory(ctx context.Context, req *GetDirectoryRequest, opts ...http.CallOption) (rsp *GetDirectoryReply, err error) + ListDirectory(ctx context.Context, req *ListDirectoryRequest, opts ...http.CallOption) (rsp *ListDirectoryReply, err error) + UpdateDirectory(ctx context.Context, req *UpdateDirectoryRequest, opts ...http.CallOption) (rsp *UpdateDirectoryReply, err error) +} + +type DirectoryHTTPClientImpl struct { + cc *http.Client +} + +func NewDirectoryHTTPClient(client *http.Client) DirectoryHTTPClient { + return &DirectoryHTTPClientImpl{client} +} + +func (c *DirectoryHTTPClientImpl) CreateDirectory(ctx context.Context, in *CreateDirectoryRequest, opts ...http.CallOption) (*CreateDirectoryReply, error) { + var out CreateDirectoryReply + pattern := "/resource/api/v1/directory" + path := binding.EncodeURL(pattern, in, false) + opts = append(opts, http.Operation(OperationDirectoryCreateDirectory)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *DirectoryHTTPClientImpl) DeleteDirectory(ctx context.Context, in *DeleteDirectoryRequest, opts ...http.CallOption) (*DeleteDirectoryReply, error) { + var out DeleteDirectoryReply + pattern := "/resource/api/v1/directory" + path := binding.EncodeURL(pattern, in, true) + opts = append(opts, http.Operation(OperationDirectoryDeleteDirectory)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *DirectoryHTTPClientImpl) GetDirectory(ctx context.Context, in *GetDirectoryRequest, opts ...http.CallOption) (*GetDirectoryReply, error) { + var out GetDirectoryReply + pattern := "/resource/api/v1/directory" + path := binding.EncodeURL(pattern, in, true) + opts = append(opts, http.Operation(OperationDirectoryGetDirectory)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *DirectoryHTTPClientImpl) ListDirectory(ctx context.Context, in *ListDirectoryRequest, opts ...http.CallOption) (*ListDirectoryReply, error) { + var out ListDirectoryReply + pattern := "/resource/api/v1/directories" + path := binding.EncodeURL(pattern, in, true) + opts = append(opts, http.Operation(OperationDirectoryListDirectory)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *DirectoryHTTPClientImpl) UpdateDirectory(ctx context.Context, in *UpdateDirectoryRequest, opts ...http.CallOption) (*UpdateDirectoryReply, error) { + var out UpdateDirectoryReply + pattern := "/resource/api/v1/directory" + path := binding.EncodeURL(pattern, in, false) + opts = append(opts, http.Operation(OperationDirectoryUpdateDirectory)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} diff --git a/api/export/openapi.yaml b/api/resource/errors/openapi.yaml similarity index 100% rename from api/export/openapi.yaml rename to api/resource/errors/openapi.yaml diff --git a/api/resource/errors/resource_error_reason.pb.go b/api/resource/errors/resource_error_reason.pb.go new file mode 100644 index 0000000..534d03a --- /dev/null +++ b/api/resource/errors/resource_error_reason.pb.go @@ -0,0 +1,302 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v4.24.4 +// source: api/resource/errors/resource_error_reason.proto + +package errors + +import ( + _ "github.com/go-kratos/kratos/v2/errors" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ErrorReason int32 + +const ( + ErrorReason_ParamsError ErrorReason = 0 + ErrorReason_DatabaseError ErrorReason = 1 + ErrorReason_TransformError ErrorReason = 2 + ErrorReason_GetError ErrorReason = 3 + ErrorReason_ListError ErrorReason = 4 + ErrorReason_CreateError ErrorReason = 5 + ErrorReason_ImportError ErrorReason = 6 + ErrorReason_ExportError ErrorReason = 7 + ErrorReason_UpdateError ErrorReason = 8 + ErrorReason_DeleteError ErrorReason = 9 + ErrorReason_GetTrashError ErrorReason = 10 + ErrorReason_ListTrashError ErrorReason = 11 + ErrorReason_DeleteTrashError ErrorReason = 12 + ErrorReason_RevertTrashError ErrorReason = 13 + ErrorReason_NoSupportStoreError ErrorReason = 14 + ErrorReason_NoSupportFileTypeError ErrorReason = 15 + ErrorReason_VerifySignError ErrorReason = 16 + ErrorReason_SystemError ErrorReason = 17 + ErrorReason_ChunkUploadError ErrorReason = 18 + ErrorReason_StatusProgressError ErrorReason = 19 + ErrorReason_UploadFileError ErrorReason = 20 + ErrorReason_InitStoreError ErrorReason = 21 + ErrorReason_FileFormatError ErrorReason = 22 + ErrorReason_NotExistFileError ErrorReason = 23 + ErrorReason_AlreadyExistFileNameError ErrorReason = 24 + ErrorReason_AccessResourceError ErrorReason = 25 + ErrorReason_ExportFileNameDupError ErrorReason = 26 + ErrorReason_ExportTaskProcessError ErrorReason = 27 + ErrorReason_ResourceServerError ErrorReason = 28 + ErrorReason_ExceedMaxSizeError ErrorReason = 29 +) + +// Enum value maps for ErrorReason. +var ( + ErrorReason_name = map[int32]string{ + 0: "ParamsError", + 1: "DatabaseError", + 2: "TransformError", + 3: "GetError", + 4: "ListError", + 5: "CreateError", + 6: "ImportError", + 7: "ExportError", + 8: "UpdateError", + 9: "DeleteError", + 10: "GetTrashError", + 11: "ListTrashError", + 12: "DeleteTrashError", + 13: "RevertTrashError", + 14: "NoSupportStoreError", + 15: "NoSupportFileTypeError", + 16: "VerifySignError", + 17: "SystemError", + 18: "ChunkUploadError", + 19: "StatusProgressError", + 20: "UploadFileError", + 21: "InitStoreError", + 22: "FileFormatError", + 23: "NotExistFileError", + 24: "AlreadyExistFileNameError", + 25: "AccessResourceError", + 26: "ExportFileNameDupError", + 27: "ExportTaskProcessError", + 28: "ResourceServerError", + 29: "ExceedMaxSizeError", + } + ErrorReason_value = map[string]int32{ + "ParamsError": 0, + "DatabaseError": 1, + "TransformError": 2, + "GetError": 3, + "ListError": 4, + "CreateError": 5, + "ImportError": 6, + "ExportError": 7, + "UpdateError": 8, + "DeleteError": 9, + "GetTrashError": 10, + "ListTrashError": 11, + "DeleteTrashError": 12, + "RevertTrashError": 13, + "NoSupportStoreError": 14, + "NoSupportFileTypeError": 15, + "VerifySignError": 16, + "SystemError": 17, + "ChunkUploadError": 18, + "StatusProgressError": 19, + "UploadFileError": 20, + "InitStoreError": 21, + "FileFormatError": 22, + "NotExistFileError": 23, + "AlreadyExistFileNameError": 24, + "AccessResourceError": 25, + "ExportFileNameDupError": 26, + "ExportTaskProcessError": 27, + "ResourceServerError": 28, + "ExceedMaxSizeError": 29, + } +) + +func (x ErrorReason) Enum() *ErrorReason { + p := new(ErrorReason) + *p = x + return p +} + +func (x ErrorReason) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ErrorReason) Descriptor() protoreflect.EnumDescriptor { + return file_api_resource_errors_resource_error_reason_proto_enumTypes[0].Descriptor() +} + +func (ErrorReason) Type() protoreflect.EnumType { + return &file_api_resource_errors_resource_error_reason_proto_enumTypes[0] +} + +func (x ErrorReason) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ErrorReason.Descriptor instead. +func (ErrorReason) EnumDescriptor() ([]byte, []int) { + return file_api_resource_errors_resource_error_reason_proto_rawDescGZIP(), []int{0} +} + +var File_api_resource_errors_resource_error_reason_proto protoreflect.FileDescriptor + +var file_api_resource_errors_resource_error_reason_proto_rawDesc = []byte{ + 0x0a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x1a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x73, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0x99, + 0x0b, 0x0a, 0x0b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x20, + 0x0a, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x00, 0x1a, + 0x0f, 0xb2, 0x45, 0x0c, 0xe5, 0x8f, 0x82, 0xe6, 0x95, 0xb0, 0xe9, 0x94, 0x99, 0xe8, 0xaf, 0xaf, + 0x12, 0x25, 0x0a, 0x0d, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x10, 0x01, 0x1a, 0x12, 0xb2, 0x45, 0x0f, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xba, + 0x93, 0xe9, 0x94, 0x99, 0xe8, 0xaf, 0xaf, 0x12, 0x29, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x02, 0x1a, 0x15, 0xb2, 0x45, 0x12, + 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe8, 0xbd, 0xac, 0xe6, 0x8d, 0xa2, 0xe5, 0xa4, 0xb1, 0xe8, + 0xb4, 0xa5, 0x12, 0x23, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x03, + 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, + 0xae, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x2a, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x10, 0x04, 0x1a, 0x1b, 0xb2, 0x45, 0x18, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, + 0x96, 0xe5, 0x88, 0x97, 0xe8, 0xa1, 0xa8, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, 0xb1, + 0xe8, 0xb4, 0xa5, 0x12, 0x26, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x10, 0x05, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe5, 0x88, 0x9b, 0xe5, 0xbb, 0xba, 0xe6, + 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x26, 0x0a, 0x0b, 0x49, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x06, 0x1a, 0x15, 0xb2, 0x45, + 0x12, 0xe5, 0xaf, 0xbc, 0xe5, 0x85, 0xa5, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, 0xb1, + 0xe8, 0xb4, 0xa5, 0x12, 0x26, 0x0a, 0x0b, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x10, 0x07, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe5, 0xaf, 0xbc, 0xe5, 0x87, 0xba, 0xe6, + 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x26, 0x0a, 0x0b, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x08, 0x1a, 0x15, 0xb2, 0x45, + 0x12, 0xe6, 0x9b, 0xb4, 0xe6, 0x96, 0xb0, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, 0xb1, + 0xe8, 0xb4, 0xa5, 0x12, 0x26, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x10, 0x09, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe5, 0x88, 0xa0, 0xe9, 0x99, 0xa4, 0xe6, + 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x31, 0x0a, 0x0d, 0x47, + 0x65, 0x74, 0x54, 0x72, 0x61, 0x73, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x0a, 0x1a, 0x1e, + 0xb2, 0x45, 0x1b, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0xe5, 0x9b, 0x9e, 0xe6, 0x94, 0xb6, 0xe7, + 0xab, 0x99, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x38, + 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x73, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x10, 0x0b, 0x1a, 0x24, 0xb2, 0x45, 0x21, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0xe5, 0x9b, 0x9e, + 0xe6, 0x94, 0xb6, 0xe7, 0xab, 0x99, 0xe5, 0x88, 0x97, 0xe8, 0xa1, 0xa8, 0xe6, 0x95, 0xb0, 0xe6, + 0x8d, 0xae, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x34, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x54, 0x72, 0x61, 0x73, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x0c, 0x1a, 0x1e, + 0xb2, 0x45, 0x1b, 0xe5, 0x88, 0xa0, 0xe9, 0x99, 0xa4, 0xe5, 0x9b, 0x9e, 0xe6, 0x94, 0xb6, 0xe7, + 0xab, 0x99, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x34, + 0x0a, 0x10, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x54, 0x72, 0x61, 0x73, 0x68, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x10, 0x0d, 0x1a, 0x1e, 0xb2, 0x45, 0x1b, 0xe8, 0xbf, 0x98, 0xe5, 0x8e, 0x9f, 0xe5, + 0x9b, 0x9e, 0xe6, 0x94, 0xb6, 0xe7, 0xab, 0x99, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, + 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x34, 0x0a, 0x13, 0x4e, 0x6f, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x0e, 0x1a, 0x1b, 0xb2, + 0x45, 0x18, 0xe4, 0xb8, 0x8d, 0xe6, 0x94, 0xaf, 0xe6, 0x8c, 0x81, 0xe7, 0x9a, 0x84, 0xe5, 0xad, + 0x98, 0xe5, 0x82, 0xa8, 0xe5, 0xbc, 0x95, 0xe6, 0x93, 0x8e, 0x12, 0x37, 0x0a, 0x16, 0x4e, 0x6f, + 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x10, 0x0f, 0x1a, 0x1b, 0xb2, 0x45, 0x18, 0xe4, 0xb8, 0x8d, 0xe6, 0x94, + 0xaf, 0xe6, 0x8c, 0x81, 0xe7, 0x9a, 0x84, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe7, 0xb1, 0xbb, + 0xe5, 0x9e, 0x8b, 0x12, 0x2a, 0x0a, 0x0f, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x69, 0x67, + 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x10, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe7, 0xad, 0xbe, + 0xe5, 0x90, 0x8d, 0xe9, 0xaa, 0x8c, 0xe8, 0xaf, 0x81, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, + 0x20, 0x0a, 0x0b, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x11, + 0x1a, 0x0f, 0xb2, 0x45, 0x0c, 0xe7, 0xb3, 0xbb, 0xe7, 0xbb, 0x9f, 0xe9, 0x94, 0x99, 0xe8, 0xaf, + 0xaf, 0x12, 0x2b, 0x0a, 0x10, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x12, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe5, 0x88, 0x86, 0xe7, + 0x89, 0x87, 0xe4, 0xb8, 0x8a, 0xe4, 0xbc, 0xa0, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x2b, + 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x13, 0x1a, 0x12, 0xb2, 0x45, 0x0f, 0xe6, 0x96, 0x87, 0xe4, + 0xbb, 0xb6, 0xe4, 0xb8, 0x8a, 0xe4, 0xbc, 0xa0, 0xe4, 0xb8, 0xad, 0x12, 0x2a, 0x0a, 0x0f, 0x55, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x14, + 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe4, 0xb8, 0x8a, 0xe4, 0xbc, + 0xa0, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x32, 0x0a, 0x0e, 0x49, 0x6e, 0x69, 0x74, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x15, 0x1a, 0x1e, 0xb2, 0x45, 0x1b, + 0xe5, 0xad, 0x98, 0xe5, 0x82, 0xa8, 0xe5, 0xbc, 0x95, 0xe6, 0x93, 0x8e, 0xe5, 0x88, 0x9d, 0xe5, + 0xa7, 0x8b, 0xe5, 0x8c, 0x96, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0x12, 0x2a, 0x0a, 0x0f, 0x46, + 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x16, + 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe6, 0xa0, 0xbc, 0xe5, 0xbc, + 0x8f, 0xe9, 0x94, 0x99, 0xe8, 0xaf, 0xaf, 0x12, 0x29, 0x0a, 0x11, 0x4e, 0x6f, 0x74, 0x45, 0x78, + 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x17, 0x1a, 0x12, + 0xb2, 0x45, 0x0f, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe4, 0xb8, 0x8d, 0xe5, 0xad, 0x98, 0xe5, + 0x9c, 0xa8, 0x12, 0x34, 0x0a, 0x19, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, + 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, + 0x18, 0x1a, 0x15, 0xb2, 0x45, 0x12, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe5, 0x90, 0x8d, 0xe5, + 0xb7, 0xb2, 0xe5, 0xad, 0x98, 0xe5, 0x9c, 0xa8, 0x12, 0x34, 0x0a, 0x13, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, + 0x19, 0x1a, 0x1b, 0xb2, 0x45, 0x18, 0xe8, 0xae, 0xbf, 0xe9, 0x97, 0xae, 0xe8, 0xb5, 0x84, 0xe6, + 0xba, 0x90, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe5, 0xbc, 0x82, 0xe5, 0xb8, 0xb8, 0x12, 0x3a, + 0x0a, 0x16, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x44, 0x75, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x1a, 0x1a, 0x1e, 0xb2, 0x45, 0x1b, 0xe5, + 0xaf, 0xbc, 0xe5, 0x87, 0xba, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe9, 0x87, 0x8d, 0xe5, 0x91, + 0xbd, 0xe5, 0x90, 0x8d, 0xe9, 0x87, 0x8d, 0xe5, 0xa4, 0x8d, 0x12, 0x3a, 0x0a, 0x16, 0x45, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x10, 0x1b, 0x1a, 0x1e, 0xb2, 0x45, 0x1b, 0xe5, 0xaf, 0xbc, 0xe5, 0x87, + 0xba, 0xe4, 0xbb, 0xbb, 0xe5, 0x8a, 0xa1, 0xe6, 0xad, 0xa3, 0xe5, 0x9c, 0xa8, 0xe8, 0xbf, 0x9b, + 0xe8, 0xa1, 0x8c, 0xe4, 0xb8, 0xad, 0x12, 0x2e, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x1c, 0x1a, + 0x15, 0xb2, 0x45, 0x12, 0xe8, 0xb5, 0x84, 0xe6, 0xba, 0x90, 0xe6, 0x9c, 0x8d, 0xe5, 0x8a, 0xa1, + 0xe5, 0xbc, 0x82, 0xe5, 0xb8, 0xb8, 0x12, 0x3c, 0x0a, 0x12, 0x45, 0x78, 0x63, 0x65, 0x65, 0x64, + 0x4d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x1d, 0x1a, 0x24, + 0xb2, 0x45, 0x21, 0xe8, 0xb6, 0x85, 0xe8, 0xbf, 0x87, 0xe5, 0x85, 0x81, 0xe8, 0xae, 0xb8, 0xe4, + 0xb8, 0x8a, 0xe4, 0xbc, 0xa0, 0xe7, 0x9a, 0x84, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe5, 0xa4, + 0xa7, 0xe5, 0xb0, 0x8f, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, + 0x3b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_resource_errors_resource_error_reason_proto_rawDescOnce sync.Once + file_api_resource_errors_resource_error_reason_proto_rawDescData = file_api_resource_errors_resource_error_reason_proto_rawDesc +) + +func file_api_resource_errors_resource_error_reason_proto_rawDescGZIP() []byte { + file_api_resource_errors_resource_error_reason_proto_rawDescOnce.Do(func() { + file_api_resource_errors_resource_error_reason_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_resource_errors_resource_error_reason_proto_rawDescData) + }) + return file_api_resource_errors_resource_error_reason_proto_rawDescData +} + +var file_api_resource_errors_resource_error_reason_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_api_resource_errors_resource_error_reason_proto_goTypes = []interface{}{ + (ErrorReason)(0), // 0: errors.ErrorReason +} +var file_api_resource_errors_resource_error_reason_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_api_resource_errors_resource_error_reason_proto_init() } +func file_api_resource_errors_resource_error_reason_proto_init() { + if File_api_resource_errors_resource_error_reason_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_resource_errors_resource_error_reason_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_resource_errors_resource_error_reason_proto_goTypes, + DependencyIndexes: file_api_resource_errors_resource_error_reason_proto_depIdxs, + EnumInfos: file_api_resource_errors_resource_error_reason_proto_enumTypes, + }.Build() + File_api_resource_errors_resource_error_reason_proto = out.File + file_api_resource_errors_resource_error_reason_proto_rawDesc = nil + file_api_resource_errors_resource_error_reason_proto_goTypes = nil + file_api_resource_errors_resource_error_reason_proto_depIdxs = nil +} diff --git a/api/resource/errors/resource_error_reason.proto b/api/resource/errors/resource_error_reason.proto new file mode 100755 index 0000000..e126137 --- /dev/null +++ b/api/resource/errors/resource_error_reason.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +package errors; + +import "errors/errors.proto"; +option go_package = "./;errors"; + +enum ErrorReason { + // 设置缺省错误码 + option (errors.default_code) = 500; + + ParamsError = 0[(errors.message)="参数错误"]; + DatabaseError = 1[(errors.message)="数据库错误"]; + TransformError = 2[(errors.message)="数据转换失败"]; + GetError = 3[(errors.message)="获取数据失败"]; + ListError = 4[(errors.message)="获取列表数据失败"]; + CreateError = 5[(errors.message)="创建数据失败"]; + ImportError = 6[(errors.message)="导入数据失败"]; + ExportError = 7[(errors.message)="导出数据失败"]; + UpdateError = 8[(errors.message)="更新数据失败"]; + DeleteError = 9[(errors.message)="删除数据失败"]; + GetTrashError = 10[(errors.message)="获取回收站数据失败"]; + ListTrashError = 11[(errors.message)="获取回收站列表数据失败"]; + DeleteTrashError = 12[(errors.message)="删除回收站数据失败"]; + RevertTrashError = 13[(errors.message)="还原回收站数据失败"]; + NoSupportStoreError = 14[(errors.message)="不支持的存储引擎"]; + NoSupportFileTypeError = 15[(errors.message)="不支持的文件类型"]; + VerifySignError = 16[(errors.message)="签名验证失败"]; + SystemError = 17[(errors.message)="系统错误"]; + ChunkUploadError = 18[(errors.message)="分片上传失败"]; + StatusProgressError = 19[(errors.message)="文件上传中"]; + UploadFileError = 20[(errors.message)="文件上传失败"]; + InitStoreError = 21[(errors.message)="存储引擎初始化失败"]; + FileFormatError = 22[(errors.message)="文件格式错误"]; + NotExistFileError = 23[(errors.message)="文件不存在"]; + AlreadyExistFileNameError = 24[(errors.message)="文件名已存在"]; + AccessResourceError = 25[(errors.message)="访问资源文件异常"]; + ExportFileNameDupError = 26[(errors.message)="导出文件重命名重复"]; + ExportTaskProcessError = 27[(errors.message)="导出任务正在进行中"]; + ResourceServerError = 28[(errors.message)="资源服务异常"]; + ExceedMaxSizeError = 29[(errors.message)="超过允许上传的文件大小"]; +} \ No newline at end of file diff --git a/api/resource/errors/resource_error_reason_errors.pb.go b/api/resource/errors/resource_error_reason_errors.pb.go new file mode 100644 index 0000000..ee01b73 --- /dev/null +++ b/api/resource/errors/resource_error_reason_errors.pb.go @@ -0,0 +1,612 @@ +// Code generated by protoc-gen-go-errors. DO NOT EDIT. + +package errors + +import ( + fmt "fmt" + errors "github.com/go-kratos/kratos/v2/errors" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the kratos package it is being compiled against. +const _ = errors.SupportPackageIsVersion1 + +func IsParamsError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ParamsError.String() && e.Code == 500 +} + +func ParamsError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ParamsError.String(), "参数错误") + case 1: + return errors.New(500, ErrorReason_ParamsError.String(), "参数错误:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ParamsError.String(), "参数错误:"+msg) + } +} + +func IsDatabaseError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_DatabaseError.String() && e.Code == 500 +} + +func DatabaseError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_DatabaseError.String(), "数据库错误") + case 1: + return errors.New(500, ErrorReason_DatabaseError.String(), "数据库错误:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_DatabaseError.String(), "数据库错误:"+msg) + } +} + +func IsTransformError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_TransformError.String() && e.Code == 500 +} + +func TransformError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_TransformError.String(), "数据转换失败") + case 1: + return errors.New(500, ErrorReason_TransformError.String(), "数据转换失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_TransformError.String(), "数据转换失败:"+msg) + } +} + +func IsGetError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_GetError.String() && e.Code == 500 +} + +func GetError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_GetError.String(), "获取数据失败") + case 1: + return errors.New(500, ErrorReason_GetError.String(), "获取数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_GetError.String(), "获取数据失败:"+msg) + } +} + +func IsListError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ListError.String() && e.Code == 500 +} + +func ListError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ListError.String(), "获取列表数据失败") + case 1: + return errors.New(500, ErrorReason_ListError.String(), "获取列表数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ListError.String(), "获取列表数据失败:"+msg) + } +} + +func IsCreateError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_CreateError.String() && e.Code == 500 +} + +func CreateError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_CreateError.String(), "创建数据失败") + case 1: + return errors.New(500, ErrorReason_CreateError.String(), "创建数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_CreateError.String(), "创建数据失败:"+msg) + } +} + +func IsImportError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ImportError.String() && e.Code == 500 +} + +func ImportError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ImportError.String(), "导入数据失败") + case 1: + return errors.New(500, ErrorReason_ImportError.String(), "导入数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ImportError.String(), "导入数据失败:"+msg) + } +} + +func IsExportError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ExportError.String() && e.Code == 500 +} + +func ExportError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ExportError.String(), "导出数据失败") + case 1: + return errors.New(500, ErrorReason_ExportError.String(), "导出数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ExportError.String(), "导出数据失败:"+msg) + } +} + +func IsUpdateError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_UpdateError.String() && e.Code == 500 +} + +func UpdateError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_UpdateError.String(), "更新数据失败") + case 1: + return errors.New(500, ErrorReason_UpdateError.String(), "更新数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_UpdateError.String(), "更新数据失败:"+msg) + } +} + +func IsDeleteError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_DeleteError.String() && e.Code == 500 +} + +func DeleteError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_DeleteError.String(), "删除数据失败") + case 1: + return errors.New(500, ErrorReason_DeleteError.String(), "删除数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_DeleteError.String(), "删除数据失败:"+msg) + } +} + +func IsGetTrashError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_GetTrashError.String() && e.Code == 500 +} + +func GetTrashError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_GetTrashError.String(), "获取回收站数据失败") + case 1: + return errors.New(500, ErrorReason_GetTrashError.String(), "获取回收站数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_GetTrashError.String(), "获取回收站数据失败:"+msg) + } +} + +func IsListTrashError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ListTrashError.String() && e.Code == 500 +} + +func ListTrashError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ListTrashError.String(), "获取回收站列表数据失败") + case 1: + return errors.New(500, ErrorReason_ListTrashError.String(), "获取回收站列表数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ListTrashError.String(), "获取回收站列表数据失败:"+msg) + } +} + +func IsDeleteTrashError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_DeleteTrashError.String() && e.Code == 500 +} + +func DeleteTrashError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_DeleteTrashError.String(), "删除回收站数据失败") + case 1: + return errors.New(500, ErrorReason_DeleteTrashError.String(), "删除回收站数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_DeleteTrashError.String(), "删除回收站数据失败:"+msg) + } +} + +func IsRevertTrashError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_RevertTrashError.String() && e.Code == 500 +} + +func RevertTrashError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_RevertTrashError.String(), "还原回收站数据失败") + case 1: + return errors.New(500, ErrorReason_RevertTrashError.String(), "还原回收站数据失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_RevertTrashError.String(), "还原回收站数据失败:"+msg) + } +} + +func IsNoSupportStoreError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_NoSupportStoreError.String() && e.Code == 500 +} + +func NoSupportStoreError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_NoSupportStoreError.String(), "不支持的存储引擎") + case 1: + return errors.New(500, ErrorReason_NoSupportStoreError.String(), "不支持的存储引擎:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_NoSupportStoreError.String(), "不支持的存储引擎:"+msg) + } +} + +func IsNoSupportFileTypeError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_NoSupportFileTypeError.String() && e.Code == 500 +} + +func NoSupportFileTypeError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_NoSupportFileTypeError.String(), "不支持的文件类型") + case 1: + return errors.New(500, ErrorReason_NoSupportFileTypeError.String(), "不支持的文件类型:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_NoSupportFileTypeError.String(), "不支持的文件类型:"+msg) + } +} + +func IsVerifySignError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_VerifySignError.String() && e.Code == 500 +} + +func VerifySignError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_VerifySignError.String(), "签名验证失败") + case 1: + return errors.New(500, ErrorReason_VerifySignError.String(), "签名验证失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_VerifySignError.String(), "签名验证失败:"+msg) + } +} + +func IsSystemError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_SystemError.String() && e.Code == 500 +} + +func SystemError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_SystemError.String(), "系统错误") + case 1: + return errors.New(500, ErrorReason_SystemError.String(), "系统错误:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_SystemError.String(), "系统错误:"+msg) + } +} + +func IsChunkUploadError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ChunkUploadError.String() && e.Code == 500 +} + +func ChunkUploadError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ChunkUploadError.String(), "分片上传失败") + case 1: + return errors.New(500, ErrorReason_ChunkUploadError.String(), "分片上传失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ChunkUploadError.String(), "分片上传失败:"+msg) + } +} + +func IsStatusProgressError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_StatusProgressError.String() && e.Code == 500 +} + +func StatusProgressError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_StatusProgressError.String(), "文件上传中") + case 1: + return errors.New(500, ErrorReason_StatusProgressError.String(), "文件上传中:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_StatusProgressError.String(), "文件上传中:"+msg) + } +} + +func IsUploadFileError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_UploadFileError.String() && e.Code == 500 +} + +func UploadFileError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_UploadFileError.String(), "文件上传失败") + case 1: + return errors.New(500, ErrorReason_UploadFileError.String(), "文件上传失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_UploadFileError.String(), "文件上传失败:"+msg) + } +} + +func IsInitStoreError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_InitStoreError.String() && e.Code == 500 +} + +func InitStoreError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_InitStoreError.String(), "存储引擎初始化失败") + case 1: + return errors.New(500, ErrorReason_InitStoreError.String(), "存储引擎初始化失败:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_InitStoreError.String(), "存储引擎初始化失败:"+msg) + } +} + +func IsFileFormatError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_FileFormatError.String() && e.Code == 500 +} + +func FileFormatError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_FileFormatError.String(), "文件格式错误") + case 1: + return errors.New(500, ErrorReason_FileFormatError.String(), "文件格式错误:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_FileFormatError.String(), "文件格式错误:"+msg) + } +} + +func IsNotExistFileError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_NotExistFileError.String() && e.Code == 500 +} + +func NotExistFileError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_NotExistFileError.String(), "文件不存在") + case 1: + return errors.New(500, ErrorReason_NotExistFileError.String(), "文件不存在:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_NotExistFileError.String(), "文件不存在:"+msg) + } +} + +func IsAlreadyExistFileNameError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_AlreadyExistFileNameError.String() && e.Code == 500 +} + +func AlreadyExistFileNameError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_AlreadyExistFileNameError.String(), "文件名已存在") + case 1: + return errors.New(500, ErrorReason_AlreadyExistFileNameError.String(), "文件名已存在:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_AlreadyExistFileNameError.String(), "文件名已存在:"+msg) + } +} + +func IsAccessResourceError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_AccessResourceError.String() && e.Code == 500 +} + +func AccessResourceError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_AccessResourceError.String(), "访问资源文件异常") + case 1: + return errors.New(500, ErrorReason_AccessResourceError.String(), "访问资源文件异常:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_AccessResourceError.String(), "访问资源文件异常:"+msg) + } +} + +func IsExportFileNameDupError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ExportFileNameDupError.String() && e.Code == 500 +} + +func ExportFileNameDupError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ExportFileNameDupError.String(), "导出文件重命名重复") + case 1: + return errors.New(500, ErrorReason_ExportFileNameDupError.String(), "导出文件重命名重复:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ExportFileNameDupError.String(), "导出文件重命名重复:"+msg) + } +} + +func IsExportTaskProcessError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ExportTaskProcessError.String() && e.Code == 500 +} + +func ExportTaskProcessError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ExportTaskProcessError.String(), "导出任务正在进行中") + case 1: + return errors.New(500, ErrorReason_ExportTaskProcessError.String(), "导出任务正在进行中:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ExportTaskProcessError.String(), "导出任务正在进行中:"+msg) + } +} + +func IsResourceServerError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ResourceServerError.String() && e.Code == 500 +} + +func ResourceServerError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ResourceServerError.String(), "资源服务异常") + case 1: + return errors.New(500, ErrorReason_ResourceServerError.String(), "资源服务异常:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ResourceServerError.String(), "资源服务异常:"+msg) + } +} + +func IsExceedMaxSizeError(err error) bool { + if err == nil { + return false + } + e := errors.FromError(err) + return e.Reason == ErrorReason_ExceedMaxSizeError.String() && e.Code == 500 +} + +func ExceedMaxSizeError(args ...any) *errors.Error { + switch len(args) { + case 0: + return errors.New(500, ErrorReason_ExceedMaxSizeError.String(), "超过允许上传的文件大小") + case 1: + return errors.New(500, ErrorReason_ExceedMaxSizeError.String(), "超过允许上传的文件大小:"+fmt.Sprint(args[0])) + default: + msg := fmt.Sprintf(fmt.Sprint(args[0]), args[1:]...) + return errors.New(500, ErrorReason_ExceedMaxSizeError.String(), "超过允许上传的文件大小:"+msg) + } +} diff --git a/api/resource/export/openapi.yaml b/api/resource/export/openapi.yaml new file mode 100644 index 0000000..5f1f44f --- /dev/null +++ b/api/resource/export/openapi.yaml @@ -0,0 +1,208 @@ +# Generated with protoc-gen-openapi +# https://github.com/google/gnostic/tree/master/cmd/protoc-gen-openapi + +openapi: 3.0.3 +info: + title: Export API + version: 0.0.1 +paths: + /resource/api/v1/export: + post: + tags: + - Export + description: CreateExport 创建导出信息 + operationId: Export_CreateExport + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateExportRequest' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CreateExportReply' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' + delete: + tags: + - Export + description: DeleteExport 删除导出信息 + operationId: Export_DeleteExport + parameters: + - name: ids + in: query + schema: + type: array + items: + type: integer + format: uint32 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/DeleteExportReply' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' + /resource/api/v1/exports: + get: + tags: + - Export + description: ListExport 获取导出信息列表 + operationId: Export_ListExport + parameters: + - name: page + in: query + schema: + type: integer + format: uint32 + - name: pageSize + in: query + schema: + type: integer + format: uint32 + - name: order + in: query + schema: + type: string + - name: orderBy + in: query + schema: + type: string + - name: userId + in: query + schema: + type: integer + format: uint32 + - name: departmentId + in: query + schema: + type: integer + format: uint32 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListExportReply' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' +components: + schemas: + CreateExportReply: + type: object + properties: + id: + type: integer + format: uint32 + CreateExportRequest: + type: object + properties: + userId: + type: integer + format: uint32 + departmentId: + type: integer + format: uint32 + scene: + type: string + name: + type: string + reason: + type: string + DeleteExportReply: + type: object + properties: + total: + type: integer + format: uint32 + GoogleProtobufAny: + type: object + properties: + '@type': + type: string + description: The type of the serialized message. + additionalProperties: true + description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message. + ListExportReply: + type: object + properties: + total: + type: integer + format: uint32 + list: + type: array + items: + $ref: '#/components/schemas/ListExportReply_Export' + ListExportReply_Export: + type: object + properties: + id: + type: integer + format: uint32 + userId: + type: integer + format: uint32 + departmentId: + type: integer + format: uint32 + scene: + type: string + name: + type: string + size: + type: integer + format: uint32 + sha: + type: string + src: + type: string + status: + type: string + reason: + type: string + expiredAt: + type: integer + format: uint32 + createdAt: + type: integer + format: uint32 + updatedAt: + type: integer + format: uint32 + Status: + type: object + properties: + code: + type: integer + description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. + format: int32 + message: + type: string + description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + details: + type: array + items: + $ref: '#/components/schemas/GoogleProtobufAny' + description: A list of messages that carry the error details. There is a common set of message types for APIs to use. + description: 'The `Status` type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each `Status` message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors).' +tags: + - name: Export diff --git a/api/resource/export/resource_export.proto b/api/resource/export/resource_export.proto new file mode 100755 index 0000000..2ff0cd5 --- /dev/null +++ b/api/resource/export/resource_export.proto @@ -0,0 +1,61 @@ +syntax = "proto3"; + +package resource.api.resource.export.v1; + +option go_package = "./v1;v1"; +option java_multiple_files = true; +option java_package = "resource.api.resource.export.v1"; +option java_outer_classname = "ExportV1"; + +import "validate/validate.proto"; + +message ListExportRequest { + uint32 page = 1[(validate.rules).uint32 = {gt: 0}]; + uint32 pageSize = 2[(validate.rules).uint32 = {gt: 0,lte:50}]; + optional string order = 3[(validate.rules).string = {in: ["asc","desc"]}]; + optional string orderBy = 4[(validate.rules).string = {in: ["id","created_at","updated_at"]}]; + optional uint32 userId = 5; + optional uint32 departmentId = 6; +} + +message ListExportReply { + message Export { + uint32 id = 1; + uint32 userId = 2; + uint32 departmentId = 3; + string scene = 4; + string name = 5; + uint32 size = 6; + optional string sha = 7; + optional string src = 8; + string status = 9; + optional string reason = 10; + uint32 expiredAt = 11; + uint32 createdAt = 12; + uint32 updatedAt = 13; + } + + uint32 total = 1; + repeated Export list = 2; +} + +message CreateExportRequest { + uint32 userId = 1[(validate.rules).uint32 = {gt: 0}]; + uint32 departmentId = 2[(validate.rules).uint32 = {gt: 0}]; + string scene = 3[(validate.rules).string = {min_len: 1}]; + string name = 4[(validate.rules).string = {min_len: 1}]; + optional string reason = 5; +} + +message CreateExportReply { + uint32 id = 1; +} + +message DeleteExportRequest { + repeated uint32 ids = 1[(validate.rules).repeated = {min_items: 1, unique:true, max_items:50}]; +} + +message DeleteExportReply { + uint32 total = 1; +} + diff --git a/api/resource/export/resource_export_service.proto b/api/resource/export/resource_export_service.proto new file mode 100755 index 0000000..a1c1b16 --- /dev/null +++ b/api/resource/export/resource_export_service.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; + +package resource.api.resource.export.v1; + +option go_package = "./v1;v1"; +option java_multiple_files = true; +option java_package = "resource.api.resource.export.v1"; +option java_outer_classname = "ExportV1"; + +import "api/resource/export/resource_export.proto"; +import "google/api/annotations.proto"; + +service Export{ + + // ListExport 获取导出信息列表 + rpc ListExport (ListExportRequest) returns (ListExportReply) { + option (google.api.http) = { + get: "/resource/api/v1/exports", + }; + } + + // CreateExport 创建导出信息 + rpc CreateExport (CreateExportRequest) returns (CreateExportReply) { + option (google.api.http) = { + post: "/resource/api/v1/export", + body: "*" + }; + } + + // DeleteExport 删除导出信息 + rpc DeleteExport (DeleteExportRequest) returns (DeleteExportReply) { + option (google.api.http) = { + delete: "/resource/api/v1/export", + }; + } + +} \ No newline at end of file diff --git a/api/resource/export/v1/resource_export.pb.go b/api/resource/export/v1/resource_export.pb.go new file mode 100644 index 0000000..3473d01 --- /dev/null +++ b/api/resource/export/v1/resource_export.pb.go @@ -0,0 +1,759 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v4.24.4 +// source: api/resource/export/resource_export.proto + +package v1 + +import ( + _ "github.com/envoyproxy/protoc-gen-validate/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ListExportRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Page uint32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PageSize uint32 `protobuf:"varint,2,opt,name=pageSize,proto3" json:"pageSize,omitempty"` + Order *string `protobuf:"bytes,3,opt,name=order,proto3,oneof" json:"order,omitempty"` + OrderBy *string `protobuf:"bytes,4,opt,name=orderBy,proto3,oneof" json:"orderBy,omitempty"` + UserId *uint32 `protobuf:"varint,5,opt,name=userId,proto3,oneof" json:"userId,omitempty"` + DepartmentId *uint32 `protobuf:"varint,6,opt,name=departmentId,proto3,oneof" json:"departmentId,omitempty"` +} + +func (x *ListExportRequest) Reset() { + *x = ListExportRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_export_resource_export_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListExportRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListExportRequest) ProtoMessage() {} + +func (x *ListExportRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_export_resource_export_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListExportRequest.ProtoReflect.Descriptor instead. +func (*ListExportRequest) Descriptor() ([]byte, []int) { + return file_api_resource_export_resource_export_proto_rawDescGZIP(), []int{0} +} + +func (x *ListExportRequest) GetPage() uint32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *ListExportRequest) GetPageSize() uint32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListExportRequest) GetOrder() string { + if x != nil && x.Order != nil { + return *x.Order + } + return "" +} + +func (x *ListExportRequest) GetOrderBy() string { + if x != nil && x.OrderBy != nil { + return *x.OrderBy + } + return "" +} + +func (x *ListExportRequest) GetUserId() uint32 { + if x != nil && x.UserId != nil { + return *x.UserId + } + return 0 +} + +func (x *ListExportRequest) GetDepartmentId() uint32 { + if x != nil && x.DepartmentId != nil { + return *x.DepartmentId + } + return 0 +} + +type ListExportReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*ListExportReply_Export `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +func (x *ListExportReply) Reset() { + *x = ListExportReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_export_resource_export_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListExportReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListExportReply) ProtoMessage() {} + +func (x *ListExportReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_export_resource_export_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListExportReply.ProtoReflect.Descriptor instead. +func (*ListExportReply) Descriptor() ([]byte, []int) { + return file_api_resource_export_resource_export_proto_rawDescGZIP(), []int{1} +} + +func (x *ListExportReply) GetTotal() uint32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *ListExportReply) GetList() []*ListExportReply_Export { + if x != nil { + return x.List + } + return nil +} + +type CreateExportRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId uint32 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` + DepartmentId uint32 `protobuf:"varint,2,opt,name=departmentId,proto3" json:"departmentId,omitempty"` + Scene string `protobuf:"bytes,3,opt,name=scene,proto3" json:"scene,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Reason *string `protobuf:"bytes,5,opt,name=reason,proto3,oneof" json:"reason,omitempty"` +} + +func (x *CreateExportRequest) Reset() { + *x = CreateExportRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_export_resource_export_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateExportRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateExportRequest) ProtoMessage() {} + +func (x *CreateExportRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_export_resource_export_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateExportRequest.ProtoReflect.Descriptor instead. +func (*CreateExportRequest) Descriptor() ([]byte, []int) { + return file_api_resource_export_resource_export_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateExportRequest) GetUserId() uint32 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *CreateExportRequest) GetDepartmentId() uint32 { + if x != nil { + return x.DepartmentId + } + return 0 +} + +func (x *CreateExportRequest) GetScene() string { + if x != nil { + return x.Scene + } + return "" +} + +func (x *CreateExportRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateExportRequest) GetReason() string { + if x != nil && x.Reason != nil { + return *x.Reason + } + return "" +} + +type CreateExportReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *CreateExportReply) Reset() { + *x = CreateExportReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_export_resource_export_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateExportReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateExportReply) ProtoMessage() {} + +func (x *CreateExportReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_export_resource_export_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateExportReply.ProtoReflect.Descriptor instead. +func (*CreateExportReply) Descriptor() ([]byte, []int) { + return file_api_resource_export_resource_export_proto_rawDescGZIP(), []int{3} +} + +func (x *CreateExportReply) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +type DeleteExportRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ids []uint32 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids,omitempty"` +} + +func (x *DeleteExportRequest) Reset() { + *x = DeleteExportRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_export_resource_export_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteExportRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteExportRequest) ProtoMessage() {} + +func (x *DeleteExportRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_export_resource_export_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteExportRequest.ProtoReflect.Descriptor instead. +func (*DeleteExportRequest) Descriptor() ([]byte, []int) { + return file_api_resource_export_resource_export_proto_rawDescGZIP(), []int{4} +} + +func (x *DeleteExportRequest) GetIds() []uint32 { + if x != nil { + return x.Ids + } + return nil +} + +type DeleteExportReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` +} + +func (x *DeleteExportReply) Reset() { + *x = DeleteExportReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_export_resource_export_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteExportReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteExportReply) ProtoMessage() {} + +func (x *DeleteExportReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_export_resource_export_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteExportReply.ProtoReflect.Descriptor instead. +func (*DeleteExportReply) Descriptor() ([]byte, []int) { + return file_api_resource_export_resource_export_proto_rawDescGZIP(), []int{5} +} + +func (x *DeleteExportReply) GetTotal() uint32 { + if x != nil { + return x.Total + } + return 0 +} + +type ListExportReply_Export struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + UserId uint32 `protobuf:"varint,2,opt,name=userId,proto3" json:"userId,omitempty"` + DepartmentId uint32 `protobuf:"varint,3,opt,name=departmentId,proto3" json:"departmentId,omitempty"` + Scene string `protobuf:"bytes,4,opt,name=scene,proto3" json:"scene,omitempty"` + Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` + Size uint32 `protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"` + Sha *string `protobuf:"bytes,7,opt,name=sha,proto3,oneof" json:"sha,omitempty"` + Src *string `protobuf:"bytes,8,opt,name=src,proto3,oneof" json:"src,omitempty"` + Status string `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"` + Reason *string `protobuf:"bytes,10,opt,name=reason,proto3,oneof" json:"reason,omitempty"` + ExpiredAt uint32 `protobuf:"varint,11,opt,name=expiredAt,proto3" json:"expiredAt,omitempty"` + CreatedAt uint32 `protobuf:"varint,12,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt uint32 `protobuf:"varint,13,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` +} + +func (x *ListExportReply_Export) Reset() { + *x = ListExportReply_Export{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_export_resource_export_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListExportReply_Export) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListExportReply_Export) ProtoMessage() {} + +func (x *ListExportReply_Export) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_export_resource_export_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListExportReply_Export.ProtoReflect.Descriptor instead. +func (*ListExportReply_Export) Descriptor() ([]byte, []int) { + return file_api_resource_export_resource_export_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *ListExportReply_Export) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *ListExportReply_Export) GetUserId() uint32 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *ListExportReply_Export) GetDepartmentId() uint32 { + if x != nil { + return x.DepartmentId + } + return 0 +} + +func (x *ListExportReply_Export) GetScene() string { + if x != nil { + return x.Scene + } + return "" +} + +func (x *ListExportReply_Export) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ListExportReply_Export) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ListExportReply_Export) GetSha() string { + if x != nil && x.Sha != nil { + return *x.Sha + } + return "" +} + +func (x *ListExportReply_Export) GetSrc() string { + if x != nil && x.Src != nil { + return *x.Src + } + return "" +} + +func (x *ListExportReply_Export) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *ListExportReply_Export) GetReason() string { + if x != nil && x.Reason != nil { + return *x.Reason + } + return "" +} + +func (x *ListExportReply_Export) GetExpiredAt() uint32 { + if x != nil { + return x.ExpiredAt + } + return 0 +} + +func (x *ListExportReply_Export) GetCreatedAt() uint32 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *ListExportReply_Export) GetUpdatedAt() uint32 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +var File_api_resource_export_resource_export_proto protoreflect.FileDescriptor + +var file_api_resource_export_resource_export_proto_rawDesc = []byte{ + 0x0a, 0x29, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x65, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x65, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbe, 0x02, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x70, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, + 0x20, 0x00, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, + 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, + 0x04, 0x18, 0x32, 0x20, 0x00, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x2b, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, + 0xfa, 0x42, 0x0d, 0x72, 0x0b, 0x52, 0x03, 0x61, 0x73, 0x63, 0x52, 0x04, 0x64, 0x65, 0x73, 0x63, + 0x48, 0x00, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x07, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xfa, + 0x42, 0x1e, 0x72, 0x1c, 0x52, 0x02, 0x69, 0x64, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x48, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x1b, + 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, + 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x27, 0x0a, 0x0c, 0x64, + 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0d, 0x48, 0x03, 0x52, 0x0c, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x49, + 0x64, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x0a, + 0x0a, 0x08, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x75, + 0x73, 0x65, 0x72, 0x49, 0x64, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, + 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xe1, 0x03, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x12, 0x4b, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x1a, 0xea, 0x02, + 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, + 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, + 0x7a, 0x65, 0x12, 0x15, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x03, 0x73, 0x68, 0x61, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x73, 0x72, 0x63, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x03, 0x73, 0x72, 0x63, 0x88, 0x01, 0x01, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, + 0x41, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, + 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, + 0x06, 0x0a, 0x04, 0x5f, 0x73, 0x68, 0x61, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x73, 0x72, 0x63, 0x42, + 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xc7, 0x01, 0x0a, 0x13, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x06, 0x75, 0x73, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, + 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, + 0x20, 0x00, 0x52, 0x0c, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x05, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x12, + 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, + 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x06, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x23, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x22, 0x35, 0x0a, 0x13, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1e, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x0c, 0xfa, + 0x42, 0x09, 0x92, 0x01, 0x06, 0x08, 0x01, 0x10, 0x32, 0x18, 0x01, 0x52, 0x03, 0x69, 0x64, 0x73, + 0x22, 0x29, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x36, 0x0a, 0x1f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x08, + 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x56, 0x31, 0x50, 0x01, 0x5a, 0x07, 0x2e, 0x2f, 0x76, 0x31, + 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_resource_export_resource_export_proto_rawDescOnce sync.Once + file_api_resource_export_resource_export_proto_rawDescData = file_api_resource_export_resource_export_proto_rawDesc +) + +func file_api_resource_export_resource_export_proto_rawDescGZIP() []byte { + file_api_resource_export_resource_export_proto_rawDescOnce.Do(func() { + file_api_resource_export_resource_export_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_resource_export_resource_export_proto_rawDescData) + }) + return file_api_resource_export_resource_export_proto_rawDescData +} + +var file_api_resource_export_resource_export_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_api_resource_export_resource_export_proto_goTypes = []interface{}{ + (*ListExportRequest)(nil), // 0: resource.api.resource.export.v1.ListExportRequest + (*ListExportReply)(nil), // 1: resource.api.resource.export.v1.ListExportReply + (*CreateExportRequest)(nil), // 2: resource.api.resource.export.v1.CreateExportRequest + (*CreateExportReply)(nil), // 3: resource.api.resource.export.v1.CreateExportReply + (*DeleteExportRequest)(nil), // 4: resource.api.resource.export.v1.DeleteExportRequest + (*DeleteExportReply)(nil), // 5: resource.api.resource.export.v1.DeleteExportReply + (*ListExportReply_Export)(nil), // 6: resource.api.resource.export.v1.ListExportReply.Export +} +var file_api_resource_export_resource_export_proto_depIdxs = []int32{ + 6, // 0: resource.api.resource.export.v1.ListExportReply.list:type_name -> resource.api.resource.export.v1.ListExportReply.Export + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_api_resource_export_resource_export_proto_init() } +func file_api_resource_export_resource_export_proto_init() { + if File_api_resource_export_resource_export_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_resource_export_resource_export_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListExportRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_export_resource_export_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListExportReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_export_resource_export_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateExportRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_export_resource_export_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateExportReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_export_resource_export_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteExportRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_export_resource_export_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteExportReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_export_resource_export_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListExportReply_Export); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_api_resource_export_resource_export_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_api_resource_export_resource_export_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_api_resource_export_resource_export_proto_msgTypes[6].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_resource_export_resource_export_proto_rawDesc, + NumEnums: 0, + NumMessages: 7, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_resource_export_resource_export_proto_goTypes, + DependencyIndexes: file_api_resource_export_resource_export_proto_depIdxs, + MessageInfos: file_api_resource_export_resource_export_proto_msgTypes, + }.Build() + File_api_resource_export_resource_export_proto = out.File + file_api_resource_export_resource_export_proto_rawDesc = nil + file_api_resource_export_resource_export_proto_goTypes = nil + file_api_resource_export_resource_export_proto_depIdxs = nil +} diff --git a/api/resource/export/v1/resource_export.pb.validate.go b/api/resource/export/v1/resource_export.pb.validate.go new file mode 100644 index 0000000..c58fcbe --- /dev/null +++ b/api/resource/export/v1/resource_export.pb.validate.go @@ -0,0 +1,971 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: api/resource/export/resource_export.proto + +package v1 + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on ListExportRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *ListExportRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListExportRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListExportRequestMultiError, or nil if none found. +func (m *ListExportRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ListExportRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetPage() <= 0 { + err := ListExportRequestValidationError{ + field: "Page", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if val := m.GetPageSize(); val <= 0 || val > 50 { + err := ListExportRequestValidationError{ + field: "PageSize", + reason: "value must be inside range (0, 50]", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.Order != nil { + + if _, ok := _ListExportRequest_Order_InLookup[m.GetOrder()]; !ok { + err := ListExportRequestValidationError{ + field: "Order", + reason: "value must be in list [asc desc]", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if m.OrderBy != nil { + + if _, ok := _ListExportRequest_OrderBy_InLookup[m.GetOrderBy()]; !ok { + err := ListExportRequestValidationError{ + field: "OrderBy", + reason: "value must be in list [id created_at updated_at]", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if m.UserId != nil { + // no validation rules for UserId + } + + if m.DepartmentId != nil { + // no validation rules for DepartmentId + } + + if len(errors) > 0 { + return ListExportRequestMultiError(errors) + } + + return nil +} + +// ListExportRequestMultiError is an error wrapping multiple validation errors +// returned by ListExportRequest.ValidateAll() if the designated constraints +// aren't met. +type ListExportRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListExportRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListExportRequestMultiError) AllErrors() []error { return m } + +// ListExportRequestValidationError is the validation error returned by +// ListExportRequest.Validate if the designated constraints aren't met. +type ListExportRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListExportRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListExportRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListExportRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListExportRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListExportRequestValidationError) ErrorName() string { + return "ListExportRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e ListExportRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListExportRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListExportRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListExportRequestValidationError{} + +var _ListExportRequest_Order_InLookup = map[string]struct{}{ + "asc": {}, + "desc": {}, +} + +var _ListExportRequest_OrderBy_InLookup = map[string]struct{}{ + "id": {}, + "created_at": {}, + "updated_at": {}, +} + +// Validate checks the field values on ListExportReply with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *ListExportReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListExportReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListExportReplyMultiError, or nil if none found. +func (m *ListExportReply) ValidateAll() error { + return m.validate(true) +} + +func (m *ListExportReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Total + + for idx, item := range m.GetList() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListExportReplyValidationError{ + field: fmt.Sprintf("List[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListExportReplyValidationError{ + field: fmt.Sprintf("List[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListExportReplyValidationError{ + field: fmt.Sprintf("List[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ListExportReplyMultiError(errors) + } + + return nil +} + +// ListExportReplyMultiError is an error wrapping multiple validation errors +// returned by ListExportReply.ValidateAll() if the designated constraints +// aren't met. +type ListExportReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListExportReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListExportReplyMultiError) AllErrors() []error { return m } + +// ListExportReplyValidationError is the validation error returned by +// ListExportReply.Validate if the designated constraints aren't met. +type ListExportReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListExportReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListExportReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListExportReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListExportReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListExportReplyValidationError) ErrorName() string { return "ListExportReplyValidationError" } + +// Error satisfies the builtin error interface +func (e ListExportReplyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListExportReply.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListExportReplyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListExportReplyValidationError{} + +// Validate checks the field values on CreateExportRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateExportRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateExportRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateExportRequestMultiError, or nil if none found. +func (m *CreateExportRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateExportRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetUserId() <= 0 { + err := CreateExportRequestValidationError{ + field: "UserId", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.GetDepartmentId() <= 0 { + err := CreateExportRequestValidationError{ + field: "DepartmentId", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetScene()) < 1 { + err := CreateExportRequestValidationError{ + field: "Scene", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetName()) < 1 { + err := CreateExportRequestValidationError{ + field: "Name", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.Reason != nil { + // no validation rules for Reason + } + + if len(errors) > 0 { + return CreateExportRequestMultiError(errors) + } + + return nil +} + +// CreateExportRequestMultiError is an error wrapping multiple validation +// errors returned by CreateExportRequest.ValidateAll() if the designated +// constraints aren't met. +type CreateExportRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateExportRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateExportRequestMultiError) AllErrors() []error { return m } + +// CreateExportRequestValidationError is the validation error returned by +// CreateExportRequest.Validate if the designated constraints aren't met. +type CreateExportRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateExportRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateExportRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateExportRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateExportRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateExportRequestValidationError) ErrorName() string { + return "CreateExportRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateExportRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateExportRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateExportRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateExportRequestValidationError{} + +// Validate checks the field values on CreateExportReply with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *CreateExportReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateExportReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateExportReplyMultiError, or nil if none found. +func (m *CreateExportReply) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateExportReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Id + + if len(errors) > 0 { + return CreateExportReplyMultiError(errors) + } + + return nil +} + +// CreateExportReplyMultiError is an error wrapping multiple validation errors +// returned by CreateExportReply.ValidateAll() if the designated constraints +// aren't met. +type CreateExportReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateExportReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateExportReplyMultiError) AllErrors() []error { return m } + +// CreateExportReplyValidationError is the validation error returned by +// CreateExportReply.Validate if the designated constraints aren't met. +type CreateExportReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateExportReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateExportReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateExportReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateExportReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateExportReplyValidationError) ErrorName() string { + return "CreateExportReplyValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateExportReplyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateExportReply.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateExportReplyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateExportReplyValidationError{} + +// Validate checks the field values on DeleteExportRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteExportRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteExportRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteExportRequestMultiError, or nil if none found. +func (m *DeleteExportRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteExportRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if l := len(m.GetIds()); l < 1 || l > 50 { + err := DeleteExportRequestValidationError{ + field: "Ids", + reason: "value must contain between 1 and 50 items, inclusive", + } + if !all { + return err + } + errors = append(errors, err) + } + + _DeleteExportRequest_Ids_Unique := make(map[uint32]struct{}, len(m.GetIds())) + + for idx, item := range m.GetIds() { + _, _ = idx, item + + if _, exists := _DeleteExportRequest_Ids_Unique[item]; exists { + err := DeleteExportRequestValidationError{ + field: fmt.Sprintf("Ids[%v]", idx), + reason: "repeated value must contain unique items", + } + if !all { + return err + } + errors = append(errors, err) + } else { + _DeleteExportRequest_Ids_Unique[item] = struct{}{} + } + + // no validation rules for Ids[idx] + } + + if len(errors) > 0 { + return DeleteExportRequestMultiError(errors) + } + + return nil +} + +// DeleteExportRequestMultiError is an error wrapping multiple validation +// errors returned by DeleteExportRequest.ValidateAll() if the designated +// constraints aren't met. +type DeleteExportRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteExportRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteExportRequestMultiError) AllErrors() []error { return m } + +// DeleteExportRequestValidationError is the validation error returned by +// DeleteExportRequest.Validate if the designated constraints aren't met. +type DeleteExportRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteExportRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteExportRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteExportRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteExportRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteExportRequestValidationError) ErrorName() string { + return "DeleteExportRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteExportRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteExportRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteExportRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteExportRequestValidationError{} + +// Validate checks the field values on DeleteExportReply with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *DeleteExportReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteExportReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteExportReplyMultiError, or nil if none found. +func (m *DeleteExportReply) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteExportReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Total + + if len(errors) > 0 { + return DeleteExportReplyMultiError(errors) + } + + return nil +} + +// DeleteExportReplyMultiError is an error wrapping multiple validation errors +// returned by DeleteExportReply.ValidateAll() if the designated constraints +// aren't met. +type DeleteExportReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteExportReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteExportReplyMultiError) AllErrors() []error { return m } + +// DeleteExportReplyValidationError is the validation error returned by +// DeleteExportReply.Validate if the designated constraints aren't met. +type DeleteExportReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteExportReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteExportReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteExportReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteExportReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteExportReplyValidationError) ErrorName() string { + return "DeleteExportReplyValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteExportReplyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteExportReply.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteExportReplyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteExportReplyValidationError{} + +// Validate checks the field values on ListExportReply_Export with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListExportReply_Export) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListExportReply_Export with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListExportReply_ExportMultiError, or nil if none found. +func (m *ListExportReply_Export) ValidateAll() error { + return m.validate(true) +} + +func (m *ListExportReply_Export) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Id + + // no validation rules for UserId + + // no validation rules for DepartmentId + + // no validation rules for Scene + + // no validation rules for Name + + // no validation rules for Size + + // no validation rules for Status + + // no validation rules for ExpiredAt + + // no validation rules for CreatedAt + + // no validation rules for UpdatedAt + + if m.Sha != nil { + // no validation rules for Sha + } + + if m.Src != nil { + // no validation rules for Src + } + + if m.Reason != nil { + // no validation rules for Reason + } + + if len(errors) > 0 { + return ListExportReply_ExportMultiError(errors) + } + + return nil +} + +// ListExportReply_ExportMultiError is an error wrapping multiple validation +// errors returned by ListExportReply_Export.ValidateAll() if the designated +// constraints aren't met. +type ListExportReply_ExportMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListExportReply_ExportMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListExportReply_ExportMultiError) AllErrors() []error { return m } + +// ListExportReply_ExportValidationError is the validation error returned by +// ListExportReply_Export.Validate if the designated constraints aren't met. +type ListExportReply_ExportValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListExportReply_ExportValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListExportReply_ExportValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListExportReply_ExportValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListExportReply_ExportValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListExportReply_ExportValidationError) ErrorName() string { + return "ListExportReply_ExportValidationError" +} + +// Error satisfies the builtin error interface +func (e ListExportReply_ExportValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListExportReply_Export.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListExportReply_ExportValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListExportReply_ExportValidationError{} diff --git a/api/resource/export/v1/resource_export_service.pb.go b/api/resource/export/v1/resource_export_service.pb.go new file mode 100644 index 0000000..e6e6b69 --- /dev/null +++ b/api/resource/export/v1/resource_export_service.pb.go @@ -0,0 +1,117 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v4.24.4 +// source: api/resource/export/resource_export_service.proto + +package v1 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var File_api_resource_export_resource_export_service_proto protoreflect.FileDescriptor + +var file_api_resource_export_resource_export_service_proto_rawDesc = []byte{ + 0x0a, 0x31, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x65, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x65, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x1f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x76, 0x31, 0x1a, 0x29, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xda, 0x03, + 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x94, 0x01, 0x0a, 0x0a, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x32, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x20, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, + 0x9c, 0x01, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x12, 0x34, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x65, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1c, 0x3a, 0x01, 0x2a, 0x22, 0x17, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x99, + 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, + 0x34, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x65, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x19, 0x2a, 0x17, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x36, 0x0a, 0x1f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x45, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x56, 0x31, 0x50, 0x01, 0x5a, 0x07, 0x2e, 0x2f, 0x76, 0x31, 0x3b, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_api_resource_export_resource_export_service_proto_goTypes = []interface{}{ + (*ListExportRequest)(nil), // 0: resource.api.resource.export.v1.ListExportRequest + (*CreateExportRequest)(nil), // 1: resource.api.resource.export.v1.CreateExportRequest + (*DeleteExportRequest)(nil), // 2: resource.api.resource.export.v1.DeleteExportRequest + (*ListExportReply)(nil), // 3: resource.api.resource.export.v1.ListExportReply + (*CreateExportReply)(nil), // 4: resource.api.resource.export.v1.CreateExportReply + (*DeleteExportReply)(nil), // 5: resource.api.resource.export.v1.DeleteExportReply +} +var file_api_resource_export_resource_export_service_proto_depIdxs = []int32{ + 0, // 0: resource.api.resource.export.v1.Export.ListExport:input_type -> resource.api.resource.export.v1.ListExportRequest + 1, // 1: resource.api.resource.export.v1.Export.CreateExport:input_type -> resource.api.resource.export.v1.CreateExportRequest + 2, // 2: resource.api.resource.export.v1.Export.DeleteExport:input_type -> resource.api.resource.export.v1.DeleteExportRequest + 3, // 3: resource.api.resource.export.v1.Export.ListExport:output_type -> resource.api.resource.export.v1.ListExportReply + 4, // 4: resource.api.resource.export.v1.Export.CreateExport:output_type -> resource.api.resource.export.v1.CreateExportReply + 5, // 5: resource.api.resource.export.v1.Export.DeleteExport:output_type -> resource.api.resource.export.v1.DeleteExportReply + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_api_resource_export_resource_export_service_proto_init() } +func file_api_resource_export_resource_export_service_proto_init() { + if File_api_resource_export_resource_export_service_proto != nil { + return + } + file_api_resource_export_resource_export_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_resource_export_resource_export_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_resource_export_resource_export_service_proto_goTypes, + DependencyIndexes: file_api_resource_export_resource_export_service_proto_depIdxs, + }.Build() + File_api_resource_export_resource_export_service_proto = out.File + file_api_resource_export_resource_export_service_proto_rawDesc = nil + file_api_resource_export_resource_export_service_proto_goTypes = nil + file_api_resource_export_resource_export_service_proto_depIdxs = nil +} diff --git a/api/resource/export/v1/resource_export_service_grpc.pb.go b/api/resource/export/v1/resource_export_service_grpc.pb.go new file mode 100644 index 0000000..4147199 --- /dev/null +++ b/api/resource/export/v1/resource_export_service_grpc.pb.go @@ -0,0 +1,189 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.24.4 +// source: api/resource/export/resource_export_service.proto + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + Export_ListExport_FullMethodName = "/resource.api.resource.export.v1.Export/ListExport" + Export_CreateExport_FullMethodName = "/resource.api.resource.export.v1.Export/CreateExport" + Export_DeleteExport_FullMethodName = "/resource.api.resource.export.v1.Export/DeleteExport" +) + +// ExportClient is the client API for Export 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 ExportClient interface { + // ListExport 获取导出信息列表 + ListExport(ctx context.Context, in *ListExportRequest, opts ...grpc.CallOption) (*ListExportReply, error) + // CreateExport 创建导出信息 + CreateExport(ctx context.Context, in *CreateExportRequest, opts ...grpc.CallOption) (*CreateExportReply, error) + // DeleteExport 删除导出信息 + DeleteExport(ctx context.Context, in *DeleteExportRequest, opts ...grpc.CallOption) (*DeleteExportReply, error) +} + +type exportClient struct { + cc grpc.ClientConnInterface +} + +func NewExportClient(cc grpc.ClientConnInterface) ExportClient { + return &exportClient{cc} +} + +func (c *exportClient) ListExport(ctx context.Context, in *ListExportRequest, opts ...grpc.CallOption) (*ListExportReply, error) { + out := new(ListExportReply) + err := c.cc.Invoke(ctx, Export_ListExport_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *exportClient) CreateExport(ctx context.Context, in *CreateExportRequest, opts ...grpc.CallOption) (*CreateExportReply, error) { + out := new(CreateExportReply) + err := c.cc.Invoke(ctx, Export_CreateExport_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *exportClient) DeleteExport(ctx context.Context, in *DeleteExportRequest, opts ...grpc.CallOption) (*DeleteExportReply, error) { + out := new(DeleteExportReply) + err := c.cc.Invoke(ctx, Export_DeleteExport_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ExportServer is the server API for Export service. +// All implementations must embed UnimplementedExportServer +// for forward compatibility +type ExportServer interface { + // ListExport 获取导出信息列表 + ListExport(context.Context, *ListExportRequest) (*ListExportReply, error) + // CreateExport 创建导出信息 + CreateExport(context.Context, *CreateExportRequest) (*CreateExportReply, error) + // DeleteExport 删除导出信息 + DeleteExport(context.Context, *DeleteExportRequest) (*DeleteExportReply, error) + mustEmbedUnimplementedExportServer() +} + +// UnimplementedExportServer must be embedded to have forward compatible implementations. +type UnimplementedExportServer struct { +} + +func (UnimplementedExportServer) ListExport(context.Context, *ListExportRequest) (*ListExportReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListExport not implemented") +} +func (UnimplementedExportServer) CreateExport(context.Context, *CreateExportRequest) (*CreateExportReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateExport not implemented") +} +func (UnimplementedExportServer) DeleteExport(context.Context, *DeleteExportRequest) (*DeleteExportReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteExport not implemented") +} +func (UnimplementedExportServer) mustEmbedUnimplementedExportServer() {} + +// UnsafeExportServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ExportServer will +// result in compilation errors. +type UnsafeExportServer interface { + mustEmbedUnimplementedExportServer() +} + +func RegisterExportServer(s grpc.ServiceRegistrar, srv ExportServer) { + s.RegisterService(&Export_ServiceDesc, srv) +} + +func _Export_ListExport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListExportRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExportServer).ListExport(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Export_ListExport_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExportServer).ListExport(ctx, req.(*ListExportRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Export_CreateExport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateExportRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExportServer).CreateExport(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Export_CreateExport_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExportServer).CreateExport(ctx, req.(*CreateExportRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Export_DeleteExport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteExportRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExportServer).DeleteExport(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Export_DeleteExport_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExportServer).DeleteExport(ctx, req.(*DeleteExportRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Export_ServiceDesc is the grpc.ServiceDesc for Export service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Export_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "resource.api.resource.export.v1.Export", + HandlerType: (*ExportServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListExport", + Handler: _Export_ListExport_Handler, + }, + { + MethodName: "CreateExport", + Handler: _Export_CreateExport_Handler, + }, + { + MethodName: "DeleteExport", + Handler: _Export_DeleteExport_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/resource/export/resource_export_service.proto", +} diff --git a/api/resource/export/v1/resource_export_service_http.pb.go b/api/resource/export/v1/resource_export_service_http.pb.go new file mode 100644 index 0000000..dfb4fa3 --- /dev/null +++ b/api/resource/export/v1/resource_export_service_http.pb.go @@ -0,0 +1,153 @@ +// Code generated by protoc-gen-go-http. DO NOT EDIT. +// versions: +// - protoc-gen-go-http v2.7.3 +// - protoc v4.24.4 +// source: api/resource/export/resource_export_service.proto + +package v1 + +import ( + context "context" + http "github.com/go-kratos/kratos/v2/transport/http" + binding "github.com/go-kratos/kratos/v2/transport/http/binding" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the kratos package it is being compiled against. +var _ = new(context.Context) +var _ = binding.EncodeURL + +const _ = http.SupportPackageIsVersion1 + +const OperationExportCreateExport = "/resource.api.resource.export.v1.Export/CreateExport" +const OperationExportDeleteExport = "/resource.api.resource.export.v1.Export/DeleteExport" +const OperationExportListExport = "/resource.api.resource.export.v1.Export/ListExport" + +type ExportHTTPServer interface { + // CreateExport CreateExport 创建导出信息 + CreateExport(context.Context, *CreateExportRequest) (*CreateExportReply, error) + // DeleteExport DeleteExport 删除导出信息 + DeleteExport(context.Context, *DeleteExportRequest) (*DeleteExportReply, error) + // ListExport ListExport 获取导出信息列表 + ListExport(context.Context, *ListExportRequest) (*ListExportReply, error) +} + +func RegisterExportHTTPServer(s *http.Server, srv ExportHTTPServer) { + r := s.Route("/") + r.GET("/resource/api/v1/exports", _Export_ListExport0_HTTP_Handler(srv)) + r.POST("/resource/api/v1/export", _Export_CreateExport0_HTTP_Handler(srv)) + r.DELETE("/resource/api/v1/export", _Export_DeleteExport0_HTTP_Handler(srv)) +} + +func _Export_ListExport0_HTTP_Handler(srv ExportHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in ListExportRequest + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationExportListExport) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.ListExport(ctx, req.(*ListExportRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*ListExportReply) + return ctx.Result(200, reply) + } +} + +func _Export_CreateExport0_HTTP_Handler(srv ExportHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in CreateExportRequest + if err := ctx.Bind(&in); err != nil { + return err + } + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationExportCreateExport) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.CreateExport(ctx, req.(*CreateExportRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*CreateExportReply) + return ctx.Result(200, reply) + } +} + +func _Export_DeleteExport0_HTTP_Handler(srv ExportHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in DeleteExportRequest + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationExportDeleteExport) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.DeleteExport(ctx, req.(*DeleteExportRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*DeleteExportReply) + return ctx.Result(200, reply) + } +} + +type ExportHTTPClient interface { + CreateExport(ctx context.Context, req *CreateExportRequest, opts ...http.CallOption) (rsp *CreateExportReply, err error) + DeleteExport(ctx context.Context, req *DeleteExportRequest, opts ...http.CallOption) (rsp *DeleteExportReply, err error) + ListExport(ctx context.Context, req *ListExportRequest, opts ...http.CallOption) (rsp *ListExportReply, err error) +} + +type ExportHTTPClientImpl struct { + cc *http.Client +} + +func NewExportHTTPClient(client *http.Client) ExportHTTPClient { + return &ExportHTTPClientImpl{client} +} + +func (c *ExportHTTPClientImpl) CreateExport(ctx context.Context, in *CreateExportRequest, opts ...http.CallOption) (*CreateExportReply, error) { + var out CreateExportReply + pattern := "/resource/api/v1/export" + path := binding.EncodeURL(pattern, in, false) + opts = append(opts, http.Operation(OperationExportCreateExport)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *ExportHTTPClientImpl) DeleteExport(ctx context.Context, in *DeleteExportRequest, opts ...http.CallOption) (*DeleteExportReply, error) { + var out DeleteExportReply + pattern := "/resource/api/v1/export" + path := binding.EncodeURL(pattern, in, true) + opts = append(opts, http.Operation(OperationExportDeleteExport)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *ExportHTTPClientImpl) ListExport(ctx context.Context, in *ListExportRequest, opts ...http.CallOption) (*ListExportReply, error) { + var out ListExportReply + pattern := "/resource/api/v1/exports" + path := binding.EncodeURL(pattern, in, true) + opts = append(opts, http.Operation(OperationExportListExport)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} diff --git a/api/file/openapi.yaml b/api/resource/file/openapi.yaml similarity index 100% rename from api/file/openapi.yaml rename to api/resource/file/openapi.yaml diff --git a/api/resource/file/resource_file.proto b/api/resource/file/resource_file.proto new file mode 100755 index 0000000..b79dd26 --- /dev/null +++ b/api/resource/file/resource_file.proto @@ -0,0 +1,126 @@ +syntax = "proto3"; + +package resource.api.resource.file.v1; + +option go_package = "./v1;v1"; +option java_multiple_files = true; +option java_package = "resource.api.resource.file.v1"; +option java_outer_classname = "FileV1"; + +import "validate/validate.proto"; + +message StaticFileRequest{ + string src = 1[(validate.rules).string = {min_len:1}]; + string expire = 2[(validate.rules).string = {min_len:1}]; + string sign = 3[(validate.rules).string = {min_len:1}]; + uint32 width = 4; + uint32 height = 5; + string mode = 6; + bool download = 7; + string saveName = 8; +} + +message StaticFileReply{ + bytes data = 1; + string mime = 2; +} + +message GetFileRequest { + optional uint32 id = 1[(validate.rules).uint32 = {gt: 0}]; + optional string sha = 2[(validate.rules).string = {min_len: 1}]; +} + +message GetFileReply { + uint32 id = 1; + uint32 directoryId = 2; + string name = 3; + string type = 4; + uint32 size = 5; + string sha = 6; + string src = 7; + string url = 8; + string status = 9; + string uploadId = 10; + uint32 chunkCount = 11; + uint32 createdAt = 12; + uint32 updatedAt = 13; +} + +message ListFileRequest { + uint32 page = 1[(validate.rules).uint32 = {gt: 0}]; + uint32 pageSize = 2[(validate.rules).uint32 = {gt: 0,lte:50}]; + optional string order = 3[(validate.rules).string = {in: ["asc","desc"]}]; + optional string orderBy = 4[(validate.rules).string = {in: ["id","created_at","updated_at"]}]; + optional uint32 directoryId = 5; + optional string status = 6[(validate.rules).string = {in: [ "PROGRESS","COMPLETED"]}]; +} + +message ListFileReply { + message File { + uint32 id = 1; + uint32 directoryId = 2; + string name = 3; + string type = 4; + uint32 size = 5; + string sha = 6; + string src = 7; + string url = 8; + string status = 9; + string uploadId = 10; + uint32 chunkCount = 11; + uint32 createdAt = 12; + uint32 updatedAt = 13; + } + + uint32 total = 1; + repeated File list = 2; +} + +message PrepareUploadFileRequest { + optional uint32 directoryId = 1[(validate.rules).uint32 = {gt: 0}]; + optional string directoryPath = 2[(validate.rules).string = {min_len: 1}]; + string name = 3[(validate.rules).string = {min_len: 1}]; + uint32 size = 4[(validate.rules).uint32 = {gt:0}]; + string sha = 5[(validate.rules).string = {min_len: 1}]; +} + +message PrepareUploadFileReply { + bool uploaded = 1; + optional string src = 2; + optional uint32 chunkSize = 3; + optional uint32 chunkCount = 4; + optional string uploadId = 5; + repeated uint32 uploadChunks = 6; + optional string sha = 7; + optional string url = 8; +} + +message UploadFileRequest{ + bytes data = 1[(validate.rules).bytes = {min_len:0}]; + string uploadId = 2[(validate.rules).string = {min_len:1}]; + uint32 index = 3[(validate.rules).uint32 = {gt:0}];; +} + +message UploadFileReply{ + string src = 1; + string sha = 2; + string url = 3; +} + +message UpdateFileRequest { + uint32 id = 1[(validate.rules).uint32 = {gt: 0}]; + uint32 directoryId = 2[(validate.rules).uint32 = {gt: 0}]; + string name = 3[(validate.rules).string = {min_len: 1}]; +} + +message UpdateFileReply { +} + +message DeleteFileRequest { + repeated uint32 ids = 1[(validate.rules).repeated = {min_items: 1, unique:true, max_items:50}]; +} + +message DeleteFileReply { + uint32 total = 1; +} + diff --git a/api/resource/file/resource_file_service.proto b/api/resource/file/resource_file_service.proto new file mode 100755 index 0000000..90697b4 --- /dev/null +++ b/api/resource/file/resource_file_service.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; + +package resource.api.resource.file.v1; + +option go_package = "./v1;v1"; +option java_multiple_files = true; +option java_package = "resource.api.resource.file.v1"; +option java_outer_classname = "FileV1"; + +import "api/resource/file/resource_file.proto"; +import "google/api/annotations.proto"; + +service File{ + + // GetFile 获取指定的文件信息 + rpc GetFile (GetFileRequest) returns (GetFileReply) { + option (google.api.http) = { + get: "/resource/api/v1/file", + }; + } + + // ListFile 获取文件信息列表 + rpc ListFile (ListFileRequest) returns (ListFileReply) { + option (google.api.http) = { + get: "/resource/api/v1/files", + }; + } + + // PrepareUploadFile 预上传文件信息 + rpc PrepareUploadFile (PrepareUploadFileRequest) returns (PrepareUploadFileReply) { + option (google.api.http) = { + post: "/resource/api/v1/file/prepare_upload", + body: "*" + }; + } + + // UploadFile 上传文件 + rpc UploadFile(UploadFileRequest) returns (UploadFileReply){} + + // UpdateFile 更新文件信息 + rpc UpdateFile (UpdateFileRequest) returns (UpdateFileReply) { + option (google.api.http) = { + put: "/resource/api/v1/file", + body: "*" + }; + } + + // DeleteFile 删除文件信息 + rpc DeleteFile (DeleteFileRequest) returns (DeleteFileReply) { + option (google.api.http) = { + delete: "/resource/api/v1/file", + }; + } + +} \ No newline at end of file diff --git a/api/resource/file/v1/resource_file.pb.go b/api/resource/file/v1/resource_file.pb.go new file mode 100644 index 0000000..b7a2879 --- /dev/null +++ b/api/resource/file/v1/resource_file.pb.go @@ -0,0 +1,1586 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v4.24.4 +// source: api/resource/file/resource_file.proto + +package v1 + +import ( + _ "github.com/envoyproxy/protoc-gen-validate/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type StaticFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Src string `protobuf:"bytes,1,opt,name=src,proto3" json:"src,omitempty"` + Expire string `protobuf:"bytes,2,opt,name=expire,proto3" json:"expire,omitempty"` + Sign string `protobuf:"bytes,3,opt,name=sign,proto3" json:"sign,omitempty"` + Width uint32 `protobuf:"varint,4,opt,name=width,proto3" json:"width,omitempty"` + Height uint32 `protobuf:"varint,5,opt,name=height,proto3" json:"height,omitempty"` + Mode string `protobuf:"bytes,6,opt,name=mode,proto3" json:"mode,omitempty"` + Download bool `protobuf:"varint,7,opt,name=download,proto3" json:"download,omitempty"` + SaveName string `protobuf:"bytes,8,opt,name=saveName,proto3" json:"saveName,omitempty"` +} + +func (x *StaticFileRequest) Reset() { + *x = StaticFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StaticFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StaticFileRequest) ProtoMessage() {} + +func (x *StaticFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StaticFileRequest.ProtoReflect.Descriptor instead. +func (*StaticFileRequest) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{0} +} + +func (x *StaticFileRequest) GetSrc() string { + if x != nil { + return x.Src + } + return "" +} + +func (x *StaticFileRequest) GetExpire() string { + if x != nil { + return x.Expire + } + return "" +} + +func (x *StaticFileRequest) GetSign() string { + if x != nil { + return x.Sign + } + return "" +} + +func (x *StaticFileRequest) GetWidth() uint32 { + if x != nil { + return x.Width + } + return 0 +} + +func (x *StaticFileRequest) GetHeight() uint32 { + if x != nil { + return x.Height + } + return 0 +} + +func (x *StaticFileRequest) GetMode() string { + if x != nil { + return x.Mode + } + return "" +} + +func (x *StaticFileRequest) GetDownload() bool { + if x != nil { + return x.Download + } + return false +} + +func (x *StaticFileRequest) GetSaveName() string { + if x != nil { + return x.SaveName + } + return "" +} + +type StaticFileReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + Mime string `protobuf:"bytes,2,opt,name=mime,proto3" json:"mime,omitempty"` +} + +func (x *StaticFileReply) Reset() { + *x = StaticFileReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StaticFileReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StaticFileReply) ProtoMessage() {} + +func (x *StaticFileReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StaticFileReply.ProtoReflect.Descriptor instead. +func (*StaticFileReply) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{1} +} + +func (x *StaticFileReply) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *StaticFileReply) GetMime() string { + if x != nil { + return x.Mime + } + return "" +} + +type GetFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id *uint32 `protobuf:"varint,1,opt,name=id,proto3,oneof" json:"id,omitempty"` + Sha *string `protobuf:"bytes,2,opt,name=sha,proto3,oneof" json:"sha,omitempty"` +} + +func (x *GetFileRequest) Reset() { + *x = GetFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFileRequest) ProtoMessage() {} + +func (x *GetFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFileRequest.ProtoReflect.Descriptor instead. +func (*GetFileRequest) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{2} +} + +func (x *GetFileRequest) GetId() uint32 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +func (x *GetFileRequest) GetSha() string { + if x != nil && x.Sha != nil { + return *x.Sha + } + return "" +} + +type GetFileReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + DirectoryId uint32 `protobuf:"varint,2,opt,name=directoryId,proto3" json:"directoryId,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"` + Size uint32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` + Sha string `protobuf:"bytes,6,opt,name=sha,proto3" json:"sha,omitempty"` + Src string `protobuf:"bytes,7,opt,name=src,proto3" json:"src,omitempty"` + Url string `protobuf:"bytes,8,opt,name=url,proto3" json:"url,omitempty"` + Status string `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"` + UploadId string `protobuf:"bytes,10,opt,name=uploadId,proto3" json:"uploadId,omitempty"` + ChunkCount uint32 `protobuf:"varint,11,opt,name=chunkCount,proto3" json:"chunkCount,omitempty"` + CreatedAt uint32 `protobuf:"varint,12,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt uint32 `protobuf:"varint,13,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` +} + +func (x *GetFileReply) Reset() { + *x = GetFileReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFileReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFileReply) ProtoMessage() {} + +func (x *GetFileReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFileReply.ProtoReflect.Descriptor instead. +func (*GetFileReply) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{3} +} + +func (x *GetFileReply) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *GetFileReply) GetDirectoryId() uint32 { + if x != nil { + return x.DirectoryId + } + return 0 +} + +func (x *GetFileReply) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetFileReply) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *GetFileReply) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *GetFileReply) GetSha() string { + if x != nil { + return x.Sha + } + return "" +} + +func (x *GetFileReply) GetSrc() string { + if x != nil { + return x.Src + } + return "" +} + +func (x *GetFileReply) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *GetFileReply) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *GetFileReply) GetUploadId() string { + if x != nil { + return x.UploadId + } + return "" +} + +func (x *GetFileReply) GetChunkCount() uint32 { + if x != nil { + return x.ChunkCount + } + return 0 +} + +func (x *GetFileReply) GetCreatedAt() uint32 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *GetFileReply) GetUpdatedAt() uint32 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +type ListFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Page uint32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PageSize uint32 `protobuf:"varint,2,opt,name=pageSize,proto3" json:"pageSize,omitempty"` + Order *string `protobuf:"bytes,3,opt,name=order,proto3,oneof" json:"order,omitempty"` + OrderBy *string `protobuf:"bytes,4,opt,name=orderBy,proto3,oneof" json:"orderBy,omitempty"` + DirectoryId *uint32 `protobuf:"varint,5,opt,name=directoryId,proto3,oneof" json:"directoryId,omitempty"` + Status *string `protobuf:"bytes,6,opt,name=status,proto3,oneof" json:"status,omitempty"` +} + +func (x *ListFileRequest) Reset() { + *x = ListFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFileRequest) ProtoMessage() {} + +func (x *ListFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFileRequest.ProtoReflect.Descriptor instead. +func (*ListFileRequest) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{4} +} + +func (x *ListFileRequest) GetPage() uint32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *ListFileRequest) GetPageSize() uint32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListFileRequest) GetOrder() string { + if x != nil && x.Order != nil { + return *x.Order + } + return "" +} + +func (x *ListFileRequest) GetOrderBy() string { + if x != nil && x.OrderBy != nil { + return *x.OrderBy + } + return "" +} + +func (x *ListFileRequest) GetDirectoryId() uint32 { + if x != nil && x.DirectoryId != nil { + return *x.DirectoryId + } + return 0 +} + +func (x *ListFileRequest) GetStatus() string { + if x != nil && x.Status != nil { + return *x.Status + } + return "" +} + +type ListFileReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*ListFileReply_File `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +func (x *ListFileReply) Reset() { + *x = ListFileReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFileReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFileReply) ProtoMessage() {} + +func (x *ListFileReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFileReply.ProtoReflect.Descriptor instead. +func (*ListFileReply) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{5} +} + +func (x *ListFileReply) GetTotal() uint32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *ListFileReply) GetList() []*ListFileReply_File { + if x != nil { + return x.List + } + return nil +} + +type PrepareUploadFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DirectoryId *uint32 `protobuf:"varint,1,opt,name=directoryId,proto3,oneof" json:"directoryId,omitempty"` + DirectoryPath *string `protobuf:"bytes,2,opt,name=directoryPath,proto3,oneof" json:"directoryPath,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Size uint32 `protobuf:"varint,4,opt,name=size,proto3" json:"size,omitempty"` + Sha string `protobuf:"bytes,5,opt,name=sha,proto3" json:"sha,omitempty"` +} + +func (x *PrepareUploadFileRequest) Reset() { + *x = PrepareUploadFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PrepareUploadFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrepareUploadFileRequest) ProtoMessage() {} + +func (x *PrepareUploadFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PrepareUploadFileRequest.ProtoReflect.Descriptor instead. +func (*PrepareUploadFileRequest) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{6} +} + +func (x *PrepareUploadFileRequest) GetDirectoryId() uint32 { + if x != nil && x.DirectoryId != nil { + return *x.DirectoryId + } + return 0 +} + +func (x *PrepareUploadFileRequest) GetDirectoryPath() string { + if x != nil && x.DirectoryPath != nil { + return *x.DirectoryPath + } + return "" +} + +func (x *PrepareUploadFileRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PrepareUploadFileRequest) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *PrepareUploadFileRequest) GetSha() string { + if x != nil { + return x.Sha + } + return "" +} + +type PrepareUploadFileReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uploaded bool `protobuf:"varint,1,opt,name=uploaded,proto3" json:"uploaded,omitempty"` + Src *string `protobuf:"bytes,2,opt,name=src,proto3,oneof" json:"src,omitempty"` + ChunkSize *uint32 `protobuf:"varint,3,opt,name=chunkSize,proto3,oneof" json:"chunkSize,omitempty"` + ChunkCount *uint32 `protobuf:"varint,4,opt,name=chunkCount,proto3,oneof" json:"chunkCount,omitempty"` + UploadId *string `protobuf:"bytes,5,opt,name=uploadId,proto3,oneof" json:"uploadId,omitempty"` + UploadChunks []uint32 `protobuf:"varint,6,rep,packed,name=uploadChunks,proto3" json:"uploadChunks,omitempty"` + Sha *string `protobuf:"bytes,7,opt,name=sha,proto3,oneof" json:"sha,omitempty"` + Url *string `protobuf:"bytes,8,opt,name=url,proto3,oneof" json:"url,omitempty"` +} + +func (x *PrepareUploadFileReply) Reset() { + *x = PrepareUploadFileReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PrepareUploadFileReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrepareUploadFileReply) ProtoMessage() {} + +func (x *PrepareUploadFileReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PrepareUploadFileReply.ProtoReflect.Descriptor instead. +func (*PrepareUploadFileReply) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{7} +} + +func (x *PrepareUploadFileReply) GetUploaded() bool { + if x != nil { + return x.Uploaded + } + return false +} + +func (x *PrepareUploadFileReply) GetSrc() string { + if x != nil && x.Src != nil { + return *x.Src + } + return "" +} + +func (x *PrepareUploadFileReply) GetChunkSize() uint32 { + if x != nil && x.ChunkSize != nil { + return *x.ChunkSize + } + return 0 +} + +func (x *PrepareUploadFileReply) GetChunkCount() uint32 { + if x != nil && x.ChunkCount != nil { + return *x.ChunkCount + } + return 0 +} + +func (x *PrepareUploadFileReply) GetUploadId() string { + if x != nil && x.UploadId != nil { + return *x.UploadId + } + return "" +} + +func (x *PrepareUploadFileReply) GetUploadChunks() []uint32 { + if x != nil { + return x.UploadChunks + } + return nil +} + +func (x *PrepareUploadFileReply) GetSha() string { + if x != nil && x.Sha != nil { + return *x.Sha + } + return "" +} + +func (x *PrepareUploadFileReply) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +type UploadFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + UploadId string `protobuf:"bytes,2,opt,name=uploadId,proto3" json:"uploadId,omitempty"` + Index uint32 `protobuf:"varint,3,opt,name=index,proto3" json:"index,omitempty"` +} + +func (x *UploadFileRequest) Reset() { + *x = UploadFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UploadFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UploadFileRequest) ProtoMessage() {} + +func (x *UploadFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UploadFileRequest.ProtoReflect.Descriptor instead. +func (*UploadFileRequest) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{8} +} + +func (x *UploadFileRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *UploadFileRequest) GetUploadId() string { + if x != nil { + return x.UploadId + } + return "" +} + +func (x *UploadFileRequest) GetIndex() uint32 { + if x != nil { + return x.Index + } + return 0 +} + +type UploadFileReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Src string `protobuf:"bytes,1,opt,name=src,proto3" json:"src,omitempty"` + Sha string `protobuf:"bytes,2,opt,name=sha,proto3" json:"sha,omitempty"` + Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"` +} + +func (x *UploadFileReply) Reset() { + *x = UploadFileReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UploadFileReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UploadFileReply) ProtoMessage() {} + +func (x *UploadFileReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UploadFileReply.ProtoReflect.Descriptor instead. +func (*UploadFileReply) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{9} +} + +func (x *UploadFileReply) GetSrc() string { + if x != nil { + return x.Src + } + return "" +} + +func (x *UploadFileReply) GetSha() string { + if x != nil { + return x.Sha + } + return "" +} + +func (x *UploadFileReply) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +type UpdateFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + DirectoryId uint32 `protobuf:"varint,2,opt,name=directoryId,proto3" json:"directoryId,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *UpdateFileRequest) Reset() { + *x = UpdateFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateFileRequest) ProtoMessage() {} + +func (x *UpdateFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateFileRequest.ProtoReflect.Descriptor instead. +func (*UpdateFileRequest) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{10} +} + +func (x *UpdateFileRequest) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *UpdateFileRequest) GetDirectoryId() uint32 { + if x != nil { + return x.DirectoryId + } + return 0 +} + +func (x *UpdateFileRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type UpdateFileReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpdateFileReply) Reset() { + *x = UpdateFileReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateFileReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateFileReply) ProtoMessage() {} + +func (x *UpdateFileReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateFileReply.ProtoReflect.Descriptor instead. +func (*UpdateFileReply) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{11} +} + +type DeleteFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ids []uint32 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids,omitempty"` +} + +func (x *DeleteFileRequest) Reset() { + *x = DeleteFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteFileRequest) ProtoMessage() {} + +func (x *DeleteFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteFileRequest.ProtoReflect.Descriptor instead. +func (*DeleteFileRequest) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{12} +} + +func (x *DeleteFileRequest) GetIds() []uint32 { + if x != nil { + return x.Ids + } + return nil +} + +type DeleteFileReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` +} + +func (x *DeleteFileReply) Reset() { + *x = DeleteFileReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteFileReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteFileReply) ProtoMessage() {} + +func (x *DeleteFileReply) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteFileReply.ProtoReflect.Descriptor instead. +func (*DeleteFileReply) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{13} +} + +func (x *DeleteFileReply) GetTotal() uint32 { + if x != nil { + return x.Total + } + return 0 +} + +type ListFileReply_File struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + DirectoryId uint32 `protobuf:"varint,2,opt,name=directoryId,proto3" json:"directoryId,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"` + Size uint32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` + Sha string `protobuf:"bytes,6,opt,name=sha,proto3" json:"sha,omitempty"` + Src string `protobuf:"bytes,7,opt,name=src,proto3" json:"src,omitempty"` + Url string `protobuf:"bytes,8,opt,name=url,proto3" json:"url,omitempty"` + Status string `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"` + UploadId string `protobuf:"bytes,10,opt,name=uploadId,proto3" json:"uploadId,omitempty"` + ChunkCount uint32 `protobuf:"varint,11,opt,name=chunkCount,proto3" json:"chunkCount,omitempty"` + CreatedAt uint32 `protobuf:"varint,12,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt uint32 `protobuf:"varint,13,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` +} + +func (x *ListFileReply_File) Reset() { + *x = ListFileReply_File{} + if protoimpl.UnsafeEnabled { + mi := &file_api_resource_file_resource_file_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFileReply_File) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFileReply_File) ProtoMessage() {} + +func (x *ListFileReply_File) ProtoReflect() protoreflect.Message { + mi := &file_api_resource_file_resource_file_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFileReply_File.ProtoReflect.Descriptor instead. +func (*ListFileReply_File) Descriptor() ([]byte, []int) { + return file_api_resource_file_resource_file_proto_rawDescGZIP(), []int{5, 0} +} + +func (x *ListFileReply_File) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *ListFileReply_File) GetDirectoryId() uint32 { + if x != nil { + return x.DirectoryId + } + return 0 +} + +func (x *ListFileReply_File) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ListFileReply_File) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *ListFileReply_File) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ListFileReply_File) GetSha() string { + if x != nil { + return x.Sha + } + return "" +} + +func (x *ListFileReply_File) GetSrc() string { + if x != nil { + return x.Src + } + return "" +} + +func (x *ListFileReply_File) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *ListFileReply_File) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *ListFileReply_File) GetUploadId() string { + if x != nil { + return x.UploadId + } + return "" +} + +func (x *ListFileReply_File) GetChunkCount() uint32 { + if x != nil { + return x.ChunkCount + } + return 0 +} + +func (x *ListFileReply_File) GetCreatedAt() uint32 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *ListFileReply_File) GetUpdatedAt() uint32 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +var File_api_resource_file_resource_file_proto protoreflect.FileDescriptor + +var file_api_resource_file_resource_file_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, + 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xe6, 0x01, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x73, 0x72, 0x63, + 0x12, 0x1f, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x65, 0x12, 0x1b, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x14, + 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1a, 0x0a, 0x08, + 0x73, 0x61, 0x76, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x73, 0x61, 0x76, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x39, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x12, 0x0a, 0x04, 0x6d, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, + 0x69, 0x6d, 0x65, 0x22, 0x5d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, + 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x01, 0x52, 0x03, 0x73, 0x68, 0x61, + 0x88, 0x01, 0x01, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x73, + 0x68, 0x61, 0x22, 0xc2, 0x02, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x73, 0x68, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x1a, 0x0a, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, + 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xd5, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, + 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x70, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, + 0x20, 0x00, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, + 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, + 0x04, 0x18, 0x32, 0x20, 0x00, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x2b, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, + 0xfa, 0x42, 0x0d, 0x72, 0x0b, 0x52, 0x03, 0x61, 0x73, 0x63, 0x52, 0x04, 0x64, 0x65, 0x73, 0x63, + 0x48, 0x00, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x07, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xfa, + 0x42, 0x1e, 0x72, 0x1c, 0x52, 0x02, 0x69, 0x64, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x48, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x25, + 0x0a, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1a, 0xfa, 0x42, 0x17, 0x72, 0x15, 0x52, 0x08, 0x50, 0x52, + 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x52, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, + 0x44, 0x48, 0x03, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x08, + 0x0a, 0x06, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x42, 0x79, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x49, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, + 0xa9, 0x03, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x45, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x1a, 0xba, + 0x02, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x73, 0x68, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x12, + 0x1e, 0x0a, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xf5, 0x01, 0x0a, 0x18, + 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x0b, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, + 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x32, 0x0a, 0x0d, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x01, 0x52, 0x0d, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x61, 0x74, 0x68, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, + 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, + 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x73, 0x68, + 0x61, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x49, + 0x64, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x50, + 0x61, 0x74, 0x68, 0x22, 0xc8, 0x02, 0x0a, 0x16, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x55, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1a, + 0x0a, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x12, 0x15, 0x0a, 0x03, 0x73, 0x72, + 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x73, 0x72, 0x63, 0x88, 0x01, + 0x01, 0x12, 0x21, 0x0a, 0x09, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x09, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, + 0x65, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, + 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x75, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x08, 0x75, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0c, 0x75, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0d, + 0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x12, 0x15, + 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x03, 0x73, + 0x68, 0x61, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x05, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, + 0x5f, 0x73, 0x72, 0x63, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, + 0x7a, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x42, 0x06, + 0x0a, 0x04, 0x5f, 0x73, 0x68, 0x61, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x75, 0x72, 0x6c, 0x22, 0x74, + 0x0a, 0x11, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x7a, 0x02, 0x10, 0x00, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x23, 0x0a, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x75, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x05, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x22, 0x47, 0x0a, 0x0f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x68, 0x61, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x68, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x74, 0x0a, + 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, + 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x29, 0x0a, 0x0b, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x33, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x03, 0x69, + 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x92, 0x01, 0x06, + 0x08, 0x01, 0x10, 0x32, 0x18, 0x01, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x27, 0x0a, 0x0f, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x32, 0x0a, 0x1d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x06, 0x46, 0x69, 0x6c, 0x65, 0x56, 0x31, 0x50, 0x01, 0x5a, + 0x07, 0x2e, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_resource_file_resource_file_proto_rawDescOnce sync.Once + file_api_resource_file_resource_file_proto_rawDescData = file_api_resource_file_resource_file_proto_rawDesc +) + +func file_api_resource_file_resource_file_proto_rawDescGZIP() []byte { + file_api_resource_file_resource_file_proto_rawDescOnce.Do(func() { + file_api_resource_file_resource_file_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_resource_file_resource_file_proto_rawDescData) + }) + return file_api_resource_file_resource_file_proto_rawDescData +} + +var file_api_resource_file_resource_file_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_api_resource_file_resource_file_proto_goTypes = []interface{}{ + (*StaticFileRequest)(nil), // 0: resource.api.resource.file.v1.StaticFileRequest + (*StaticFileReply)(nil), // 1: resource.api.resource.file.v1.StaticFileReply + (*GetFileRequest)(nil), // 2: resource.api.resource.file.v1.GetFileRequest + (*GetFileReply)(nil), // 3: resource.api.resource.file.v1.GetFileReply + (*ListFileRequest)(nil), // 4: resource.api.resource.file.v1.ListFileRequest + (*ListFileReply)(nil), // 5: resource.api.resource.file.v1.ListFileReply + (*PrepareUploadFileRequest)(nil), // 6: resource.api.resource.file.v1.PrepareUploadFileRequest + (*PrepareUploadFileReply)(nil), // 7: resource.api.resource.file.v1.PrepareUploadFileReply + (*UploadFileRequest)(nil), // 8: resource.api.resource.file.v1.UploadFileRequest + (*UploadFileReply)(nil), // 9: resource.api.resource.file.v1.UploadFileReply + (*UpdateFileRequest)(nil), // 10: resource.api.resource.file.v1.UpdateFileRequest + (*UpdateFileReply)(nil), // 11: resource.api.resource.file.v1.UpdateFileReply + (*DeleteFileRequest)(nil), // 12: resource.api.resource.file.v1.DeleteFileRequest + (*DeleteFileReply)(nil), // 13: resource.api.resource.file.v1.DeleteFileReply + (*ListFileReply_File)(nil), // 14: resource.api.resource.file.v1.ListFileReply.File +} +var file_api_resource_file_resource_file_proto_depIdxs = []int32{ + 14, // 0: resource.api.resource.file.v1.ListFileReply.list:type_name -> resource.api.resource.file.v1.ListFileReply.File + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_api_resource_file_resource_file_proto_init() } +func file_api_resource_file_resource_file_proto_init() { + if File_api_resource_file_resource_file_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_resource_file_resource_file_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StaticFileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StaticFileReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFileReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListFileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListFileReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PrepareUploadFileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PrepareUploadFileReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UploadFileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UploadFileReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateFileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateFileReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteFileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteFileReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_resource_file_resource_file_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListFileReply_File); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_api_resource_file_resource_file_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_api_resource_file_resource_file_proto_msgTypes[4].OneofWrappers = []interface{}{} + file_api_resource_file_resource_file_proto_msgTypes[6].OneofWrappers = []interface{}{} + file_api_resource_file_resource_file_proto_msgTypes[7].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_resource_file_resource_file_proto_rawDesc, + NumEnums: 0, + NumMessages: 15, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_resource_file_resource_file_proto_goTypes, + DependencyIndexes: file_api_resource_file_resource_file_proto_depIdxs, + MessageInfos: file_api_resource_file_resource_file_proto_msgTypes, + }.Build() + File_api_resource_file_resource_file_proto = out.File + file_api_resource_file_resource_file_proto_rawDesc = nil + file_api_resource_file_resource_file_proto_goTypes = nil + file_api_resource_file_resource_file_proto_depIdxs = nil +} diff --git a/api/file/v1/resource_file.pb.validate.go b/api/resource/file/v1/resource_file.pb.validate.go similarity index 63% rename from api/file/v1/resource_file.pb.validate.go rename to api/resource/file/v1/resource_file.pb.validate.go index d541ce1..96fcfb3 100644 --- a/api/file/v1/resource_file.pb.validate.go +++ b/api/resource/file/v1/resource_file.pb.validate.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-validate. DO NOT EDIT. -// source: resource_file.proto +// source: api/resource/file/resource_file.proto package v1 @@ -35,58 +35,191 @@ var ( _ = sort.Sort ) -// Validate checks the field values on File with the rules defined in the proto -// definition for this message. If any rules are violated, the first error -// encountered is returned, or nil if there are no violations. -func (m *File) Validate() error { +// Validate checks the field values on StaticFileRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *StaticFileRequest) Validate() error { return m.validate(false) } -// ValidateAll checks the field values on File with the rules defined in the -// proto definition for this message. If any rules are violated, the result is -// a list of violation errors wrapped in FileMultiError, or nil if none found. -func (m *File) ValidateAll() error { +// ValidateAll checks the field values on StaticFileRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// StaticFileRequestMultiError, or nil if none found. +func (m *StaticFileRequest) ValidateAll() error { return m.validate(true) } -func (m *File) validate(all bool) error { +func (m *StaticFileRequest) validate(all bool) error { if m == nil { return nil } var errors []error - // no validation rules for Id + if utf8.RuneCountInString(m.GetSrc()) < 1 { + err := StaticFileRequestValidationError{ + field: "Src", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } - // no validation rules for DirectoryId + if utf8.RuneCountInString(m.GetExpire()) < 1 { + err := StaticFileRequestValidationError{ + field: "Expire", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } - // no validation rules for Name + if utf8.RuneCountInString(m.GetSign()) < 1 { + err := StaticFileRequestValidationError{ + field: "Sign", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } - // no validation rules for Type + // no validation rules for Width - // no validation rules for Size + // no validation rules for Height - // no validation rules for Sha + // no validation rules for Mode - // no validation rules for Src + // no validation rules for Download - // no validation rules for Storage + // no validation rules for SaveName - // no validation rules for CreatedAt + if len(errors) > 0 { + return StaticFileRequestMultiError(errors) + } + + return nil +} + +// StaticFileRequestMultiError is an error wrapping multiple validation errors +// returned by StaticFileRequest.ValidateAll() if the designated constraints +// aren't met. +type StaticFileRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m StaticFileRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m StaticFileRequestMultiError) AllErrors() []error { return m } + +// StaticFileRequestValidationError is the validation error returned by +// StaticFileRequest.Validate if the designated constraints aren't met. +type StaticFileRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e StaticFileRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e StaticFileRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e StaticFileRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e StaticFileRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e StaticFileRequestValidationError) ErrorName() string { + return "StaticFileRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e StaticFileRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sStaticFileRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = StaticFileRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = StaticFileRequestValidationError{} + +// Validate checks the field values on StaticFileReply with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *StaticFileReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on StaticFileReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// StaticFileReplyMultiError, or nil if none found. +func (m *StaticFileReply) ValidateAll() error { + return m.validate(true) +} + +func (m *StaticFileReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Data + + // no validation rules for Mime if len(errors) > 0 { - return FileMultiError(errors) + return StaticFileReplyMultiError(errors) } return nil } -// FileMultiError is an error wrapping multiple validation errors returned by -// File.ValidateAll() if the designated constraints aren't met. -type FileMultiError []error +// StaticFileReplyMultiError is an error wrapping multiple validation errors +// returned by StaticFileReply.ValidateAll() if the designated constraints +// aren't met. +type StaticFileReplyMultiError []error // Error returns a concatenation of all the error messages it wraps. -func (m FileMultiError) Error() string { +func (m StaticFileReplyMultiError) Error() string { var msgs []string for _, err := range m { msgs = append(msgs, err.Error()) @@ -95,11 +228,11 @@ func (m FileMultiError) Error() string { } // AllErrors returns a list of validation violation errors. -func (m FileMultiError) AllErrors() []error { return m } +func (m StaticFileReplyMultiError) AllErrors() []error { return m } -// FileValidationError is the validation error returned by File.Validate if the -// designated constraints aren't met. -type FileValidationError struct { +// StaticFileReplyValidationError is the validation error returned by +// StaticFileReply.Validate if the designated constraints aren't met. +type StaticFileReplyValidationError struct { field string reason string cause error @@ -107,22 +240,22 @@ type FileValidationError struct { } // Field function returns field value. -func (e FileValidationError) Field() string { return e.field } +func (e StaticFileReplyValidationError) Field() string { return e.field } // Reason function returns reason value. -func (e FileValidationError) Reason() string { return e.reason } +func (e StaticFileReplyValidationError) Reason() string { return e.reason } // Cause function returns cause value. -func (e FileValidationError) Cause() error { return e.cause } +func (e StaticFileReplyValidationError) Cause() error { return e.cause } // Key function returns key value. -func (e FileValidationError) Key() bool { return e.key } +func (e StaticFileReplyValidationError) Key() bool { return e.key } // ErrorName returns error name. -func (e FileValidationError) ErrorName() string { return "FileValidationError" } +func (e StaticFileReplyValidationError) ErrorName() string { return "StaticFileReplyValidationError" } // Error satisfies the builtin error interface -func (e FileValidationError) Error() string { +func (e StaticFileReplyValidationError) Error() string { cause := "" if e.cause != nil { cause = fmt.Sprintf(" | caused by: %v", e.cause) @@ -134,14 +267,14 @@ func (e FileValidationError) Error() string { } return fmt.Sprintf( - "invalid %sFile.%s: %s%s", + "invalid %sStaticFileReply.%s: %s%s", key, e.field, e.reason, cause) } -var _ error = FileValidationError{} +var _ error = StaticFileReplyValidationError{} var _ interface { Field() string @@ -149,7 +282,7 @@ var _ interface { Key() bool Cause() error ErrorName() string -} = FileValidationError{} +} = StaticFileReplyValidationError{} // Validate checks the field values on GetFileRequest with the rules defined in // the proto definition for this message. If any rules are violated, the first @@ -173,32 +306,35 @@ func (m *GetFileRequest) validate(all bool) error { var errors []error - if utf8.RuneCountInString(m.GetSrc()) < 1 { - err := GetFileRequestValidationError{ - field: "Src", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - // no validation rules for Width - - // no validation rules for Height - - // no validation rules for Mode + if m.Id != nil { - // no validation rules for IsRange + if m.GetId() <= 0 { + err := GetFileRequestValidationError{ + field: "Id", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } - // no validation rules for Start + } - // no validation rules for End + if m.Sha != nil { - // no validation rules for Download + if utf8.RuneCountInString(m.GetSha()) < 1 { + err := GetFileRequestValidationError{ + field: "Sha", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } - // no validation rules for SaveName + } if len(errors) > 0 { return GetFileRequestMultiError(errors) @@ -300,9 +436,31 @@ func (m *GetFileReply) validate(all bool) error { var errors []error - // no validation rules for Data + // no validation rules for Id - // no validation rules for Mime + // no validation rules for DirectoryId + + // no validation rules for Name + + // no validation rules for Type + + // no validation rules for Size + + // no validation rules for Sha + + // no validation rules for Src + + // no validation rules for Url + + // no validation rules for Status + + // no validation rules for UploadId + + // no validation rules for ChunkCount + + // no validation rules for CreatedAt + + // no validation rules for UpdatedAt if len(errors) > 0 { return GetFileReplyMultiError(errors) @@ -381,32 +539,43 @@ var _ interface { ErrorName() string } = GetFileReplyValidationError{} -// Validate checks the field values on GetFileByShaRequest with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *GetFileByShaRequest) Validate() error { +// Validate checks the field values on ListFileRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *ListFileRequest) Validate() error { return m.validate(false) } -// ValidateAll checks the field values on GetFileByShaRequest with the rules +// ValidateAll checks the field values on ListFileRequest with the rules // defined in the proto definition for this message. If any rules are // violated, the result is a list of violation errors wrapped in -// GetFileByShaRequestMultiError, or nil if none found. -func (m *GetFileByShaRequest) ValidateAll() error { +// ListFileRequestMultiError, or nil if none found. +func (m *ListFileRequest) ValidateAll() error { return m.validate(true) } -func (m *GetFileByShaRequest) validate(all bool) error { +func (m *ListFileRequest) validate(all bool) error { if m == nil { return nil } var errors []error - if utf8.RuneCountInString(m.GetSha()) < 1 { - err := GetFileByShaRequestValidationError{ - field: "Sha", - reason: "value length must be at least 1 runes", + if m.GetPage() <= 0 { + err := ListFileRequestValidationError{ + field: "Page", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if val := m.GetPageSize(); val <= 0 || val > 50 { + err := ListFileRequestValidationError{ + field: "PageSize", + reason: "value must be inside range (0, 50]", } if !all { return err @@ -414,20 +583,69 @@ func (m *GetFileByShaRequest) validate(all bool) error { errors = append(errors, err) } + if m.Order != nil { + + if _, ok := _ListFileRequest_Order_InLookup[m.GetOrder()]; !ok { + err := ListFileRequestValidationError{ + field: "Order", + reason: "value must be in list [asc desc]", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if m.OrderBy != nil { + + if _, ok := _ListFileRequest_OrderBy_InLookup[m.GetOrderBy()]; !ok { + err := ListFileRequestValidationError{ + field: "OrderBy", + reason: "value must be in list [id created_at updated_at]", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if m.DirectoryId != nil { + // no validation rules for DirectoryId + } + + if m.Status != nil { + + if _, ok := _ListFileRequest_Status_InLookup[m.GetStatus()]; !ok { + err := ListFileRequestValidationError{ + field: "Status", + reason: "value must be in list [PROGRESS COMPLETED]", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + if len(errors) > 0 { - return GetFileByShaRequestMultiError(errors) + return ListFileRequestMultiError(errors) } return nil } -// GetFileByShaRequestMultiError is an error wrapping multiple validation -// errors returned by GetFileByShaRequest.ValidateAll() if the designated -// constraints aren't met. -type GetFileByShaRequestMultiError []error +// ListFileRequestMultiError is an error wrapping multiple validation errors +// returned by ListFileRequest.ValidateAll() if the designated constraints +// aren't met. +type ListFileRequestMultiError []error // Error returns a concatenation of all the error messages it wraps. -func (m GetFileByShaRequestMultiError) Error() string { +func (m ListFileRequestMultiError) Error() string { var msgs []string for _, err := range m { msgs = append(msgs, err.Error()) @@ -436,11 +654,11 @@ func (m GetFileByShaRequestMultiError) Error() string { } // AllErrors returns a list of validation violation errors. -func (m GetFileByShaRequestMultiError) AllErrors() []error { return m } +func (m ListFileRequestMultiError) AllErrors() []error { return m } -// GetFileByShaRequestValidationError is the validation error returned by -// GetFileByShaRequest.Validate if the designated constraints aren't met. -type GetFileByShaRequestValidationError struct { +// ListFileRequestValidationError is the validation error returned by +// ListFileRequest.Validate if the designated constraints aren't met. +type ListFileRequestValidationError struct { field string reason string cause error @@ -448,24 +666,174 @@ type GetFileByShaRequestValidationError struct { } // Field function returns field value. -func (e GetFileByShaRequestValidationError) Field() string { return e.field } +func (e ListFileRequestValidationError) Field() string { return e.field } // Reason function returns reason value. -func (e GetFileByShaRequestValidationError) Reason() string { return e.reason } +func (e ListFileRequestValidationError) Reason() string { return e.reason } // Cause function returns cause value. -func (e GetFileByShaRequestValidationError) Cause() error { return e.cause } +func (e ListFileRequestValidationError) Cause() error { return e.cause } // Key function returns key value. -func (e GetFileByShaRequestValidationError) Key() bool { return e.key } +func (e ListFileRequestValidationError) Key() bool { return e.key } // ErrorName returns error name. -func (e GetFileByShaRequestValidationError) ErrorName() string { - return "GetFileByShaRequestValidationError" +func (e ListFileRequestValidationError) ErrorName() string { return "ListFileRequestValidationError" } + +// Error satisfies the builtin error interface +func (e ListFileRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListFileRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) } +var _ error = ListFileRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListFileRequestValidationError{} + +var _ListFileRequest_Order_InLookup = map[string]struct{}{ + "asc": {}, + "desc": {}, +} + +var _ListFileRequest_OrderBy_InLookup = map[string]struct{}{ + "id": {}, + "created_at": {}, + "updated_at": {}, +} + +var _ListFileRequest_Status_InLookup = map[string]struct{}{ + "PROGRESS": {}, + "COMPLETED": {}, +} + +// Validate checks the field values on ListFileReply with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *ListFileReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListFileReply with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in ListFileReplyMultiError, or +// nil if none found. +func (m *ListFileReply) ValidateAll() error { + return m.validate(true) +} + +func (m *ListFileReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Total + + for idx, item := range m.GetList() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListFileReplyValidationError{ + field: fmt.Sprintf("List[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListFileReplyValidationError{ + field: fmt.Sprintf("List[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListFileReplyValidationError{ + field: fmt.Sprintf("List[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ListFileReplyMultiError(errors) + } + + return nil +} + +// ListFileReplyMultiError is an error wrapping multiple validation errors +// returned by ListFileReply.ValidateAll() if the designated constraints +// aren't met. +type ListFileReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListFileReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListFileReplyMultiError) AllErrors() []error { return m } + +// ListFileReplyValidationError is the validation error returned by +// ListFileReply.Validate if the designated constraints aren't met. +type ListFileReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListFileReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListFileReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListFileReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListFileReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListFileReplyValidationError) ErrorName() string { return "ListFileReplyValidationError" } + // Error satisfies the builtin error interface -func (e GetFileByShaRequestValidationError) Error() string { +func (e ListFileReplyValidationError) Error() string { cause := "" if e.cause != nil { cause = fmt.Sprintf(" | caused by: %v", e.cause) @@ -477,14 +845,14 @@ func (e GetFileByShaRequestValidationError) Error() string { } return fmt.Sprintf( - "invalid %sGetFileByShaRequest.%s: %s%s", + "invalid %sListFileReply.%s: %s%s", key, e.field, e.reason, cause) } -var _ error = GetFileByShaRequestValidationError{} +var _ error = ListFileReplyValidationError{} var _ interface { Field() string @@ -492,7 +860,7 @@ var _ interface { Key() bool Cause() error ErrorName() string -} = GetFileByShaRequestValidationError{} +} = ListFileReplyValidationError{} // Validate checks the field values on PrepareUploadFileRequest with the rules // defined in the proto definition for this message. If any rules are @@ -516,13 +884,9 @@ func (m *PrepareUploadFileRequest) validate(all bool) error { var errors []error - // no validation rules for DirectoryId - - // no validation rules for DirectoryPath - - if utf8.RuneCountInString(m.GetApp()) < 1 { + if utf8.RuneCountInString(m.GetName()) < 1 { err := PrepareUploadFileRequestValidationError{ - field: "App", + field: "Name", reason: "value length must be at least 1 runes", } if !all { @@ -531,10 +895,10 @@ func (m *PrepareUploadFileRequest) validate(all bool) error { errors = append(errors, err) } - if utf8.RuneCountInString(m.GetName()) < 1 { + if m.GetSize() <= 0 { err := PrepareUploadFileRequestValidationError{ - field: "Name", - reason: "value length must be at least 1 runes", + field: "Size", + reason: "value must be greater than 0", } if !all { return err @@ -553,15 +917,34 @@ func (m *PrepareUploadFileRequest) validate(all bool) error { errors = append(errors, err) } - if m.GetSize() <= 0 { - err := PrepareUploadFileRequestValidationError{ - field: "Size", - reason: "value must be greater than 0", + if m.DirectoryId != nil { + + if m.GetDirectoryId() <= 0 { + err := PrepareUploadFileRequestValidationError{ + field: "DirectoryId", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) } - if !all { - return err + + } + + if m.DirectoryPath != nil { + + if utf8.RuneCountInString(m.GetDirectoryPath()) < 1 { + err := PrepareUploadFileRequestValidationError{ + field: "DirectoryPath", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) } - errors = append(errors, err) + } if len(errors) > 0 { @@ -666,9 +1049,7 @@ func (m *PrepareUploadFileReply) validate(all bool) error { var errors []error - if m.Uploaded != nil { - // no validation rules for Uploaded - } + // no validation rules for Uploaded if m.Src != nil { // no validation rules for Src @@ -690,6 +1071,10 @@ func (m *PrepareUploadFileReply) validate(all bool) error { // no validation rules for Sha } + if m.Url != nil { + // no validation rules for Url + } + if len(errors) > 0 { return PrepareUploadFileReplyMultiError(errors) } @@ -770,32 +1155,32 @@ var _ interface { ErrorName() string } = PrepareUploadFileReplyValidationError{} -// Validate checks the field values on PageFileRequest with the rules defined +// Validate checks the field values on UploadFileRequest with the rules defined // in the proto definition for this message. If any rules are violated, the // first error encountered is returned, or nil if there are no violations. -func (m *PageFileRequest) Validate() error { +func (m *UploadFileRequest) Validate() error { return m.validate(false) } -// ValidateAll checks the field values on PageFileRequest with the rules +// ValidateAll checks the field values on UploadFileRequest with the rules // defined in the proto definition for this message. If any rules are // violated, the result is a list of violation errors wrapped in -// PageFileRequestMultiError, or nil if none found. -func (m *PageFileRequest) ValidateAll() error { +// UploadFileRequestMultiError, or nil if none found. +func (m *UploadFileRequest) ValidateAll() error { return m.validate(true) } -func (m *PageFileRequest) validate(all bool) error { +func (m *UploadFileRequest) validate(all bool) error { if m == nil { return nil } var errors []error - if m.GetDirectoryId() <= 0 { - err := PageFileRequestValidationError{ - field: "DirectoryId", - reason: "value must be greater than 0", + if len(m.GetData()) < 0 { + err := UploadFileRequestValidationError{ + field: "Data", + reason: "value length must be at least 0 bytes", } if !all { return err @@ -803,9 +1188,9 @@ func (m *PageFileRequest) validate(all bool) error { errors = append(errors, err) } - if utf8.RuneCountInString(m.GetApp()) < 1 { - err := PageFileRequestValidationError{ - field: "App", + if utf8.RuneCountInString(m.GetUploadId()) < 1 { + err := UploadFileRequestValidationError{ + field: "UploadId", reason: "value length must be at least 1 runes", } if !all { @@ -814,9 +1199,9 @@ func (m *PageFileRequest) validate(all bool) error { errors = append(errors, err) } - if m.GetPage() <= 0 { - err := PageFileRequestValidationError{ - field: "Page", + if m.GetIndex() <= 0 { + err := UploadFileRequestValidationError{ + field: "Index", reason: "value must be greater than 0", } if !all { @@ -825,35 +1210,20 @@ func (m *PageFileRequest) validate(all bool) error { errors = append(errors, err) } - if val := m.GetPageSize(); val <= 0 || val > 100 { - err := PageFileRequestValidationError{ - field: "PageSize", - reason: "value must be inside range (0, 100]", - } - if !all { - return err - } - errors = append(errors, err) - } - - if m.Name != nil { - // no validation rules for Name - } - if len(errors) > 0 { - return PageFileRequestMultiError(errors) + return UploadFileRequestMultiError(errors) } return nil } -// PageFileRequestMultiError is an error wrapping multiple validation errors -// returned by PageFileRequest.ValidateAll() if the designated constraints +// UploadFileRequestMultiError is an error wrapping multiple validation errors +// returned by UploadFileRequest.ValidateAll() if the designated constraints // aren't met. -type PageFileRequestMultiError []error +type UploadFileRequestMultiError []error // Error returns a concatenation of all the error messages it wraps. -func (m PageFileRequestMultiError) Error() string { +func (m UploadFileRequestMultiError) Error() string { var msgs []string for _, err := range m { msgs = append(msgs, err.Error()) @@ -862,11 +1232,11 @@ func (m PageFileRequestMultiError) Error() string { } // AllErrors returns a list of validation violation errors. -func (m PageFileRequestMultiError) AllErrors() []error { return m } +func (m UploadFileRequestMultiError) AllErrors() []error { return m } -// PageFileRequestValidationError is the validation error returned by -// PageFileRequest.Validate if the designated constraints aren't met. -type PageFileRequestValidationError struct { +// UploadFileRequestValidationError is the validation error returned by +// UploadFileRequest.Validate if the designated constraints aren't met. +type UploadFileRequestValidationError struct { field string reason string cause error @@ -874,22 +1244,24 @@ type PageFileRequestValidationError struct { } // Field function returns field value. -func (e PageFileRequestValidationError) Field() string { return e.field } +func (e UploadFileRequestValidationError) Field() string { return e.field } // Reason function returns reason value. -func (e PageFileRequestValidationError) Reason() string { return e.reason } +func (e UploadFileRequestValidationError) Reason() string { return e.reason } // Cause function returns cause value. -func (e PageFileRequestValidationError) Cause() error { return e.cause } +func (e UploadFileRequestValidationError) Cause() error { return e.cause } // Key function returns key value. -func (e PageFileRequestValidationError) Key() bool { return e.key } +func (e UploadFileRequestValidationError) Key() bool { return e.key } // ErrorName returns error name. -func (e PageFileRequestValidationError) ErrorName() string { return "PageFileRequestValidationError" } +func (e UploadFileRequestValidationError) ErrorName() string { + return "UploadFileRequestValidationError" +} // Error satisfies the builtin error interface -func (e PageFileRequestValidationError) Error() string { +func (e UploadFileRequestValidationError) Error() string { cause := "" if e.cause != nil { cause = fmt.Sprintf(" | caused by: %v", e.cause) @@ -901,14 +1273,14 @@ func (e PageFileRequestValidationError) Error() string { } return fmt.Sprintf( - "invalid %sPageFileRequest.%s: %s%s", + "invalid %sUploadFileRequest.%s: %s%s", key, e.field, e.reason, cause) } -var _ error = PageFileRequestValidationError{} +var _ error = UploadFileRequestValidationError{} var _ interface { Field() string @@ -916,82 +1288,50 @@ var _ interface { Key() bool Cause() error ErrorName() string -} = PageFileRequestValidationError{} - -// Validate checks the field values on PageFileReply with the rules defined in -// the proto definition for this message. If any rules are violated, the first -// error encountered is returned, or nil if there are no violations. -func (m *PageFileReply) Validate() error { - return m.validate(false) -} +} = UploadFileRequestValidationError{} -// ValidateAll checks the field values on PageFileReply with the rules defined +// Validate checks the field values on UploadFileReply with the rules defined // in the proto definition for this message. If any rules are violated, the -// result is a list of violation errors wrapped in PageFileReplyMultiError, or -// nil if none found. -func (m *PageFileReply) ValidateAll() error { - return m.validate(true) -} - -func (m *PageFileReply) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - for idx, item := range m.GetList() { - _, _ = idx, item - - if all { - switch v := interface{}(item).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, PageFileReplyValidationError{ - field: fmt.Sprintf("List[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, PageFileReplyValidationError{ - field: fmt.Sprintf("List[%v]", idx), - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return PageFileReplyValidationError{ - field: fmt.Sprintf("List[%v]", idx), - reason: "embedded message failed validation", - cause: err, - } - } - } +// first error encountered is returned, or nil if there are no violations. +func (m *UploadFileReply) Validate() error { + return m.validate(false) +} - } +// ValidateAll checks the field values on UploadFileReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UploadFileReplyMultiError, or nil if none found. +func (m *UploadFileReply) ValidateAll() error { + return m.validate(true) +} - if m.Total != nil { - // no validation rules for Total +func (m *UploadFileReply) validate(all bool) error { + if m == nil { + return nil } + var errors []error + + // no validation rules for Src + + // no validation rules for Sha + + // no validation rules for Url + if len(errors) > 0 { - return PageFileReplyMultiError(errors) + return UploadFileReplyMultiError(errors) } return nil } -// PageFileReplyMultiError is an error wrapping multiple validation errors -// returned by PageFileReply.ValidateAll() if the designated constraints +// UploadFileReplyMultiError is an error wrapping multiple validation errors +// returned by UploadFileReply.ValidateAll() if the designated constraints // aren't met. -type PageFileReplyMultiError []error +type UploadFileReplyMultiError []error // Error returns a concatenation of all the error messages it wraps. -func (m PageFileReplyMultiError) Error() string { +func (m UploadFileReplyMultiError) Error() string { var msgs []string for _, err := range m { msgs = append(msgs, err.Error()) @@ -1000,11 +1340,11 @@ func (m PageFileReplyMultiError) Error() string { } // AllErrors returns a list of validation violation errors. -func (m PageFileReplyMultiError) AllErrors() []error { return m } +func (m UploadFileReplyMultiError) AllErrors() []error { return m } -// PageFileReplyValidationError is the validation error returned by -// PageFileReply.Validate if the designated constraints aren't met. -type PageFileReplyValidationError struct { +// UploadFileReplyValidationError is the validation error returned by +// UploadFileReply.Validate if the designated constraints aren't met. +type UploadFileReplyValidationError struct { field string reason string cause error @@ -1012,22 +1352,22 @@ type PageFileReplyValidationError struct { } // Field function returns field value. -func (e PageFileReplyValidationError) Field() string { return e.field } +func (e UploadFileReplyValidationError) Field() string { return e.field } // Reason function returns reason value. -func (e PageFileReplyValidationError) Reason() string { return e.reason } +func (e UploadFileReplyValidationError) Reason() string { return e.reason } // Cause function returns cause value. -func (e PageFileReplyValidationError) Cause() error { return e.cause } +func (e UploadFileReplyValidationError) Cause() error { return e.cause } // Key function returns key value. -func (e PageFileReplyValidationError) Key() bool { return e.key } +func (e UploadFileReplyValidationError) Key() bool { return e.key } // ErrorName returns error name. -func (e PageFileReplyValidationError) ErrorName() string { return "PageFileReplyValidationError" } +func (e UploadFileReplyValidationError) ErrorName() string { return "UploadFileReplyValidationError" } // Error satisfies the builtin error interface -func (e PageFileReplyValidationError) Error() string { +func (e UploadFileReplyValidationError) Error() string { cause := "" if e.cause != nil { cause = fmt.Sprintf(" | caused by: %v", e.cause) @@ -1039,14 +1379,14 @@ func (e PageFileReplyValidationError) Error() string { } return fmt.Sprintf( - "invalid %sPageFileReply.%s: %s%s", + "invalid %sUploadFileReply.%s: %s%s", key, e.field, e.reason, cause) } -var _ error = PageFileReplyValidationError{} +var _ error = UploadFileReplyValidationError{} var _ interface { Field() string @@ -1054,7 +1394,7 @@ var _ interface { Key() bool Cause() error ErrorName() string -} = PageFileReplyValidationError{} +} = UploadFileReplyValidationError{} // Validate checks the field values on UpdateFileRequest with the rules defined // in the proto definition for this message. If any rules are violated, the @@ -1089,10 +1429,10 @@ func (m *UpdateFileRequest) validate(all bool) error { errors = append(errors, err) } - if utf8.RuneCountInString(m.GetApp()) < 1 { + if m.GetDirectoryId() <= 0 { err := UpdateFileRequestValidationError{ - field: "App", - reason: "value length must be at least 1 runes", + field: "DirectoryId", + reason: "value must be greater than 0", } if !all { return err @@ -1111,17 +1451,6 @@ func (m *UpdateFileRequest) validate(all bool) error { errors = append(errors, err) } - if m.GetDirectoryId() <= 0 { - err := UpdateFileRequestValidationError{ - field: "DirectoryId", - reason: "value must be greater than 0", - } - if !all { - return err - } - errors = append(errors, err) - } - if len(errors) > 0 { return UpdateFileRequestMultiError(errors) } @@ -1202,6 +1531,106 @@ var _ interface { ErrorName() string } = UpdateFileRequestValidationError{} +// Validate checks the field values on UpdateFileReply with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *UpdateFileReply) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateFileReply with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UpdateFileReplyMultiError, or nil if none found. +func (m *UpdateFileReply) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateFileReply) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return UpdateFileReplyMultiError(errors) + } + + return nil +} + +// UpdateFileReplyMultiError is an error wrapping multiple validation errors +// returned by UpdateFileReply.ValidateAll() if the designated constraints +// aren't met. +type UpdateFileReplyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateFileReplyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateFileReplyMultiError) AllErrors() []error { return m } + +// UpdateFileReplyValidationError is the validation error returned by +// UpdateFileReply.Validate if the designated constraints aren't met. +type UpdateFileReplyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateFileReplyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateFileReplyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateFileReplyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateFileReplyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateFileReplyValidationError) ErrorName() string { return "UpdateFileReplyValidationError" } + +// Error satisfies the builtin error interface +func (e UpdateFileReplyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateFileReply.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateFileReplyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateFileReplyValidationError{} + // Validate checks the field values on DeleteFileRequest with the rules defined // in the proto definition for this message. If any rules are violated, the // first error encountered is returned, or nil if there are no violations. @@ -1224,10 +1653,10 @@ func (m *DeleteFileRequest) validate(all bool) error { var errors []error - if len(m.GetIds()) < 1 { + if l := len(m.GetIds()); l < 1 || l > 50 { err := DeleteFileRequestValidationError{ field: "Ids", - reason: "value must contain at least 1 item(s)", + reason: "value must contain between 1 and 50 items, inclusive", } if !all { return err @@ -1235,26 +1664,25 @@ func (m *DeleteFileRequest) validate(all bool) error { errors = append(errors, err) } - if utf8.RuneCountInString(m.GetApp()) < 1 { - err := DeleteFileRequestValidationError{ - field: "App", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } + _DeleteFileRequest_Ids_Unique := make(map[uint32]struct{}, len(m.GetIds())) - if m.GetDirectoryId() <= 0 { - err := DeleteFileRequestValidationError{ - field: "DirectoryId", - reason: "value must be greater than 0", - } - if !all { - return err + for idx, item := range m.GetIds() { + _, _ = idx, item + + if _, exists := _DeleteFileRequest_Ids_Unique[item]; exists { + err := DeleteFileRequestValidationError{ + field: fmt.Sprintf("Ids[%v]", idx), + reason: "repeated value must contain unique items", + } + if !all { + return err + } + errors = append(errors, err) + } else { + _DeleteFileRequest_Ids_Unique[item] = struct{}{} } - errors = append(errors, err) + + // no validation rules for Ids[idx] } if len(errors) > 0 { @@ -1337,75 +1765,44 @@ var _ interface { ErrorName() string } = DeleteFileRequestValidationError{} -// Validate checks the field values on UploadFileRequest with the rules defined +// Validate checks the field values on DeleteFileReply with the rules defined // in the proto definition for this message. If any rules are violated, the // first error encountered is returned, or nil if there are no violations. -func (m *UploadFileRequest) Validate() error { +func (m *DeleteFileReply) Validate() error { return m.validate(false) } -// ValidateAll checks the field values on UploadFileRequest with the rules +// ValidateAll checks the field values on DeleteFileReply with the rules // defined in the proto definition for this message. If any rules are // violated, the result is a list of violation errors wrapped in -// UploadFileRequestMultiError, or nil if none found. -func (m *UploadFileRequest) ValidateAll() error { +// DeleteFileReplyMultiError, or nil if none found. +func (m *DeleteFileReply) ValidateAll() error { return m.validate(true) } -func (m *UploadFileRequest) validate(all bool) error { +func (m *DeleteFileReply) validate(all bool) error { if m == nil { return nil } var errors []error - if len(m.GetData()) < 0 { - err := UploadFileRequestValidationError{ - field: "Data", - reason: "value length must be at least 0 bytes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if utf8.RuneCountInString(m.GetUploadId()) < 1 { - err := UploadFileRequestValidationError{ - field: "UploadId", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if m.GetIndex() <= 0 { - err := UploadFileRequestValidationError{ - field: "Index", - reason: "value must be greater than 0", - } - if !all { - return err - } - errors = append(errors, err) - } + // no validation rules for Total if len(errors) > 0 { - return UploadFileRequestMultiError(errors) + return DeleteFileReplyMultiError(errors) } return nil } -// UploadFileRequestMultiError is an error wrapping multiple validation errors -// returned by UploadFileRequest.ValidateAll() if the designated constraints +// DeleteFileReplyMultiError is an error wrapping multiple validation errors +// returned by DeleteFileReply.ValidateAll() if the designated constraints // aren't met. -type UploadFileRequestMultiError []error +type DeleteFileReplyMultiError []error // Error returns a concatenation of all the error messages it wraps. -func (m UploadFileRequestMultiError) Error() string { +func (m DeleteFileReplyMultiError) Error() string { var msgs []string for _, err := range m { msgs = append(msgs, err.Error()) @@ -1414,11 +1811,11 @@ func (m UploadFileRequestMultiError) Error() string { } // AllErrors returns a list of validation violation errors. -func (m UploadFileRequestMultiError) AllErrors() []error { return m } +func (m DeleteFileReplyMultiError) AllErrors() []error { return m } -// UploadFileRequestValidationError is the validation error returned by -// UploadFileRequest.Validate if the designated constraints aren't met. -type UploadFileRequestValidationError struct { +// DeleteFileReplyValidationError is the validation error returned by +// DeleteFileReply.Validate if the designated constraints aren't met. +type DeleteFileReplyValidationError struct { field string reason string cause error @@ -1426,24 +1823,22 @@ type UploadFileRequestValidationError struct { } // Field function returns field value. -func (e UploadFileRequestValidationError) Field() string { return e.field } +func (e DeleteFileReplyValidationError) Field() string { return e.field } // Reason function returns reason value. -func (e UploadFileRequestValidationError) Reason() string { return e.reason } +func (e DeleteFileReplyValidationError) Reason() string { return e.reason } // Cause function returns cause value. -func (e UploadFileRequestValidationError) Cause() error { return e.cause } +func (e DeleteFileReplyValidationError) Cause() error { return e.cause } // Key function returns key value. -func (e UploadFileRequestValidationError) Key() bool { return e.key } +func (e DeleteFileReplyValidationError) Key() bool { return e.key } // ErrorName returns error name. -func (e UploadFileRequestValidationError) ErrorName() string { - return "UploadFileRequestValidationError" -} +func (e DeleteFileReplyValidationError) ErrorName() string { return "DeleteFileReplyValidationError" } // Error satisfies the builtin error interface -func (e UploadFileRequestValidationError) Error() string { +func (e DeleteFileReplyValidationError) Error() string { cause := "" if e.cause != nil { cause = fmt.Sprintf(" | caused by: %v", e.cause) @@ -1455,14 +1850,14 @@ func (e UploadFileRequestValidationError) Error() string { } return fmt.Sprintf( - "invalid %sUploadFileRequest.%s: %s%s", + "invalid %sDeleteFileReply.%s: %s%s", key, e.field, e.reason, cause) } -var _ error = UploadFileRequestValidationError{} +var _ error = DeleteFileReplyValidationError{} var _ interface { Field() string @@ -1470,48 +1865,70 @@ var _ interface { Key() bool Cause() error ErrorName() string -} = UploadFileRequestValidationError{} +} = DeleteFileReplyValidationError{} -// Validate checks the field values on UploadFileReply with the rules defined -// in the proto definition for this message. If any rules are violated, the -// first error encountered is returned, or nil if there are no violations. -func (m *UploadFileReply) Validate() error { +// Validate checks the field values on ListFileReply_File with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListFileReply_File) Validate() error { return m.validate(false) } -// ValidateAll checks the field values on UploadFileReply with the rules +// ValidateAll checks the field values on ListFileReply_File with the rules // defined in the proto definition for this message. If any rules are // violated, the result is a list of violation errors wrapped in -// UploadFileReplyMultiError, or nil if none found. -func (m *UploadFileReply) ValidateAll() error { +// ListFileReply_FileMultiError, or nil if none found. +func (m *ListFileReply_File) ValidateAll() error { return m.validate(true) } -func (m *UploadFileReply) validate(all bool) error { +func (m *ListFileReply_File) validate(all bool) error { if m == nil { return nil } var errors []error - // no validation rules for Src + // no validation rules for Id + + // no validation rules for DirectoryId + + // no validation rules for Name + + // no validation rules for Type + + // no validation rules for Size // no validation rules for Sha + // no validation rules for Src + + // no validation rules for Url + + // no validation rules for Status + + // no validation rules for UploadId + + // no validation rules for ChunkCount + + // no validation rules for CreatedAt + + // no validation rules for UpdatedAt + if len(errors) > 0 { - return UploadFileReplyMultiError(errors) + return ListFileReply_FileMultiError(errors) } return nil } -// UploadFileReplyMultiError is an error wrapping multiple validation errors -// returned by UploadFileReply.ValidateAll() if the designated constraints +// ListFileReply_FileMultiError is an error wrapping multiple validation errors +// returned by ListFileReply_File.ValidateAll() if the designated constraints // aren't met. -type UploadFileReplyMultiError []error +type ListFileReply_FileMultiError []error // Error returns a concatenation of all the error messages it wraps. -func (m UploadFileReplyMultiError) Error() string { +func (m ListFileReply_FileMultiError) Error() string { var msgs []string for _, err := range m { msgs = append(msgs, err.Error()) @@ -1520,11 +1937,11 @@ func (m UploadFileReplyMultiError) Error() string { } // AllErrors returns a list of validation violation errors. -func (m UploadFileReplyMultiError) AllErrors() []error { return m } +func (m ListFileReply_FileMultiError) AllErrors() []error { return m } -// UploadFileReplyValidationError is the validation error returned by -// UploadFileReply.Validate if the designated constraints aren't met. -type UploadFileReplyValidationError struct { +// ListFileReply_FileValidationError is the validation error returned by +// ListFileReply_File.Validate if the designated constraints aren't met. +type ListFileReply_FileValidationError struct { field string reason string cause error @@ -1532,22 +1949,24 @@ type UploadFileReplyValidationError struct { } // Field function returns field value. -func (e UploadFileReplyValidationError) Field() string { return e.field } +func (e ListFileReply_FileValidationError) Field() string { return e.field } // Reason function returns reason value. -func (e UploadFileReplyValidationError) Reason() string { return e.reason } +func (e ListFileReply_FileValidationError) Reason() string { return e.reason } // Cause function returns cause value. -func (e UploadFileReplyValidationError) Cause() error { return e.cause } +func (e ListFileReply_FileValidationError) Cause() error { return e.cause } // Key function returns key value. -func (e UploadFileReplyValidationError) Key() bool { return e.key } +func (e ListFileReply_FileValidationError) Key() bool { return e.key } // ErrorName returns error name. -func (e UploadFileReplyValidationError) ErrorName() string { return "UploadFileReplyValidationError" } +func (e ListFileReply_FileValidationError) ErrorName() string { + return "ListFileReply_FileValidationError" +} // Error satisfies the builtin error interface -func (e UploadFileReplyValidationError) Error() string { +func (e ListFileReply_FileValidationError) Error() string { cause := "" if e.cause != nil { cause = fmt.Sprintf(" | caused by: %v", e.cause) @@ -1559,14 +1978,14 @@ func (e UploadFileReplyValidationError) Error() string { } return fmt.Sprintf( - "invalid %sUploadFileReply.%s: %s%s", + "invalid %sListFileReply_File.%s: %s%s", key, e.field, e.reason, cause) } -var _ error = UploadFileReplyValidationError{} +var _ error = ListFileReply_FileValidationError{} var _ interface { Field() string @@ -1574,4 +1993,4 @@ var _ interface { Key() bool Cause() error ErrorName() string -} = UploadFileReplyValidationError{} +} = ListFileReply_FileValidationError{} diff --git a/api/resource/file/v1/resource_file_service.pb.go b/api/resource/file/v1/resource_file_service.pb.go new file mode 100644 index 0000000..be0ff0b --- /dev/null +++ b/api/resource/file/v1/resource_file_service.pb.go @@ -0,0 +1,153 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v4.24.4 +// source: api/resource/file/resource_file_service.proto + +package v1 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var File_api_resource_file_resource_file_service_proto protoreflect.FileDescriptor + +var file_api_resource_file_resource_file_service_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x1d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x25, + 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x66, 0x69, 0x6c, + 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x32, 0xe4, 0x06, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x84, 0x01, 0x0a, + 0x07, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x2e, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1e, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0xb4, + 0x01, 0x0a, 0x11, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x46, 0x69, 0x6c, 0x65, 0x12, 0x37, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, 0x6c, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, + 0x24, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x75, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x70, 0x0a, 0x0a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, + 0x69, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x90, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x66, + 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, + 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, + 0x3a, 0x01, 0x2a, 0x1a, 0x15, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x0a, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x17, 0x2a, 0x15, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x32, 0x0a, 0x1d, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x06, 0x46, 0x69, 0x6c, + 0x65, 0x56, 0x31, 0x50, 0x01, 0x5a, 0x07, 0x2e, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_api_resource_file_resource_file_service_proto_goTypes = []interface{}{ + (*GetFileRequest)(nil), // 0: resource.api.resource.file.v1.GetFileRequest + (*ListFileRequest)(nil), // 1: resource.api.resource.file.v1.ListFileRequest + (*PrepareUploadFileRequest)(nil), // 2: resource.api.resource.file.v1.PrepareUploadFileRequest + (*UploadFileRequest)(nil), // 3: resource.api.resource.file.v1.UploadFileRequest + (*UpdateFileRequest)(nil), // 4: resource.api.resource.file.v1.UpdateFileRequest + (*DeleteFileRequest)(nil), // 5: resource.api.resource.file.v1.DeleteFileRequest + (*GetFileReply)(nil), // 6: resource.api.resource.file.v1.GetFileReply + (*ListFileReply)(nil), // 7: resource.api.resource.file.v1.ListFileReply + (*PrepareUploadFileReply)(nil), // 8: resource.api.resource.file.v1.PrepareUploadFileReply + (*UploadFileReply)(nil), // 9: resource.api.resource.file.v1.UploadFileReply + (*UpdateFileReply)(nil), // 10: resource.api.resource.file.v1.UpdateFileReply + (*DeleteFileReply)(nil), // 11: resource.api.resource.file.v1.DeleteFileReply +} +var file_api_resource_file_resource_file_service_proto_depIdxs = []int32{ + 0, // 0: resource.api.resource.file.v1.File.GetFile:input_type -> resource.api.resource.file.v1.GetFileRequest + 1, // 1: resource.api.resource.file.v1.File.ListFile:input_type -> resource.api.resource.file.v1.ListFileRequest + 2, // 2: resource.api.resource.file.v1.File.PrepareUploadFile:input_type -> resource.api.resource.file.v1.PrepareUploadFileRequest + 3, // 3: resource.api.resource.file.v1.File.UploadFile:input_type -> resource.api.resource.file.v1.UploadFileRequest + 4, // 4: resource.api.resource.file.v1.File.UpdateFile:input_type -> resource.api.resource.file.v1.UpdateFileRequest + 5, // 5: resource.api.resource.file.v1.File.DeleteFile:input_type -> resource.api.resource.file.v1.DeleteFileRequest + 6, // 6: resource.api.resource.file.v1.File.GetFile:output_type -> resource.api.resource.file.v1.GetFileReply + 7, // 7: resource.api.resource.file.v1.File.ListFile:output_type -> resource.api.resource.file.v1.ListFileReply + 8, // 8: resource.api.resource.file.v1.File.PrepareUploadFile:output_type -> resource.api.resource.file.v1.PrepareUploadFileReply + 9, // 9: resource.api.resource.file.v1.File.UploadFile:output_type -> resource.api.resource.file.v1.UploadFileReply + 10, // 10: resource.api.resource.file.v1.File.UpdateFile:output_type -> resource.api.resource.file.v1.UpdateFileReply + 11, // 11: resource.api.resource.file.v1.File.DeleteFile:output_type -> resource.api.resource.file.v1.DeleteFileReply + 6, // [6:12] is the sub-list for method output_type + 0, // [0:6] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_api_resource_file_resource_file_service_proto_init() } +func file_api_resource_file_resource_file_service_proto_init() { + if File_api_resource_file_resource_file_service_proto != nil { + return + } + file_api_resource_file_resource_file_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_resource_file_resource_file_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_resource_file_resource_file_service_proto_goTypes, + DependencyIndexes: file_api_resource_file_resource_file_service_proto_depIdxs, + }.Build() + File_api_resource_file_resource_file_service_proto = out.File + file_api_resource_file_resource_file_service_proto_rawDesc = nil + file_api_resource_file_resource_file_service_proto_goTypes = nil + file_api_resource_file_resource_file_service_proto_depIdxs = nil +} diff --git a/api/resource/file/v1/resource_file_service_grpc.pb.go b/api/resource/file/v1/resource_file_service_grpc.pb.go new file mode 100644 index 0000000..109f08d --- /dev/null +++ b/api/resource/file/v1/resource_file_service_grpc.pb.go @@ -0,0 +1,306 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.24.4 +// source: api/resource/file/resource_file_service.proto + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + File_GetFile_FullMethodName = "/resource.api.resource.file.v1.File/GetFile" + File_ListFile_FullMethodName = "/resource.api.resource.file.v1.File/ListFile" + File_PrepareUploadFile_FullMethodName = "/resource.api.resource.file.v1.File/PrepareUploadFile" + File_UploadFile_FullMethodName = "/resource.api.resource.file.v1.File/UploadFile" + File_UpdateFile_FullMethodName = "/resource.api.resource.file.v1.File/UpdateFile" + File_DeleteFile_FullMethodName = "/resource.api.resource.file.v1.File/DeleteFile" +) + +// 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 { + // GetFile 获取指定的文件信息 + GetFile(ctx context.Context, in *GetFileRequest, opts ...grpc.CallOption) (*GetFileReply, error) + // ListFile 获取文件信息列表 + ListFile(ctx context.Context, in *ListFileRequest, opts ...grpc.CallOption) (*ListFileReply, error) + // PrepareUploadFile 预上传文件信息 + PrepareUploadFile(ctx context.Context, in *PrepareUploadFileRequest, opts ...grpc.CallOption) (*PrepareUploadFileReply, error) + // UploadFile 上传文件 + UploadFile(ctx context.Context, in *UploadFileRequest, opts ...grpc.CallOption) (*UploadFileReply, error) + // UpdateFile 更新文件信息 + UpdateFile(ctx context.Context, in *UpdateFileRequest, opts ...grpc.CallOption) (*UpdateFileReply, error) + // DeleteFile 删除文件信息 + DeleteFile(ctx context.Context, in *DeleteFileRequest, opts ...grpc.CallOption) (*DeleteFileReply, error) +} + +type fileClient struct { + cc grpc.ClientConnInterface +} + +func NewFileClient(cc grpc.ClientConnInterface) FileClient { + return &fileClient{cc} +} + +func (c *fileClient) GetFile(ctx context.Context, in *GetFileRequest, opts ...grpc.CallOption) (*GetFileReply, error) { + out := new(GetFileReply) + err := c.cc.Invoke(ctx, File_GetFile_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *fileClient) ListFile(ctx context.Context, in *ListFileRequest, opts ...grpc.CallOption) (*ListFileReply, error) { + out := new(ListFileReply) + err := c.cc.Invoke(ctx, File_ListFile_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *fileClient) PrepareUploadFile(ctx context.Context, in *PrepareUploadFileRequest, opts ...grpc.CallOption) (*PrepareUploadFileReply, error) { + out := new(PrepareUploadFileReply) + err := c.cc.Invoke(ctx, File_PrepareUploadFile_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *fileClient) UploadFile(ctx context.Context, in *UploadFileRequest, opts ...grpc.CallOption) (*UploadFileReply, error) { + out := new(UploadFileReply) + err := c.cc.Invoke(ctx, File_UploadFile_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *fileClient) UpdateFile(ctx context.Context, in *UpdateFileRequest, opts ...grpc.CallOption) (*UpdateFileReply, error) { + out := new(UpdateFileReply) + err := c.cc.Invoke(ctx, File_UpdateFile_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *fileClient) DeleteFile(ctx context.Context, in *DeleteFileRequest, opts ...grpc.CallOption) (*DeleteFileReply, error) { + out := new(DeleteFileReply) + err := c.cc.Invoke(ctx, File_DeleteFile_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// FileServer is the server API for File service. +// All implementations must embed UnimplementedFileServer +// for forward compatibility +type FileServer interface { + // GetFile 获取指定的文件信息 + GetFile(context.Context, *GetFileRequest) (*GetFileReply, error) + // ListFile 获取文件信息列表 + ListFile(context.Context, *ListFileRequest) (*ListFileReply, error) + // PrepareUploadFile 预上传文件信息 + PrepareUploadFile(context.Context, *PrepareUploadFileRequest) (*PrepareUploadFileReply, error) + // UploadFile 上传文件 + UploadFile(context.Context, *UploadFileRequest) (*UploadFileReply, error) + // UpdateFile 更新文件信息 + UpdateFile(context.Context, *UpdateFileRequest) (*UpdateFileReply, error) + // DeleteFile 删除文件信息 + DeleteFile(context.Context, *DeleteFileRequest) (*DeleteFileReply, error) + mustEmbedUnimplementedFileServer() +} + +// UnimplementedFileServer must be embedded to have forward compatible implementations. +type UnimplementedFileServer struct { +} + +func (UnimplementedFileServer) GetFile(context.Context, *GetFileRequest) (*GetFileReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetFile not implemented") +} +func (UnimplementedFileServer) ListFile(context.Context, *ListFileRequest) (*ListFileReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListFile not implemented") +} +func (UnimplementedFileServer) PrepareUploadFile(context.Context, *PrepareUploadFileRequest) (*PrepareUploadFileReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method PrepareUploadFile not implemented") +} +func (UnimplementedFileServer) UploadFile(context.Context, *UploadFileRequest) (*UploadFileReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method UploadFile not implemented") +} +func (UnimplementedFileServer) UpdateFile(context.Context, *UpdateFileRequest) (*UpdateFileReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateFile not implemented") +} +func (UnimplementedFileServer) DeleteFile(context.Context, *DeleteFileRequest) (*DeleteFileReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteFile not implemented") +} +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.ServiceRegistrar, srv FileServer) { + s.RegisterService(&File_ServiceDesc, srv) +} + +func _File_GetFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FileServer).GetFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: File_GetFile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FileServer).GetFile(ctx, req.(*GetFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _File_ListFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FileServer).ListFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: File_ListFile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FileServer).ListFile(ctx, req.(*ListFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _File_PrepareUploadFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PrepareUploadFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FileServer).PrepareUploadFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: File_PrepareUploadFile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FileServer).PrepareUploadFile(ctx, req.(*PrepareUploadFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _File_UploadFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UploadFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FileServer).UploadFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: File_UploadFile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FileServer).UploadFile(ctx, req.(*UploadFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _File_UpdateFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FileServer).UpdateFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: File_UpdateFile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FileServer).UpdateFile(ctx, req.(*UpdateFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _File_DeleteFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FileServer).DeleteFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: File_DeleteFile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FileServer).DeleteFile(ctx, req.(*DeleteFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// File_ServiceDesc is the grpc.ServiceDesc for File service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var File_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "resource.api.resource.file.v1.File", + HandlerType: (*FileServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetFile", + Handler: _File_GetFile_Handler, + }, + { + MethodName: "ListFile", + Handler: _File_ListFile_Handler, + }, + { + MethodName: "PrepareUploadFile", + Handler: _File_PrepareUploadFile_Handler, + }, + { + MethodName: "UploadFile", + Handler: _File_UploadFile_Handler, + }, + { + MethodName: "UpdateFile", + Handler: _File_UpdateFile_Handler, + }, + { + MethodName: "DeleteFile", + Handler: _File_DeleteFile_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/resource/file/resource_file_service.proto", +} diff --git a/api/resource/file/v1/resource_file_service_http.pb.go b/api/resource/file/v1/resource_file_service_http.pb.go new file mode 100644 index 0000000..9ad5ba1 --- /dev/null +++ b/api/resource/file/v1/resource_file_service_http.pb.go @@ -0,0 +1,230 @@ +// Code generated by protoc-gen-go-http. DO NOT EDIT. +// versions: +// - protoc-gen-go-http v2.7.3 +// - protoc v4.24.4 +// source: api/resource/file/resource_file_service.proto + +package v1 + +import ( + context "context" + http "github.com/go-kratos/kratos/v2/transport/http" + binding "github.com/go-kratos/kratos/v2/transport/http/binding" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the kratos package it is being compiled against. +var _ = new(context.Context) +var _ = binding.EncodeURL + +const _ = http.SupportPackageIsVersion1 + +const OperationFileDeleteFile = "/resource.api.resource.file.v1.File/DeleteFile" +const OperationFileGetFile = "/resource.api.resource.file.v1.File/GetFile" +const OperationFileListFile = "/resource.api.resource.file.v1.File/ListFile" +const OperationFilePrepareUploadFile = "/resource.api.resource.file.v1.File/PrepareUploadFile" +const OperationFileUpdateFile = "/resource.api.resource.file.v1.File/UpdateFile" + +type FileHTTPServer interface { + // DeleteFile DeleteFile 删除文件信息 + DeleteFile(context.Context, *DeleteFileRequest) (*DeleteFileReply, error) + // GetFile GetFile 获取指定的文件信息 + GetFile(context.Context, *GetFileRequest) (*GetFileReply, error) + // ListFile ListFile 获取文件信息列表 + ListFile(context.Context, *ListFileRequest) (*ListFileReply, error) + // PrepareUploadFile PrepareUploadFile 预上传文件信息 + PrepareUploadFile(context.Context, *PrepareUploadFileRequest) (*PrepareUploadFileReply, error) + // UpdateFile UpdateFile 更新文件信息 + UpdateFile(context.Context, *UpdateFileRequest) (*UpdateFileReply, error) +} + +func RegisterFileHTTPServer(s *http.Server, srv FileHTTPServer) { + r := s.Route("/") + r.GET("/resource/api/v1/file", _File_GetFile0_HTTP_Handler(srv)) + r.GET("/resource/api/v1/files", _File_ListFile0_HTTP_Handler(srv)) + r.POST("/resource/api/v1/file/prepare_upload", _File_PrepareUploadFile0_HTTP_Handler(srv)) + r.PUT("/resource/api/v1/file", _File_UpdateFile0_HTTP_Handler(srv)) + r.DELETE("/resource/api/v1/file", _File_DeleteFile0_HTTP_Handler(srv)) +} + +func _File_GetFile0_HTTP_Handler(srv FileHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in GetFileRequest + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationFileGetFile) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.GetFile(ctx, req.(*GetFileRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*GetFileReply) + return ctx.Result(200, reply) + } +} + +func _File_ListFile0_HTTP_Handler(srv FileHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in ListFileRequest + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationFileListFile) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.ListFile(ctx, req.(*ListFileRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*ListFileReply) + return ctx.Result(200, reply) + } +} + +func _File_PrepareUploadFile0_HTTP_Handler(srv FileHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in PrepareUploadFileRequest + if err := ctx.Bind(&in); err != nil { + return err + } + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationFilePrepareUploadFile) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.PrepareUploadFile(ctx, req.(*PrepareUploadFileRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*PrepareUploadFileReply) + return ctx.Result(200, reply) + } +} + +func _File_UpdateFile0_HTTP_Handler(srv FileHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in UpdateFileRequest + if err := ctx.Bind(&in); err != nil { + return err + } + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationFileUpdateFile) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.UpdateFile(ctx, req.(*UpdateFileRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*UpdateFileReply) + return ctx.Result(200, reply) + } +} + +func _File_DeleteFile0_HTTP_Handler(srv FileHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in DeleteFileRequest + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationFileDeleteFile) + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return srv.DeleteFile(ctx, req.(*DeleteFileRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*DeleteFileReply) + return ctx.Result(200, reply) + } +} + +type FileHTTPClient interface { + DeleteFile(ctx context.Context, req *DeleteFileRequest, opts ...http.CallOption) (rsp *DeleteFileReply, err error) + GetFile(ctx context.Context, req *GetFileRequest, opts ...http.CallOption) (rsp *GetFileReply, err error) + ListFile(ctx context.Context, req *ListFileRequest, opts ...http.CallOption) (rsp *ListFileReply, err error) + PrepareUploadFile(ctx context.Context, req *PrepareUploadFileRequest, opts ...http.CallOption) (rsp *PrepareUploadFileReply, err error) + UpdateFile(ctx context.Context, req *UpdateFileRequest, opts ...http.CallOption) (rsp *UpdateFileReply, err error) +} + +type FileHTTPClientImpl struct { + cc *http.Client +} + +func NewFileHTTPClient(client *http.Client) FileHTTPClient { + return &FileHTTPClientImpl{client} +} + +func (c *FileHTTPClientImpl) DeleteFile(ctx context.Context, in *DeleteFileRequest, opts ...http.CallOption) (*DeleteFileReply, error) { + var out DeleteFileReply + pattern := "/resource/api/v1/file" + path := binding.EncodeURL(pattern, in, true) + opts = append(opts, http.Operation(OperationFileDeleteFile)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *FileHTTPClientImpl) GetFile(ctx context.Context, in *GetFileRequest, opts ...http.CallOption) (*GetFileReply, error) { + var out GetFileReply + pattern := "/resource/api/v1/file" + path := binding.EncodeURL(pattern, in, true) + opts = append(opts, http.Operation(OperationFileGetFile)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *FileHTTPClientImpl) ListFile(ctx context.Context, in *ListFileRequest, opts ...http.CallOption) (*ListFileReply, error) { + var out ListFileReply + pattern := "/resource/api/v1/files" + path := binding.EncodeURL(pattern, in, true) + opts = append(opts, http.Operation(OperationFileListFile)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *FileHTTPClientImpl) PrepareUploadFile(ctx context.Context, in *PrepareUploadFileRequest, opts ...http.CallOption) (*PrepareUploadFileReply, error) { + var out PrepareUploadFileReply + pattern := "/resource/api/v1/file/prepare_upload" + path := binding.EncodeURL(pattern, in, false) + opts = append(opts, http.Operation(OperationFilePrepareUploadFile)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} + +func (c *FileHTTPClientImpl) UpdateFile(ctx context.Context, in *UpdateFileRequest, opts ...http.CallOption) (*UpdateFileReply, error) { + var out UpdateFileReply + pattern := "/resource/api/v1/file" + path := binding.EncodeURL(pattern, in, false) + opts = append(opts, http.Operation(OperationFileUpdateFile)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} diff --git a/autocode/directory.json b/autocode/directory.json new file mode 100644 index 0000000..986aa96 --- /dev/null +++ b/autocode/directory.json @@ -0,0 +1,126 @@ +{ + "table":"directory", + "keyword": "directory", + "module": "directory", + "comment": "文件目录信息", + "description": "文件目录信息", + "type": "tree", + "fields": [ + { + "keyword": "id", + "title": "主键", + "type": "primaryKey", + "required": true, + "default": "", + "operation": { + "create": false, + "update": true, + "list": true, + "get": true + } + }, + { + "keyword": "parent_id", + "title": "父id", + "type": "foreignKey", + "required": true, + "default": "", + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + } + }, + { + "keyword": "name", + "title": "名称", + "type": "varchar64", + "required": true, + "default": "", + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + } + }, + { + "keyword": "scope", + "title": "权限类型", + "type": "char", + "required": true, + "default": "", + "rules": { + "in": ["PRIVATE", "PUBLIC"] + }, + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + } + }, + { + "keyword": "accept", + "title": "允许后缀", + "type": "tinytext", + "required": true, + "default": "", + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + } + }, + { + "keyword": "max_size", + "title": "大小限额/M", + "type": "unsignedInteger", + "required": true, + "default": "", + "rules": { + "gte": 1 + }, + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + } + }, + + { + "keyword": "created_at", + "title": "创建时间", + "type": "time", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "updated_at", + "title": "更新时间", + "type": "time", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + } + ], + "index": [ + ["created_at"], + ["updated_at"] + ], + "methods": ["Get","List", "Create", "Update", "Delete"] +} \ No newline at end of file diff --git a/autocode/export.json b/autocode/export.json new file mode 100644 index 0000000..04eb32a --- /dev/null +++ b/autocode/export.json @@ -0,0 +1,189 @@ +{ + "table":"export", + "keyword": "export", + "module": "export", + "comment": "导出信息", + "description": "导出信息", + "type": "list", + "fields": [ + { + "keyword": "id", + "title": "主键", + "type": "primaryKey", + "required": true, + "default": "", + "operation": { + "create": false, + "update": true, + "list": true, + "get": true + } + }, + { + "keyword": "user_id", + "title": "用户id", + "type": "foreignKey", + "required": true, + "default": "", + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + }, + "queryType": "=" + }, + { + "keyword": "department_id", + "title": "部门id", + "type": "foreignKey", + "required": true, + "default": "", + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + }, + "queryType": "=" + }, + { + "keyword": "scene", + "title": "场景", + "type": "char", + "required": true, + "default": "", + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + } + }, + { + "keyword": "name", + "title": "名称", + "type": "varchar64", + "required": true, + "default": "", + "operation": { + "create": true, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "size", + "title": "大小", + "type": "unsignedInteger", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "sha", + "title": "大小限额/M", + "type": "varchar64", + "required": false, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "src", + "title": "路径", + "type": "varchar128", + "required": false, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "status", + "title": "打包状态", + "type": "char", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "reason", + "title": "错误原因", + "type": "tinytext", + "required": false, + "default": "", + "operation": { + "create": true, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "expired_at", + "title": "过期时间", + "type": "time", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "created_at", + "title": "创建时间", + "type": "time", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "updated_at", + "title": "更新时间", + "type": "time", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + } + ], + "unique": [ + ["sha"] + ], + "index": [ + ["created_at"], + ["updated_at"] + ], + "methods": ["Get","List", "Create", "Update", "Delete"] +} \ No newline at end of file diff --git a/autocode/file.json b/autocode/file.json new file mode 100644 index 0000000..4e528b0 --- /dev/null +++ b/autocode/file.json @@ -0,0 +1,175 @@ +{ + "table":"file", + "keyword": "file", + "module": "file", + "comment": "文件信息", + "description": "文件信息", + "type": "list", + "fields": [ + { + "keyword": "id", + "title": "主键", + "type": "primaryKey", + "required": true, + "default": "", + "operation": { + "create": false, + "update": true, + "list": true, + "get": true + } + }, + { + "keyword": "directory_id", + "title": "目录id", + "type": "foreignKey", + "required": true, + "default": "", + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + }, + "queryType": "=" + }, + { + "keyword": "name", + "title": "名称", + "type": "varchar64", + "required": true, + "default": "", + "operation": { + "create": true, + "update": true, + "list": true, + "get": true + } + }, + { + "keyword": "type", + "title": "类型", + "type": "char", + "required": true, + "default": "", + "operation": { + "create": true, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "size", + "title": "大小", + "type": "unsignedInteger", + "required": true, + "default": "", + "operation": { + "create": true, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "sha", + "title": "大小限额/M", + "type": "varchar64", + "required": true, + "default": "", + "operation": { + "create": true, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "src", + "title": "路径", + "type": "varchar128", + "required": false, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "status", + "title": "上传状态", + "type": "char", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "upload_id", + "title": "上传id", + "type": "varchar64", + "required": true, + "default": "", + "operation": { + "create": true, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "chunk_count", + "title": "切片数量", + "type": "unsignedInteger", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "created_at", + "title": "创建时间", + "type": "time", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + }, + { + "keyword": "updated_at", + "title": "更新时间", + "type": "time", + "required": true, + "default": "", + "operation": { + "create": false, + "update": false, + "list": true, + "get": true + } + } + ], + "unique": [ + ["sha"] + ], + "index": [ + ["created_at"], + ["updated_at"] + ], + "methods": ["Get","List", "Create", "Update", "Delete"] +} \ No newline at end of file diff --git a/cmd/resource/main.go b/cmd/resource/main.go index 8ca61c5..7f758f7 100644 --- a/cmd/resource/main.go +++ b/cmd/resource/main.go @@ -8,43 +8,36 @@ import ( "github.com/go-kratos/kratos/v2" "github.com/go-kratos/kratos/v2/transport/grpc" "github.com/go-kratos/kratos/v2/transport/http" - configure "github.com/limes-cloud/configure/api/client" "github.com/limes-cloud/kratosx" "github.com/limes-cloud/kratosx/config" - "github.com/limes-cloud/kratosx/pkg/print" + "github.com/limes-cloud/kratosx/pkg/printx" _ "go.uber.org/automaxprocs" - resourceconf "github.com/limes-cloud/resource/internal/config" - "github.com/limes-cloud/resource/internal/router" + "github.com/limes-cloud/resource/internal/conf" "github.com/limes-cloud/resource/internal/service" ) func main() { app := kratosx.New( - kratosx.Config(configure.NewFromEnv()), kratosx.RegistrarServer(RegisterServer), kratosx.Options(kratos.AfterStart(func(ctx context.Context) error { kt := kratosx.MustContext(ctx) - print.ArtFont(fmt.Sprintf("Hello %s !", kt.Name())) + printx.ArtFont(fmt.Sprintf("Hello %s !", kt.Name())) return nil })), ) - if err := app.Run(); err != nil { log.Fatal("run service fail", err) } } func RegisterServer(c config.Config, hs *http.Server, gs *grpc.Server) { - // 初始化并监听配置变更 - conf := &resourceconf.Config{} + cfg := &conf.Config{} c.ScanWatch("business", func(value config.Value) { - if err := value.Scan(conf); err != nil { + if err := value.Scan(&cfg); err != nil { panic("business config format error:" + err.Error()) } }) - // 注册服务 - fileSrv := service.New(conf, hs, gs) - router.Register(hs, fileSrv) + service.New(cfg, hs, gs) } diff --git a/deploy/data.sql b/deploy/data.sql deleted file mode 100644 index 8a1b019..0000000 --- a/deploy/data.sql +++ /dev/null @@ -1,94 +0,0 @@ -SET NAMES utf8mb4; -SET FOREIGN_KEY_CHECKS = 0; - --- ---------------------------- --- Table structure for chunk --- ---------------------------- -DROP TABLE IF EXISTS `chunk`; -CREATE TABLE `chunk` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分片id', - `upload_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '上传id', - `index` bigint NOT NULL COMMENT '切片下标', - `size` bigint NOT NULL COMMENT '切片大小', - `sha` varchar(128) NOT NULL COMMENT '切片sha', - `data` mediumblob NOT NULL COMMENT '切片数据', - `created_at` bigint unsigned DEFAULT NULL COMMENT '创建时间', - PRIMARY KEY (`id`), - UNIQUE KEY `upload_id` (`upload_id`,`index`), - UNIQUE KEY `ui` (`upload_id`,`index`), - KEY `idx_chunk_created_at` (`created_at`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - --- ---------------------------- --- Table structure for directory --- ---------------------------- -DROP TABLE IF EXISTS `directory`; -CREATE TABLE `directory` ( - `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `created_at` bigint DEFAULT NULL COMMENT '创建时间', - `updated_at` bigint DEFAULT NULL COMMENT '修改时间', - `parent_id` int unsigned NOT NULL COMMENT '父id', - `name` varchar(128) NOT NULL COMMENT '目录名称', - `app` varchar(32) NOT NULL COMMENT '所属应用', - PRIMARY KEY (`id`), - UNIQUE KEY `pna` (`parent_id`,`name`,`app`), - KEY `idx_directory_created_at` (`created_at`), - KEY `idx_directory_updated_at` (`updated_at`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='目录信息'; - --- ---------------------------- --- Table structure for export --- ---------------------------- -DROP TABLE IF EXISTS `export`; -CREATE TABLE `export` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '文件id', - `user_id` bigint NOT NULL COMMENT '用户id', - `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '文件名', - `size` bigint NOT NULL DEFAULT '0' COMMENT '文件大小', - `version` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '版本', - `src` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '文件路径', - `reason` varchar(512) NOT NULL DEFAULT '' COMMENT '错误原因', - `status` varchar(32) NOT NULL DEFAULT '' COMMENT '导出状态', - `created_at` bigint unsigned DEFAULT NULL COMMENT '创建时间', - `updated_at` bigint unsigned DEFAULT NULL COMMENT '修改时间', - PRIMARY KEY (`id`), - UNIQUE KEY `version` (`version`,`user_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='导出任务'; - --- ---------------------------- --- Table structure for file --- ---------------------------- -DROP TABLE IF EXISTS `file`; -CREATE TABLE `file` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '文件id', - `directory_id` bigint NOT NULL COMMENT '目录id', - `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '文件名', - `type` varchar(64) NOT NULL COMMENT '文件类型', - `size` bigint NOT NULL COMMENT '文件大小', - `sha` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'sha值', - `src` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '文件路径', - `storage` varchar(32) NOT NULL COMMENT '存储引擎', - `status` enum('PROGRESS','COMPLETED','FAILED') DEFAULT 'PROGRESS' COMMENT '上传状态', - `upload_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '上传id', - `chunk_count` int DEFAULT '1' COMMENT '切片数量', - `created_at` bigint unsigned DEFAULT NULL COMMENT '创建时间', - `updated_at` bigint unsigned DEFAULT NULL COMMENT '修改时间', - `deleted_at` bigint unsigned DEFAULT NULL COMMENT '删除时间', - PRIMARY KEY (`id`), - UNIQUE KEY `sha` (`sha`,`directory_id`), - UNIQUE KEY `upload_id` (`upload_id`), - KEY `deleted_at` (`deleted_at`), - KEY `directory_id` (`directory_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件信息'; - --- ---------------------------- --- Table structure for gorm_init --- ---------------------------- -DROP TABLE IF EXISTS `gorm_init`; -CREATE TABLE `gorm_init` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `init` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4; - -SET FOREIGN_KEY_CHECKS = 1; diff --git a/examples/export_test.go b/examples/export_test.go deleted file mode 100644 index 2e3a091..0000000 --- a/examples/export_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package examples - -import ( - "context" - "testing" - - "github.com/go-kratos/kratos/v2/transport/grpc" - "github.com/limes-cloud/kratosx" - "github.com/zeebo/assert" - - exportpb "github.com/limes-cloud/resource/api/export/v1" -) - -func TestExport(t *testing.T) { - ctx := kratosx.MustContext(context.Background()) - insecure, err := grpc.DialInsecure(ctx, grpc.WithEndpoint("127.0.0.1:8003")) - assert.NoError(t, err) - - client := exportpb.NewServiceClient(insecure) - _, err = client.AddExport(ctx, &exportpb.AddExportRequest{ - Name: "test.zip", - Files: []*exportpb.AddExportRequest_ExportFile{ - { - Sha: "2a0786fe9127b8116bc30ed2ce9581e2", - Rename: "1", - }, - { - Sha: "36e2e87f7b73219343da52a28ba47eec", - Rename: "2", - }, - { - Sha: "6d06733ef579fbcef68b9f95745a3e99", - Rename: "3", - }, - }, - }) - assert.NoError(t, err) -} - -func TestExportExcel(t *testing.T) { - ctx := kratosx.MustContext(context.Background()) - insecure, err := grpc.DialInsecure(ctx, grpc.WithEndpoint("127.0.0.1:8003")) - assert.NoError(t, err) - - client := exportpb.NewServiceClient(insecure) - _, err = client.AddExportExcel(ctx, &exportpb.AddExportExcelRequest{ - Name: "test.zip", - Rows: []*exportpb.AddExportExcelRequest_Row{ - { - Cols: []*exportpb.AddExportExcelRequest_Col{ - { - Type: "string", - Value: "hello", - }, - { - Type: "string", - Value: "world", - }, - { - Type: "image", - Value: "2a0786fe9127b8116bc30ed2ce9581e2", - }, - }, - }, - { - Cols: []*exportpb.AddExportExcelRequest_Col{ - { - Type: "string", - Value: "hello1", - }, - { - Type: "string", - Value: "world2", - }, - { - Type: "image", - Value: "36e2e87f7b73219343da52a28ba47eec", - }, - }, - }, - }, - }) - assert.NoError(t, err) -} diff --git a/go.mod b/go.mod index 6e332b9..e6a1074 100644 --- a/go.mod +++ b/go.mod @@ -3,18 +3,14 @@ module github.com/limes-cloud/resource go 1.21.1 require ( - github.com/aliyun/aliyun-oss-go-sdk v3.0.1+incompatible + github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible github.com/envoyproxy/protoc-gen-validate v1.0.4 - github.com/gabriel-vasile/mimetype v1.4.3 github.com/go-kratos/kratos/v2 v2.7.3 - github.com/golang/protobuf v1.5.4 + github.com/go-redis/redis/v8 v8.11.5 github.com/google/uuid v1.6.0 - github.com/limes-cloud/configure v1.0.32 - github.com/limes-cloud/kratosx v1.0.31 - github.com/limes-cloud/manager v1.0.13 + github.com/limes-cloud/kratosx v1.0.39 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 - github.com/tencentyun/cos-go-sdk-v5 v0.7.45 - github.com/zeebo/assert v1.3.0 + github.com/tencentyun/cos-go-sdk-v5 v0.7.49 go.uber.org/automaxprocs v1.5.3 golang.org/x/image v0.15.0 google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 @@ -29,6 +25,7 @@ require ( github.com/ClickHouse/clickhouse-go/v2 v2.23.2 // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/billcobbler/casbin-redis-watcher/v2 v2.0.0-20211014141847-d29c8619193d // indirect github.com/casbin/casbin/v2 v2.88.0 // indirect github.com/casbin/gorm-adapter/v3 v3.24.0 // indirect @@ -48,19 +45,22 @@ require ( github.com/go-faster/errors v0.7.1 // indirect github.com/go-kratos/aegis v0.2.1-0.20230616030432-99110a3f05f4 // indirect github.com/go-kratos/kratos/contrib/log/zap/v2 v2.0.0-20240504101732-d0d5761f9ca8 // indirect + github.com/go-kratos/kratos/contrib/metrics/prometheus/v2 v2.0.0-20240322155018-41971ffa647a // indirect github.com/go-kratos/kratos/contrib/registry/consul/v2 v2.0.0-20240504101732-d0d5761f9ca8 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-playground/assert/v2 v2.2.0 // indirect github.com/go-playground/form/v4 v4.2.1 // indirect - github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-redsync/redsync/v4 v4.12.1 // indirect github.com/go-resty/resty/v2 v2.12.0 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect - github.com/google/go-querystring v1.1.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-querystring v1.0.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect @@ -92,27 +92,25 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/mojocn/base64Captcha v1.3.6 // indirect - github.com/mozillazg/go-httpheader v0.3.1 // indirect + github.com/mozillazg/go-httpheader v0.2.1 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/panjf2000/ants/v2 v2.9.1 // indirect github.com/paulmach/orb v0.11.1 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - github.com/richardlehane/mscfb v1.0.4 // indirect - github.com/richardlehane/msoleps v1.0.3 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/shirou/gopsutil/v3 v3.24.4 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/numcpus v0.8.0 // indirect - github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect - github.com/xuri/excelize/v2 v2.8.1 // indirect - github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/otel v1.26.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect @@ -143,3 +141,5 @@ require ( modernc.org/memory v1.8.0 // indirect modernc.org/sqlite v1.29.8 // indirect ) + +replace github.com/limes-cloud/kratosx v1.0.39 => ../../framework/kratosx diff --git a/go.sum b/go.sum index 0a3a35c..1676ffb 100644 --- a/go.sum +++ b/go.sum @@ -717,8 +717,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/alexflint/go-filemutex v1.2.0/go.mod h1:mYyQSWvw9Tx2/H2n9qXPb52tTYfE0pZAWcBq5mK025c= -github.com/aliyun/aliyun-oss-go-sdk v3.0.1+incompatible h1:so4m5rRA32Tc5GgKg/5gKUu0CRsYmVO3ThMP6T3CwLc= -github.com/aliyun/aliyun-oss-go-sdk v3.0.1+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= @@ -747,6 +747,7 @@ github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/billcobbler/casbin-redis-watcher/v2 v2.0.0-20211014141847-d29c8619193d h1:YVk4z1FRH7kId4x7MfaR9stVsOMZMBZtdH1xkWFnY6Y= @@ -1103,8 +1104,6 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.4 h1:LFu2R3+ZOPgSMWMOL+saa/zXRjw0ID2G8FepO53BGlg= @@ -1140,6 +1139,8 @@ github.com/go-kratos/aegis v0.2.1-0.20230616030432-99110a3f05f4 h1:LGUYBh6R1CGe1 github.com/go-kratos/aegis v0.2.1-0.20230616030432-99110a3f05f4/go.mod h1:jqdJn8QOoobkmqfhO51kb/qUeHAQ8r0WpjPKl7cP3nQ= github.com/go-kratos/kratos/contrib/log/zap/v2 v2.0.0-20240504101732-d0d5761f9ca8 h1:Qoi9jssHMmgY/bIIT+HWzZcKy/DTktfSZkwdH1Rzp7Y= github.com/go-kratos/kratos/contrib/log/zap/v2 v2.0.0-20240504101732-d0d5761f9ca8/go.mod h1:eD/bSXiReDHdcaE5Mk1RqUCMYpYjEmV39sHxCa/o/II= +github.com/go-kratos/kratos/contrib/metrics/prometheus/v2 v2.0.0-20240322155018-41971ffa647a h1:3hRhRQwrS0ryRyxgr/i1p0FILs9SSbzQ7XaQ6JP+mTE= +github.com/go-kratos/kratos/contrib/metrics/prometheus/v2 v2.0.0-20240322155018-41971ffa647a/go.mod h1:jZUwXef+0aVWFsVRGevBu3Clf7DyaXpiRStfpF4P64U= github.com/go-kratos/kratos/contrib/registry/consul/v2 v2.0.0-20240504101732-d0d5761f9ca8 h1:uTpt/+092FZ0q0JeqGjim5ZConxuZHfTgSxMCuFp4k8= github.com/go-kratos/kratos/contrib/registry/consul/v2 v2.0.0-20240504101732-d0d5761f9ca8/go.mod h1:2dO01eHwztTovqoaig4CT368XQHks2ubQ6YwuR8moIc= github.com/go-kratos/kratos/v2 v2.7.3 h1:T9MS69qk4/HkVUuHw5GS9PDVnOfzn+kxyF0CL5StqxA= @@ -1190,8 +1191,14 @@ github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lY github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/form/v4 v4.2.1 h1:HjdRDKO0fftVMU5epjPW2SOREcZ6/wLUzEobqUGJuPw= github.com/go-playground/form/v4 v4.2.1/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U= +github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= +github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4= +github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-redsync/redsync/v4 v4.12.1 h1:hCtdZ45DJxMxNdPiby5GlQwOKQmcka2587Y466qPqlA= +github.com/go-redsync/redsync/v4 v4.12.1/go.mod h1:sn72ojgeEhxUuRjrliK0NRrB0Zl6kOZ3BDvNN3P2jAY= github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA= github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -1276,6 +1283,7 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= +github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -1304,9 +1312,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-containerregistry v0.14.0/go.mod h1:aiJ2fp/SXvkWgmYHioXnbMdlgB8eXiiYOY55gfN91Wk= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -1380,6 +1387,7 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafov/m3u8 v0.12.0/go.mod h1:nqzOkfBiZJENr52zTVd/Dcl03yzphIMbJqkXGu+u080= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -1556,12 +1564,6 @@ github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmt github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/limes-cloud/configure v1.0.32 h1:3xspc0rR9d7dUbyF9PyEJcTOZpqxMh+tbDFoqz1VqyM= -github.com/limes-cloud/configure v1.0.32/go.mod h1:rUWafdOaLO2nk1fuhQVRJw6vM7UAOP+QhEyqgw2oow0= -github.com/limes-cloud/kratosx v1.0.31 h1:L9ygmB30i8zo/3ZSZ+qemboAI7jrN3vnc0Wa2H48kvY= -github.com/limes-cloud/kratosx v1.0.31/go.mod h1:xmk+1VUhM/vK7JE1eTPebFIBdiS49KFYN2Hf6g8UVQY= -github.com/limes-cloud/manager v1.0.13 h1:eikvmvZuRzUgoYuE7rsC/5lVcVn5ZpVRFpZjjp1ORZ4= -github.com/limes-cloud/manager v1.0.13/go.mod h1:wv50Xwr4IuNk9UuH5lF546Uyil+83I2MQ6rvf2CIusA= github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 h1:1KuuSOy4ZNgW0KA2oYIngXVFhQcXxhLqCVK7cBcldkk= @@ -1664,16 +1666,13 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mojocn/base64Captcha v1.3.6 h1:gZEKu1nsKpttuIAQgWHO+4Mhhls8cAKyiV2Ew03H+Tw= github.com/mojocn/base64Captcha v1.3.6/go.mod h1:i5CtHvm+oMbj1UzEPXaA8IH/xHFZ3DGY3Wh3dBpZ28E= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= -github.com/mozillazg/go-httpheader v0.3.1 h1:IRP+HFrMX2SlwY9riuio7raffXUpzAosHtZu25BSJok= -github.com/mozillazg/go-httpheader v0.3.1/go.mod h1:PuT8h0pw6efvp8ZeUec1Rs7dwjK08bt6gKSReGMqtdA= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -1837,12 +1836,16 @@ github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrb github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1854,6 +1857,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= +github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1867,18 +1872,19 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rafaeljusto/redigomock v0.0.0-20170720131524-7ae0511314e9 h1:AgFSzGRVSy1kZ8EBHycQc6qK9gVqhJnVI2H/dk2cY/Y= github.com/rafaeljusto/redigomock v0.0.0-20170720131524-7ae0511314e9/go.mod h1:JaY6n2sDr+z2WTsXkOmNRUfDy6FN0L6Nk7x06ndm4tY= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/redis/go-redis/v9 v9.4.0 h1:Yzoz33UZw9I/mFhx4MNrB6Fk+XHO1VukNcCa1+lwyKk= +github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/rueidis v1.0.19 h1:s65oWtotzlIFN8eMPhyYwxlwLR1lUdhza2KtWprKYSo= +github.com/redis/rueidis v1.0.19/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= -github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= -github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= -github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= -github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1989,6 +1995,8 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08YuiTGPZLls0Wq99X9bWd0Q5ZSBesM= +github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1997,8 +2005,8 @@ github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0= -github.com/tencentyun/cos-go-sdk-v5 v0.7.45 h1:5/ZGOv846tP6+2X7w//8QjLgH2KcUK+HciFbfjWquFU= -github.com/tencentyun/cos-go-sdk-v5 v0.7.45/go.mod h1:DH9US8nB+AJXqwu/AMOrCFN1COv3dpytXuJWHgdg7kE= +github.com/tencentyun/cos-go-sdk-v5 v0.7.49 h1:A3UIV4i+/T2XOfgQnUF9HgoQ6SI8QRz8Dd1F8CLkl4k= +github.com/tencentyun/cos-go-sdk-v5 v0.7.49/go.mod h1:UN+VdbCl1hg+kKi5RXqZgaP+Boqfmk+D04GRc4XFk70= github.com/testcontainers/testcontainers-go v0.25.0/go.mod h1:4sC9SiJyzD1XFi59q8umTQYWxnkweEc5OjVtTUlJzqQ= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= @@ -2046,12 +2054,6 @@ github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY= -github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= -github.com/xuri/excelize/v2 v2.8.1 h1:pZLMEwK8ep+CLIUWpWmvW8IWE/yxqG0I1xcN6cVMGuQ= -github.com/xuri/excelize/v2 v2.8.1/go.mod h1:oli1E4C3Pa5RXg1TBXn4ENCXDV5JUMlBluUhG7c+CEE= -github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A= -github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= github.com/yashtewari/glob-intersection v0.1.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -2067,7 +2069,6 @@ github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= diff --git a/internal/biz/directory/biz.go b/internal/biz/directory/biz.go new file mode 100755 index 0000000..c2c3100 --- /dev/null +++ b/internal/biz/directory/biz.go @@ -0,0 +1,75 @@ +package directory + +import ( + "github.com/limes-cloud/kratosx" + "github.com/limes-cloud/kratosx/pkg/tree" + "github.com/limes-cloud/resource/api/resource/errors" + "github.com/limes-cloud/resource/internal/conf" +) + +type UseCase struct { + conf *conf.Config + repo Repo +} + +func NewUseCase(config *conf.Config, repo Repo) *UseCase { + return &UseCase{conf: config, repo: repo} +} + +// GetDirectory 获取指定的文件目录信息 +func (u *UseCase) GetDirectory(ctx kratosx.Context, req *GetDirectoryRequest) (*Directory, error) { + var ( + res *Directory + err error + ) + + if req.Id != nil { + res, err = u.repo.GetDirectory(ctx, *req.Id) + } else { + return nil, errors.ParamsError() + } + + if err != nil { + return nil, errors.GetError(err.Error()) + } + return res, nil +} + +// ListDirectory 获取文件目录信息列表树 +func (u *UseCase) ListDirectory(ctx kratosx.Context, req *ListDirectoryRequest) ([]tree.Tree, uint32, error) { + list, total, err := u.repo.ListDirectory(ctx, req) + if err != nil { + return nil, 0, errors.ListError(err.Error()) + } + var ts []tree.Tree + for _, item := range list { + ts = append(ts, item) + } + return tree.BuildArrayTree(ts), total, nil +} + +// CreateDirectory 创建文件目录信息 +func (u *UseCase) CreateDirectory(ctx kratosx.Context, req *Directory) (uint32, error) { + id, err := u.repo.CreateDirectory(ctx, req) + if err != nil { + return 0, errors.CreateError(err.Error()) + } + return id, nil +} + +// UpdateDirectory 更新文件目录信息 +func (u *UseCase) UpdateDirectory(ctx kratosx.Context, req *Directory) error { + if err := u.repo.UpdateDirectory(ctx, req); err != nil { + return errors.UpdateError(err.Error()) + } + return nil +} + +// DeleteDirectory 删除文件目录信息 +func (u *UseCase) DeleteDirectory(ctx kratosx.Context, ids []uint32) (uint32, error) { + total, err := u.repo.DeleteDirectory(ctx, ids) + if err != nil { + return 0, errors.DeleteError(err.Error()) + } + return total, nil +} diff --git a/internal/biz/directory/entity.go b/internal/biz/directory/entity.go new file mode 100755 index 0000000..88d13ef --- /dev/null +++ b/internal/biz/directory/entity.go @@ -0,0 +1,41 @@ +package directory + +import ( + "github.com/limes-cloud/kratosx/pkg/tree" +) + +type Directory struct { + Id uint32 `json:"id"` + ParentId uint32 `json:"parentId"` + Name string `json:"name"` + Accept string `json:"accept"` + MaxSize uint32 `json:"maxSize"` + CreatedAt int64 `json:"createdAt"` + UpdatedAt int64 `json:"updatedAt"` + Children []*Directory `json:"Children"` +} + +// ID 获取菜单树ID +func (m *Directory) ID() uint32 { + return m.Id +} + +// Parent 获取父ID +func (m *Directory) Parent() uint32 { + return m.ParentId +} + +// AppendChildren 添加子节点 +func (m *Directory) AppendChildren(child any) { + menu := child.(*Directory) + m.Children = append(m.Children, menu) +} + +// ChildrenNode 获取子节点 +func (m *Directory) ChildrenNode() []tree.Tree { + var list []tree.Tree + for _, item := range m.Children { + list = append(list, item) + } + return list +} diff --git a/internal/biz/directory/repo.go b/internal/biz/directory/repo.go new file mode 100755 index 0000000..fb32fc9 --- /dev/null +++ b/internal/biz/directory/repo.go @@ -0,0 +1,28 @@ +package directory + +import ( + "github.com/limes-cloud/kratosx" +) + +type Repo interface { + // GetDirectory 获取指定的文件目录信息 + GetDirectory(ctx kratosx.Context, id uint32) (*Directory, error) + + // ListDirectory 获取文件目录信息列表 + ListDirectory(ctx kratosx.Context, req *ListDirectoryRequest) ([]*Directory, uint32, error) + + // CreateDirectory 创建文件目录信息 + CreateDirectory(ctx kratosx.Context, req *Directory) (uint32, error) + + // UpdateDirectory 更新文件目录信息 + UpdateDirectory(ctx kratosx.Context, req *Directory) error + + // DeleteDirectory 删除文件目录信息 + DeleteDirectory(ctx kratosx.Context, ids []uint32) (uint32, error) + + // GetDirectoryParentIds 获取父文件目录信息ID列表 + GetDirectoryParentIds(ctx kratosx.Context, id uint32) ([]uint32, error) + + // GetDirectoryChildrenIds 获取子文件目录信息ID列表 + GetDirectoryChildrenIds(ctx kratosx.Context, id uint32) ([]uint32, error) +} diff --git a/internal/biz/directory/types.go b/internal/biz/directory/types.go new file mode 100755 index 0000000..85e1bca --- /dev/null +++ b/internal/biz/directory/types.go @@ -0,0 +1,10 @@ +package directory + +type GetDirectoryRequest struct { + Id *uint32 `json:"id"` +} + +type ListDirectoryRequest struct { + Order *string `json:"order"` + OrderBy *string `json:"orderBy"` +} diff --git a/internal/biz/export/biz.go b/internal/biz/export/biz.go old mode 100644 new mode 100755 index 13040ab..98deebe --- a/internal/biz/export/biz.go +++ b/internal/biz/export/biz.go @@ -1,179 +1,44 @@ package export import ( - "encoding/json" - "fmt" - "os" - "github.com/limes-cloud/kratosx" - "github.com/limes-cloud/kratosx/pkg/util" - "github.com/limes-cloud/kratosx/types" - "github.com/limes-cloud/manager/api/auth" - "github.com/limes-cloud/resource/api/errors" - "github.com/limes-cloud/resource/internal/biz/file" - "github.com/limes-cloud/resource/internal/config" + "github.com/limes-cloud/resource/api/resource/errors" + "github.com/limes-cloud/resource/internal/conf" ) type UseCase struct { - config *config.Config - repo Repo - fileRepo file.Repo - factory Factory + conf *conf.Config + repo Repo } -func NewUseCase(config *config.Config, repo Repo, factory Factory) *UseCase { - return &UseCase{config: config, repo: repo, factory: factory} +func NewUseCase(config *conf.Config, repo Repo) *UseCase { + return &UseCase{conf: config, repo: repo} } -func (u *UseCase) PageExport(ctx kratosx.Context, in *PageExportRequest) ([]*Export, uint32, error) { - info, err := auth.Get(ctx) - if err != nil { - return nil, 0, err - } - in.UserId = info.UserId - - list, total, err := u.repo.PageExport(ctx, in) +// ListExport 获取导出信息列表 +func (u *UseCase) ListExport(ctx kratosx.Context, req *ListExportRequest) ([]*Export, uint32, error) { + list, total, err := u.repo.ListExport(ctx, req) if err != nil { - return nil, 0, errors.Database() - } - for ind, item := range list { - list[ind].Src = u.factory.ExportFileSrc(item.Src) + return nil, 0, errors.ListError(err.Error()) } return list, total, nil } -func (u *UseCase) DeleteExport(ctx kratosx.Context, id uint32) error { - info, err := auth.Get(ctx) - if err != nil { - return err - } - exp, err := u.repo.GetExport(ctx, id) +// CreateExport 创建导出信息 +func (u *UseCase) CreateExport(ctx kratosx.Context, req *Export) (uint32, error) { + id, err := u.repo.CreateExport(ctx, req) if err != nil { - return errors.NotFound() + return 0, errors.CreateError(err.Error()) } - if err := u.repo.DeleteExport(ctx, info.UserId, id); err != nil { - return errors.Database() - } - _ = os.Remove(u.config.Export.LocalDir + exp.Src) - return nil -} - -func (u *UseCase) AddExport(ctx kratosx.Context, in *AddExportRequest) (uint32, error) { - info, err := auth.Get(ctx) - if err != nil { - return 0, err - } - - b, _ := json.Marshal(in) - version := util.MD5(b) - - exp, err := u.repo.GetExportByVersion(ctx, info.UserId, version) - src := fmt.Sprintf("%s.zip", version) - var id uint32 - if err == nil { - if exp.Status == StatusProcess { - return 0, errors.ExportTaskProcess() - } - if exp.Status == StatusFinish { - return exp.ID, nil - } - exp.Status = StatusProcess - if err := u.repo.UpdateExport(ctx, exp); err != nil { - ctx.Logger().Errorw("msg", "update export status error", "err", err.Error()) - } - id = exp.ID - } else { - id, err = u.repo.AddExport(ctx, &Export{ - UserId: info.UserId, - Src: src, - Name: in.Name, - Version: version, - Status: StatusProcess, - }) - if err != nil { - return 0, errors.DatabaseFormat(err.Error()) - } - } - - in.Name = u.config.Export.LocalDir + "/" + src - go func() { - kCtx := ctx.Clone() - size, err := u.factory.ExportFile(kCtx, in) - exp := &Export{ - BaseModel: types.BaseModel{ID: id}, - Status: StatusFinish, - Size: uint32(size), - Version: version, - } - if err != nil { - exp.Status = StatusFail - exp.Reason = err.Error() - } - - if err := u.repo.UpdateExport(kCtx, exp); err != nil { - ctx.Logger().Errorw("msg", "update export status error", "err", err.Error()) - } - }() - return id, nil } -func (u *UseCase) AddExportExcel(ctx kratosx.Context, in *AddExportExcelRequest) (uint32, error) { - info, err := auth.Get(ctx) +// DeleteExport 删除导出信息 +func (u *UseCase) DeleteExport(ctx kratosx.Context, ids []uint32) (uint32, error) { + total, err := u.repo.DeleteExport(ctx, ids) if err != nil { - return 0, err - } - - b, _ := json.Marshal(in) - version := util.MD5(b) - - exp, err := u.repo.GetExportByVersion(ctx, info.UserId, version) - src := fmt.Sprintf("%s.xlsx", version) - var id uint32 - if err == nil { - if exp.Status == StatusProcess { - return 0, errors.ExportTaskProcess() - } - if exp.Status == StatusFinish { - return exp.ID, nil - } - exp.Status = StatusProcess - if err := u.repo.UpdateExport(ctx, exp); err != nil { - ctx.Logger().Errorw("msg", "update export status error", "err", err.Error()) - } - id = exp.ID - } else { - id, err = u.repo.AddExport(ctx, &Export{ - UserId: info.UserId, - Src: src, - Name: in.Name, - Version: version, - Status: StatusProcess, - }) - if err != nil { - return 0, errors.DatabaseFormat(err.Error()) - } + return 0, errors.DeleteError(err.Error()) } - - in.Name = u.config.Export.LocalDir + "/" + src - go func() { - kCtx := ctx.Clone() - size, err := u.factory.ExportExcel(kCtx, in) - exp := &Export{ - BaseModel: types.BaseModel{ID: id}, - Status: StatusFinish, - Size: uint32(size), - } - if err != nil { - exp.Status = StatusFail - exp.Reason = err.Error() - } - - if err := u.repo.UpdateExport(kCtx, exp); err != nil { - ctx.Logger().Errorw("msg", "update export status error", "err", err.Error()) - } - }() - - return id, nil + return total, nil } diff --git a/internal/biz/export/biz_test.go b/internal/biz/export/biz_test.go deleted file mode 100644 index 0fd21d2..0000000 --- a/internal/biz/export/biz_test.go +++ /dev/null @@ -1 +0,0 @@ -package export diff --git a/internal/biz/export/entity.go b/internal/biz/export/entity.go old mode 100644 new mode 100755 index d48f3bd..e037925 --- a/internal/biz/export/entity.go +++ b/internal/biz/export/entity.go @@ -1,21 +1,17 @@ package export -import "github.com/limes-cloud/kratosx/types" - -const ( - StatusProcess = "process" - StatusFinish = "finish" - StatusFail = "fail" - StatusExpire = "expire" -) - type Export struct { - types.BaseModel - UserId uint32 `json:"user_id"` - Name string `json:"name"` - Size uint32 `json:"size"` - Src string `json:"src"` - Version string `json:"version"` - Reason string `json:"reason"` - Status string `json:"status"` + Id uint32 `json:"id"` + UserId uint32 `json:"userId"` + DepartmentId uint32 `json:"departmentId"` + Scene string `json:"scene"` + Name string `json:"name"` + Size uint32 `json:"size"` + Sha *string `json:"sha"` + Src *string `json:"src"` + Status string `json:"status"` + Reason *string `json:"reason"` + ExpiredAt int64 `json:"expiredAt"` + CreatedAt int64 `json:"createdAt"` + UpdatedAt int64 `json:"updatedAt"` } diff --git a/internal/biz/export/factory.go b/internal/biz/export/factory.go deleted file mode 100644 index d5f69fc..0000000 --- a/internal/biz/export/factory.go +++ /dev/null @@ -1,11 +0,0 @@ -package export - -import ( - "github.com/limes-cloud/kratosx" -) - -type Factory interface { - ExportFileSrc(src string) string - ExportFile(ctx kratosx.Context, in *AddExportRequest) (int64, error) - ExportExcel(ctx kratosx.Context, in *AddExportExcelRequest) (int64, error) -} diff --git a/internal/biz/export/repo.go b/internal/biz/export/repo.go old mode 100644 new mode 100755 index 85d6657..baf703a --- a/internal/biz/export/repo.go +++ b/internal/biz/export/repo.go @@ -5,11 +5,12 @@ import ( ) type Repo interface { - PageExport(ctx kratosx.Context, req *PageExportRequest) ([]*Export, uint32, error) - AddExport(ctx kratosx.Context, c *Export) (uint32, error) - GetExportByVersion(ctx kratosx.Context, uid uint32, version string) (*Export, error) - GetExport(ctx kratosx.Context, id uint32) (*Export, error) - UpdateExport(ctx kratosx.Context, c *Export) error - DeleteExport(ctx kratosx.Context, uid, id uint32) error - UpdateExportExpire(ctx kratosx.Context, t int64) error + // ListExport 获取导出信息列表 + ListExport(ctx kratosx.Context, req *ListExportRequest) ([]*Export, uint32, error) + + // CreateExport 创建导出信息 + CreateExport(ctx kratosx.Context, req *Export) (uint32, error) + + // DeleteExport 删除导出信息 + DeleteExport(ctx kratosx.Context, ids []uint32) (uint32, error) } diff --git a/internal/biz/export/types.go b/internal/biz/export/types.go old mode 100644 new mode 100755 index 60b912f..0880d32 --- a/internal/biz/export/types.go +++ b/internal/biz/export/types.go @@ -1,28 +1,10 @@ package export -type PageExportRequest struct { - Page uint32 `json:"page"` - PageSize uint32 `json:"page_size"` - UserId uint32 `json:"user_id"` -} - -type ExportFile struct { - Sha string `json:"sha"` - Rename string `json:"rename"` -} - -type ExportExcel struct { - Type string `json:"type"` - Value string `json:"value"` -} - -type AddExportRequest struct { - Name string `json:"name"` - Files []*ExportFile `json:"files"` - Ids []uint32 `json:"ids"` -} - -type AddExportExcelRequest struct { - Name string `json:"name"` - Rows [][]*ExportExcel `json:"rows"` +type ListExportRequest struct { + Page uint32 `json:"page"` + PageSize uint32 `json:"pageSize"` + Order *string `json:"order"` + OrderBy *string `json:"orderBy"` + UserId *uint32 `json:"userId"` + DepartmentId *uint32 `json:"departmentId"` } diff --git a/internal/biz/file/biz.go b/internal/biz/file/biz.go old mode 100644 new mode 100755 index f5a23ee..ac8f5b4 --- a/internal/biz/file/biz.go +++ b/internal/biz/file/biz.go @@ -1,350 +1,259 @@ package file import ( - "bytes" - "io" - "mime" - "os" - "path/filepath" + oe "errors" + "fmt" + "math" "strings" "sync" + "time" - "github.com/golang/protobuf/proto" "github.com/google/uuid" "github.com/limes-cloud/kratosx" + "github.com/limes-cloud/kratosx/pkg/valx" + "google.golang.org/protobuf/proto" + "gorm.io/gorm" - "github.com/limes-cloud/resource/api/errors" - "github.com/limes-cloud/resource/internal/config" - "github.com/limes-cloud/resource/internal/consts" - "github.com/limes-cloud/resource/internal/pkg/image" + "github.com/limes-cloud/resource/api/resource/errors" + "github.com/limes-cloud/resource/internal/conf" + "github.com/limes-cloud/resource/internal/pkg/util" ) type UseCase struct { - config *config.Config - repo Repo - factory Factory - muiOnce map[string]*sync.Once - rw sync.RWMutex + conf *conf.Config + repo Repo + rw sync.RWMutex + mui map[string]*sync.Once } -func NewUseCase(config *config.Config, repo Repo, factory Factory) *UseCase { - return &UseCase{config: config, repo: repo, factory: factory, muiOnce: make(map[string]*sync.Once)} +func NewUseCase(config *conf.Config, repo Repo) *UseCase { + return &UseCase{conf: config, repo: repo, mui: make(map[string]*sync.Once), rw: sync.RWMutex{}} } -func (u *UseCase) AllDirectoryByParentID(ctx kratosx.Context, pid uint32, app string) ([]*Directory, error) { - list, err := u.repo.AllDirectoryByParentID(ctx, pid, app) - if err != nil { - return nil, errors.Database() - } - return list, nil -} - -func (u *UseCase) AddDirectory(ctx kratosx.Context, in *Directory) (uint32, error) { - if in.ParentID != 0 { - directory, err := u.repo.GetDirectoryByID(ctx, in.ParentID) - if err != nil { - return 0, errors.NotExistDirectory() - } - if directory.App != in.App { - return 0, errors.System() - } - } - id, err := u.repo.AddDirectory(ctx, in) - if err != nil { - return 0, errors.DatabaseFormat(err.Error()) - } - return id, nil -} - -func (u *UseCase) UpdateDirectory(ctx kratosx.Context, in *Directory) error { - directory, err := u.repo.GetDirectoryByID(ctx, in.ID) - if err != nil { - return errors.NotExistDirectory() - } - if directory.App != in.App { - return errors.System() - } - - if err := u.repo.UpdateDirectory(ctx, in); err != nil { - return errors.DatabaseFormat(err.Error()) - } - return nil -} - -func (u *UseCase) DeleteDirectory(ctx kratosx.Context, id uint32, app string) error { - directory, err := u.repo.GetDirectoryByID(ctx, id) - if err != nil { - return errors.NotExistDirectory() - } - if directory.App != app { - return errors.System() - } - - // 是否存在文件 - if count, _ := u.repo.FileCountByDirectoryID(ctx, id); count != 0 { - return errors.DeleteDirectoryFormat("当前目录下存在文件或目录") - } - - // 判断是否存在目录 - if count, _ := u.repo.DirectoryCountByParentID(ctx, id); count != 0 { - return errors.DeleteDirectoryFormat("当前目录下存在文件或目录") - } - - if err := u.repo.DeleteDirectory(ctx, id); err != nil { - return errors.Database() - } - return nil -} - -func (u *UseCase) GetFile(ctx kratosx.Context, in *GetFileRequest) (*GetFileResponse, error) { - store, err := u.factory.Store(ctx) - if err != nil { - return nil, errors.System() - } - reader, err := store.Get(in.Src) - if err != nil { - return nil, errors.NotExistResource() - } - - var rb []byte - if in.IsRange { - file := reader.(*os.File) - if _, err := file.Seek(in.Start, io.SeekStart); err != nil { - return nil, errors.AccessResourceFormat(err.Error()) - } - tempReader := bytes.NewBuffer([]byte{}) - if _, err := io.CopyN(tempReader, file, in.End-in.Start+1); err != nil { - return nil, errors.AccessResourceFormat(err.Error()) - } - rb, _ = io.ReadAll(tempReader) +// GetFile 获取指定的文件信息 +func (u *UseCase) GetFile(ctx kratosx.Context, req *GetFileRequest) (*File, error) { + var ( + res *File + err error + ) + + if req.Id != nil { + res, err = u.repo.GetFile(ctx, *req.Id) + } else if req.Sha != nil { + res, err = u.repo.GetFileBySha(ctx, *req.Sha) } else { - rb, _ = io.ReadAll(reader) + return nil, errors.ParamsError() } - fileMime := mime.TypeByExtension(filepath.Ext(in.Src)) - if fileMime == "" { - fileMime = u.factory.FileMime(rb) - } - // 如果是图片,则进行裁剪 - if strings.Contains(fileMime, "image/") && in.Width > 0 && in.Height > 0 { - tp := strings.Split(fileMime, "/")[1] - if img, err := image.New(tp, rb); err == nil { - if in.Mode == "" { - in.Mode = image.AspectFill - } - if nrb, err := img.Resize(in.Width, in.Height, in.Mode); err == nil { - rb = nrb - } - } + if res.Status != STATUS_COMPLETED { + return nil, errors.NotExistFileError() } - return &GetFileResponse{ - Data: rb, - Mime: fileMime, - }, nil -} - -func (u *UseCase) GetFileBySha(ctx kratosx.Context, sha string) (*File, error) { - file, err := u.repo.GetFileBySha(ctx, sha) if err != nil { - return nil, err + return nil, errors.NotExistFileError(err.Error()) } - file.Src = u.factory.FileSrc(file.Src) - return file, nil + return res, nil } -func (u *UseCase) PageFile(ctx kratosx.Context, in *PageFileRequest) ([]*File, uint32, error) { - list, total, err := u.repo.PageFile(ctx, in) +// ListFile 获取文件信息列表 +func (u *UseCase) ListFile(ctx kratosx.Context, req *ListFileRequest) ([]*File, uint32, error) { + list, total, err := u.repo.ListFile(ctx, req) if err != nil { - return nil, 0, errors.DatabaseFormat(err.Error()) - } - for ind, item := range list { - list[ind].Src = u.factory.FileSrc(item.Src) + return nil, 0, errors.ListError(err.Error()) } return list, total, nil } -// UpdateFile 修改文件名称 -func (u *UseCase) UpdateFile(ctx kratosx.Context, file *File) error { - if err := u.repo.UpdateFile(ctx, file); err != nil { - return errors.DatabaseFormat(err.Error()) - } - return nil -} - -// DeleteFiles 删除文件 -func (u *UseCase) DeleteFiles(ctx kratosx.Context, pid uint32, ids []uint32) error { - if err := u.repo.DeleteFiles(ctx, pid, ids); err != nil { - return errors.DatabaseFormat(err.Error()) - } - return nil -} - -// PrepareUploadFile 预上传文件 -func (u *UseCase) PrepareUploadFile(ctx kratosx.Context, in *PrepareUploadFileRequest) (*PrepareUploadFileReply, error) { - if in.DirectoryPath == "" && in.DirectoryId == 0 { - return nil, errors.Params() - } - - var err error - var directory *Directory - if in.DirectoryPath != "" { - paths := strings.Split(in.DirectoryPath, "/") - directory, err = u.repo.GetDirectoryByPaths(ctx, in.App, paths) +// PrepareUploadFile 预上传文件信息 +func (u *UseCase) PrepareUploadFile(ctx kratosx.Context, req *PrepareUploadFileRequest) (*PrepareUploadFileReply, error) { + var ( + err error + limit *DirectoryLimit + directoryId uint32 + ) + if req.DirectoryId != nil { + limit, err = u.repo.GetDirectoryLimitById(ctx, *req.DirectoryId) } else { - directory, err = u.repo.GetDirectoryByID(ctx, in.DirectoryId) + paths := strings.Split(*req.DirectoryPath, "/") + limit, err = u.repo.GetDirectoryLimitByPath(ctx, paths) } if err != nil { - return nil, errors.DatabaseFormat(err.Error()) + return nil, errors.DatabaseError(err.Error()) } + directoryId = limit.DirectoryId + chunkSize := util.GetKBSize(u.conf.ChunkSize) - file, err := u.repo.GetFileBySha(ctx, in.Sha) + // 校验是否存在上传记录 + oldFile, err := u.repo.GetFileBySha(ctx, req.Sha) + if err != nil && !oe.Is(err, gorm.ErrRecordNotFound) { + return nil, errors.UpdateError(err.Error()) + } if err == nil { // 触发秒传 - if file.Status == consts.STATUS_COMPLETED { - _ = u.repo.CopyFile(ctx, file, directory.ID, in.Name) + if oldFile.Status == STATUS_COMPLETED { + if err := u.repo.CopyFile(ctx, oldFile, directoryId, req.Name); err != nil { + return nil, errors.UploadFileError(err.Error()) + } return &PrepareUploadFileReply{ - Uploaded: proto.Bool(true), - Src: proto.String(u.factory.FileSrc(file.Src)), - Sha: proto.String(file.Sha), + Uploaded: true, + Src: proto.String(oldFile.Src), + Sha: proto.String(oldFile.Sha), + URL: proto.String(oldFile.URL), }, nil } - - var chunks []int - if file.ChunkCount > 1 && file.UploadID != nil { - store, err := u.factory.Store(ctx) - if err != nil { - return nil, errors.InitStoreFormat(err.Error()) - } - chunk, err := store.NewPutChunkByUploadID(file.Src, *file.UploadID) - if err != nil { - return nil, errors.ChunkUpload() - } - chunks = chunk.UploadedChunkIndex() + // 触发断点续传 + chunkFactory, err := u.repo.GetStore().NewPutChunkByUploadID(oldFile.Sha, oldFile.UploadId) + if err != nil { + ctx.Logger().Warnf("get upload chunks error:%s", err.Error()) } return &PrepareUploadFileReply{ - Uploaded: proto.Bool(false), - UploadId: file.UploadID, - ChunkSize: proto.Uint32(uint32(u.factory.MaxChunkSize())), - ChunkCount: proto.Uint32(file.ChunkCount), - UploadChunks: chunks, - Sha: proto.String(file.Sha), + Uploaded: false, + UploadId: proto.String(oldFile.UploadId), + ChunkSize: proto.Uint32(chunkSize), + ChunkCount: proto.Uint32(oldFile.ChunkCount), + UploadChunks: chunkFactory.UploadedChunkIndex(), + Sha: proto.String(oldFile.Sha), }, nil } - // 检查文件大小 - if err := u.factory.CheckSize(int64(in.Size)); err != nil { - return nil, err + // 校验文件大小 + if size := util.GetKBSize(limit.MaxSize); size < req.Size { + return nil, errors.ExceedMaxSizeError() } - // 获取文件类型 - fileType := u.factory.GetType(in.Name) - - // 检查文件后缀 - if err := u.factory.CheckType(fileType); err != nil { - return nil, err + // 校验文件类型 + tp := util.GetFileType(req.Name) + if !valx.InList(limit.Accepts, tp) { + return nil, errors.NoSupportFileTypeError() } // 构建文件对象 - file = &File{ - DirectoryID: directory.ID, - Size: in.Size, - Sha: in.Sha, - Name: in.Name, - Src: u.factory.StoreKey(in.Sha, fileType), - Status: consts.STATUS_PROGRESS, - Storage: u.factory.Storage(), - Type: fileType, - UploadID: proto.String(uuid.NewString()), + file := &File{ + DirectoryId: directoryId, + Size: req.Size, + Sha: req.Sha, + Name: req.Name, + Src: fmt.Sprintf("%s.%s", req.Sha, tp), + Status: STATUS_PROGRESS, + Type: tp, + UploadId: uuid.NewString(), ChunkCount: 1, } // 判断是否需要切片 - if u.factory.MaxSingularSize() < int64(in.Size) { - store, err := u.factory.Store(ctx) - if err != nil { - return nil, err - } - - pc, err := store.NewPutChunk(file.Src) + if chunkSize < req.Size { + file.ChunkCount = uint32(math.Ceil(float64(req.Size) / float64(chunkSize))) + chunkFactory, err := u.repo.GetStore().NewPutChunk(file.Src) if err != nil { - return nil, errors.ChunkUpload() + return nil, errors.UpdateError(err.Error()) } - file.UploadID = proto.String(pc.UploadID()) - file.ChunkCount = uint32(u.factory.ChunkCount(int64(in.Size))) + file.UploadId = chunkFactory.UploadID() } - if err := u.repo.AddFile(ctx, file); err != nil { - return nil, errors.Database() + if _, err = u.repo.CreateFile(ctx, file); err != nil { + return nil, errors.UpdateError(err.Error()) } return &PrepareUploadFileReply{ - Uploaded: proto.Bool(false), - UploadId: file.UploadID, - ChunkSize: proto.Uint32(uint32(u.factory.MaxChunkSize())), + Uploaded: false, + UploadId: proto.String(file.UploadId), + ChunkSize: proto.Uint32(chunkSize), ChunkCount: proto.Uint32(file.ChunkCount), - UploadChunks: []int{}, + UploadChunks: nil, }, nil } -func (u *UseCase) UploadFile(ctx kratosx.Context, in *UploadFileRequest) (*UploadFileReply, error) { - file, err := u.repo.GetFileByUploadID(ctx, in.UploadId) +// UploadFile 上传文件信息 +func (u *UseCase) UploadFile(ctx kratosx.Context, req *UploadFileRequest) (*UploadFileReply, error) { + file, err := u.repo.GetFileByUploadId(ctx, req.UploadId) if err != nil { - return nil, errors.UploadFileFormat("上传id不存在") + return nil, errors.UpdateError("不存在上传任务") } - if file.Status == consts.STATUS_COMPLETED { - return nil, errors.UploadFileFormat("请勿重复上传") + if file.Status == STATUS_COMPLETED { + return nil, errors.UpdateError("请勿重复上传") } - store, err := u.factory.Store(ctx) if err != nil { - return nil, err + return nil, errors.UpdateError(err.Error()) } // 直接上传 if file.ChunkCount == 1 { - if err := store.PutBytes(file.Src, in.Data); err != nil { - return nil, errors.UploadFileFormat(err.Error()) + if err = u.repo.GetStore().PutBytes(file.Src, req.Data); err != nil { + return nil, err } - if err := u.repo.UpdateFileSuccess(ctx, file.ID); err != nil { - return nil, errors.UploadFileFormat(err.Error()) + if err = u.repo.UpdateFileStatus(ctx, file.Id, STATUS_COMPLETED); err != nil { + return nil, errors.UploadFileError(err.Error()) } - return &UploadFileReply{ - Src: u.factory.FileSrc(file.Src), - Sha: file.Sha, - }, nil - } + } else { + chunkFactory, err := u.repo.GetStore().NewPutChunkByUploadID(file.Src, req.UploadId) + if err != nil { + return nil, errors.UpdateError(err.Error()) + } + if err = chunkFactory.AppendBytes(req.Data, int(req.Index)); err != nil { + return nil, err + } + u.rw.Lock() + if u.mui[req.UploadId] == nil { + u.mui[req.UploadId] = &sync.Once{} + } + u.rw.Unlock() + + // 当前已经上传完成 + if chunkFactory.ChunkCount() == int(file.ChunkCount) { + u.rw.RLock() + if u.mui[req.UploadId] != nil { + var cErr error + u.mui[req.UploadId].Do(func() { + if err := chunkFactory.Complete(); err != nil { + cErr = err + return + } + if err := u.repo.UpdateFileStatus(ctx, file.Id, STATUS_COMPLETED); err != nil { + cErr = err + } + go func() { + time.Sleep(10 * time.Second) + delete(u.mui, req.UploadId) + }() + }) + if cErr != nil { + return nil, errors.UpdateError(err.Error()) + } + } - // 切片上传 - chunk, err := store.NewPutChunkByUploadID(file.Src, in.UploadId) - if err != nil { - return nil, errors.ChunkUploadFormat(err.Error()) + u.rw.RUnlock() + } } - if err := chunk.AppendBytes(in.Data, int(in.Index)); err != nil { - return nil, errors.ChunkUploadFormat(err.Error()) - } + return &UploadFileReply{ + Src: file.Src, + Sha: file.Sha, + URL: file.URL, + }, nil +} - u.rw.Lock() - if u.muiOnce[in.UploadId] == nil { - u.muiOnce[in.UploadId] = &sync.Once{} +// UpdateFile 更新文件信息 +func (u *UseCase) UpdateFile(ctx kratosx.Context, req *File) error { + if err := u.repo.UpdateFile(ctx, req); err != nil { + return errors.UpdateError(err.Error()) } - u.rw.Unlock() + return nil +} - if chunk.ChunkCount() == int(file.ChunkCount) { - u.rw.RLock() - if u.muiOnce[in.UploadId] != nil { - u.muiOnce[in.UploadId].Do(func() { - _ = chunk.Complete() - _ = u.repo.UpdateFileSuccess(ctx, file.ID) - }) - } - delete(u.muiOnce, in.UploadId) - u.rw.RUnlock() +// DeleteFile 删除文件信息 +func (u *UseCase) DeleteFile(ctx kratosx.Context, ids []uint32) (uint32, error) { + total, err := u.repo.DeleteFile(ctx, ids) + if err != nil { + return 0, errors.DeleteError(err.Error()) } + return total, nil +} - return &UploadFileReply{ - Src: u.factory.FileSrc(file.Src), - Sha: file.Sha, - }, nil +// VerifyURL 验证访问url +func (u *UseCase) VerifyURL(key string, expire string, sign string) error { + if err := u.repo.GetStore().VerifyTemporaryURL(key, expire, sign); err != nil { + return errors.VerifySignError(err.Error()) + } + return nil } diff --git a/internal/biz/file/biz_test.go b/internal/biz/file/biz_test.go deleted file mode 100644 index b691ba5..0000000 --- a/internal/biz/file/biz_test.go +++ /dev/null @@ -1 +0,0 @@ -package file diff --git a/internal/biz/file/const.go b/internal/biz/file/const.go new file mode 100644 index 0000000..ea01057 --- /dev/null +++ b/internal/biz/file/const.go @@ -0,0 +1,6 @@ +package file + +const ( + STATUS_PROGRESS = "PROGRESS" + STATUS_COMPLETED = "COMPLETED" +) diff --git a/internal/biz/file/entity.go b/internal/biz/file/entity.go old mode 100644 new mode 100755 index 4800e8d..9e4ae3e --- a/internal/biz/file/entity.go +++ b/internal/biz/file/entity.go @@ -1,25 +1,23 @@ package file -import "github.com/limes-cloud/kratosx/types" - -type Directory struct { - types.BaseModel - ParentID uint32 `json:"parent_id"` - Name string `json:"name"` - App string `json:"app"` +type File struct { + Id uint32 `json:"id"` + DirectoryId uint32 `json:"directoryId"` + Name string `json:"name"` + Type string `json:"type"` + Size uint32 `json:"size"` + Sha string `json:"sha"` + Src string `json:"src"` + URL string `json:"url"` + Status string `json:"status"` + UploadId string `json:"uploadId"` + ChunkCount uint32 `json:"chunkCount"` + CreatedAt int64 `json:"createdAt"` + UpdatedAt int64 `json:"updatedAt"` } -type File struct { - types.BaseModel - DirectoryID uint32 `json:"directory_id"` - Name string `json:"name"` - Type string `json:"type"` - Size uint32 `json:"size"` - Sha string `json:"sha"` - Src string `json:"src"` - UploadID *string `json:"upload_id"` - ChunkCount uint32 `json:"chunk_count"` - Storage string `json:"storage"` - Status string `json:"status"` - Directory *Directory `json:"directory"` +type DirectoryLimit struct { + DirectoryId uint32 `json:"directoryId"` + Accepts []string `json:"accepts"` + MaxSize uint32 `json:"maxSize"` } diff --git a/internal/biz/file/factory.go b/internal/biz/file/factory.go deleted file mode 100644 index 039e7b9..0000000 --- a/internal/biz/file/factory.go +++ /dev/null @@ -1,22 +0,0 @@ -package file - -import ( - "github.com/limes-cloud/kratosx" - - "github.com/limes-cloud/resource/internal/pkg/store" -) - -type Factory interface { - Storage() string - ChunkCount(size int64) int - GetType(name string) string - StoreKey(sha string, tp string) string - CheckType(tp string) error - CheckSize(size int64) error - MaxSingularSize() int64 - MaxChunkSize() int64 - FileSrcFormat() string - FileSrc(src string) string - FileMime(body []byte) string - Store(ctx kratosx.Context) (store.Store, error) -} diff --git a/internal/biz/file/repo.go b/internal/biz/file/repo.go old mode 100644 new mode 100755 index 92c6007..9635181 --- a/internal/biz/file/repo.go +++ b/internal/biz/file/repo.go @@ -2,30 +2,44 @@ package file import ( "github.com/limes-cloud/kratosx" + + "github.com/limes-cloud/resource/internal/pkg/store" ) type Repo interface { - AddDirectory(ctx kratosx.Context, in *Directory) (uint32, error) - GetDirectoryByID(ctx kratosx.Context, id uint32) (*Directory, error) - GetDirectoryByName(ctx kratosx.Context, id uint32, name string) (*Directory, error) - GetDirectoryByPaths(ctx kratosx.Context, app string, paths []string) (*Directory, error) - UpdateDirectory(ctx kratosx.Context, in *Directory) error - DeleteDirectory(ctx kratosx.Context, id uint32) error - AllDirectoryByParentID(ctx kratosx.Context, pid uint32, app string) ([]*Directory, error) - DirectoryCountByParentID(ctx kratosx.Context, id uint32) (int64, error) - - CopyFile(ctx kratosx.Context, src *File, did uint32, name string) error - - // FileCountByName(ctx kratosx.Context, did uint32, name string) (int64, error) - FileCountByDirectoryID(ctx kratosx.Context, id uint32) (int64, error) - - GetFileByID(ctx kratosx.Context, id uint32) (*File, error) - GetFileBySha(ctx kratosx.Context, keyword string) (*File, error) - GetFileByUploadID(ctx kratosx.Context, uid string) (*File, error) - PageFile(ctx kratosx.Context, req *PageFileRequest) ([]*File, uint32, error) - AddFile(ctx kratosx.Context, c *File) error - UpdateFile(ctx kratosx.Context, file *File) error - UpdateFileSuccess(ctx kratosx.Context, id uint32) error - DeleteFile(ctx kratosx.Context, id uint32) error - DeleteFiles(ctx kratosx.Context, pid uint32, ids []uint32) error + // GetFile 获取指定的文件信息 + GetFile(ctx kratosx.Context, id uint32) (*File, error) + + // ListFile 获取文件信息列表 + ListFile(ctx kratosx.Context, req *ListFileRequest) ([]*File, uint32, error) + + // CreateFile 创建文件信息 + CreateFile(ctx kratosx.Context, req *File) (uint32, error) + + // CopyFile 复制文件信息 + CopyFile(ctx kratosx.Context, src *File, directoryId uint32, fileName string) error + + // UpdateFile 更新文件信息 + UpdateFile(ctx kratosx.Context, req *File) error + + // UpdateFileStatus 更新文 件状态 + UpdateFileStatus(ctx kratosx.Context, id uint32, status string) error + + // DeleteFile 删除文件信息 + DeleteFile(ctx kratosx.Context, ids []uint32) (uint32, error) + + // GetFileBySha 获取指定的文件信息 + GetFileBySha(ctx kratosx.Context, sha string) (*File, error) + + // GetFileByUploadId 获取指定的文件信息 + GetFileByUploadId(ctx kratosx.Context, uid string) (*File, error) + + // GetDirectoryLimitByPath 获取指定的path上传限制信息 + GetDirectoryLimitByPath(ctx kratosx.Context, paths []string) (*DirectoryLimit, error) + + // GetDirectoryLimitById 获取指定的id上传限制信息 + GetDirectoryLimitById(ctx kratosx.Context, id uint32) (*DirectoryLimit, error) + + // GetStore 获取上传器 + GetStore() store.Store } diff --git a/internal/biz/file/types.go b/internal/biz/file/types.go old mode 100644 new mode 100755 index b8064c0..f5269f1 --- a/internal/biz/file/types.go +++ b/internal/biz/file/types.go @@ -1,58 +1,46 @@ package file -type PageFileRequest struct { - Page uint32 `json:"page"` - PageSize uint32 `json:"page_size"` - Name string `json:"name"` - DirectoryId uint32 `json:"directory_id"` +type GetFileRequest struct { + Id *uint32 `json:"id"` + Sha *string `json:"sha"` } -type GetDirectoryByAppRequest struct { - App string `json:"app"` - ParentID uint32 `json:"parent_id"` +type ListFileRequest struct { + Page uint32 `json:"page"` + PageSize uint32 `json:"pageSize"` + Order *string `json:"order"` + OrderBy *string `json:"orderBy"` + DirectoryId *uint32 `json:"directoryId"` + Status *string `json:"status"` } type PrepareUploadFileRequest struct { - DirectoryId uint32 `json:"directory_id"` - DirectoryPath string `json:"directory_path"` - App string `json:"app"` - Name string `json:"name"` - Sha string `json:"sha"` - Size uint32 `json:"size"` + DirectoryId *uint32 `json:"directoryId"` + DirectoryPath *string `json:"directoryPath"` + Name string `json:"name"` + Size uint32 `json:"size"` + Sha string `json:"sha"` } type PrepareUploadFileReply struct { - Uploaded *bool `json:"uploaded"` - Src *string `json:"src"` - ChunkSize *uint32 `json:"chunk_size"` - ChunkCount *uint32 `json:"chunk_count"` - UploadId *string `json:"upload_id"` - UploadChunks []int `json:"upload_chunks"` - Sha *string `json:"sha"` + Uploaded bool `json:"uploaded"` + Src *string `json:"src"` + ChunkSize *uint32 `json:"chunkSize"` + ChunkCount *uint32 `json:"chunkCount"` + UploadId *string `json:"uploadId"` + UploadChunks []uint32 `json:"uploadChunks"` + Sha *string `json:"sha"` + URL *string `json:"url"` } type UploadFileRequest struct { Data []byte `json:"data"` - UploadId string `json:"upload_id"` + UploadId string `json:"uploadId"` Index uint32 `json:"index"` } type UploadFileReply struct { - Src string - Sha string -} - -type GetFileRequest struct { - Src string `json:"src"` - Width int `json:"width"` - Height int `json:"height"` - Mode string `json:"mode"` - IsRange bool `json:"is_range"` - Start int64 `json:"start"` - End int64 `json:"end"` -} - -type GetFileResponse struct { - Data []byte `json:"data"` - Mime string `json:"mime"` + Src string `json:"src"` + Sha string `json:"sha"` + URL string `json:"url"` } diff --git a/internal/conf/conf.go b/internal/conf/conf.go new file mode 100644 index 0000000..dc3b77e --- /dev/null +++ b/internal/conf/conf.go @@ -0,0 +1,27 @@ +package conf + +import "time" + +type Config struct { + // Secret string + // Expire time.Duration + DefaultMaxSize uint32 + + DefaultAcceptTypes []string + ChunkSize uint32 + Export struct { + LocalDir string + Expire time.Duration + } + Storage struct { + Type string + Endpoint string + Id string + Secret string + Bucket string + Region string + LocalDir string + ServerURL string + TemporaryExpire time.Duration + } +} diff --git a/internal/config/config.yaml b/internal/conf/conf.yaml similarity index 61% rename from internal/config/config.yaml rename to internal/conf/conf.yaml index dd034cb..c22bac2 100644 --- a/internal/config/config.yaml +++ b/internal/conf/conf.yaml @@ -1,17 +1,15 @@ -env: TEST +env: PROD server: http: - host: 127.0.0.1 - port: 7003 - timeout: 10s + addr: 127.0.0.1:7003 + timeout: 60s marshal: emitUnpopulated: true useProtoNames: true grpc: - host: 127.0.0.1 - port: 8003 - timeout: 10s + addr: 127.0.0.1:8003 + timeout: 60s log: level: 0 output: @@ -38,23 +36,32 @@ database: config: transformError: enable: true - initializer: - enable: true - path: deploy/data.sql maxLifetime: 2h #最大生存时间 maxOpenConn: 20 #最大连接数量 maxIdleConn: 10 #最大空闲数量 - logLevel: 4 #日志等级 + logLevel: 3 #日志等级 slowThreshold: 2s #慢sql阈值 +redis: + cache: + enable: true + host: 127.0.0.1:6379 + username: '' + password: '' business: + chunkSize: 1 + defaultMaxSize: 10 + defaultAcceptTypes: ["jpg","png","txt","ppt","pptx","mp4","pdf"] storage: type: local - serverPath: /resource/v1/static + endpoint: xxx + id: xxx + secret: xxx + bucket: resource-1323879016 + region: ap-nanjing +# serverUrl: http://cos.qlime.cn + serverUrl: http://127.0.0.1:7003/resource/api/v1/static localDir: static - maxSingularSize: 400 - maxChunkSize: 200 - maxChunkCount: 200 - acceptTypes: ["jpg","png","txt","ppt","pptx","mp4"] + temporaryExpire: 600s export: + ServerPath: '' localDir: static/export - expire: 3d \ No newline at end of file diff --git a/internal/config/config.go b/internal/config/config.go deleted file mode 100644 index 00fc867..0000000 --- a/internal/config/config.go +++ /dev/null @@ -1,24 +0,0 @@ -package config - -import "time" - -type Config struct { - Export struct { - LocalDir string - Expire time.Duration - } - Storage struct { - Type string - Endpoint string - Key string - Secret string - Bucket string - Region string - ServerPath string - LocalDir string - MaxSingularSize int64 - MaxChunkSize int64 - MaxChunkCount int64 - AcceptTypes []string - } -} diff --git a/internal/consts/consts.go b/internal/consts/consts.go deleted file mode 100644 index 2af9554..0000000 --- a/internal/consts/consts.go +++ /dev/null @@ -1,13 +0,0 @@ -package consts - -const ( - STATUS_PROGRESS = "PROGRESS" - STATUS_COMPLETED = "COMPLETED" - STATUS_FAILED = "FAILED" -) - -const ( - STORE_ALIYUN = "aliyun" - STORE_TENCENT = "tencent" - STORE_LOCAL = "local" -) diff --git a/internal/data/directory.go b/internal/data/directory.go new file mode 100755 index 0000000..2fcffe0 --- /dev/null +++ b/internal/data/directory.go @@ -0,0 +1,174 @@ +package data + +import ( + "errors" + "fmt" + + "github.com/limes-cloud/kratosx" + "github.com/limes-cloud/kratosx/pkg/valx" + "google.golang.org/protobuf/proto" + + biz "github.com/limes-cloud/resource/internal/biz/directory" + "github.com/limes-cloud/resource/internal/data/model" +) + +type directoryRepo struct { +} + +func NewDirectoryRepo() biz.Repo { + return &directoryRepo{} +} + +// ToDirectoryEntity model转entity +func (r directoryRepo) ToDirectoryEntity(m *model.Directory) *biz.Directory { + e := &biz.Directory{} + _ = valx.Transform(m, e) + return e +} + +// ToDirectoryModel entity转model +func (r directoryRepo) ToDirectoryModel(e *biz.Directory) *model.Directory { + m := &model.Directory{} + _ = valx.Transform(e, m) + return m +} + +// GetDirectory 获取指定的数据 +func (r directoryRepo) GetDirectory(ctx kratosx.Context, id uint32) (*biz.Directory, error) { + var ( + m = model.Directory{} + fs = []string{"*"} + ) + db := ctx.DB().Select(fs) + if err := db.First(&m, id).Error; err != nil { + return nil, err + } + + return r.ToDirectoryEntity(&m), nil +} + +// ListDirectory 获取列表 +func (r directoryRepo) ListDirectory(ctx kratosx.Context, req *biz.ListDirectoryRequest) ([]*biz.Directory, uint32, error) { + var ( + bs []*biz.Directory + ms []*model.Directory + total int64 + fs = []string{"*"} + ) + + db := ctx.DB().Model(model.Directory{}).Select(fs) + + if err := db.Count(&total).Error; err != nil { + return nil, 0, err + } + + if req.OrderBy == nil || *req.OrderBy == "" { + req.OrderBy = proto.String("id") + } + if req.Order == nil || *req.Order == "" { + req.Order = proto.String("asc") + } + db = db.Order(fmt.Sprintf("%s %s", *req.OrderBy, *req.Order)) + if *req.OrderBy != "id" { + db = db.Order("id asc") + } + + if err := db.Find(&ms).Error; err != nil { + return nil, 0, err + } + + for _, m := range ms { + bs = append(bs, r.ToDirectoryEntity(m)) + } + return bs, uint32(total), nil +} + +// CreateDirectory 创建数据 +func (r directoryRepo) CreateDirectory(ctx kratosx.Context, req *biz.Directory) (uint32, error) { + m := r.ToDirectoryModel(req) + return m.Id, ctx.Transaction(func(ctx kratosx.Context) error { + if err := ctx.DB().Create(m).Error; err != nil { + return err + } + return r.appendDirectoryChildren(ctx, req.ParentId, m.Id) + }) +} + +// UpdateDirectory 更新数据 +func (r directoryRepo) UpdateDirectory(ctx kratosx.Context, req *biz.Directory) error { + if req.Id == req.ParentId { + return errors.New("父级不能为自己") + } + old, err := r.GetDirectory(ctx, req.Id) + if err != nil { + return err + } + + return ctx.Transaction(func(ctx kratosx.Context) error { + if old.ParentId != req.ParentId { + if err := r.removeDirectoryParent(ctx, req.Id); err != nil { + return err + } + if err := r.appendDirectoryChildren(ctx, req.ParentId, req.Id); err != nil { + return err + } + } + return ctx.DB().Updates(r.ToDirectoryModel(req)).Error + }) +} + +// DeleteDirectory 删除数据 +func (r directoryRepo) DeleteDirectory(ctx kratosx.Context, ids []uint32) (uint32, error) { + var del []uint32 + for _, id := range ids { + del = append(del, id) + childrenIds, err := r.GetDirectoryChildrenIds(ctx, id) + if err != nil { + return 0, err + } + del = append(del, childrenIds...) + } + db := ctx.DB().Where("id in ?", del).Delete(&model.Directory{}) + return uint32(db.RowsAffected), db.Error +} + +// GetDirectoryChildrenIds 获取指定id的所有子id +func (r directoryRepo) GetDirectoryChildrenIds(ctx kratosx.Context, id uint32) ([]uint32, error) { + var ids []uint32 + return ids, ctx.DB().Model(model.DirectoryClosure{}). + Select("children"). + Where("parent=?", id). + Scan(&ids).Error +} + +// GetDirectoryParentIds 获取指定id的所有父id +func (r directoryRepo) GetDirectoryParentIds(ctx kratosx.Context, id uint32) ([]uint32, error) { + var ids []uint32 + return ids, ctx.DB().Model(model.DirectoryClosure{}). + Select("parent"). + Where("children=?", id). + Scan(&ids).Error +} + +// appendDirectoryChildren 添加id到指定的父id下 +func (r directoryRepo) appendDirectoryChildren(ctx kratosx.Context, pid uint32, id uint32) error { + list := []*model.DirectoryClosure{ + { + Parent: pid, + Children: id, + }, + } + ids, _ := r.GetDirectoryParentIds(ctx, pid) + for _, item := range ids { + list = append(list, &model.DirectoryClosure{ + Parent: item, + Children: id, + }) + } + return ctx.DB().Create(&list).Error +} + +// removeDirectoryParent 删除指定id的所有父层级 +func (r directoryRepo) removeDirectoryParent(ctx kratosx.Context, id uint32) error { + return ctx.DB().Delete(&model.DirectoryClosure{}, "children=?", id).Error +} diff --git a/internal/data/export.go b/internal/data/export.go new file mode 100755 index 0000000..0d2d6fe --- /dev/null +++ b/internal/data/export.go @@ -0,0 +1,89 @@ +package data + +import ( + "fmt" + + "github.com/limes-cloud/kratosx" + "github.com/limes-cloud/kratosx/pkg/valx" + "google.golang.org/protobuf/proto" + + biz "github.com/limes-cloud/resource/internal/biz/export" + "github.com/limes-cloud/resource/internal/data/model" +) + +type exportRepo struct { +} + +func NewExportRepo() biz.Repo { + return &exportRepo{} +} + +// ToExportEntity model转entity +func (r exportRepo) ToExportEntity(m *model.Export) *biz.Export { + e := &biz.Export{} + _ = valx.Transform(m, e) + return e +} + +// ToExportModel entity转model +func (r exportRepo) ToExportModel(e *biz.Export) *model.Export { + m := &model.Export{} + _ = valx.Transform(e, m) + return m +} + +// ListExport 获取列表 +func (r exportRepo) ListExport(ctx kratosx.Context, req *biz.ListExportRequest) ([]*biz.Export, uint32, error) { + var ( + bs []*biz.Export + ms []*model.Export + total int64 + fs = []string{"*"} + ) + + db := ctx.DB().Model(model.Export{}).Select(fs) + + if req.UserId != nil { + db = db.Where("user_id = ?", *req.UserId) + } + if req.DepartmentId != nil { + db = db.Where("department_id = ?", *req.DepartmentId) + } + + if err := db.Count(&total).Error; err != nil { + return nil, 0, err + } + db = db.Offset(int((req.Page - 1) * req.PageSize)).Limit(int(req.PageSize)) + + if req.OrderBy == nil || *req.OrderBy == "" { + req.OrderBy = proto.String("id") + } + if req.Order == nil || *req.Order == "" { + req.Order = proto.String("asc") + } + db = db.Order(fmt.Sprintf("%s %s", *req.OrderBy, *req.Order)) + if *req.OrderBy != "id" { + db = db.Order("id asc") + } + + if err := db.Find(&ms).Error; err != nil { + return nil, 0, err + } + + for _, m := range ms { + bs = append(bs, r.ToExportEntity(m)) + } + return bs, uint32(total), nil +} + +// CreateExport 创建数据 +func (r exportRepo) CreateExport(ctx kratosx.Context, req *biz.Export) (uint32, error) { + m := r.ToExportModel(req) + return m.Id, ctx.DB().Create(m).Error +} + +// DeleteExport 删除数据 +func (r exportRepo) DeleteExport(ctx kratosx.Context, ids []uint32) (uint32, error) { + db := ctx.DB().Where("id in ?", ids).Delete(&model.Export{}) + return uint32(db.RowsAffected), db.Error +} diff --git a/internal/data/export/repo.go b/internal/data/export/repo.go deleted file mode 100644 index 42adcbf..0000000 --- a/internal/data/export/repo.go +++ /dev/null @@ -1,54 +0,0 @@ -package export - -import ( - "github.com/limes-cloud/kratosx" - - "github.com/limes-cloud/resource/internal/biz/export" -) - -type repo struct { -} - -func NewRepo() export.Repo { - return &repo{} -} - -func (r repo) GetExport(ctx kratosx.Context, id uint32) (*export.Export, error) { - dir := export.Export{} - return &dir, ctx.DB().First(&dir, "id=?", id).Error -} - -func (r repo) GetExportByVersion(ctx kratosx.Context, uid uint32, version string) (*export.Export, error) { - dir := export.Export{} - return &dir, ctx.DB().First(&dir, "version=? and user_id=?", version, uid).Error -} - -func (r repo) PageExport(ctx kratosx.Context, in *export.PageExportRequest) ([]*export.Export, uint32, error) { - var list []*export.Export - total := int64(0) - - db := ctx.DB().Model(export.Export{}) - if err := db.Count(&total).Error; err != nil { - return nil, uint32(total), err - } - - db = db.Offset(int((in.Page - 1) * in.PageSize)).Limit(int(in.PageSize)) - - return list, uint32(total), db.Find(&list).Error -} - -func (r repo) AddExport(ctx kratosx.Context, export *export.Export) (uint32, error) { - return export.ID, ctx.DB().Create(export).Error -} - -func (r repo) UpdateExport(ctx kratosx.Context, export *export.Export) error { - return ctx.DB().Where("id=?", export.ID).Updates(export).Error -} - -func (r repo) UpdateExportExpire(ctx kratosx.Context, t int64) error { - return ctx.DB().Where("created_at <= ?", t).Update("status", export.StatusExpire).Error -} - -func (r repo) DeleteExport(ctx kratosx.Context, uid uint32, id uint32) error { - return ctx.DB().Where("id=? and user_id=?", id, uid).Delete(export.Export{}).Error -} diff --git a/internal/data/file.go b/internal/data/file.go new file mode 100755 index 0000000..69b4166 --- /dev/null +++ b/internal/data/file.go @@ -0,0 +1,284 @@ +package data + +import ( + "context" + "errors" + "fmt" + "strings" + + "github.com/google/uuid" + "github.com/limes-cloud/kratosx" + "github.com/limes-cloud/kratosx/pkg/valx" + "google.golang.org/protobuf/proto" + "gorm.io/gorm" + "gorm.io/gorm/logger" + + biz "github.com/limes-cloud/resource/internal/biz/file" + "github.com/limes-cloud/resource/internal/conf" + "github.com/limes-cloud/resource/internal/data/model" + "github.com/limes-cloud/resource/internal/pkg/store" + "github.com/limes-cloud/resource/internal/pkg/store/aliyun" + "github.com/limes-cloud/resource/internal/pkg/store/local" + "github.com/limes-cloud/resource/internal/pkg/store/tencent" +) + +type fileRepo struct { + conf *conf.Config + store store.Store +} + +func NewFileRepo(conf *conf.Config) biz.Repo { + ctx := kratosx.MustContext(context.Background()) + cfg := &store.Config{ + Endpoint: conf.Storage.Endpoint, + Id: conf.Storage.Id, + Secret: conf.Storage.Secret, + Bucket: conf.Storage.Bucket, + LocalDir: conf.Storage.LocalDir, + DB: ctx.DB().Session(&gorm.Session{ + Logger: logger.Default.LogMode(logger.Silent), + }), + Cache: ctx.Redis(), + TemporaryExpire: conf.Storage.TemporaryExpire, + ServerURL: conf.Storage.ServerURL, + } + var ( + err error + st store.Store + ) + switch conf.Storage.Type { + case store.STORE_ALIYUN: + st, err = aliyun.New(cfg) + case store.STORE_TENCENT: + st, err = tencent.New(cfg) + case store.STORE_LOCAL: + st, err = local.New(cfg) + default: + err = errors.New("not support storage:" + conf.Storage.Type) + } + if err != nil { + panic(err) + } + return &fileRepo{ + conf: conf, + store: st, + } +} + +// ToFileEntity model转entity +func (r fileRepo) ToFileEntity(ctx kratosx.Context, m *model.File) *biz.File { + e := &biz.File{ + Id: m.Id, + DirectoryId: m.DirectoryId, + Name: m.Name, + Type: m.Type, + Size: m.Size, + Sha: m.Sha, + Src: m.Src, + Status: m.Status, + UploadId: m.UploadId, + ChunkCount: m.ChunkCount, + CreatedAt: m.CreatedAt, + UpdatedAt: m.UpdatedAt, + } + accessURL, err := r.store.GenTemporaryURL(m.Src) + if err != nil { + ctx.Logger().Warnf("gen template url error:%s", err.Error()) + } else { + e.URL = accessURL + } + return e +} + +// ToFileModel entity转model +func (r fileRepo) ToFileModel(e *biz.File) *model.File { + m := &model.File{} + _ = valx.Transform(e, m) + return m +} + +// GetFileBySha 获取指定数据 +func (r fileRepo) GetFileBySha(ctx kratosx.Context, sha string) (*biz.File, error) { + var ( + m = model.File{} + fs = []string{"*"} + ) + db := ctx.DB().Select(fs) + if err := db.Where("sha = ?", sha).First(&m).Error; err != nil { + return nil, err + } + + return r.ToFileEntity(ctx, &m), nil +} + +// GetFile 获取指定的数据 +func (r fileRepo) GetFile(ctx kratosx.Context, id uint32) (*biz.File, error) { + var ( + m = model.File{} + fs = []string{"*"} + ) + db := ctx.DB().Select(fs) + if err := db.First(&m, id).Error; err != nil { + return nil, err + } + + return r.ToFileEntity(ctx, &m), nil +} + +// ListFile 获取列表 +func (r fileRepo) ListFile(ctx kratosx.Context, req *biz.ListFileRequest) ([]*biz.File, uint32, error) { + var ( + bs []*biz.File + ms []*model.File + total int64 + fs = []string{"*"} + ) + + db := ctx.DB().Model(model.File{}).Select(fs) + + if req.DirectoryId != nil { + db = db.Where("directory_id = ?", *req.DirectoryId) + } + if req.Status != nil { + db = db.Where("status = ?", *req.Status) + } + + if err := db.Count(&total).Error; err != nil { + return nil, 0, err + } + db = db.Offset(int((req.Page - 1) * req.PageSize)).Limit(int(req.PageSize)) + + if req.OrderBy == nil || *req.OrderBy == "" { + req.OrderBy = proto.String("id") + } + if req.Order == nil || *req.Order == "" { + req.Order = proto.String("asc") + } + db = db.Order(fmt.Sprintf("%s %s", *req.OrderBy, *req.Order)) + if *req.OrderBy != "id" { + db = db.Order("id asc") + } + + if err := db.Find(&ms).Error; err != nil { + return nil, 0, err + } + + for _, m := range ms { + bs = append(bs, r.ToFileEntity(ctx, m)) + } + return bs, uint32(total), nil +} + +// CreateFile 创建数据 +func (r fileRepo) CreateFile(ctx kratosx.Context, req *biz.File) (uint32, error) { + m := r.ToFileModel(req) + return m.Id, ctx.DB().Create(m).Error +} + +// UpdateFile 更新数据 +func (r fileRepo) UpdateFile(ctx kratosx.Context, req *biz.File) error { + return ctx.DB().Updates(r.ToFileModel(req)).Error +} + +// DeleteFile 删除数据 +func (r fileRepo) DeleteFile(ctx kratosx.Context, ids []uint32) (uint32, error) { + var files []*model.File + if err := ctx.DB().Where("id in ?", ids).Find(&files).Error; err != nil { + return 0, err + } + + for _, item := range files { + if item.Status == biz.STATUS_COMPLETED { + _ = r.store.Delete(item.Src) + } else { + chunk, err := r.store.NewPutChunkByUploadID(item.Src, item.UploadId) + if err == nil { + _ = chunk.Abort() + } + } + } + + db := ctx.DB().Where("id in ?", ids).Delete(model.File{}) + return uint32(db.RowsAffected), db.Error +} + +func (r fileRepo) CopyFile(ctx kratosx.Context, src *biz.File, directoryId uint32, fileName string) error { + if src.DirectoryId == directoryId { + return nil + } + uids := strings.Split(uuid.NewString(), "-") + file := model.File{ + DirectoryId: directoryId, + Src: src.Src, + Name: fileName, + Status: src.Status, + UploadId: src.UploadId + "_copy_" + uids[0], + Type: src.Type, + Size: src.Size, + ChunkCount: src.ChunkCount, + Sha: src.Sha, + } + return ctx.DB().Create(&file).Error +} + +func (r fileRepo) UpdateFileStatus(ctx kratosx.Context, id uint32, status string) error { + return ctx.DB().Model(model.File{}).Where("id=?", id).Update("status", status).Error +} + +func (r fileRepo) GetFileByUploadId(ctx kratosx.Context, uid string) (*biz.File, error) { + var m model.File + if err := ctx.DB().Where("upload_id = ?", uid).First(&m).Error; err != nil { + return nil, err + } + + return r.ToFileEntity(ctx, &m), nil +} + +func (r fileRepo) GetDirectoryLimitByPath(ctx kratosx.Context, paths []string) (*biz.DirectoryLimit, error) { + var ( + dir = model.Directory{} + parent = uint32(0) + ) + + for _, path := range paths { + path = strings.TrimSpace(path) + if path == "" { + continue + } + nr := model.Directory{} + if err := ctx.DB().Where(model.Directory{ + ParentId: parent, + Name: path, + }).Attrs(model.Directory{ + Accept: strings.Join(r.conf.DefaultAcceptTypes, ","), + MaxSize: r.conf.DefaultMaxSize, + }).FirstOrCreate(&nr).Error; err != nil { + return nil, err + } + parent = nr.Id + dir = nr + } + + return &biz.DirectoryLimit{ + DirectoryId: dir.Id, + Accepts: strings.Split(dir.Accept, ","), + MaxSize: dir.MaxSize, + }, nil +} + +func (r fileRepo) GetDirectoryLimitById(ctx kratosx.Context, id uint32) (*biz.DirectoryLimit, error) { + var dir = model.Directory{} + if err := ctx.DB().Where("id=?", id).First(&dir).Error; err != nil { + return nil, err + } + + return &biz.DirectoryLimit{ + DirectoryId: dir.Id, + Accepts: strings.Split(dir.Accept, ","), + MaxSize: dir.MaxSize, + }, nil +} + +func (r fileRepo) GetStore() store.Store { + return r.store +} diff --git a/internal/data/file/repo.go b/internal/data/file/repo.go deleted file mode 100644 index 301dec8..0000000 --- a/internal/data/file/repo.go +++ /dev/null @@ -1,146 +0,0 @@ -package file - -import ( - "github.com/limes-cloud/kratosx" - - "github.com/limes-cloud/resource/internal/biz/file" - "github.com/limes-cloud/resource/internal/consts" -) - -type repo struct { -} - -func NewRepo() file.Repo { - return &repo{} -} - -func (r repo) AddDirectory(ctx kratosx.Context, in *file.Directory) (uint32, error) { - return in.ID, ctx.DB().Create(in).Error -} - -func (r repo) GetDirectoryByID(ctx kratosx.Context, id uint32) (*file.Directory, error) { - dir := file.Directory{} - return &dir, ctx.DB().First(&dir, "id=?", id).Error -} - -func (r repo) GetDirectoryByName(ctx kratosx.Context, id uint32, name string) (*file.Directory, error) { - dir := file.Directory{} - return &dir, ctx.DB().First(&dir, "parent_id=? and name=?", id, name).Error -} - -func (r repo) GetDirectoryByPaths(ctx kratosx.Context, app string, paths []string) (*file.Directory, error) { - dir := file.Directory{} - parent := uint32(0) - for _, path := range paths { - nr := file.Directory{} - if err := ctx.DB().Where(file.Directory{ - App: app, - ParentID: parent, - Name: path, - }).FirstOrCreate(&nr).Error; err != nil { - return nil, err - } - parent = nr.ID - dir = nr - } - return &dir, nil -} - -func (r repo) UpdateDirectory(ctx kratosx.Context, in *file.Directory) error { - return ctx.DB().Model(file.Directory{}).Updates(in).Error -} - -func (r repo) DeleteDirectory(ctx kratosx.Context, id uint32) error { - return ctx.DB().Where("id=?", id).Delete(file.Directory{}).Error -} - -func (r repo) AllDirectoryByParentID(ctx kratosx.Context, pid uint32, app string) ([]*file.Directory, error) { - var list []*file.Directory - return list, ctx.DB().Model(file.Directory{}).Find(&list, "parent_id=? and app=?", pid, app).Error -} - -func (r repo) DirectoryCountByParentID(ctx kratosx.Context, id uint32) (int64, error) { - var count int64 - return count, ctx.DB().Model(file.Directory{}).Where("parent_id=?", id).Count(&count).Error -} - -func (r repo) CopyFile(ctx kratosx.Context, src *file.File, did uint32, name string) error { - if src.DirectoryID == did { - return nil - } - - nf := *src - nf.ID = 0 - nf.DirectoryID = did - nf.Name = name - nf.CreatedAt = 0 - nf.UpdatedAt = 0 - nf.UploadID = nil - - return ctx.DB().Create(&nf).Error -} - -func (r repo) FileCountByName(ctx kratosx.Context, did uint32, name string) (int64, error) { - count := int64(0) - return count, ctx.DB().Model(file.File{}).Where("directory_id=? and name like ?", did, name+"%").Count(&count).Error -} - -func (r repo) FileCountByDirectoryID(ctx kratosx.Context, id uint32) (int64, error) { - count := int64(0) - return count, ctx.DB().Model(file.File{}).Where("directory_id=? ", id).Count(&count).Error -} - -func (r repo) GetFileByID(ctx kratosx.Context, id uint32) (*file.File, error) { - fe := file.File{} - return &fe, ctx.DB().First(&fe, "id=?", id).Error -} - -func (r repo) GetFileBySha(ctx kratosx.Context, sha string) (*file.File, error) { - fe := file.File{} - return &fe, ctx.DB().First(&fe, "sha=?", sha).Error -} - -func (r repo) GetFileByUploadID(ctx kratosx.Context, uid string) (*file.File, error) { - fe := file.File{} - return &fe, ctx.DB().First(&fe, "upload_id=?", uid).Error -} - -func (r repo) PageFile(ctx kratosx.Context, in *file.PageFileRequest) ([]*file.File, uint32, error) { - var list []*file.File - total := int64(0) - - db := ctx.DB().Model(file.File{}) - if in.Name != "" { - db = db.Where("name=?", in.Name) - } - if in.DirectoryId != 0 { - db = db.Where("directory_id=?", in.DirectoryId) - } - if err := db.Count(&total).Error; err != nil { - return nil, uint32(total), err - } - - db = db.Offset(int((in.Page - 1) * in.PageSize)).Limit(int(in.PageSize)) - - return list, uint32(total), db.Find(&list).Error -} - -func (r repo) AddFile(ctx kratosx.Context, file *file.File) error { - return ctx.DB().Create(file).Error -} - -func (r repo) UpdateFile(ctx kratosx.Context, file *file.File) error { - return ctx.DB().Where("id=?", file.ID).Updates(file).Error -} - -func (r repo) UpdateFileSuccess(ctx kratosx.Context, id uint32) error { - return ctx.DB().Model(file.File{}).Where("id=?", id).UpdateColumn("status", consts.STATUS_COMPLETED).Error -} - -func (r repo) DeleteFile(ctx kratosx.Context, id uint32) error { - return ctx.DB().Where("id=?", id).Delete(file.File{}).Error -} - -func (r repo) DeleteFiles(ctx kratosx.Context, did uint32, ids []uint32) error { - return ctx.DB().Where("directory_id=? and id in ?", did, ids).Delete(file.File{}).Error -} diff --git a/internal/data/model/directory.go b/internal/data/model/directory.go new file mode 100755 index 0000000..be74295 --- /dev/null +++ b/internal/data/model/directory.go @@ -0,0 +1,19 @@ +package model + +import ( + "github.com/limes-cloud/kratosx/types" +) + +type Directory struct { + ParentId uint32 `json:"parentId" gorm:"column:parent_id"` + Name string `json:"name" gorm:"column:name"` + Accept string `json:"accept" gorm:"column:accept"` + MaxSize uint32 `json:"maxSize" gorm:"column:max_size"` + types.BaseModel +} + +type DirectoryClosure struct { + ID uint32 `json:"id" gorm:"column:id"` + Parent uint32 `json:"parent" gorm:"column:parent"` + Children uint32 `json:"children" gorm:"column:children"` +} diff --git a/internal/data/model/export.go b/internal/data/model/export.go new file mode 100755 index 0000000..fc4038c --- /dev/null +++ b/internal/data/model/export.go @@ -0,0 +1,19 @@ +package model + +import ( + "github.com/limes-cloud/kratosx/types" +) + +type Export struct { + UserId uint32 `json:"userId" gorm:"column:user_id"` + DepartmentId uint32 `json:"departmentId" gorm:"column:department_id"` + Scene string `json:"scene" gorm:"column:scene"` + Name string `json:"name" gorm:"column:name"` + Size uint32 `json:"size" gorm:"column:size"` + Sha *string `json:"sha" gorm:"column:sha"` + Src *string `json:"src" gorm:"column:src"` + Status string `json:"status" gorm:"column:status"` + Reason *string `json:"reason" gorm:"column:reason"` + ExpiredAt int64 `json:"expiredAt" gorm:"column:expired_at"` + types.BaseModel +} diff --git a/internal/data/model/file.go b/internal/data/model/file.go new file mode 100755 index 0000000..2c49df4 --- /dev/null +++ b/internal/data/model/file.go @@ -0,0 +1,18 @@ +package model + +import ( + "github.com/limes-cloud/kratosx/types" +) + +type File struct { + DirectoryId uint32 `json:"directoryId" gorm:"column:directory_id"` + Name string `json:"name" gorm:"column:name"` + Type string `json:"type" gorm:"column:type"` + Size uint32 `json:"size" gorm:"column:size"` + Sha string `json:"sha" gorm:"column:sha"` + Src string `json:"src" gorm:"column:src"` + Status string `json:"status" gorm:"column:status"` + UploadId string `json:"uploadId" gorm:"column:upload_id"` + ChunkCount uint32 `json:"chunkCount" gorm:"column:chunk_count"` + types.BaseModel +} diff --git a/internal/factory/factory.go b/internal/factory/factory.go deleted file mode 100644 index d565933..0000000 --- a/internal/factory/factory.go +++ /dev/null @@ -1,362 +0,0 @@ -package factory - -import ( - "context" - "fmt" - "io" - "math" - "os" - "path/filepath" - "strings" - "sync" - "time" - - "github.com/gabriel-vasile/mimetype" - "github.com/limes-cloud/kratosx" - "github.com/limes-cloud/kratosx/pkg/util" - "github.com/limes-cloud/kratosx/pkg/xlsx" - - "github.com/limes-cloud/resource/api/errors" - "github.com/limes-cloud/resource/internal/biz/export" - "github.com/limes-cloud/resource/internal/biz/file" - "github.com/limes-cloud/resource/internal/config" - "github.com/limes-cloud/resource/internal/consts" - store2 "github.com/limes-cloud/resource/internal/pkg/store" - "github.com/limes-cloud/resource/internal/pkg/store/aliyun" - "github.com/limes-cloud/resource/internal/pkg/store/local" - "github.com/limes-cloud/resource/internal/pkg/store/tencent" -) - -type Factory struct { - conf *config.Config - fileRepo file.Repo - exportRepo export.Repo -} - -var ( - _ins *Factory - once sync.Once -) - -func New(conf *config.Config, fileRepo file.Repo, exportRepo export.Repo) *Factory { - once.Do(func() { - _ins = &Factory{conf: conf, fileRepo: fileRepo, exportRepo: exportRepo} - go func() { - _ins.ClearExportCache() - time.Sleep(1 * time.Hour) - }() - }) - return _ins -} - -func (f *Factory) Storage() string { - return f.conf.Storage.Type -} - -// ChunkCount 通过文件大小获取分片数量 -func (f *Factory) ChunkCount(size int64) int { - return int(math.Ceil(float64(size) / float64(f.MaxChunkSize()))) -} - -// GetType 获取文件类型 -func (f *Factory) GetType(name string) string { - index := strings.LastIndex(name, ".") - suffix := "" - if index != -1 { - suffix = name[index+1:] - } - return suffix -} - -// StoreKey 获取存储的key -func (f *Factory) StoreKey(sha, tp string) string { - return fmt.Sprintf("%s.%s", sha, tp) -} - -// CheckType 检查文件类型是否合法 -func (f *Factory) CheckType(tp string) error { - if !util.InList(f.conf.Storage.AcceptTypes, tp) { - return errors.UploadFileFormat("不支持的文件后缀") - } - return nil -} - -// CheckSize 检查大小是否合法 -func (f *Factory) CheckSize(size int64) error { - if size > f.MaxChunkSize()*f.conf.Storage.MaxChunkCount { - return errors.UploadFileFormat("超过传输文件大小") - } - return nil -} - -// MaxSingularSize 获取单个文件的最大大小,单位KB -func (f *Factory) MaxSingularSize() int64 { - return f.conf.Storage.MaxSingularSize * 1024 -} - -// MaxChunkSize 获取分片的大小 单位KB -func (f *Factory) MaxChunkSize() int64 { - return f.conf.Storage.MaxChunkSize * 1024 -} - -func (f *Factory) FileSrcFormat() string { - switch f.Storage() { - case consts.STORE_ALIYUN: - return "https://" + f.conf.Storage.Bucket + ".oss-cn-" + f.conf.Storage.Region + ".aliyuncs.com" + "/{src}" - case consts.STORE_TENCENT: - return "https://" + f.conf.Storage.Bucket + ".cos." + f.conf.Storage.Region + ".myqcloud.com" + "/{src}" - case consts.STORE_LOCAL: - return f.conf.Storage.ServerPath + "/{src}" - } - return "%s" -} - -func (f *Factory) ExportFileSrc(src string) string { - prefix := f.conf.Export.LocalDir - if index := strings.Index(f.conf.Export.LocalDir, "/"); index != -1 { - prefix = f.conf.Export.LocalDir[index:] - } - return f.conf.Storage.ServerPath + prefix + "/" + src -} - -func (f *Factory) FileSrc(src string) string { - return strings.Replace(f.FileSrcFormat(), "{src}", src, 1) -} - -// FileMime 获取文件的Mime -func (f *Factory) FileMime(body []byte) string { - return mimetype.Detect(body).String() -} - -func (f *Factory) Store(ctx kratosx.Context) (store2.Store, error) { - c := &store2.Config{ - Endpoint: f.conf.Storage.Endpoint, - Key: f.conf.Storage.Key, - Secret: f.conf.Storage.Secret, - Bucket: f.conf.Storage.Bucket, - LocalDir: f.conf.Storage.LocalDir, - DB: ctx.DB(), - } - switch f.Storage() { - case consts.STORE_ALIYUN: - return aliyun.New(c) - case consts.STORE_TENCENT: - return tencent.New(c) - case consts.STORE_LOCAL: - return local.New(c) - default: - return nil, errors.NoSupportStore() - } -} - -// ExportFile 导出指定的文件列表 -func (f *Factory) ExportFile(ctx kratosx.Context, in *export.AddExportRequest) (int64, error) { - if util.IsExistFile(in.Name) { - _ = os.Chtimes(in.Name, time.Now(), time.Now()) - stat, err := os.Stat(in.Name) - if err != nil { - return 0, err - } - return stat.Size(), nil - } - - dir := f.conf.Export.LocalDir - if !util.IsExistFolder(dir) { - if err := os.MkdirAll(dir, os.ModePerm); err != nil { - return 0, err - } - } - - var exports = make(map[string]string) - - if len(in.Ids) != 0 { - for _, id := range in.Ids { - fe, err := f.fileRepo.GetFileByID(ctx, id) - if err != nil { - ctx.Logger().Errorw("msg", "get file error", "err", err.Error()) - continue - } - exports[fe.Src] = fe.Src - } - } else { - for _, item := range in.Files { - if item.Sha == "" { - continue - } - fe, err := f.fileRepo.GetFileBySha(ctx, item.Sha) - if err != nil { - ctx.Logger().Errorw("msg", "get file error", "err", err.Error()) - continue - } - exports[fe.Src] = fe.Src - if item.Rename != "" { - exports[fe.Src] = item.Rename + filepath.Ext(fe.Src) - } - } - } - - store, err := f.Store(ctx) - if err != nil { - return 0, err - } - if f.Storage() != consts.STORE_LOCAL { - var remoteExports = make(map[string]string) - for src, rename := range exports { - path := dir + "/" + rename - if util.IsExistFile(path) { - continue - } - - fd, err := os.Create(path) - if err != nil { - ctx.Logger().Errorw("msg", "create file err", "path", path, "err", err.Error()) - continue - } - - reader, err := store.Get(src) - if err != nil { - ctx.Logger().Errorw("msg", "get remote file error", "path", path, "err", err.Error()) - continue - } - - if _, err := io.Copy(fd, reader); err != nil { - ctx.Logger().Errorw("msg", "save remote file error", "path", path, "download err", err.Error()) - continue - } - - remoteExports[path] = rename + filepath.Ext(path) - } - exports = remoteExports - } else { - var localExports = make(map[string]string) - for src, rename := range exports { - path := strings.ReplaceAll(f.conf.Storage.LocalDir+"/"+src, "//", "/") - localExports[path] = rename - } - exports = localExports - } - if err := util.ZipFiles(in.Name, exports); err != nil { - return 0, err - } - - stat, err := os.Stat(in.Name) - if err != nil { - return 0, err - } - return stat.Size(), nil -} - -// ExportExcel 导出指定的数据列表为excel -func (f *Factory) ExportExcel(ctx kratosx.Context, in *export.AddExportExcelRequest) (int64, error) { - if util.IsExistFile(in.Name) { - _ = os.Chtimes(in.Name, time.Now(), time.Now()) - stat, err := os.Stat(in.Name) - if err != nil { - return 0, err - } - return stat.Size(), nil - } - dir := f.conf.Export.LocalDir - if !util.IsExistFolder(dir) { - if err := os.MkdirAll(dir, os.ModePerm); err != nil { - return 0, err - } - } - - store, err := f.Store(ctx) - if err != nil { - return 0, err - } - - xlsxFile := xlsx.New(in.Name).Writer() - for _, list := range in.Rows { - var temp []any - for _, item := range list { - switch item.Type { - case "image": - if item.Value == "" { - continue - } - fe, err := f.fileRepo.GetFileBySha(ctx.Clone(), item.Value) - if err != nil { - ctx.Logger().Errorw("msg", "get file error", "err", err.Error()) - continue - } - if f.Storage() != consts.STORE_LOCAL { - path := dir + "/" + fe.Src - if util.IsExistFile(path) { - if fd, err := os.Open(path); err == nil { - temp = append(temp, fd) - continue - } - } - - fd, err := os.Create(path) - if err != nil { - ctx.Logger().Errorw("path", path, "create file err", err.Error()) - continue - } - - reader, err := store.Get(fe.Src) - if err != nil { - ctx.Logger().Errorw("path", path, "get err", err.Error()) - continue - } - - if _, err := io.Copy(fd, reader); err != nil { - ctx.Logger().Errorw("path", path, "download err", err.Error()) - continue - } - temp = append(temp, fd) - } else { - path := strings.ReplaceAll(f.conf.Storage.LocalDir+"/"+fe.Src, "//", "/") - fd, err := os.Open(path) - if err != nil { - ctx.Logger().Errorw("path", path, "download err", err.Error()) - continue - } - temp = append(temp, fd) - } - - default: - temp = append(temp, item.Value) - } - } - if err := xlsxFile.WriteRow(temp); err != nil { - ctx.Logger().Errorw("msg", "write xlsx row error", "err", err.Error()) - } - } - - if err := xlsxFile.Save(); err != nil { - return 0, err - } - stat, err := os.Stat(in.Name) - if err != nil { - return 0, err - } - return stat.Size(), nil -} - -func (f *Factory) ClearExportCache() { - dir := f.conf.Export.LocalDir - if !util.IsExistFolder(dir) { - return - } - _ = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if path == dir { - return nil - } - if err != nil { - return err - } - d := time.Since(info.ModTime()) - if d.Seconds() >= f.conf.Export.Expire.Seconds() { - _ = os.RemoveAll(path) - } - return err - }) - _ = f.exportRepo.UpdateExportExpire( - kratosx.MustContext(context.Background()), - time.Now().Unix()-int64(f.conf.Export.Expire.Seconds()), - ) -} diff --git a/internal/pkg/image/image.go b/internal/pkg/image/image.go index 36be19c..ee8adbb 100644 --- a/internal/pkg/image/image.go +++ b/internal/pkg/image/image.go @@ -9,9 +9,8 @@ import ( "image/png" "strings" - "golang.org/x/image/bmp" - "github.com/nfnt/resize" + "golang.org/x/image/bmp" ) const ( diff --git a/internal/pkg/store/aliyun/store.go b/internal/pkg/store/aliyun/store.go index 26d1158..9088096 100644 --- a/internal/pkg/store/aliyun/store.go +++ b/internal/pkg/store/aliyun/store.go @@ -2,17 +2,26 @@ package aliyun import ( "bytes" + "context" + "crypto/md5" "errors" + "fmt" "io" "strconv" + "time" "github.com/aliyun/aliyun-oss-go-sdk/oss" + "github.com/go-redis/redis/v8" + "github.com/limes-cloud/kratosx/pkg/lock" - store2 "github.com/limes-cloud/resource/internal/pkg/store" + "github.com/limes-cloud/resource/internal/pkg/store" ) type aliyun struct { bucket *oss.Bucket + expire time.Duration + cache *redis.Client + cdn string } type upload struct { @@ -20,12 +29,12 @@ type upload struct { upload oss.InitiateMultipartUploadResult } -func New(conf *store2.Config) (store2.Store, error) { - if conf.Endpoint == "" || conf.Key == "" || conf.Secret == "" { +func New(conf *store.Config) (store.Store, error) { + if conf.Endpoint == "" || conf.Id == "" || conf.Secret == "" { return nil, errors.New("store config error") } - client, err := oss.New(conf.Endpoint, conf.Key, conf.Secret) + client, err := oss.New(conf.Endpoint, conf.Id, conf.Secret) if err != nil { return nil, err } @@ -37,9 +46,46 @@ func New(conf *store2.Config) (store2.Store, error) { return &aliyun{ bucket: bucket, + expire: conf.TemporaryExpire, + cache: conf.Cache, + cdn: conf.ServerURL, }, nil } +func (s *aliyun) GenTemporaryURL(key string) (string, error) { + var ( + err error + target string + locker = lock.New(s.cache, key+":lock") + ) + ck := fmt.Sprintf("resource:%x", md5.Sum([]byte(key))) + err = locker.AcquireFunc(context.Background(), + func() error { + target, err = s.cache.Get(context.Background(), ck).Result() + return err + }, + func() error { + t := time.Now().Add(s.expire).Format("200601021504") + st := s.bucket.Client.Config.AccessKeySecret + t + "/" + key + target = fmt.Sprintf("%s/%s/%s/%s", + s.cdn, + t, + fmt.Sprintf("%x", md5.Sum([]byte(st))), + key, + ) + return s.cache.Set(context.Background(), ck, target, s.expire-10*time.Second).Err() + }, + ) + if err != nil { + return "", err + } + return target, nil +} + +func (s *aliyun) VerifyTemporaryURL(key string, expire string, sign string) error { + return nil +} + func (s *aliyun) PutBytes(key string, in []byte) error { return s.bucket.PutObject(key, bytes.NewReader(in)) } @@ -74,7 +120,7 @@ func (s *aliyun) Exists(key string) (bool, error) { return s.bucket.IsObjectExist(key) } -func (s *aliyun) NewPutChunk(key string) (store2.PutChunk, error) { +func (s *aliyun) NewPutChunk(key string) (store.PutChunk, error) { up, err := s.bucket.InitiateMultipartUpload(key) if err != nil { return nil, err @@ -85,7 +131,7 @@ func (s *aliyun) NewPutChunk(key string) (store2.PutChunk, error) { }, nil } -func (s *aliyun) NewPutChunkByUploadID(key, id string) (store2.PutChunk, error) { +func (s *aliyun) NewPutChunkByUploadID(key, id string) (store.PutChunk, error) { up := oss.InitiateMultipartUploadResult{ XMLName: struct{ Space, Local string }{Space: "", Local: "InitiateMultipartUploadResult"}, UploadID: id, @@ -98,11 +144,11 @@ func (s *aliyun) NewPutChunkByUploadID(key, id string) (store2.PutChunk, error) }, nil } -func (u *upload) UploadedChunkIndex() []int { - var arr []int +func (u *upload) UploadedChunkIndex() []uint32 { + var arr []uint32 lsRes, _ := u.bucket.ListUploadedParts(u.upload) for _, item := range lsRes.UploadedParts { - arr = append(arr, item.PartNumber) + arr = append(arr, uint32(item.PartNumber)) } return arr } diff --git a/internal/pkg/store/config.go b/internal/pkg/store/config.go index 027f20d..28de19f 100644 --- a/internal/pkg/store/config.go +++ b/internal/pkg/store/config.go @@ -1,12 +1,20 @@ package store -import "gorm.io/gorm" +import ( + "time" + + "github.com/go-redis/redis/v8" + "gorm.io/gorm" +) type Config struct { - Endpoint string - Key string - Secret string - Bucket string - LocalDir string - DB *gorm.DB + Endpoint string + Id string + Secret string + Bucket string + DB *gorm.DB + Cache *redis.Client + LocalDir string + ServerURL string + TemporaryExpire time.Duration } diff --git a/internal/pkg/store/local/store.go b/internal/pkg/store/local/store.go index bf8f908..193e9a3 100644 --- a/internal/pkg/store/local/store.go +++ b/internal/pkg/store/local/store.go @@ -2,22 +2,32 @@ package local import ( "bytes" + "context" + "crypto/md5" "errors" + "fmt" "io" "os" "strings" + "time" "unsafe" + "github.com/go-redis/redis/v8" "github.com/google/uuid" - "github.com/limes-cloud/kratosx/pkg/util" + "github.com/limes-cloud/kratosx/pkg/crypto" + "github.com/limes-cloud/kratosx/pkg/lock" "gorm.io/gorm" - store2 "github.com/limes-cloud/resource/internal/pkg/store" + "github.com/limes-cloud/resource/internal/pkg/store" ) type local struct { - dir string - db *gorm.DB + dir string + db *gorm.DB + secret string + cache *redis.Client + expire time.Duration + url string } type upload struct { @@ -26,16 +36,68 @@ type upload struct { local *local } -func New(conf *store2.Config) (store2.Store, error) { - if conf.LocalDir == "" { - return nil, errors.New("upload config error") - } +func New(conf *store.Config) (store.Store, error) { return &local{ - dir: conf.LocalDir, - db: conf.DB, + dir: conf.LocalDir, + db: conf.DB, + secret: conf.Secret, + expire: conf.TemporaryExpire, + cache: conf.Cache, + url: conf.ServerURL, }, nil } +func (s *local) GenTemporaryURL(key string) (string, error) { + var ( + err error + target string + locker = lock.New(s.cache, key+":lock") + ) + ck := fmt.Sprintf("resource:%x", md5.Sum([]byte(key))) + err = locker.AcquireFunc(context.Background(), + func() error { + target, err = s.cache.Get(context.Background(), ck).Result() + return err + }, + func() error { + t := time.Now().Add(s.expire).Format("200601021504") + st := s.secret + t + "/" + key + target = fmt.Sprintf("%s/%s/%s/%s", + s.url, + t, + fmt.Sprintf("%x", md5.Sum([]byte(st))), + key, + ) + return s.cache.Set(context.Background(), ck, target, s.expire-10*time.Second).Err() + }, + ) + if err != nil { + return "", err + } + return target, nil +} + +func (s *local) VerifyTemporaryURL(key string, expire string, sign string) error { + t, err := time.Parse("200601021504", expire) + if err != nil { + return err + } + + // 校验时间 + if time.Now().Unix() > t.Unix() { + return errors.New("url is expire") + } + + // 重新计算签名 + st := s.secret + expire + "/" + key + oriSign := fmt.Sprintf("%x", md5.Sum([]byte(st))) + if oriSign != sign { + return errors.New("sign is invoke") + } + + return nil +} + func (s *local) PutBytes(key string, in []byte) error { return s.Put(key, bytes.NewReader(in)) } @@ -105,7 +167,7 @@ func (s *local) makeDir(path string) error { return nil } -func (s *local) NewPutChunk(key string) (store2.PutChunk, error) { +func (s *local) NewPutChunk(key string) (store.PutChunk, error) { return &upload{ uuid: uuid.NewString(), local: s, @@ -113,7 +175,7 @@ func (s *local) NewPutChunk(key string) (store2.PutChunk, error) { }, nil } -func (s *local) NewPutChunkByUploadID(key, id string) (store2.PutChunk, error) { +func (s *local) NewPutChunkByUploadID(key, id string) (store.PutChunk, error) { return &upload{ uuid: id, local: s, @@ -127,12 +189,12 @@ func (u *upload) ChunkCount() int { return len(chunks) } -func (u *upload) UploadedChunkIndex() []int { - var arr []int +func (u *upload) UploadedChunkIndex() []uint32 { + var arr []uint32 chunk := Chunk{} chunks, _ := chunk.Parts(u.local.db, u.uuid) for _, item := range chunks { - arr = append(arr, item.Index) + arr = append(arr, uint32(item.Index)) } return arr } @@ -147,7 +209,7 @@ func (u *upload) Append(r io.Reader, index int) error { return err } - sha := util.Sha256(all) + sha := crypto.Sha256(all) oldChunk := Chunk{} // 查询是否已经存在数据 @@ -158,7 +220,7 @@ func (u *upload) Append(r io.Reader, index int) error { chunk := Chunk{ UploadID: u.uuid, Index: index, - Sha: util.Sha256(all), + Sha: crypto.Sha256(all), Size: len(all), Data: *(*string)(unsafe.Pointer(&all)), } @@ -171,7 +233,7 @@ func (u *upload) AppendBytes(r []byte, index int) error { UploadID: u.uuid, Index: index, Size: len(r), - Sha: util.Sha256(r), + Sha: crypto.Sha256(r), Data: *(*string)(unsafe.Pointer(&r)), } diff --git a/internal/pkg/store/tencent/store.go b/internal/pkg/store/tencent/store.go index b7d7722..29ca915 100644 --- a/internal/pkg/store/tencent/store.go +++ b/internal/pkg/store/tencent/store.go @@ -3,18 +3,26 @@ package tencent import ( "bytes" "context" + "crypto/md5" "errors" + "fmt" "io" "net/http" "net/url" + "time" + "github.com/go-redis/redis/v8" + "github.com/limes-cloud/kratosx/pkg/lock" "github.com/tencentyun/cos-go-sdk-v5" - store2 "github.com/limes-cloud/resource/internal/pkg/store" + "github.com/limes-cloud/resource/internal/pkg/store" ) type tencent struct { client *cos.Client + expire time.Duration + cache *redis.Client + cdn string } type upload struct { @@ -22,8 +30,8 @@ type upload struct { upload *cos.InitiateMultipartUploadResult } -func New(conf *store2.Config) (store2.Store, error) { - if conf.Endpoint == "" || conf.Secret == "" || conf.Key == "" { +func New(conf *store.Config) (store.Store, error) { + if conf.Endpoint == "" || conf.Secret == "" || conf.Id == "" { return nil, errors.New("upload config error") } @@ -35,12 +43,46 @@ func New(conf *store2.Config) (store2.Store, error) { b := &cos.BaseURL{BucketURL: u} client := cos.NewClient(b, &http.Client{ Transport: &cos.AuthorizationTransport{ - SecretID: conf.Secret, - SecretKey: conf.Key, + SecretID: conf.Id, + SecretKey: conf.Secret, }, }) - return &tencent{client: client}, nil + return &tencent{client: client, expire: conf.TemporaryExpire, cache: conf.Cache, cdn: conf.ServerURL}, nil +} + +func (s *tencent) GenTemporaryURL(key string) (string, error) { + var ( + err error + target string + locker = lock.New(s.cache, key+":lock") + ) + ck := fmt.Sprintf("resource:%x", md5.Sum([]byte(key))) + err = locker.AcquireFunc(context.Background(), + func() error { + target, err = s.cache.Get(context.Background(), ck).Result() + return err + }, + func() error { + t := time.Now().Add(s.expire).Format("200601021504") + st := s.client.GetCredential().GetSecretKey() + t + "/" + key + target = fmt.Sprintf("%s/%s/%s/%s", + s.cdn, + t, + fmt.Sprintf("%x", md5.Sum([]byte(st))), + key, + ) + return s.cache.Set(context.Background(), ck, target, s.expire-10*time.Second).Err() + }, + ) + if err != nil { + return "", err + } + return target, nil +} + +func (s *tencent) VerifyTemporaryURL(key string, expire string, sign string) error { + return nil } func (s *tencent) PutBytes(key string, in []byte) error { @@ -113,7 +155,7 @@ func httpError(response *cos.Response) error { return errors.New(string(bt)) } -func (s *tencent) NewPutChunk(key string) (store2.PutChunk, error) { +func (s *tencent) NewPutChunk(key string) (store.PutChunk, error) { up, _, err := s.client.Object.InitiateMultipartUpload(context.Background(), key, nil) if err != nil { return nil, err @@ -124,7 +166,7 @@ func (s *tencent) NewPutChunk(key string) (store2.PutChunk, error) { }, nil } -func (s *tencent) NewPutChunkByUploadID(key, id string) (store2.PutChunk, error) { +func (s *tencent) NewPutChunkByUploadID(key, id string) (store.PutChunk, error) { bucket, _, err := s.client.Bucket.Get(context.Background(), nil) if err != nil { return nil, err @@ -142,11 +184,11 @@ func (s *tencent) NewPutChunkByUploadID(key, id string) (store2.PutChunk, error) }, nil } -func (u *upload) UploadedChunkIndex() []int { - var arr []int +func (u *upload) UploadedChunkIndex() []uint32 { + var arr []uint32 lsRes, _, _ := u.client.Object.ListParts(context.Background(), u.upload.Key, u.upload.UploadID, nil) for _, item := range lsRes.Parts { - arr = append(arr, item.PartNumber) + arr = append(arr, uint32(item.PartNumber)) } return arr } diff --git a/internal/pkg/store/types.go b/internal/pkg/store/types.go index 9721609..47eded9 100644 --- a/internal/pkg/store/types.go +++ b/internal/pkg/store/types.go @@ -2,40 +2,66 @@ package store import "io" +const ( + STORE_ALIYUN = "aliyun" + STORE_TENCENT = "tencent" + STORE_LOCAL = "local" +) + type Store interface { + // GenTemporaryURL 生成临时访问路径 + GenTemporaryURL(key string) (string, error) + + // VerifyTemporaryURL 验证临时url + VerifyTemporaryURL(key string, expire string, sign string) error + // PutBytes 上传文件 PutBytes(key string, in []byte) error + // Put 上传文件 Put(key string, r io.Reader) error + // PutFromLocal 从本地上传文件 PutFromLocal(key string, localPath string) error + // Get 查询文件 Get(key string) (io.ReadCloser, error) + // Delete 删除文件 Delete(key string) error + // Size 获取文件大小 Size(key string) (int64, error) + // Exists 判断文件大小 Exists(key string) (bool, error) + // NewPutChunk 创建上传切片对象 NewPutChunk(key string) (PutChunk, error) + // NewPutChunkByUploadID 通过upload_id创建切片对象 NewPutChunkByUploadID(key string, id string) (PutChunk, error) } type PutChunk interface { // UploadedChunkIndex 已经上传的切片下标 - UploadedChunkIndex() []int + UploadedChunkIndex() []uint32 + // ChunkCount 查询切片数量 ChunkCount() int + // UploadID 获取上传id UploadID() string + // AppendBytes 添加字节 AppendBytes(in []byte, index int) error + // Append 添加io Append(r io.Reader, index int) error + // Abort 取消上传 Abort() error + // Complete 完成合并 Complete() error } diff --git a/internal/pkg/util/util.go b/internal/pkg/util/util.go new file mode 100644 index 0000000..6ca6d11 --- /dev/null +++ b/internal/pkg/util/util.go @@ -0,0 +1,19 @@ +package util + +import ( + "strings" +) + +// GetFileType 获取文件类型 +func GetFileType(name string) string { + index := strings.LastIndex(name, ".") + suffix := "" + if index != -1 { + suffix = name[index+1:] + } + return suffix +} + +func GetKBSize(mSize uint32) uint32 { + return mSize * 1024 +} diff --git a/internal/router/router.go b/internal/router/router.go deleted file mode 100644 index e83bf0d..0000000 --- a/internal/router/router.go +++ /dev/null @@ -1,16 +0,0 @@ -package router - -import ( - "github.com/go-kratos/kratos/v2/transport/http" - - "github.com/limes-cloud/resource/internal/service" -) - -func Register(hs *http.Server, fileSrv *service.FileService) { - cr := hs.Route("/") - cr.GET("/resource/v1/static/export/{src}", SrcBlob(fileSrv)) - cr.GET("/resource/v1/static/{src}", SrcBlob(fileSrv)) - cr.POST("/resource/v1/upload", Upload(fileSrv)) - cr.POST("/resource/client/v1/upload", Upload(fileSrv)) - // cr.GET("/resource/v1/download", Download(fileSrv)) -} diff --git a/internal/router/upload.go b/internal/router/upload.go deleted file mode 100644 index 601b82a..0000000 --- a/internal/router/upload.go +++ /dev/null @@ -1,46 +0,0 @@ -package router - -import ( - "context" - "io" - - "github.com/go-kratos/kratos/v2/transport/http" - "github.com/limes-cloud/kratosx/pkg/util" - - "github.com/limes-cloud/resource/api/errors" - pb "github.com/limes-cloud/resource/api/file/v1" - "github.com/limes-cloud/resource/internal/service" -) - -func Upload(srv *service.FileService) http.HandlerFunc { - return func(ctx http.Context) error { - var in pb.UploadFileRequest - - in.UploadId = ctx.Request().FormValue("upload_id") - in.Index = util.ToUint32(ctx.Request().FormValue("index")) - file, _, err := ctx.Request().FormFile("data") - if err != nil { - return errors.UploadFileFormat(err.Error()) - } - - in.Data, err = io.ReadAll(file) - if err != nil { - return errors.UploadFileFormat(err.Error()) - } - - if in.UploadId == "" || int(in.Index) <= 0 || len(in.Data) == 0 { - return errors.UploadFileFormat("参数缺失") - } - - h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { - return srv.UploadFile(ctx, req.(*pb.UploadFileRequest)) - }) - - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*pb.UploadFileReply) - return ctx.Result(200, reply) - } -} diff --git a/internal/router/blob.go b/internal/service/blob.go similarity index 51% rename from internal/router/blob.go rename to internal/service/blob.go index fe54849..43de204 100644 --- a/internal/router/blob.go +++ b/internal/service/blob.go @@ -1,4 +1,4 @@ -package router +package service import ( "bytes" @@ -10,10 +10,9 @@ import ( thttp "github.com/go-kratos/kratos/v2/transport/http" - "github.com/limes-cloud/resource/api/errors" - pb "github.com/limes-cloud/resource/api/file/v1" + "github.com/limes-cloud/resource/api/resource/errors" + pb "github.com/limes-cloud/resource/api/resource/file/v1" "github.com/limes-cloud/resource/internal/pkg/image" - "github.com/limes-cloud/resource/internal/service" ) type ResponseWriterWrapper struct { @@ -42,32 +41,45 @@ func (w *ResponseWriterWrapper) WriteString(s string) (int, error) { return w.body.WriteString(s) } -func SrcBlob(srv *service.FileService) thttp.HandlerFunc { +func (s *FileService) LocalPath(next http.Handler, src string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + r.URL.Path = src + next.ServeHTTP(w, r) + }) +} + +func (s *FileService) SrcBlob() thttp.HandlerFunc { return func(ctx thttp.Context) error { - var in pb.GetFileRequest - if err := ctx.BindQuery(&in); err != nil { + var req pb.StaticFileRequest + if err := ctx.BindQuery(&req); err != nil { return err } - if err := ctx.BindVars(&in); err != nil { + if err := ctx.BindVars(&req); err != nil { + return err + } + + if err := s.uc.VerifyURL(req.Src, req.Expire, req.Sign); err != nil { return err } blw := NewWriter() - fs := http.FileServer(http.Dir(srv.Config().Storage.LocalDir)) - fs = http.StripPrefix(srv.Config().Storage.ServerPath, fs) + fs := http.FileServer(http.Dir(s.conf.Storage.LocalDir)) + fs = s.LocalPath(fs, req.Src) fs.ServeHTTP(blw, ctx.Request()) + // http.Redirect(w, r, "https://taadis.com", http.StatusMovedPermanently) + // 处理图片裁剪 cType := blw.header.Get("Content-Type") - if strings.Contains(cType, "image/") && in.Width > 0 && in.Height > 0 { + if strings.Contains(cType, "image/") && req.Width > 0 && req.Height > 0 { blw.header.Del("Content-Length") tp := strings.Split(cType, "/")[1] rb := blw.body.Bytes() if img, err := image.New(tp, rb); err == nil { - if in.Mode == "" { - in.Mode = image.AspectFill + if req.Mode == "" { + req.Mode = image.AspectFill } - if nrb, err := img.Resize(int(in.Width), int(in.Height), in.Mode); err == nil { + if nrb, err := img.Resize(int(req.Width), int(req.Height), req.Mode); err == nil { blw.body = bytes.NewBuffer(nrb) blw.header.Set("Content-Length", strconv.Itoa(len(nrb))) } @@ -80,10 +92,10 @@ func SrcBlob(srv *service.FileService) thttp.HandlerFunc { header.Set(key, blw.header.Get(key)) } - if in.Download { - fn := in.Src - if in.SaveName != "" { - fn = in.SaveName + filepath.Ext(in.Src) + if req.Download { + fn := req.Src + if req.SaveName != "" { + fn = req.SaveName + filepath.Ext(req.Src) } header.Set("Content-Type", "application/octet-stream") header.Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", fn)) @@ -91,37 +103,9 @@ func SrcBlob(srv *service.FileService) thttp.HandlerFunc { ctx.Response().WriteHeader(blw.code) if _, err := ctx.Response().Write(blw.body.Bytes()); err != nil { - return errors.System() + return errors.SystemError() } return nil } } - -// func SrcBlob(srv *service.FileService) http.HandlerFunc { -// return func(ctx http.Context) error { -// var in pb.GetFileRequest -// if err := ctx.BindQuery(&in); err != nil { -// return err -// } -// if err := ctx.BindVars(&in); err != nil { -// return err -// } -// -// h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { -// return srv.GetFile(ctx, req.(*pb.GetFileRequest)) -// }) -// out, err := h(ctx, &in) -// if err != nil { -// return err -// } -// reply := out.(*pb.GetFileReply) -// header := ctx.Response().Header() -// header.Set("Content-Length", fmt.Sprint(len(reply.Data))) -// if in.IsRange { -// header.Set("Content-Range", fmt.Sprintf("bytes %d-%d", in.Start, in.End)) -// } -// -// return ctx.Blob(200, reply.Mime, reply.Data) -// } -// } diff --git a/internal/service/directory.go b/internal/service/directory.go new file mode 100755 index 0000000..2fd3729 --- /dev/null +++ b/internal/service/directory.go @@ -0,0 +1,132 @@ +package service + +import ( + "context" + "github.com/go-kratos/kratos/v2/transport/grpc" + "github.com/go-kratos/kratos/v2/transport/http" + "github.com/limes-cloud/kratosx" + "github.com/limes-cloud/kratosx/pkg/valx" + pb "github.com/limes-cloud/resource/api/resource/directory/v1" + "github.com/limes-cloud/resource/api/resource/errors" + "github.com/limes-cloud/resource/internal/biz/directory" + "github.com/limes-cloud/resource/internal/conf" + "github.com/limes-cloud/resource/internal/data" +) + +type DirectoryService struct { + pb.UnimplementedDirectoryServer + uc *directory.UseCase +} + +func NewDirectoryService(conf *conf.Config) *DirectoryService { + return &DirectoryService{ + uc: directory.NewUseCase(conf, data.NewDirectoryRepo()), + } +} + +func init() { + register(func(c *conf.Config, hs *http.Server, gs *grpc.Server) { + srv := NewDirectoryService(c) + pb.RegisterDirectoryHTTPServer(hs, srv) + pb.RegisterDirectoryServer(gs, srv) + }) +} + +// GetDirectory 获取指定的文件目录信息 +func (s *DirectoryService) GetDirectory(c context.Context, req *pb.GetDirectoryRequest) (*pb.GetDirectoryReply, error) { + var ( + in = directory.GetDirectoryRequest{} + ctx = kratosx.MustContext(c) + ) + + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() + } + + result, err := s.uc.GetDirectory(ctx, &in) + if err != nil { + return nil, err + } + + reply := pb.GetDirectoryReply{} + if err := valx.Transform(result, &reply); err != nil { + ctx.Logger().Warnw("msg", "reply transform err", "err", err.Error()) + return nil, errors.TransformError() + } + return &reply, nil +} + +// ListDirectory 获取文件目录信息列表 +func (s *DirectoryService) ListDirectory(c context.Context, req *pb.ListDirectoryRequest) (*pb.ListDirectoryReply, error) { + var ( + in = directory.ListDirectoryRequest{} + ctx = kratosx.MustContext(c) + ) + + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() + } + + result, total, err := s.uc.ListDirectory(ctx, &in) + if err != nil { + return nil, err + } + + reply := pb.ListDirectoryReply{Total: total} + if err := valx.Transform(result, &reply.List); err != nil { + ctx.Logger().Warnw("msg", "reply transform err", "err", err.Error()) + return nil, errors.TransformError() + } + + return &reply, nil +} + +// CreateDirectory 创建文件目录信息 +func (s *DirectoryService) CreateDirectory(c context.Context, req *pb.CreateDirectoryRequest) (*pb.CreateDirectoryReply, error) { + var ( + in = directory.Directory{} + ctx = kratosx.MustContext(c) + ) + + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() + } + + id, err := s.uc.CreateDirectory(ctx, &in) + if err != nil { + return nil, err + } + + return &pb.CreateDirectoryReply{Id: id}, nil +} + +// UpdateDirectory 更新文件目录信息 +func (s *DirectoryService) UpdateDirectory(c context.Context, req *pb.UpdateDirectoryRequest) (*pb.UpdateDirectoryReply, error) { + var ( + in = directory.Directory{} + ctx = kratosx.MustContext(c) + ) + + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() + } + + if err := s.uc.UpdateDirectory(ctx, &in); err != nil { + return nil, err + } + + return &pb.UpdateDirectoryReply{}, nil +} + +// DeleteDirectory 删除文件目录信息 +func (s *DirectoryService) DeleteDirectory(c context.Context, req *pb.DeleteDirectoryRequest) (*pb.DeleteDirectoryReply, error) { + total, err := s.uc.DeleteDirectory(kratosx.MustContext(c), req.Ids) + if err != nil { + return nil, err + } + return &pb.DeleteDirectoryReply{Total: total}, nil +} diff --git a/internal/service/entrance.go b/internal/service/entrance.go new file mode 100755 index 0000000..932c9e0 --- /dev/null +++ b/internal/service/entrance.go @@ -0,0 +1,22 @@ +package service + +import ( + "github.com/go-kratos/kratos/v2/transport/grpc" + "github.com/go-kratos/kratos/v2/transport/http" + + "github.com/limes-cloud/resource/internal/conf" +) + +type registryFunc func(c *conf.Config, hs *http.Server, gs *grpc.Server) + +var registries []registryFunc + +func register(fn registryFunc) { + registries = append(registries, fn) +} + +func New(c *conf.Config, hs *http.Server, gs *grpc.Server) { + for _, registry := range registries { + registry(c, hs, gs) + } +} diff --git a/internal/service/export.go b/internal/service/export.go new file mode 100755 index 0000000..fb76f3d --- /dev/null +++ b/internal/service/export.go @@ -0,0 +1,88 @@ +package service + +import ( + "context" + "github.com/go-kratos/kratos/v2/transport/grpc" + "github.com/go-kratos/kratos/v2/transport/http" + "github.com/limes-cloud/kratosx" + "github.com/limes-cloud/kratosx/pkg/valx" + "github.com/limes-cloud/resource/api/resource/errors" + pb "github.com/limes-cloud/resource/api/resource/export/v1" + "github.com/limes-cloud/resource/internal/biz/export" + "github.com/limes-cloud/resource/internal/conf" + "github.com/limes-cloud/resource/internal/data" +) + +type ExportService struct { + pb.UnimplementedExportServer + uc *export.UseCase +} + +func NewExportService(conf *conf.Config) *ExportService { + return &ExportService{ + uc: export.NewUseCase(conf, data.NewExportRepo()), + } +} + +func init() { + register(func(c *conf.Config, hs *http.Server, gs *grpc.Server) { + srv := NewExportService(c) + pb.RegisterExportHTTPServer(hs, srv) + pb.RegisterExportServer(gs, srv) + }) +} + +// ListExport 获取导出信息列表 +func (s *ExportService) ListExport(c context.Context, req *pb.ListExportRequest) (*pb.ListExportReply, error) { + var ( + in = export.ListExportRequest{} + ctx = kratosx.MustContext(c) + ) + + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() + } + + result, total, err := s.uc.ListExport(ctx, &in) + if err != nil { + return nil, err + } + + reply := pb.ListExportReply{Total: total} + if err := valx.Transform(result, &reply.List); err != nil { + ctx.Logger().Warnw("msg", "reply transform err", "err", err.Error()) + return nil, errors.TransformError() + } + + return &reply, nil +} + +// CreateExport 创建导出信息 +func (s *ExportService) CreateExport(c context.Context, req *pb.CreateExportRequest) (*pb.CreateExportReply, error) { + var ( + in = export.Export{} + ctx = kratosx.MustContext(c) + ) + + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() + } + + id, err := s.uc.CreateExport(ctx, &in) + if err != nil { + return nil, err + } + + return &pb.CreateExportReply{Id: id}, nil +} + +// DeleteExport 删除导出信息 +func (s *ExportService) DeleteExport(c context.Context, req *pb.DeleteExportRequest) (*pb.DeleteExportReply, error) { + total, err := s.uc.DeleteExport(kratosx.MustContext(c), req.Ids) + if err != nil { + return nil, err + } + return &pb.DeleteExportReply{Total: total}, nil +} diff --git a/internal/service/exports.go b/internal/service/exports.go deleted file mode 100644 index a169ff6..0000000 --- a/internal/service/exports.go +++ /dev/null @@ -1,99 +0,0 @@ -package service - -import ( - "context" - - "github.com/golang/protobuf/ptypes/empty" - "github.com/limes-cloud/kratosx" - "github.com/limes-cloud/kratosx/pkg/util" - - "github.com/limes-cloud/resource/api/errors" - pb "github.com/limes-cloud/resource/api/export/v1" - biz "github.com/limes-cloud/resource/internal/biz/export" - "github.com/limes-cloud/resource/internal/config" - data "github.com/limes-cloud/resource/internal/data/export" - "github.com/limes-cloud/resource/internal/data/file" - "github.com/limes-cloud/resource/internal/factory" -) - -type ExportService struct { - pb.UnimplementedServiceServer - uc *biz.UseCase - conf *config.Config -} - -func NewExport(conf *config.Config) *ExportService { - return &ExportService{ - conf: conf, - uc: biz.NewUseCase(conf, data.NewRepo(), factory.New(conf, file.NewRepo(), data.NewRepo())), - } -} - -func (fs *ExportService) Config() *config.Config { - return fs.conf -} - -// PageExport 文件分野查询 -func (fs *ExportService) PageExport(ctx context.Context, in *pb.PageExportRequest) (*pb.PageExportReply, error) { - req := biz.PageExportRequest{} - if err := util.Transform(in, &req); err != nil { - return nil, errors.TransformFormat(err.Error()) - } - - list, total, err := fs.uc.PageExport(kratosx.MustContext(ctx), &req) - if err != nil { - return nil, err - } - - reply := pb.PageExportReply{Total: &total} - if err := util.Transform(list, &reply.List); err != nil { - return nil, errors.TransformFormat(err.Error()) - } - return &reply, nil -} - -// AddExport 删除文件 -func (fs *ExportService) AddExport(ctx context.Context, in *pb.AddExportRequest) (*pb.AddExportReply, error) { - if len(in.Ids) == 0 && len(in.Files) == 0 { - return nil, errors.Params() - } - req := biz.AddExportRequest{} - if err := util.Transform(in, &req); err != nil { - return nil, errors.TransformFormat(err.Error()) - } - id, err := fs.uc.AddExport(kratosx.MustContext(ctx), &req) - if err != nil { - return nil, err - } - return &pb.AddExportReply{ - Id: id, - }, nil -} - -// AddExportExcel 删除文件 -func (fs *ExportService) AddExportExcel(ctx context.Context, in *pb.AddExportExcelRequest) (*pb.AddExportExcelReply, error) { - req := biz.AddExportExcelRequest{Name: in.Name} - for _, row := range in.Rows { - var temp []*biz.ExportExcel - for _, col := range row.Cols { - temp = append(temp, &biz.ExportExcel{ - Type: col.Type, - Value: col.Value, - }) - } - req.Rows = append(req.Rows, temp) - } - - id, err := fs.uc.AddExportExcel(kratosx.MustContext(ctx), &req) - if err != nil { - return nil, err - } - return &pb.AddExportExcelReply{ - Id: id, - }, nil -} - -// DeleteExport 删除文件 -func (fs *ExportService) DeleteExport(ctx context.Context, in *pb.DeleteExportRequest) (*empty.Empty, error) { - return &empty.Empty{}, fs.uc.DeleteExport(kratosx.MustContext(ctx), in.Id) -} diff --git a/internal/service/file.go b/internal/service/file.go old mode 100644 new mode 100755 index 85e0449..8891299 --- a/internal/service/file.go +++ b/internal/service/file.go @@ -3,181 +3,170 @@ package service import ( "context" - "github.com/golang/protobuf/ptypes/empty" + "github.com/go-kratos/kratos/v2/transport/grpc" + "github.com/go-kratos/kratos/v2/transport/http" "github.com/limes-cloud/kratosx" - "github.com/limes-cloud/kratosx/pkg/util" - - "github.com/limes-cloud/resource/api/errors" - pb "github.com/limes-cloud/resource/api/file/v1" - biz "github.com/limes-cloud/resource/internal/biz/file" - "github.com/limes-cloud/resource/internal/config" - "github.com/limes-cloud/resource/internal/data/export" - data "github.com/limes-cloud/resource/internal/data/file" - "github.com/limes-cloud/resource/internal/factory" + "github.com/limes-cloud/kratosx/pkg/valx" + + "github.com/limes-cloud/resource/api/resource/errors" + pb "github.com/limes-cloud/resource/api/resource/file/v1" + "github.com/limes-cloud/resource/internal/biz/file" + "github.com/limes-cloud/resource/internal/conf" + "github.com/limes-cloud/resource/internal/data" ) type FileService struct { - pb.UnimplementedServiceServer - uc *biz.UseCase - conf *config.Config + pb.UnimplementedFileServer + uc *file.UseCase + conf *conf.Config } -func NewFile(conf *config.Config) *FileService { +func NewFileService(conf *conf.Config) *FileService { return &FileService{ + uc: file.NewUseCase(conf, data.NewFileRepo(conf)), conf: conf, - uc: biz.NewUseCase(conf, data.NewRepo(), factory.New(conf, data.NewRepo(), export.NewRepo())), } } -func (fs *FileService) Config() *config.Config { - return fs.conf +func init() { + register(func(c *conf.Config, hs *http.Server, gs *grpc.Server) { + srv := NewFileService(c) + pb.RegisterFileHTTPServer(hs, srv) + pb.RegisterFileServer(gs, srv) + + cr := hs.Route("/") + // cr.GET("/resource/v1/static/export/{src}", srv.SrcBlob()) + cr.GET("/resource/api/v1/static/{expire}/{sign}/{src}", srv.SrcBlob()) + cr.POST("/resource/api/v1/upload", srv.Upload()) + cr.POST("/resource/client/v1/upload", srv.Upload()) + }) } -// AllDirectory 获取目录 -func (fs *FileService) AllDirectory(ctx context.Context, in *pb.AllDirectoryRequest) (*pb.AllDirectoryReply, error) { - list, err := fs.uc.AllDirectoryByParentID(kratosx.MustContext(ctx), in.ParentId, in.App) - if err != nil { - return nil, err - } +// GetFile 获取指定的文件信息 +func (s *FileService) GetFile(c context.Context, req *pb.GetFileRequest) (*pb.GetFileReply, error) { + var ( + in = file.GetFileRequest{} + ctx = kratosx.MustContext(c) + ) - reply := pb.AllDirectoryReply{} - if err := util.Transform(list, &reply.List); err != nil { - return nil, errors.TransformFormat(err.Error()) + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() } - return &reply, nil -} -// AddDirectory 添加目录 -func (fs *FileService) AddDirectory(ctx context.Context, in *pb.AddDirectoryRequest) (*pb.Directory, error) { - req := biz.Directory{} - if err := util.Transform(in, &req); err != nil { - return nil, errors.TransformFormat(err.Error()) - } - id, err := fs.uc.AddDirectory(kratosx.MustContext(ctx), &req) + result, err := s.uc.GetFile(ctx, &in) if err != nil { return nil, err } - req.ID = id - reply := pb.Directory{} - if err := util.Transform(req, &reply); err != nil { - return nil, errors.TransformFormat(err.Error()) - } - return &reply, nil -} - -// UpdateDirectory 更新目录 -func (fs *FileService) UpdateDirectory(ctx context.Context, in *pb.UpdateDirectoryRequest) (*empty.Empty, error) { - req := biz.Directory{} - if err := util.Transform(in, &req); err != nil { - return nil, errors.TransformFormat(err.Error()) + reply := pb.GetFileReply{} + if err := valx.Transform(result, &reply); err != nil { + ctx.Logger().Warnw("msg", "reply transform err", "err", err.Error()) + return nil, errors.TransformError() } - return nil, fs.uc.UpdateDirectory(kratosx.MustContext(ctx), &req) + return &reply, nil } -// DeleteDirectory 删除目录 -func (fs *FileService) DeleteDirectory(ctx context.Context, in *pb.DeleteDirectoryRequest) (*empty.Empty, error) { - return nil, fs.uc.DeleteDirectory(kratosx.MustContext(ctx), in.Id, in.App) -} +// ListFile 获取文件信息列表 +func (s *FileService) ListFile(c context.Context, req *pb.ListFileRequest) (*pb.ListFileReply, error) { + var ( + in = file.ListFileRequest{} + ctx = kratosx.MustContext(c) + ) -// PrepareUploadFile 文件预上传 -func (fs *FileService) PrepareUploadFile(ctx context.Context, in *pb.PrepareUploadFileRequest) (*pb.PrepareUploadFileReply, error) { - req := biz.PrepareUploadFileRequest{} - if err := util.Transform(in, &req); err != nil { - return nil, errors.TransformFormat(err.Error()) + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() } - res, err := fs.uc.PrepareUploadFile(kratosx.MustContext(ctx), &req) + result, total, err := s.uc.ListFile(ctx, &in) if err != nil { return nil, err } - reply := pb.PrepareUploadFileReply{} - if err := util.Transform(res, &reply); err != nil { - return nil, errors.TransformFormat(err.Error()) + reply := pb.ListFileReply{Total: total} + if err := valx.Transform(result, &reply.List); err != nil { + ctx.Logger().Warnw("msg", "reply transform err", "err", err.Error()) + return nil, errors.TransformError() } + return &reply, nil } -// UploadFile 文件上传 -func (fs *FileService) UploadFile(ctx context.Context, in *pb.UploadFileRequest) (*pb.UploadFileReply, error) { - req := biz.UploadFileRequest{} - if err := util.Transform(in, &req); err != nil { - return nil, errors.TransformFormat(err.Error()) - } +// PrepareUploadFile 预上传文件信息 +func (s *FileService) PrepareUploadFile(c context.Context, req *pb.PrepareUploadFileRequest) (*pb.PrepareUploadFileReply, error) { + var ( + in = file.PrepareUploadFileRequest{} + ctx = kratosx.MustContext(c) + ) - res, err := fs.uc.UploadFile(kratosx.MustContext(ctx), &req) - if err != nil { - return nil, err + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() } - reply := pb.UploadFileReply{} - if err := util.Transform(res, &reply); err != nil { - return nil, errors.TransformFormat(err.Error()) + if req.DirectoryPath == nil && req.DirectoryId == nil { + return nil, errors.ParamsError() } - return &reply, nil -} -// GetFileBySha 文件查询 -func (fs *FileService) GetFileBySha(ctx context.Context, in *pb.GetFileByShaRequest) (*pb.File, error) { - res, err := fs.uc.GetFileBySha(kratosx.MustContext(ctx), in.Sha) + res, err := s.uc.PrepareUploadFile(ctx, &in) if err != nil { return nil, err } - reply := pb.File{} - if err := util.Transform(res, &reply); err != nil { - return nil, errors.TransformFormat(err.Error()) - } - return &reply, nil + return &pb.PrepareUploadFileReply{ + Uploaded: res.Uploaded, + Src: res.Src, + ChunkSize: res.ChunkSize, + ChunkCount: res.ChunkCount, + UploadId: res.UploadId, + UploadChunks: res.UploadChunks, + Sha: res.Sha, + Url: res.URL, + }, nil } -// PageFile 文件分野查询 -func (fs *FileService) PageFile(ctx context.Context, in *pb.PageFileRequest) (*pb.PageFileReply, error) { - req := biz.PageFileRequest{} - if err := util.Transform(in, &req); err != nil { - return nil, errors.TransformFormat(err.Error()) - } - - list, total, err := fs.uc.PageFile(kratosx.MustContext(ctx), &req) +// UploadFile 上传文件信息 +func (s *FileService) UploadFile(c context.Context, req *pb.UploadFileRequest) (*pb.UploadFileReply, error) { + reply, err := s.uc.UploadFile(kratosx.MustContext(c), &file.UploadFileRequest{ + UploadId: req.UploadId, + Index: req.Index, + Data: req.Data, + }) if err != nil { return nil, err } + return &pb.UploadFileReply{ + Src: reply.Src, + Sha: reply.Sha, + Url: reply.URL, + }, nil +} - reply := pb.PageFileReply{Total: &total} - if err := util.Transform(list, &reply.List); err != nil { - return nil, errors.TransformFormat(err.Error()) +// UpdateFile 更新文件信息 +func (s *FileService) UpdateFile(c context.Context, req *pb.UpdateFileRequest) (*pb.UpdateFileReply, error) { + var ( + in = file.File{} + ctx = kratosx.MustContext(c) + ) + + if err := valx.Transform(req, &in); err != nil { + ctx.Logger().Warnw("msg", "req transform err", "err", err.Error()) + return nil, errors.TransformError() } - return &reply, nil -} -// UpdateFile 修改文件 -func (fs *FileService) UpdateFile(ctx context.Context, in *pb.UpdateFileRequest) (*empty.Empty, error) { - req := biz.File{} - if err := util.Transform(in, &req); err != nil { - return nil, errors.TransformFormat(err.Error()) + if err := s.uc.UpdateFile(ctx, &in); err != nil { + return nil, err } - return nil, fs.uc.UpdateFile(kratosx.MustContext(ctx), &req) -} -// DeleteFile 删除文件 -func (fs *FileService) DeleteFile(ctx context.Context, in *pb.DeleteFileRequest) (*empty.Empty, error) { - return nil, fs.uc.DeleteFiles(kratosx.MustContext(ctx), in.DirectoryId, in.Ids) + return &pb.UpdateFileReply{}, nil } -// GetFile 获取文件 -func (fs *FileService) GetFile(ctx context.Context, in *pb.GetFileRequest) (*pb.GetFileReply, error) { - req := biz.GetFileRequest{} - if err := util.Transform(in, &req); err != nil { - return nil, errors.TransformFormat(err.Error()) - } - - res, err := fs.uc.GetFile(kratosx.MustContext(ctx), &req) +// DeleteFile 删除文件信息 +func (s *FileService) DeleteFile(c context.Context, req *pb.DeleteFileRequest) (*pb.DeleteFileReply, error) { + total, err := s.uc.DeleteFile(kratosx.MustContext(c), req.Ids) if err != nil { return nil, err } - return &pb.GetFileReply{ - Data: res.Data, - Mime: res.Mime, - }, nil + return &pb.DeleteFileReply{Total: total}, nil } diff --git a/internal/service/service.go b/internal/service/service.go deleted file mode 100644 index 4cf8276..0000000 --- a/internal/service/service.go +++ /dev/null @@ -1,23 +0,0 @@ -package service - -import ( - "github.com/go-kratos/kratos/v2/transport/grpc" - "github.com/go-kratos/kratos/v2/transport/http" - - exportpb "github.com/limes-cloud/resource/api/export/v1" - filepb "github.com/limes-cloud/resource/api/file/v1" - "github.com/limes-cloud/resource/internal/config" -) - -func New(c *config.Config, hs *http.Server, gs *grpc.Server) *FileService { - fileSrv := NewFile(c) - filepb.RegisterServiceHTTPServer(hs, fileSrv) - filepb.RegisterServiceServer(gs, fileSrv) - - exportSrv := NewExport(c) - exportpb.RegisterServiceHTTPServer(hs, exportSrv) - exportpb.RegisterServiceServer(gs, exportSrv) - - // 自定义路由 - return fileSrv -} diff --git a/internal/service/upload.go b/internal/service/upload.go new file mode 100644 index 0000000..578791e --- /dev/null +++ b/internal/service/upload.go @@ -0,0 +1,44 @@ +package service + +import ( + "context" + "io" + + "github.com/go-kratos/kratos/v2/transport/http" + "github.com/limes-cloud/kratosx/pkg/valx" + + "github.com/limes-cloud/resource/api/resource/errors" + pb "github.com/limes-cloud/resource/api/resource/file/v1" +) + +func (s *FileService) Upload() http.HandlerFunc { + return func(ctx http.Context) error { + var in pb.UploadFileRequest + + in.UploadId = ctx.Request().FormValue("uploadId") + in.Index = valx.ToUint32(ctx.Request().FormValue("index")) + file, _, err := ctx.Request().FormFile("data") + if err != nil { + return errors.UploadFileError(err.Error()) + } + + in.Data, err = io.ReadAll(file) + if err != nil { + return errors.UploadFileError(err.Error()) + } + if in.UploadId == "" || int(in.Index) <= 0 || len(in.Data) == 0 { + return errors.ParamsError() + } + + h := ctx.Middleware(func(ctx context.Context, req any) (any, error) { + return s.UploadFile(ctx, req.(*pb.UploadFileRequest)) + }) + + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*pb.UploadFileReply) + return ctx.Result(200, reply) + } +} diff --git a/static/2a0786fe9127b8116bc30ed2ce9581e2.png b/static/2a0786fe9127b8116bc30ed2ce9581e2.png deleted file mode 100755 index c38943e333fe3e51f6d9246438c47cffc482df4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3055 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 O9%PNR!_=C2B>fvcm2SfT diff --git a/static/36e2e87f7b73219343da52a28ba47eec.png b/static/36e2e87f7b73219343da52a28ba47eec.png deleted file mode 100755 index 55153772a899d73f97f99b9b4a57de4fcf721851..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3006 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 LNkvXXu0mjf0)9u8 literal 0 HcmV?d00001 diff --git a/static/6d06733ef579fbcef68b9f95745a3e99.png b/static/6d06733ef579fbcef68b9f95745a3e99.png deleted file mode 100755 index 151ba9f368010b5e446257d0e277042572f29170..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3178 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 VPZs9Y-7g+Eu;#YtYEw_bzW_m9qnrQ$ diff --git a/static/6dc607ee0b87559d8932377d46b9a3ea.png b/static/6dc607ee0b87559d8932377d46b9a3ea.png new file mode 100755 index 0000000000000000000000000000000000000000..a16c235c1a03d678f93ca886bf1c36ece12abcad GIT binary patch literal 3740 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 VPZs9Y-7g+Eu;#YtYEw_bzW_m9qnrQ$ diff --git a/static/b8dd9fe625169e3e199064bd5a8d56e4.pdf b/static/b8dd9fe625169e3e199064bd5a8d56e4.pdf deleted file mode 100644 index 46afa336c3c2552977aeeddf3d2e6c6d8220b88e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 610649 zcmeFYWmsLy(k?o25AHT`cXyw-I|PEeI|PEeLvRc3?he7-U4j!_f&~IxveuTh&nNfX z`{O%5&K|S-8C@;a^;TE+=s89;g_1akfrXI^37(?y?LvZQ0Wt&ajjWL1`T3dDJRMA# z#0*^wZS2jNlnl*Hoq?=x#VSm4hIZ!EUKTV!CRGYho$>D;**Jff2nr&>o7$QDA=+;t{zb+=WMdMuceQf?vM|Y7nmFqM*?zau1OBz$ z@2vmO?hV*mPcDB$ref-B@9Ol{@0+L+9xjrqE`~0qZ)r(Y4&a{>N~&@J|3LXBzLuhq zm8r4ITe-CDn|e5be~9`g!NLZ73%|AXM;R+S@Gbn4 zzJ-61tU&fZ`h5cmvbXz<62t=hlN*Q?$ns~epf{L*vIM;${1ZRuO^Ck@8k3Tfy|JpP zi!Rffp)skMdbs?l4$(hvVt?MGe~;4}b`wiOQF{;FHyN0LEL<#Xj9jchPIhiKJ>c8m z+PS<9)0;{CA)%y`y{p5UM1Pp*9|V&slbVyEowLL5;WYMS5>sUoH+8c#HdT=nePga> zXyp7>lZi<=tTo0u}mncA7VSO8gAxHvd| zH*uVal&BS#v(Y}k}pM8(BL#f^8Y?0U&5pUUZe>ASmdqq~~mDxa`x zf9(Fy8J=Vj6gOklnxKC?Sf0ctQvK=qs=V3vapM@ft?*cxG?RL(0C+(Z> zZBs&d_lFswS96J_9C5Nj_go(+foM&3l`Gw@=i@Wqndc`V8_jZ5lsbq2{ga=KkkM*g zwRWZr%+VTjmTLKXqqBU$xFYk>=%?k18?n!cB9EZkTP-KM@Q4V)Y*Q^o%U@>w50E@AYY{_)O>%K|C&M z8p^1S4!&dbH0QUOJioy%2@`&XZp9bN7&Bt%w=LBy^TQ*tO zUg?q{TN`H0X^6M3mD;~FJf2^4d#(9$$p@Un0{x-AI2!Vz*~+)%^S_P`4#M(**W%mL zR6p1HvihN%gbvtksI$#mbWzX+K8gf zD)=F*`?*JxK{su3ZhipouGL80P=IXam~5lpilrlp?HMgHHoLsI7uR)@IBj@D7pZ^z zaU8t~_rd`hqeM9xT86AwncY54)Xx_I%9~Ar)JWS(<*u zjgp6TSibwpahI?XjSl%mXN=Gie49v`0>MT~RjryM5(2`ElQ!^pz^k4@#6}85mhAo` zTK{#1;&y#RJA}OQRhu@ILa_$GKr8^EPBe0GA0XGV=+wM%XJeJQ1~4#gR++vY?)(9F zvPD}N7$2=Z&l`U0AkUw zfHWw66F1z?Qqx_8GktoQyNy&gq=++Jl55h+{NDKW3${NIzg1R4ryh&Pp488oQBl(` zQwgYIi|B^2hT{02!_R(^vb+lh5ht>OugeVcDZALBuOjIVh;78ho+BF+oaUl2GpvWv0wgSj}p?5^*q?vUZvGn)>Gwf`3~QI zp9-2pC9CFoSSdl_WB#*F8bc@gwG~^Xek}8jBr6=JB+v;p4~}IF>paJ$pP6L=OM~N7 z`b;X57S{nU$qH`jB8OH3urQ}D{xxo;hbb$M$Ec|X_IFxuwX@1a$|i8*nj_)nlre9v^d?X(TsWpDA~F3Z2L zKAo(1i1Wt`U&$k##CJQiW-a#PVQ*wtsAJ7bx*U&3$Ke?z@i6$F&GgMzYwTn40TwW! z0xAtGtPC1=!Pc;EbN)PI|)mvq-e@ZFMk=59O(Rx>3Yh` z6->g~3jUq>0lW*2LtKs!RBbYh)X!NMG;RkCAk1vFIIjT^5eN1|*I{SK1OKFyDw&<^ z+;?!3Qs{IilTw;5-SSt`h*+ES35Ag3H_{WvCYH!yfmXHJrO@Pa!)81kEsYk`fdl z33o@FONyv2ERqo>9I=nYm7RG%AGj$y&53f~;%LGpR7^c(>yj3?V}k=~*EyBU0})Dj z)e#qR!leLEoI`V6=Z_S()EJO5~hgeZ1D~5 zp~ON092!Xh{(;eqn!$qjivaBG``HZo^Z2kSuWk=3P?zTHCPb}fkOKzglxCZ7&l^c* zs~jX`rqpZ_TSoDXjG@B*C&yk-67~F9)TCWyFq2@66|VU>g+Kd1!RFAffm6+pu{4cg%{5k!78no7`FiE$Zdx5REk$l{guxJ-n0j7?zq@*QNvL>U` zo@fJ&8VFx8egf+%+3w~CZs4+M=d4}%q#5t4@m)j&M%w^C6Y=L=o?A=($cm@BWdP;e=ngK=Z;Mgt4|`Za zsEnuIixH}R5&>}nSa0>`xdMdG5tdH7zp^=5rFrZPV)lmEQNt}QAi`PXt3UzBU&}m3 zNQrq;5UibCNo&N($ilSxs2Q-A_N*WcEl*J84f#VK_KVcVA)rKG$-9Jkk$n`hh#L3~R3z|vC3=>=GwUs%g)B~mMZ5ci zc@nQ=)g&j`@K{@}QOWUoF)})Tu$YsabjEmgGkyf(lZHfZKG`y4&C;`j+xkS@W0UA#j2a^kJO!#mmZ8>HP_(I7CpNgZ|1XS>_= z!D~HmpLp0PyDgI3J4^TDqKJqp?P_VszIVpFW^JZrb+g}W%jQ_kH05pQ`Anhz*Jha< zvPL`?p2chXv0<5?ykUgmUttp9cIj}7f;>`?H8AVvYpY4{lUFrL6Uoi7b1fz*Zw+gt zKRQvc;ORlPYFt01_QV&O5RZ10RLbSE-+W5uLd*3I32`=H?e7EzuTfBQY3S7?EgFDc6M|to_~;DW(A?V8zOcCwcR;Ma8-0 z7|A9yUv_1JOTTaQRBx$9#lSoRk^44+ObCZzE{|;B%sD*yQ~Adquuj{!_#RYq=I?0` zGa4xRAFiWJMP5~KASpg3j)RXf0jY}xtg@$+ouofZjdR}xpgN(Z;ZZu_eaD>5={$kg zF_Jj4R4$YFo*6bWk$Dppn2$<|QjjCC8$lX(Upvia#7gK$je{E3Z_=npl)mM}5U@1Bb6?K~f>y)pXDb z#k>hq3?rB6&^M$jthCw7%xXQ+Wjy^@(X+O3(a=YN>aTds))V^;xidDTt+~tB^(E^* zlB;p1Ru71rtJb89RYej#nxhyJNdI!V`@#21_Zm(l*dScgO)ZB8x7x?}k|+zQmQlYJ z2pyD*UBCF;h^w{Jvn3A@rbAqs^H5{b)=E-CK(g65(<(Kd(00m&(66!3Z$7^;j&hzd z5zK)N%Knx>?_}NmagB|A_tyRZiE~3*G{NMoPaiFkxSuz_Jx&xqwBEN~e{*6gK)Qz} z%Lxdnp*B_#LAP?(tc@R=!bhs-yZUj-TAr2M6M{&7?(U}hS&G2PL5w!(R~3DtN3P@e z=MD__AP_4`b0*ygIBmNrQy%3P4&@h4_c?Viead)O9lt&^)t6Q@ zex#5xQhrP%R}&9X@NCk4bi;DW0rc)yW|nLznxs9CYb!OhJz0(XBJvL{c<6cSvEr>{ zZF7@5!?z*y-JVP8hWbD^PnFbs#;QB4qNl_l9?fO>Ktqf*9qBT<7)TijDbLy%ABM9N zvRcMlsjA()WP_!V9`*PW-ZTx#grG}h`IWw^QBgWRA`Fn8awhsoZpaRuu690p(mfCY$<`v>(|t{BobEGa)#jQ zkt*0lL1FDdJ<>rA6k-O=8C^CERGtkBR!d%*IE++UdZRs2Oi2EF8&qlLYVyh3mCS;P zrUdVcN`q9&S_UvEl?q?e2zK8uQEm-z526nN?e9DZc9k8zcEFE$u;a*@Zqd?1_*zaj zeWc*M{v?Mo)<5rB`ju_7a|;Vyd<}o!6A`^&=Y_Dkml@2ptG;P{77;yabj7J!{BS)M zwr<4rxK3?5#cvgJU;E&iS^8f8mF5FSgs{cNV;K}a&-3(?Zb&zaWCAJUT>|Yh?(dIL?*?PLY06k6M;la%2aWvyhB$lrqPDr?)mY`MHo$ z6>-g)TbY>0uj8lzy4gaR0RR5Vtxo&T^N{<+$M_wg(Va{>a>QGu$Q?c z>2MWnkiEgm)$o^VTzcqR!K?XM2o90SL?TX5gH&)1fpcZ-D70`612DR!TGR|Z+U?Sr zuYpi4WMky0b=TmTT78thFJR#7SDz9<6$$%0A#C{QE7!1@*f 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%0D3r%g=4JN!4lAy9K;`QdvKBn!<(E6sYAuEgW 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%0DBGo@2?w||LOP4F|}XP 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⁢G$4y*RqK1Y96RcSlsr{^H2l}zd-=Z!6%fClv{jXHAdiag>@UR&5?wi_&b=BcalTE5oeyiELQL$BLbE^C!u z*|LU6lt#=eH24mn9SEFLpF9WEO|*%(*BGA%I?&F<2ba`7!eifV@9XzB=XcMYJ9qBPJ#+RSnMv|IyR5zTTA#hv+IyuIEk5zJ@;y}g zb}ym4#)d=!&KHNkbTUtxk?vH9Kb$8&)xY4Ot$P+NIQEsmvTf#AOPMfZ!`{B8OmoDV zo+Te#nSXkS`waz0L>6MXn^5ZR%_IMq>qPFx z&8fvmIDfVOUyT%pJ9HfW1TKpcW&ye2`QX#jC(LXslSB! za8611-7XCu`8paAJqqi!TaponZPfC6X7Yy*>RN;jo%wQ79!yDxk!v#c2rSgTJd7Rz zZ@5m%Z1ayVdy6YnHM^!zJ~qDkS6SU6cpe!i0S`P^b*UjJ2|Zb_J&#XtKM-d7h={-D zQhc=f_+?fh5bBKpHN@3<6(THU1SzdnVl4MC$DS!R>^)9Io$QzK5?KIng>(>}PYQkM z9AhbDyY71^^MVrz7_CFbP$%u~D+?nqCs+%FHgw9@S%ScP#1oAu)>nEPS++F>`l%u1 zPahe-`(vyl0z(O@^wDW#Cyx25`PxG`k0A{P9qXFXD&0JuL&b*z+o>-c=^sZO56Qis zsh6R`CbfCnkp1Kk{UV?=91p*c={@5dj_V2Qn6hem&H2=4>xwrQRns36BEU6dy5BDY zRH=}~&pc<%m6B4Pf8(}*MeQh{j^}Vd+-afQI5p~!R-W?zcE_Z&gByQ^B04Ns&s)b| z1b+Pd_FV@*4V5t5@}9=QxLMh9)e|p$W6p4Q`~VN_z8{}SJTkuido(EdBhzRw5ragD z0`R+vO6DxUx=&&k6n_Q+{?DTy|GU7y|5fPWA6f8!LM#4f5q$qAu!I_>``-p^{^s`o zj`cdd4&W4zQ4sq$xG!r`GL){8Lq}|Xfl~=0X}Xq3+vxqWEA@fDi1E2Pr#RL>fnd~- zFl735W-W)*@)9s*zaw@UkDU{etmLz!^moi0=V{wKXdOv@d%~uSy7&8$C*Vi%t+`$t z?K&E%zrJY9r;3j~=TgFAB)Z}NyJ4Xdiv3r4UpA9|nwNqT%0 zX}R58#L#=`z{h1JrcOB!>y9n(62N>ZfGFRBG$fMj=ln{-0LI(bWLf$xaG*c+`S#o> zj*e?2<9o2HEo^K1a}_&GozlI^^RSXs?#U%$5b?sKzE-iL_d;g{F4{(SY$oYY8l;=h z7A`uK`i5VEIm%+C>Q7}fa#xF^E8W-ZE^67E+^Uis7}YA^=$u|+VL9%y2w@3t$BPu(j)yYC*QAq%Em(Y4z&3?GoBfmi;a)-c-A1TNPbW* zW^MfX&B5S}bpQ+F5N?3gXbTdRRW8l?=iQfU!E2vv@+s>c-{UBSnvyIPZ3v5iHxt#J z;e1lmP*N>QA^|vLoQ$0PnH%}XYa&tAD#+s`l$@k~19E|*FYwReYQq+<_#h!6EUm>-l_pcOrMK}?v;km6_bUq z@Xs)j(z<_Nz0==QUgEv>HTAU700V zO`gJZvO6n*P}L}nu>)!}ZT!sn{G$h7vgJhvD>-U6mrEd&p1gT>65)`Qdw41XWhNIc zy)z$FWw+_N^>U>wVg(@D8NS#{#vm-sBdN!veWwV(f;1`x&PnWlb>dMaZGG6QnkLSc zK)jc>Z)*}rv3~|i1miX+q9F&p^ZS69Xp9{$8UH&#u<>#=>vk&!#42463>9X}FbHR}4_rY3P5PfoO} zgVsUG-GcC-sr+saS63Vq>Qoy)?an|$<0zl}smMoi7kz9L=CoCgFPNvZGU_eY*LEz( z`S#?wKvZ99&mNEP*A{HQ7vx6#Zhs+xnR1Nv`c`e(3j*?c#b0fi9 zy#?1OS|6V>?vSWiSALW^UgQlv4Eh+FsCx#|tkhTBXzqdxye{?n2HY|lN|HxEbWto% z001|^I5?ysDCU}KuLPfeh)vN{`8LT(31=@U!C|iPG5q)k& zfj8HG5Z08Vk}@5cfm4)_wbmxG`91F| zeZJkJp@I1ZW8D|!fR{e4Q*O| zz8|&7zxV_v{Od^??zrIQa!8}o=MDf^#$`7(zNkm)ob%FFVrJUxNAEw2DMUeU{g!;6 zKm5hVr~kfsDY0XGHAz?)=3&(=kQUEIqaM@p_d6c@ifShX5Tn1FO4s=mWOp%k>;DIj zm@b6c#X=}5?kliZ&G&`7EUGZl?)5K$j`2~#VVGR1sCp8yyA_^!-l(kPP^pM0W%pYP zh;xr?gN(kW@EtaQvLu8lL#k4UFAnp3#89Y}X_J+FWNtMKgnj@?v@u_53@bEA0kF}~ zJP-MYD8VJ0Iplk|myTq}G-a!qp)B&)iJRWVIq_?iO6DzYU3ODOt86PnXIYFNtLA>%ni^ z6+cD+o`x-b;&7b^5e{>rW(4y8z}~3#qKV4eS95}Ap0Bn;qFyb)&u59R1hG|_(#;$E zzuuh^ZW!FSV#FHxu^0qUp#aFD$rTVQkqY|iD$o7xLnLi|OBKqJp_wO1baK;H5bQ$E z*<)n)BBo8#XKA|~1?`P|1?|<9+zR+#{gG2E-r4T!pk8PBBIam`+hFLEtrj2 z^>(GF9CG$bTM74yA1u~meNx3+V@Xm_q>oh*$DI3TwkYt;AtV8I(P(DG6=G1Ft<8F@@K$oJU{y1&?bcVv`Ddqww6POA|m$& z{ZKl_XLCNN7hOS@1Urw*Jl-GCv;G<>5FcSMgohH^=QH$WQ-os)17WF9pw()t)`y#~ z>d6kfX3`r%8jWWYzdTNR+oiqG$C$zd<<&ZEYM*?>fnTreMQD z@*A!`ZcK(Pm9Yn+srTB|s@qOgZ-1S_BWVfME2OYibI=MK^;Rbefhz^?kHVYuw_N>K z89qLGs(uF#H6?z(aWz*{^%}((0S1=p6*h~E1%(7)*1#hXogTRno59SlgZ6E&pLfKd zdPZZDg*xY8<ata5zWc#Z?NlW5mH+iMTKddmLx~?nt^5kjx%}Oi;42iy3nDu}_fHG( zrbLU#_;Vch$gJ}nc1LQ{Q&9;5Yb;C`(Wi_%x)%w!fNsd<)Ij4oR|?dvdjq2F=Ktv9 z<8BBXT)@lEV@%P^qv&`pgg81ra<4Az_J&A%87+1~dX$#Rm*G{CFYM%8q_j^n7@A<8 zC^`keig`YF-!>~}>Pu9}<+yl6-P^lmSl`@rOU91`uUUeRV{zJ_L?e07~J*0pQmp9agw zM(p{Y9dG2!#TusL-LpG7ASK*Y@v)6lzSFpT!#-`w2WbLS@RfG`61%On^yka>QY9n! zdA)iilX$ii8cJWOT*3EGVl=q)H!r7sj{;ZKg_{?ymxww zTyx`tYx$2MUX}f&@f7x5*u_djxI*#Jd&3Br6kp#G+i~m|0#(DqD8r+WN=dl~c9pkp zypsAwcmFP;uId>HuBD#3M+EYSI};!5*JsXs1O%bMBSuK_!PBoyElA#p%U3jdNpQp_ za)lt`?cS9{DFlup_qz5Y`iS*A)FogyrFAJ+aB>kn5dDm=PfH>f1>ZXo(MMsoF$L|~ zP{z?kI`_5r*J{i9CIl6|Z>P)$e1BoAx?TiEk{TA^dUzGXk$H1(^A?!j^2smM{lno| z*7%4Ytor=L??Dj)M8*?HZNdi;LtC>cquX2G7o&mda#cGhPmFyEm zPK-WEobqEXLsY#vtugoF&_QpY_%yiB4XQ^@>9hxlUkr~SA{fW%&n(6P#=+o@@`u$| zM=vX+<#_@$05E$gGPuv7&)9sq_&`8_0P;C#bJ^7W!r+VkkDCnfzuVYyG&^7 z^||Nr*5u7>zrjNRg6AUnV;T1dY{*lLUxH(u?EN`XPR$?Bf;{ZO#V~$lNhk&YqD&6mc+)`auv~(3wl=B%Is*_ zMD^Y1!%KE2*6!ZF*cTa+8T}DZ7j(^Y$?ozy&x4BIS;;F&kkp2jCJyaa!1mhKCtW>7|T(moE1e5t#|amc`P= zxVlTW!quHZojL+_9k?rQzL+ke_`fqY6=<8ZhGsrjY+4 zik--DEP-dJ%37s8w9?TJCo z<)Qi8RJ^j89BZBy=$R0RH$EiQXf{2q0e}llOb@ESHr>c9hu$s6-nt2%!ibu0KhB{W z;>JFVOAW?DRm0XjBkO(p`%KCjP34`AExnZqy(9saDVZep_Rm`5wmsS;$DRTg;ZuCk z@qo4LTOC5JY%JP|sE;lYH8K||cox}7&<59QX>9H|_?$iVT%bqwGPT_Nnh^JEEF44h}azS ztqfNsTR&sBN8fLrISjF|hTl7?I(6a`?aBh&@lg`>`k8X6Eku0r$-8n#9?nAXF@?Z* z84H8}SfsVL+P^U|y>uJWQ`6(Kw|8-m!yYI%KZ)4983b6qddhJFuuqGn_oH~;oT<`| zDT$9EQ%-x;X3e^{l5>%|Nn}_+Rgc9B9xy$Z8XlSeK2F!yTOYUpC+Ci2CZQ#5*SY=i zrexNZC^K3ouaTcZO5*o=CTH{C1&jDptVqM2*U0YxM<;tOs(xi0!?Vs+P4$pacKaJ5 z1{A0Z87#hVM&M_afI_FIdIdq84F-3w|h&e>Ht*- zc@lz9JSp>g%*Q@P1FUK$=EBrD&W7{LbU1@#wLitxP-?!0m45Cw@TdK9rv%Tkp@j;& zQU;<-(TGroV6+G9cBx}yU4d7RuKHXg!Ev1brPr<~_)>ZJQpqk+mt^cf4om_76Z&WK zVr$Nskk6$E)mJ#(k$gv=Ml5_L?UO>%G8dmz?eod-I)FeMQW*2_4FV3_hqU6T5{NWP zyD82gh1YeLav8lhj?m`cyKvEnJC_VR*nV~ZV$a1KFkS>XF*PxA@_>!9rwKMjc;gJX zJBD&w6czIw%&q*esNW|lX^LV!xq)sR*0ntTKJnlYozDfX5Vju1#z0f5d;{k>TS4l1 z;?~nn)=wI-<8h~W&05+%n31h{;}iEn&^?V^m(fJJgL6MD6KC0e3ml?EUG&0{$s^YY z5K>+=qyco-KwPcL_Y?zxzU_;VXw{M`>VgnuloZfQy{D8y+}}>1py>mM;s@uhtCtZV z-UJGomK0=md1vG7NH4mZQ_^t*JQ7eHnXyI7jH0`=;u`nFl$=tWQ`b54F_V`k^l9f@ zStjr8s?9se&C;Wcc`JLD&cs5cvq*4Ha=sU7l(n*IUU?LaIcnOT7)-=7bdIXVNY9Qw z2SgRtk4jV=Ms9`*gPS$gx@F%l3{ovM*^hp1!b;j?K1F4&20 z3g+VB4>M|`09JD13H7CA3ybhWJ*@=e2O;*%7qO}=ka*60|b6V$|s=mPOO@1BaB zp{cpC1b<#Vn{MsU4uQNir8DQt+BH*A`FAVGvm@YQZwAexh=;0gf{(xYU+fxb@Iuco z|8KQHrP^(L6PRlN+szDsc9~OGRac;*-t?$F0~Mc`TG?Jo{Ht7(?Y#J%@Fkt*rhm;M zY6~Vv%o@&m8f3j$N3O7Ht8_#-a43Aw|FK11rCLca6rvGMjmG`I7z-#w(2h`P!V8bv zKTH7a%&qvJY{NZw*9I%F)|(X2ZvK5y>(^7*7eR^+fM2io!H~r-T?u)OqHS&2+8d z;tvDGE4q2&&+XYohXmYUAZHKPRD0v1z+Re{UC*khaq*k68c%qa0Bn1wI7d#>@)OtF zixoRREFZ?x$|SS(Zwo{Kj4N0!?-8V6MM%VZDhEC#i)*GDPA(4PDc`FswO^UiUakKm z9B?V2>!ueSr>-K^Gy$Qfq2U%k7xacIOGj53*a2T8NX=a=#$M>2T~2`wG4Exx@<8<0 zGACnr5|7hnbT^AJq07LdV4EKugwT&KNA*$`Q$Wf0N9Qk^$A2pEd6SR~CcK=hi#oUf zqToJc&Ka*b346CLP2xK`RAZeL+{iyH>~3-LtT_Sg5S~2|h^3Tn9XY%VOBckf${~jI z@|x}~8`ig+wv%yL^?L%#O{o!vU|3j4(Pmt-UwBW^CsLf@V=Wihz=FjT*`AaNrCLQs z^Nlqj4`d-ZUB;9&GWJy_Z8xoLGjfTnmgs4}!M9BJ(JlVjqR*Y*Ccx}#b9edV$wWoD zK^!C>@M6OXiPa(m@r?tda6)KpJ2q?Nj$KWC3iC1AV?}ztycU&ug1oj_t;jUm$?U~i zy@V9;DE3W9*2vmY&UBFo`L53mE2X+*gyY7zzlYTesV7T&9KV|4&IxY5uSBjlKj^5; zv4Hk6U&E;4L^<#!pgYE%Swuht8-At%X-p!t*THzfZ_E~Z&6HGF#{G+);i2zlQ67ud#6Z5?v?`)*NU=qkr$?tE~K%Q@GQV(tDsriVhxG=t1FWhYmXx`DY~8@ z$Ol0DGb+FTChqt14hc)$kS;Lq0^HKZYifU3U@bzlK8ZXV%NI*AiuT!BoK&W*)It#* zb$5WCM}(ja&Px}H5_Q|{;3)@$G|V|W%onRPC>QvWpb1Rw)RVA=NKcN^Bj{bV8mRLc zIZ$O4XVJqu(&;n*%l_^gdx6?&3aoT-xh6WdMWWOpoLrD3I%Ojn##6#}zM`0#W{T zN479yu1ehTB9711+RoD!zlM0#=sNwN>;$+kA7wnQ)2K(vAhu~4JLjkiP1zUHh`>F! z%-Pb`J0QbK>oGc#G}EbK9Nk3}-2->r$jwoaIY2;o2ZS>(yu@~FC+j-w$vxQg@9BC* zovsLCjYm%e1Fq4tyUGWsU}mBz*`d9NWCDSY{J2{I;m;I*@D~k1#d#C+aH4 zq8df)OkXRHo%KvBN{t3E8T@clh=GXBOVM=Hth_Ggj6YXT+y83gLE0~d+y>T>nt>Ir z=!?`;9F*;X&e6l5weFVzr^LZ>@MtC2NX|{q<5t`_YvAbVE0}x4)Vu85kxrTJCA ze)x1BL=aFg`J#UkR~QBoKmPs$fJsYl-|H2;5@qb+)RUHzsn~Z6{QmdkB!q}P>oO+? zK8KBwO~%O(;Mmod35xs}$naOK2|t1X#9yn+G4)`m@*?~Fk3f`D1#N{s>nXg`0tr6y zty)XYkOO#rLv$tSlx~5jjh8V41gk{F`J{$|&1;>3356{rGZS83pZ=xT_h)?#YVZEK`@A=nmG11${vskk2ckmG6uI-=< zHUO7X_^iB}oG``gX49+8nj7IE7x)TK5Y!VnH(iu#+fAr&G}J;;q@W*pFtE|n4sj|m z9`fpQwhxl@8d)1=gUR@;r^aXb^anR~{+_9IdDdz19hCGzvVJ7%nNtw3cYV#91J&?8 zfoEiE`H~Hji*Frl>D?=Ox%L^Gr$kfSHz5<@eN7rIGozyFz4);KG8qI)Pc=H_a?ESf z{}DL_7z@)%-Lu0Kq`;5qPh6=o?nH{cx0-i`|3o8kd1QN^g#zR`rEKD z01wZ}fflXK=c-s6Z~{m?H9I)7)1q>po|I5=!mrnTO?BV<+hF66d&$X3<0`2#pjB)A z!JxJ&f+#+NiYPw){bWrFIyQXuGm1m|Y2*R-9j(7Q5&Dm#=2yKBO8@a({ORZa=8v4P z(Z&4`2r` zt@-pfTInGpG^Q|Qb(NC?8?FNMX@+JUNiD(_+$rQjB6eO;zI(d}FCyoa4k{8rwlnLu zu)bYM#Vl=5sS%K-WMzMsX7Q0RdxuA1Hf-l?^ZPN5Drt1@M)R!)-%p*iVYxRMUN&T= zlkkWx91bMt`+fk78eQ3rEZa0F#`ZvlIZN~^VA-By6wIkufPiYGmk)lKyz0321ICtK z`)N~%U$>&t-FHI`HT8M0Yb2&(FW~(P6pC{R7Dq^K@`o!PZ6HNn)3YSaBbw2oxrVBG zmsMSi#0(ln>^y}UQb@aBNHYOLO$}WYI2_%iP>7&QgIai20hM~^MJqcW6%AT=fV8cp z$Ako}KJ{tU8&p_E+u7PJOj(dqY>IXZ>k{yo_Sm9UK)4L1GNM2aR6Fd;w*b%R?1i8X zR1ljgqrc8#gFiq-RG)ZIILc)jzg{SW`<$C&;49d zf~vt~Wje&l+`!8MV+^z|KcD|hH$N~WHGnC9b7cHIsu&GrpYU>DSixqwHr3dAYO7{7 zK$2D^I3+Hr_qk|lx0bW@>{Y!;p0(76N!U~E{&ME96*OGy)l^|ET7}@N!Pcr18HX+z zhasmv0WN1It@0FlHyVM5*w2>@f$j_*im75iK>*V=IxCa2m4m6ErJ_jjyI>=qp=l%S z4R;ThQJr(Jn^co5=pQE}buN}eVgVqIa*lho@4j11h7fu^)86-VJ)IXt=JOb+4n=;+ zuk?OtkZ`Q@t|&lKNW|GJy{-Vgd`Rg8Yvsts1So@g(Uo3;3vY4j?3B29y;W`lDZ^?$ zPef8|vQK3Hh37y+Xz4tK{5%a?2yu$hRDiI?( z_7Ze{0Uz$0c(aB2X|y~8T)$WrbYQ=2}>`H{*q7Hllky@S?= zzXe-u_O@MFZp=N5ewXMm;hnR8?F2!!Ad8~PBR_0tX z*enpv=8bf*hGxz;Hz=YiV*#Ts6Wa}o)51`3gD!~Q$dm5u0CBE zmPCMd#qLsq-5N)t)uk#ub4h;sUiTf;BL3S`7xQAX=UhI<>-F~p@%OigR47~aw{-q+ z;xBz5$^poC9FoVF}*AI@17lxAe2x}fxr zhS=R$?pCwobn8zTG4(Q{1M07?r&4^<57IeL3Y1u_Jd@Vb!A(+~{K3cm7GaJbRLO;6 zf!d$(uc)~MeX#P2r-j3B^Sw)3Miys>hPcW-s9VHhMYJ){`OhtE5k|$8(9YFXmR>EO zgQY*$anPB(k*U0~a}Aps=o1k7`(xbYe=~q=4J97Qqs8gNI2gQ{yXgN%VJBk~9x#(5)8D3C@(SI_BpA-go?INH4 z^Z*E+n%C=tiCUwcB~mKZmE@>>!CC)$v>G@jYfmoZ-Gx+wD+;U(h=y@QU2C^uiG%QI zZVQKZK?MQ(GmE~@@7EIXvYPnHX0&!t8{6cJLIP|y!JAJ@b8+cHgT@o`9>+yMb?}|L zG_*7{AOGghnS1f8Cm!97++f-`x$i;h_wA8T-}rVST3dB!MQXLHO+} zi!MwD-kY7GLKBmE+Gyr<6UUZ>arz+izV!8${6?yjuka?Q*+@>LC23upRSY?|0Cz!y z>vas(CU4c}25irgS>i!K-4K!j0BlyaDQ`a0sy_@n@d0pz#`oplLNwu$hPTJG;{qOI zn(r{!>&-T*XmQwx@W#Whh_=q7&hFJ21||+V+%CPe3xM@u*a`{wRYVi zB(;v9TzmGG-u@z7G4_gpG+<0`UMjx{g9=`<!QSTj84EESsGea}UxKA%N3( z`{8^N(}CjTp!f@oQ5I3nY|$;WaVlHGh|lW+_P1J~@ERZeaw6g;b#lzV^EU|+7T~lD zn+1J7Zlt*n1YCoaksFz{he#LB$zEcu%;zr_^C*~uzoCbUude^S%$?2H#>-tNG)9@? z;+yVg$yBZFJWpUB${mf=s{S~fpC2tvJuP!9T68=gZIg0tH~MX5?VYwkV>^~|TuIM^ zG~%xO@KTYhO+LS;i6K6)D1ufBm}<qtHP|k0~xlnzAe+A zprMifWt;sSsMX`9?GpUDzyHm8vbx6^!~AUqah^&MAMzvJv<)l7YBgmBS&OqPKcbVi zVOO;wwLEPsJ=9o1Rg(kmT#eh)EVR0f8MCjoxB3{+Hx+GnQ>4|kYqUZ|lZz#h9uWE} z^kOk$WaqfO!)pW>I)Op0M8Q3gs=~{MN^+@C z#DHVH%;I!`cRwe=4OJ5pN1|Sh?`Svr$Rk++3iW7y-z#ZhA>(8NshTA8DUmdK=k?M! zR>jp8r_?WJ-4nHUjdrJD#HLtZvknnSd()kSLlkCu>rB3!Lw=)+XzNljg7n1v)Xkr&LHwf@y^tPj_vu_r05ywE zUa_?(S<-+{s+8~u$8yZ|b@()=cIEMUk6|1jf0Ji`h>(WX)_wQE=EoVK##X!PI;dR_ zmj0Wy?}z3=P3Q8bgZr{R5D{J(N+h-*!|=A)q9ahPHmv{Mg@0e(k!^|0utzId?@b`O|Di9M--L_oxd|JVj>Vgsw>2IeseCY1T+?)WPd?X^-YlUNU6A6atL9AtJ4i4SuIm*{5p5< zivFaq7*`_))te4m3)|zk&lFAdYx-V}{uA9rCHvPeA1n*bW-3q)_D+iWc@}3%bg_{H z?ITA&OCU>x0RUxT3Dd12T2DobBY|(Zoy@$a4)r$~n3}u$EMP(_OivlAX*cvl@r_pE z&O`{*>{$b6gjbGy36xb52XlIU=LDy%PNq7rSe*)LcetB&@*2A-dA%_@>$17_y4}f* zr! zdmyKFiz_FbE-k`&eb3!^(S?H!`4~H}o@rKcI1b_6p>q0FhWdbe%HR zqqzn-VnyZ+Gv7EBHtn~A+O|5^3*KO>8ZjwswqzbXZp+|iTN z(}wil)0}>Iywc47RxQCfbqtEB097n|_uU+`2D>(w;e6$9stB)4P^Z(3hS|JOB;g>a z?Lc+BIa{=xE=i-1$u@-_ii1^kovH!?q^)I)CYMA7UzJg^B22PQBU1tTR48dA>Z948 zq_>3#=MYlV8hkTL_M3$)_d?`QvnEfZ&fl})mvk}o^c!pl%D2+@^psrPLBgtiyQ#*) z8QuTTw|<IXTU+Mx zQXP<%N0k^v_ZErXytVMP!nVn*ur`2nhKRrR5J=@Sv|D3 zE5GSa^|ef(m~|Xlm_ODR?>q>F%ZC=f@VH4U>94qYAjfisI1^Na^eENmeCG#jm!D0mVjZT5vBH7E3px^}AT}ER>T)FuDo(QTkUh3f88A zR|Yl|xEJ6xqZBA8$572+ZJI0#4|UQyAO1M(T-H1J3t5UsX^;AySIa!g$^Fv)fddWg zigq(yLXjpz)~9U0;Aw85FwD!}I#9a^L?L>tY=0-I2?LFhCzNd}%RizDwr+7sdCBcMDNO&gZmlo#S5|=b?U7~C3`LMLH^8pp znRCdZiubE-s*EafKL7|bF*!rw=+ zBgRF85p-YDbt>1m)IL&y8BKl135MyjB!m9FA7rKR^x;9&FTU(~&*4ExlhXE@Nha!^ z11NHME`KYI%Q0RSjeqEX%~4c3NUncrgC-S54<(BzNu36^{Kn@YbPot?L~X&rOV>xx#- zLU{{oT@s5-xNA31|7l-yg?cdx-Gx;0wGhq!XmJ0o&S@jo=oDrG;tZErp!X%Fshfu1W&f0Mwx!1Txp}6@Q}$-B9=I*xt;HFHqpc5-2GxdKApIEu~#C+`O}q;5=Vq8=jPN&FcRl%qolg%ycOZ+$ zQ=S3k&$%l*O5rK)SgOzs=q(+Lao7|okHoAa%U+(N$iGAd^c&NhsW=O#uzVzl8 z*{;(Wc~qVJySO!MdnAaM+FEu$>xpc-)m9v;YQV(7A|&fHop`&{saZ-QuE1@iSP@iS zgsi0WSKw?hp<(^FmCw|zmh)&T5pm5G58YlS*gh>U;8kGvA{Xwzki4wjQoqBQA7RTU zRGCsI!BH6=|Gi6{A)4Jgu1H=gORM6{8g{4x)TIjf5rp-t%wSu`P4wJe)n^GVeO}&O z??xjMS02Ab9=U$zAYy01-nIogg47E-*1^n{5X<(SQK3FUz31&HVEnxH^a8x>{#fym zz&F&R(HFlD;FPpQEk`8SFf{m^f@d^XC+`;RtcpK*{{zSVDL(y}X@IC9m)v)g%bX65!hCn>R%IxM`BhzMLf; z&M1AWJ6}ghdhkO|{VI3mw{1UO`tsUv7u6YV#w4F(ab<8R44d(AATGUn@k%RETw3^= zTcM-9z3h7Ci9H6CJGrnBEOIQrqB3`9rH;BtvWSSg?+eSv>c4AJ5A5Ap^PvEpdMd3x zAWJ%4c6fS*ADqT0Cba7Jc5@@{2x0c{ zpH9^ucN2Zga^TWg=-@hzDvtNCy%ApV%40UKmFSK)IJgogKVGqEKlc&??7F0IV`MP?c0K`RVtnI< zU0kh=bypbKG_d^Un;wxjT}#SQ8Zkm%wbw0t68!edmF%7<8@{|^(d&}B2(R29CHTu| zBuvbjQ0Sb140hP*=W&ngw7J$*sNdlz`ZpD;t<0n{jY^)aIIUvCN7gc+x_0d}wAI{J zeW6{dVbGM4cViDEd&|A&U1vFo+g5sOY6Z1;*kM};@=BeyR zli~)A$F)DspVTn5u!LLN(y!k!7p99gukR%Qy5@{;58Owa)4j-^7&h@PF&B9AIOpXA zl+0qtR+dm(*JgmRwn@s+lv+N#)(82X54%*A#nl`8oipz10eJ{!Vg=y1 zW7v_K9gP=tYpQoX>PaXZ@Pg@s6Dm3{$|P4lI=7p@PctpwCxbWn?ard1Idka8D&u|s zUOycvCUQ&KU02p^BFEWjCnc73&t{=ana6afNaWqTdX8l1{xiDktl6PCzAw~Tc-k7h zMjNNgCe=QTGMja;6bPrromW$(9ItMyN z-ZYA#cQC?+Z+TN|8YQ|sybTuN^o{aenwsT2r2=npnq=0qjES|RIt8_S^xM$NPuaJQ z60W|(;q3l6@MvCso_TGF;-@E#p4D? zUN1`dT&YC&UOFWZ%41gm(AKimSFCjrPPtTCKzY)vAr#G&-wcd?ds;NR=&AkIsHFWQ zS>|7%B~+jM=}Kx^nKPNUC-QL9oGj{lK%l~FAHp}H@V&uF3IAHU0I1@X5R0bbFE=2r zboVc6wlU8_&BM43RcF8VKRNHeb7E9Y#8%hWkby1;3uj*#9*KR;*1vJmw-Rb!9?Dw| z8jEg`s^04tZdeJ}x%R%Z%J!MqG68k&Av0V1B+>b$2afb-nb6eBxJf_rv~nIBGPjcT zlbYb+wp}Uv&L0XX>b(A1DHeV!br?`LdaS8Z;glhp>T4C5$#zfW*&>OD6)o-bNYLkZ zx`y z{Q-IXhNmc>V(uunAZV&YEL0u2$KY4tyOlRx7-{(B zWlUDnlJC~cF)OVW0ar1aeuj&`q2Le7Z!tFZjsz-)y*H@jm$`S-(dgMr`+e>#D&D)< za-+n!k=JCW(fO1F^v68B6;njn0SnYEPM$5AIw1A`1O3jSB zQ#G3-Vn6Ht@v#Gx@Ao(m^@i~-6@f_yMc@GQp_Hh1uO+QS0+?xul39c0ZS$4od)bDH zs^MKjped)j+YPu0|GrsDT6In8(SMfwgsj_s;4+F@mrV!6(5e#xsVrv6m>{bSrQxV| z)oVb>1~6PiBZAH%Ge0Ytx6X~V7T~gtSJimI!^+i}! zYgbMy|l{8^el1cMn`8f567|B-CFZ##+>PPu{R{qbFOQ#cn?qus36PuJ60Gz)J z=eRtjv3{(E4IK#qQvpSpmyXrrq~THaVE|A1zjbT>Q@7s+>{@@~ z?eO>g(^b}&sqs29@H7rp$ZGx00l-hJ!bfxmD9OK3=6M5>{X{o#aA)2poT#hiXg#TY z@IL6=jtZOW!_sj)^-h9cw4vFOxc+l3H;|HXiWEAI1^96?aWN>`MjPz5OlG$oCNamJ zw-}s1Ona$WA{=~BvGWt`g|)?AN*8}$rmM7UR@n*Vzb{W2+OtZ5rnUFQ~bh$Rc zZg&r`f%YC7AGdk~ySGooBbr&51X9g)Tc7QmpUD#+iRls!OaLy3I^!TgC$kAS2at=nO&t*_`*{smtiKC zEyOa#?X^&F`nAM=hce3eYbaO_?4VJeGh(5kRa4!TRnxw?vVUD;TxN-gs5sIAfncZB ztDSeeMmN)5$Vk4a}`~%act5~1;ps|gmaNaxdUoxJg=CiR4xT})upUo z1y>q>jFv)ZR-OGl8@?Iueo2ctIDREnrOp;!@n-PTvRk4Gl*t*zc00g_{37n@bbBfv zT2LEg$fmm|%9vUD=E6qYr=H1ZIv|gXZ(Au0UXL(;-D&A_S+hmLmGDd{6x1GbV8FUKdlHZmYF$4zZCW)ljiL zkb7az2hh%#*o4wQasqO5!iStbZ>{Sg_A*2(yp#=8a6x+=*(fVB!1~bmOT9>T-3Tpx zk^__yXrrP_g3e#a{fC*SX#Q;^G8ZW!5){Tl-mD^H$zp499a+<5c02W}`$d7nu9In8 z;8*mYl~jk9k2Tb)aY9Ej4_03`0Z-=9=uFBro9wPWG(x9u>5OQ~$+8Pim-6_>p|2MV zj@ag1GycSdhi2czzLa(QJvJJ(U*?l(Vj0BMLM2vkAy2YchaffG-&Sw;ES3xC+NlSq zqtwfW-t!Q}pnzbkw8yGPg2s!t&>)iN#I(XCNl9KaEz#;P-G!YH^yyEGXQ=a+gJ|VM z;?!A36*}(!A>!Fz<5Tq+YY??`Elyy&T)SF*{iruG?VOZ{cMlwPVTg(Sbg3OD=CsqdPO{W!siMX4X3k>Mczd7^DPtN2a zuy1+XqdF;c!q<7h#VSJ{of#NfeE-`&V(BZ}uih+s{-FbnZ^_xeEm%K)Z~Ubd{{uyw z`qRQcZ_e=ipUVEh=QRHx(aef)bL#iaCDict`JZ!FcgtVk$hm*Y^xY1~KVQ!EGkpYb zUjJR@`s|0eoXp~iE;OFmOZXk(x8q*MW~o6Br}RpIdZ^7$*2x$mK# zlp2V!fwW^2>+IUMZ%@c!f8Gw3YyQx_PbQP&1&n3>2Yc@w)b!T2joMLZDhf)q0@9UU zBPgIEqSCvF5b3=`BGOcvh=9}xD7{Lrk=_Zt1qeN~01_Z1q?{k>-rN0@^So!~`)1ym z^YDign7GQl?sd28T5GxQf^}U?r;3l-QTZP?K1T-xyLbNhVP%fn1gjq*WvqX1>t{+2 zXrbM658MctK5z}H^v8D^laocEV&7Lsu{*)q@P{KCMpJxTUNyqzO5f5W3Qw#=_Pd_a zqUZnH05jTQss>dME5qj6a89L>aLUCOu06$zyK`N!Rn8twn%n%~L+SjdAdD{ni0n_< z1O>(c&KOqZ<+{p$Jc&FgZQ42CHJjE6V@oW5)>WE2iYLUSWtnnWv5bug8V2ip;3M+& zaN>pkkmhANT2U-IU5!%VQRRj9tv}HZXO=YSMi<5KQ3RX@0~3S7hdyYCvD(S`%nSrv zCKV0|GtqK>wmtVxD%yGL-Pf~#$qVM$N;vGeV`JZrEl|h65xiNJ7Sbrsg&D3( zH|o`nbp2iTJHf`bNT>4T`3G|;bE|$$;!uJa`TanHvXy`ppQ{|aoUl2_BD$T6jY<2*vCnu*Uwl62FBz%8bW}B%{Q_%J zv2BZ*AzZAiG^kTw3+33naaqdN1$a2^=(Q5bplyB|G>%oubFDt=Fy8E16s_4{C}BBm zNVr*TB_08&a>vGHms#6st^o7j6#cP(gB%^neKW@7afkZQI$s|LGEx1kgiBrP38x|3 zNh~taE5OVpBKWo*?1% zxp+vZZ$k=R?g`7&*v(7^&Px2T5$|}H)G|p})iW6@3OpQ*PK4r@L(?h5eiVuVr6-q3 zr*lvBdvF}-n*1t^3#Z796qa3-GsEJh(64+IWExEQYBqMza+@VIg7Miys$RG1EvPzTr^E0wO zr_|}JK@BvmL%==-O{?A(2t23ww+WT9*OoTD6hqLM)Xy_Zw~}) z;!U@u`#j5lo;^nPL`UX>bRH$uVqR|WzWjTaVevOXrZHvy zj#iAmj>qC%MW2of4RA%X7CnT4l+L4CV9l!2mKrmu(~*KJ+426yM?{t}L=WBeXkf2Y z2A0;n_*f?tz8mcKr^7qES@T^uy<0bnH-`wQ;o*nLw9;f(w2{uhrdvy(YSKBcWrLQm znjjUPo{69 zYaR%}+sw8(A#toj+Ts|gM;ba>+UlrE>GZ|B7B;hQisnUCm3f!xIdTOAK((O!PJ4rC z?E^JQAQo~;vk$u{q@DQBGxftJ-Vm0HJO5p=QCxb5kvOouf<+@_LqE}0IU7{4pSb{f zM(lj8*an!zQL13-`<6iSlP;eMK7UOvP2PSg?=eKaf>+K~;bq}j);oFMaz@Mc3}o#t zl6(Ezu#d;wWI>PXcCv0Wx&=H=mNk+x2(u|bU!C89bd3()ZUJR$O1@n1dB{YLoy2A{qY^J z!y8hf^HG&>QeO#|+PG>m2Z)@#Jn|-U+JWO(kf3e^C2 zAfc|&iRYeHAu)zC+^3@HrpdJg+x|568b5|%BcT+QTDGSTlEM6UA9RciyOz#=H-=V` zXIIxLMP=(R6iFW>Rg~1;-o4v34%0U0@t4zh={`{*^iO%o$-(?@R^|Y`bLIPL0?k|I39q-!{E#MHAFz)?hn8ll|e9f$kB0gqP}x z0-4$E46^Q+p|Gr&g+bBE0o`*U`U=+X!K~Fl(C97Vu$FW5%}VL2jjheP&(?_95z^E& z43JDD*hkj3o!B^tbVZ+C?~htIr#;V}30P0S@87Hz;E{H{m~UE7HV9&1(d*6`D^UM!n98OHoz!9qX%&t0WuRgU#qF!ZUlkKC zshsPMmKcsRjXxPOxK!9e61ToKx+7ogg~z^dF)Tx0kWLXs(H*~VfmO~4QV)28FmV`U z7sNzispG(Lu(k^BSuf0dvgm!2U1pAveqTaql{0)}GMjwmTp$$ihIHpXwB(L+69b&@k)yh_cEp!*LhD zhuGsjM3tI&c|IA>I52I@LH8I~-dN^Z=k2uBx0TVxUJ&TcYDKg0o}lanX_qHQYF-Qy z5&@%!W95^3XI#2+%LL-Ey_S$NZF)NZ_S$&Gk0>c%(XR%g5Qr5R`2BZ(MDrYcPr2CJN6Fuf9nsd9R|!!A`RK0HD#wfEGahpD%Iczu{qK*sl_ zDi8e8aSCV=Am5BkDJ&P5aBS?9xNT*y$n*9u$fFUPow^Yqmhi!e&n3ZEWD&5#m(6o; z1|ZV-fobx{y*$orXpv<lKD$VluFEEr|dVNFnjH@3AN*w?OzSd^s?O-K3#(jz34Gvo^6Yy ziV77y2B?e=Iw0MgQ&1xa!Fia;_P&0MkQTA*O@5FmDEz)bO>Row`~qgJC7g1TsAN>_ zjwgk}&O9j#OFE0U7@3K(Dzh7ntunQ%%c8CF&mYR)HX~c#e4*z&RlEq~MRAjm8@PB< zWuH1)DnSS3Xbz;3GlF!#(#{mFF?3m0;|M`ZGn!8@wzTt8Z|tbqe9_yw1%&N~TV4a+ zrgt8VyaXv0<7V581yn|#JVttBU2&Wik3c93BBTTnG-~G-+^=muzGL$R_MHxzjoa=rdUv;>|s{!AgXWB&*U8pR)UeSO|_$kb!i`hi>5mtHz{;|#iJOrM2? z+x6PDvSUqs&sG&?0s2QIXm(|~bxM+YMk_``Y`lEiNd<|oxN&ctsw?RxcxiL}W()SY zlzxvf1^)o_TYYg#SUs~OOi_Nl7uHkc>2wA(Z^LiMo7O_NRV7CjJBiULUm z5D3g{&H^c2jkG}L#(KI*aDZSZ^sgX(>-}5e5K&0pYp$Y@zusjWsVg_Bhp`qS%Oa=+61${s+AU4#f}=caOQ~1My>%tmA_!y-`a}XMs#b+e(EWCl9M}# z(Vg`Oc>Vg-wkw%vV!vCCNNrY21fBnfs4ytWwM)Fy(hZ_?=WIsVkNA;7ab4>kWE6e+^b=xv)bo>S z!@c+uRXDr#zu>=<2llW(%4RRSNC!&J?Y7XKG_!r~V)Nsp-7`ztlOi`R3SIp1 zNk&Fc!^7T8P)F^VrJ1R-pt{R5=l$RB*_eRM1hp-mJHNPiL-MAO;9WBd@C)aQlHxZ6 zZ`)bhIjY;6n3@URF>|#rHG870AgEyB?DWXY@wT0fy`8O@t@A|*!F#sOW{&oD)+Wwo z7tKwqoy-K4EUbY)2`cUX>5iGH-E%X+2WGZlpbtq2F(ENIIogwd4AnhhHL)vfTxskJ zI>~&vW~st&va6n@fx5~!`arG_{J}oea<9jMw%<;zs^0qswy{o~P&oV~b0bt{ z&BCqSb|t6*_4JO=t9!?;M9SzQ{0_@&HighMUssCY@)M-AP=2iS&wpAG6rwSO_;DvGLHR?a%3A67`8NX2!9hm(nm^e}I{^jURDxq0r1xk6QT--;le z$v59A{HEI*w8<=aAw_kJ4=dmQn%YZ0O-{*>%N;7K%k7>UB%bA*y!^wx^O_3kNN^Le zBIQD#Kv#zHBuCk1{QQ(Q-l<5Jfv6>U4>aaVwhrJ@q+~^BKO!4!-RSrfP#YOp{A%e? z%f*mae#;4Ye%)XvTHt`q41O@1;W&(?o$b0Ccr6=(UoF~pn)T*!<1$&4t06w!c6Zw2 zQCqBcY|rr5UYpU9%I|QJ94Y=aZX> zX=2^SHqj}epOl&C5pA#u3cZ~C>#Lor9Oif0yQJ`$9@}+262~sl(PcSF(GB4|KYpvo z^PE$A14!l-(Sy_|QFf-;X8WnSVu(%s@lMiFPN>rH3uXzlrS^SMAb_R<=u>Jg!?wF_ z>?c_Vlw0abotrntD#FEUddk}(4Owve3K+H0S*J@f9Bzm+7KC6@})- zup&)0sanxY+JXdr%u#nEa<$t%Z1sck6R~JAH>T$1WfvNS1FRb853C_A9ox=qc-kgrLCM zQH2S|r!|jhb1mhdGOe(5en{AahEYh~itsswo!7(*3x0sAzxSKPtrz2fW8)kL{*!3C z>vWpW*DTTvpzhjOM&=knP3xP@G2iQkLF=RCRflUxaIAMjHWP0Em1E0A_o+`(T=P${ zy_UrO$`acx32uG+cSMiv@{ho6GW+^sEeR#ha!`O8Ku>g(gP4v)84+D3jxes}Q4>zf z82>shr;P} z7$)x$wlqal>#F1`q(jCQ?SiHc%UzN1h!j%OMSH*0CI5 z38~T1XhCBV)>vJiyNs{Qc+-_#U&7S?8Zdr|3_$e(DZQ9SsBX&SB=l>TzmB@c1r6jc zI!XnULg%MPS##Hv%N7n_+0$XEa%rs?<$7}kjj+oL1{jSLEd#hWj!=anZ%*tHvN!jt z@{LQ^A4A|{sE*OZ?3*=JCHaxS|1@^YFUaul> zSQ7uAqNAc3tdn=~-$XCZn`RD7y-D#x0&}1(I7)>z;Bdh$72~n9RNKl5YTenX2j! zzzvkBEWSJK$kgRqMKfw?$tn&NJK{8E=~r{YW@pPqcgi|Eu*NUhA>+zoL_|K7aMDxM zXCglQ(*8nx0v2Kpp`2#q--9YQgzZjL?dC7H=?>K=6NWbT)XZ(Xt9@FPQ~X?g6u>R< z=}ojT9uiz5-G_2RR3(odTz&uMnQE89_wz?sfGxyLr_~=IUD(KV%IZmIZKJB#j)vR` zr4PP#oDaeaYl>D>{9#(L5q{Dm(wkG`?91ecL|pf}G~OP*hvV47JC*ntJJ+zVV!6zP z9`){crFXA^7JZ8EkDq-!Y#p-~I$?Z?OBkde4>5o2QaUyDe&tF&`$LcFkU0dV*^MJ1 zUSjNie4>PBov+gtfyKDSDq2AN5_VWHcqN}mtO!p`+(y8CC}Vee%=av>mqe*p0moZc zE9iNZCyHudAf#_r)s)8!0i24pLxmihjqiZfOt=k!pyYl;vQOsCY3$5ADm?;3 z)qvJHQscQB*h8z`Jo=J|UmVa@>k4?{<1z#zyJ(vXok`VYS&5i=>T`XC{vf|DNp-HiK3h6-6PMGUu$3`iF%!>zlSeE zriqqSHC6g?3={B0r1w{d0kS!MwbIGLZ#lWwT>B^IIkRqF84Y<~BF`WTDdFvsjQHd{#Q-a zC+l+|Durq0sh%_nRCHNI3S=26rqQE{dy5FKH@Gh#bq_naOHlUW9v6#^-Rf^%9_ksm z_Zx?IZ#v$kBEjj*vv3Q<40X~Pi_^rx?{XK){8pasP3{J**d5XO%+xTfCwmDRc+I-5 zPH|Xy$MP*fsN$mmw4r)DMu$AE*u@FWOI>g$8&J~oTc^doN_ZIY0+01xYq)oxD-T** zo1mNKzD___!m0#6Y@$88T$wmqR_xq8AW>po0n&_v-us?5_e)68K|GenS-jjsyAI=% zGif%Q6I#+b^|adaxrlnG8QX>Uw}x^Zq9ybbrl**J6^>fAlPG3rwLi&5;_K`Zn&tS+ zE(xXkvO-0Y_PR^eF~RZS@(G_OJ<2WQO64LmJZuqNG_gCv5`V*$n6C70}(&rlB28wQ~W4o+kpk!MQygmL=J9TyU(Cjz)fqT*B21m42O}^apmMuRR6q}D&WoaR4#xIZ=zjZFtY4|-E2&5 zQ@&aaH9z5V6Y_K_uHo(=`IfyWo>Eoh)q5>k!ZB@n$`Y8?HWn=GOY{Dox}wQd$%G;D z=@q*>sjIggZc+J#H9qr*q*unGdkA3hCu^3@caR)33-5uQSo>2g?WeaN>u*$~NTp@H zU5OyD2on2PyK+CImykVxBa(97@3s*FllLdY0(Mv`AVX?!Xk9na_W1*wU=?9t zaZc@g{yv8QoU@JbkFkqp@NQ{^Pn;M?kbzUaZ_xF(u>?n~ebQaM@%m^bx`0N&qKd&9 zG~YV%0jt3|pT>E`i$;MO&_AF%wTl=7<_t=;Ae5cd4i|kmaM$1&^v6PZI_qXKakdn-7ZSh zJ#Kg|QK%R=QdMgjoF@(gm0fVGCM$7k*hR|<3VQrlsK-AhJKJxZGpcPw`chdG1}u~# zpNo(lSxSm;O|QH`WM1arqw>t_ui5>c0x80f5oJ~OYFUCJa_rF#*u)EqF02wtn@8*n zpda}8QBBiM&iiB0(*@3ZH@yW+w(u_--nA2~`pox8ha+-Z_KqPrWG;yli1KLv7QUJ= zKscFD7D&R3?^8xiFfio`xn;SN)?u$9$JjGKM%^54_#(}!E3;=__--TS#q;4=5RGbx zn`~>oF%-8`xuK=3GKcUwRuOt@_C%Jlu|vw+7@z`m(ll7gM2*Zinnh$1y1~os$u^94)oeP(6+cf-+anw!LOyiz3uB7HrPK4ODQ+t5T`#Jr1yeCN z{0M$_QBSq%{!8twChGpTLqkDYW%)b&o`@4g8B+T8_Dfi*s?61fJ^ITn8Xh^iuy(fH z+ZTL^6@;?94FkoVwXf)`2pZ~ShGu?KIec5vQAAQR;BxvjL6Ctt1SkP?Q@%J;aQa%_ z&Si8K_ZAZaYSDgarSH47TUO@nn_SSm{=Mp8SijOs;)P2ea`tVKaL(OVev|#dInTe< zgxJ^#ZIxbM9YtzLtTcXzi=%GY53ag>*{roQlJHBm_J_XPr7boX2@cRg7evdI zQw>`^?KU#%>ck@fr!+Y_>Mo;!@b9}Jv19UOXF^Bik>e=^z_bPoD{sGFSb!HIoX3bB zIuv|8rCT+VVy%hHuyoMqNVXGo*y`h=&wB@w))Z{MG5;FZ_c_O}aW|+V#!qBWml-2d z+Y_G3b)*#80b7~2p)#>vJoeaoZ>%#I2H>#@%0OxXOiJr&lRU+InJj`dl0*B`kVC%} z?tNtv5iJLge!c+29sZ{K@hSQ^otU^=P{&cKg%tZj>XmCnNfFF^y{C553}4ji-nVhP zq5-xjck4}~^BcJ_lEcfc6-+C8dphvq!bO^qSALSqAn~FhGJ&OOsxX;c$E!t=ya8Pk zt2Mj4h#M9}fltE9YRRLXtV!qC^dCFHr zoKV0!+`YfQKfyW?cc^kLU3{g>{dmO*EWQ&PmrT`neCpO>t98_!rp{{sv7uy`Ujy^m z-V=>+8WS-(P7xmWKn}W_rkzucwco@iE@vaU4XZi_N?oUWrqYNf>?5jD+H>hWg{M4hqCJ*l6`#( zoC5`1XN0>)&+1xw$F1C@rtpgiqFJ<(vnV;uozx|H`^4mt<9K1butGNPtTk{ZiWkVp ze~ZO|k3cZ7zTLab3W834I@63fB|p#AbrK!eRJX2FoLG2{`OoZZ4pDIVj~M=sCV`mtt_eMqvv;2Cc90k!65}lSoeh#i+=iv^YeDKiu(Mg zY?u(YRnO3ag7uwkm^f1n+U=2@$%d=R0}EWKK;yW=!L$tXL!>E#NjsF=Bejw2LCLDH zgFiGLNGJa2zYP}9IKmkM+|aAQtqar)0-QRa5HBn+f=v(3m_zqGH z>Ml+d7?>!ZYj5HyIfiWxQT3ot9k8)HDa=NrIpe}13CpRXt#rFB(g@;2saskF7YTtX~ply4-*_SHt-5p;~>aHVsqQg1_-)0fQ5s zkk8KBefoAp-(}pR+}@A0G&s`oT>XBk+DDJ-iUBJR6d2qKG6|q)cOuojx}C`qfo`Db zh<1I6V?TuYkCXbX5VDEp7Z(kvpmUA*8hLei)Y=UX5{H%=#+Q&Ki8_^H+@&b--Kxhe zoXOvTP?~MXbG_cfzrQxLgE9=-G@6lRMo`aj{TgJ0{Cd9>wHG7X__fEgXvAQr9cN_( zSC^uG9tUdm20-^IdHgGdZ$fPikwIV6mS5 z%zI&}`?jwiq0?>S9(U-L)gftdWS|P`hnSiR@h4G?hDM!lMO}_iAv^1y!&Mu{7)xH1 z0M(`l;-#(Botk6WWV&cjS&3-i3akr>&sBY;tFfO_m-;olm-n-F74mr41tTpJ)b(8V zo>C?pgiXMg*&qv5=^Fva$VT|HImG36KoQ@L-^Z{9ksbc0&i=K$up>YW>6*CFRlzh; zJ3nNgJtl}4`QT(>2RF#c9KGuE>QQY;44{6^pU6rQ;1^#byjNgV0iz~|Kp0eI*r#=n z$21gGts(=Zqj@NDD=f5O!zoBtD0n~l{w%Sm*yC5y;>#zVOK$!Uy~p38q7#BfL?G1& zu&R6Rea1JkA;-7H#Z>Q;z4vyO-#9#+s7(~Ig%UP#*;MgJZOQxM-q!s}PuDIf0iOHj z-{pB#a>Urelc``RW^FLTC3)FM8f@K8a4dhIl93tvncWYF@ajo$jsmbQMaE*jfQ8MA zI^5LoEgDfbxMVUIio8%RdeaG4AM`_@T)pyDr+U>2d31ky3jaIk@Nc`h=hr?lS$)s;DO1duNo8>>w9a6)EHlGlCR&mR9&g zr8+mXh}j%jUxQA{v+9GNK z5`Io*w2s{N6375aLUkKgs9W@R7Ai@nZC{X_P{1wJExrVVFy(CpZ!s6<$9&dY;lOeH zVXjm1F;$P&?p8=U8Sm~a^-m;9XQP`v{-Mm9-4d^_^?Q}~JYWV}xq6Rl`pE{jjb${{coZT^AHM;zEVX;A@EPBDnrntB|J}P4wi2crE_wBC?d1JBPCL2Yk z^te}RDw&^CH=OHDmNOQmzXeJk3jFjPrx(*kL)9%D?FOj@ID(+WA`q)H- z5js%|wkgzusN<7&7$CtW9j4f%+ivTD`lcShm5E69Vg|zv%qwWq48J~bU|9h(oyJVCyX1eiuRe zSiYeFjfHuH(Szj$gs;IcSJL?w6}93^t{2r_=vlG*oL7BJl#BmZzg6_Gy8phE_NuYq zL~XU<$_vo9?=!wdp4AqX3p{c_#RABdmgoqu$eqkg+>I2h8FtBNTU-E0bFDlG;FvC2 z!9iF$L~0w{?QVtXWF#SqXqSo9@@z<+BC&J_p9H0kEpYI+wkKQ7DR{2@@3}&^~ zstoKa<#ePm2o;MdY~a3Ws;(%4IBR9e{6_5^YmP}RD**j>ToD(v7LJC{2i4_kCl5R< zivNBgJR-NU%j}94s3rmYK4m+l<%WyOcvWk>{q;=$>p<`d#E3Lh6P-hO%)P@i$F(9~ z*wMThM4iu`WVIVLL{x{nrhP5VhtEQ48GT&hpHiW0R`Wl~KC^9=aloa2yK(%$l>Dz9 ze;4L_??-(Yob2bDa)G}$N~2KUN?1(Pej8#4Mqts`A>cBTYAR2%E!9nbu+|v6WND%#xQsy6Fke?rL3C1sr z;=6S(=4ZA3N2T>=xp4pEzZuzIZ7fe+Jn)k0*WSJ8(|7GB=q|MR)z4>uex16hY25Xn|Mb^HP!|EqHURk{D=yAe!F1xtW#eGl?-!A%Fx z?4#f4@Cj`YS-dk@O2z$<~1(y3t!h(O0#a&ES(9P=D~}7Rdw7_^MO1tZKld=a-}%&mrw9Lq*-jkXM7Ino%skrBpKtToKq|J| zzBkByuvQuy5Aw3p6LfT)Ju8k11Jdc(eYCz`9yr+kl7;49SZ;9BHbPTkHUEa~ean&L zprXR-T@Jbs3(e^QESlO&MH|edcIc?=c%zqPrNUpWp;L4ATD*FpqumS?{Xa0QZd71_mEO2`ViPUj9vWS3SH%OQF|qZT}8bwb0Q4$@^GbE#g%ej3_}_|=mr zRXh)?5qbQ7hR*{kl!bSynJe!W(OW)%C(bM@!oL`vYUqIB1T2zbP5?07ILDV7?LU+U zQCG=MmUSaJ$r?hP*ZHR9BD(%v?dGpMm;=bFn~37QfCHOss1o(K#~1lwg=$n6ynYTzC(N7qWNr;el!xj>`@phtfX`3 zuZS}&!Oz!GBo($f(Bz+cb3ITKRNnSF!EdVYS2gY*3r9dT3>%YA#^-19e*jt(^pFn! zCp??g`aRlYbSI6^e)U2kQ0j9ioq8HgtdLQNuksz&59$Ofkq=)pEu)icN_#KiNG2{+ zy5n57?V7eb-16aj7(rA`KAZ;*-y@jqvCreOF>p`qYVXL;ISD` zB%<=c)-~h3qQ?{;k4^L+7K5ug3w}_R8PV4lL&Q(oNp+GTEG`CLRm-vV#WMnf8 zE+E1=24E*;CG+WS3EJDjtzp-fv})gXz_R@-+M=^Z@Y{RCE~^IUzI8ao3b@@emD9C! z6O66bC+`60awQbAfJN)@RqrjyRMyeQRK1`ZH*3{WpDo81UHaIs#j>jUq9{GT;}Fyu5;C~cFSvE<6)B@$PW znB1h?-0ULVF=~X?71r|P^6NbMh8O7}8i~<%MVY3Nz4GgqGvH_AK(^TUw{+WL@$Ii? z_)dx`I~3gK86V7b8QJZ%S2bjKS^l_rN2nB9%=qOmIIvui{CUq!yfVklsh2}w?iXpRKYlok7YX$s>{)%jPY(cgdW6O zt;C&AML{ohH4*{#*&Lx&T9X@!R^CLr&Q{TPtFqdB>FR#d{;H@wbr`j~Y*^%6aUvED z(KUe1qY*xdJ z^C$!IDyFuGjK{(tbQqPW$5gn&lQ1Sh%04#B29$IG95Yqj_?GCf?)FhVC;@Ezx&-V~ zBsMg=OGlum6CP<;Im0q-Bj)n_tCUXD@w%L+JLO$=JaPj_YaW)kBJQo62v8NTVJ=+x zA;E3lTZ5TgrNv;#fh;Q$7j;4A2-`bxRK{r1eYFLBDK>WWkJY*i6=?a4?_++)>78e6 zMWH*p);M^i_uxvrkR;$BOFFk2zjqUylZY3hzaFJ>GUO2LUou<7+M=;mD-0>Y!F874 zifu$0nNX^W9S68Aa2L<E06mtNBb_k=1XIN*hu1Pv+*rGb26ROF&r4@zKi3m{H zDxCo)|KO&y`+P2D9V+BCz94>%ZP`XF>cpV#St+en7}XoIGWS72?lG#4NtJ5B#7_I& z1%@a6^3;YgJ0?Wd@hh3&L8B2xC7zOwj1FQ(x3T5k@ z)EW&+iglNsu}yj<ph-a7*j9S`z^6GwkekF& z{Vy_`^K(Fyx25N-;t_PZtf&!3&@J?GeT#P@HGXp~=gfod;GFSBkw6?a^kg3c^I(f> zIz}Ef)JOKfH-V|0<&`S$8rKncCHLCzPEUWlUdRUDNzoNF!u<5=#RQRnvoq7vjXU8w z&@0Sl948})lEot_Tn2b4M)tp{&tmqUY&d7cNr1~9wdJ+y{Ylmg?^k}v%_P4_T%**xpaLn(g&UOAg3-jNg&Q~iVI zk@17)@qH!Lk$`i|BUDlOG*L{#JWJnAqyKivm0fVdeZLH-Y zpBZKwF?rju!+5Dw>_g2nDDYaxPDYnSW~Ps`gmU|ouDhSxC1}#ALpYBQqVgqm5Q@m$ z&K~*7br4C)0QVOgfdk@XGK*@rRRPzEsQfk=PbP zvi0CvYxxnqrz9tQ*GhgC$GLozA^qmcFsi0Tpn9#Z+oT3{nc`>c0$I?JSViY zekA4LM+At{mUkMXJi2z$1pK`KV8$qY2d$^&L&<$dHYJ$=$l;2A*bhV*8)3otB6bC} z#+)T*C<690td_BwHC?|)r{yM8xhP;1E)uP1U6gs-=`K}jI4SN=LEHy#o1S8Hd_+~X ze3D_sw2@;_+=x=qtgnN#n!F6doM{tetjH`aU)oxrm6p!Y+&1_}-Rvl2E5ufp% z`356J+m$u)lcz_#$ z{zg|Ctbrgp4-;gq*B1l=aTm9+?{V2IWL5SYEt{C`NfsGP`;D&8M9EsWo$u%A2ZbF% zOzoTR9&7n*ZcXm3J!f?ZfU|x_+rwS{Z=&sUyL5CgMKhH0Dxc_jcTJ+E$B;SFdb#zv zOV2&n>W$bx*S7r_P$5>f@5#03@o7m4R-h*bQ+B#}q8M`ePVFvyKFp)BW&Q(jZz%i` zNBB2?{!*a{)!`8%-WrTQ^n)8Aq)Y-=UGCB$g+AMudqmkimrY6d2y$aV-8{Xuw-U21 z9DvX_rdZ3;A>M}NW>la)K{u!5sNo;ChPoYJydjQ;_Se*48NH~QCC}cE+}GEuKS)`^ zIjuZ&O17&m!BZ7nlUg>iTniKC>Md8x{B~UWKOI@gafnB0cxRN2YOn)P#7_X8WM{o) z0`)yaM^+*5&_)xl3YRAcZm5Z+eOU_MZfb3q-w@|qnh`XZzaA>VhY+XE*SV)%q zn5i@~FJDvz6F6Lw#sqq0Ka?Rh7XsbW7!6OOs&ff^20UmCIJaDYbidE&IQ~~K|C1C8 zXhij}a<&tZ=;3$&eA(?IQ7{qS1QtdrI7_c*@oZf96{QxoRw3;Qc1gaCq^}Ilx}2+ghi$)LDM(wJx>Fg=iK)>?X2#j+8>iv@V4W zma;vcvLRcWEoiaYXrse2=+W`ACAdQGD>zKM+Z$KDLqAzC&QusFN<-Y7S5}y|dJvAZ zc=+hdItzcOoXNuXg}%J`n((BACk&I6+d`Y%vgqW7hG$KYm2+SJGm;Htmbo==dP8PC`)&f*b?_aHZ&l^SaF>4$q_0u*CPE5Lw! zAtU$>cHrj_X{c({R`^zRo$X`pgu+1DOWCoDN=YJ2HWijV)r}VXLwhD<)&xVtoal*( zGAVVc-sDUKe)f!&nAo$((f)=+R^;a1FrZjZcH7yU`B`=;Vq=Y_Vg8)&*XCqNUez9k z^?gNBRo#6ZzZl5b=WYvp^myjTO=+);(EN>8#KbV?#;2*LWkEM#1c>bSlfqh{fv&t z>L{{uKTFVpn%?gqMW48^?!Flb4iNy< ztDd(4M9aQ*6LF~>M)sD8dOmaVE`G#&RK;p?J+O}vKyQgGq zrssNP<;79+VEX|Xy+fYBQCVI(Q4YB<*KgMwr?u4H#=J>tWDKjDSQ~~@W(h|wFFG>) zJi$W^Jl|PaXG7zfD&ILgz((~{2mC0?eq?cb05Gl8Xx07kQ8 zO3Uw@29C_MEYmhDTj<)dL_N^IyUG`Bh3XA^7TD|7-ymyMK!y8EbrZY6y!2)wsmee6 z2TzP^v`$V`6}XBlXibshn|R+>@nH;f)8cui6EXR%DZa?K+|=^Gqz$&w=j$!cT?6Zd z^WzwZ4`h4U4w3g+b4@{EcYFiD)h*woIbRAxmUS53rG~Nms;DMBDSU0f)AE@$ws>({ zq}dgJyi@AWLrI|t&R;J5fzN@X{RG)T5_{a$o}(wUF?XNa%`BU7cF*E-3UJGor*dhu z?*tKmtJV(`s&c(rDOOhb7#20Kfn3@#`3SMp97SomP1$J8p4o{i#dx4mfb*;VE`Sg}0^&q3jd2&Y&0WA+E zz8kgWzXT4e`Q5GM)niIz^+LV9z@Wq~HpT^Q@-$N?yFcP!Y7NX%+n5j_Nj1BD%tdh-;(6^sCdHd!-#MI_PLKaQziPcedOJ}3gqM-=QI92*qODx$Dc(x|u|MRH@4G_REZ6SbDP^aHiF<)H`B+CL-9JQ;TWAfSCA?MCwb zD+AElwqJ1YfAQPDXcfN|3im($S2X{JM8l0{{0p}BzsdO!2y*WMRMU5EwvxXnfWXH1 zoeA;(3pND>R#Sv5jK7QA@#tFZ^eFKA8WAG$=7Z|pt0@s5eLgEqaLIq|JxwLVO*}5u z>)k+i@utZkQYw@A6r24`yNln^C`ZkT)p^)*sU6N`<;=1XW?nOoMZ0=!JEw)aN#1Ar zQ>FbQLx~IlRt+Y)ENZIL3at#lOM&Mv=N;=~GVJqHzD~DHO*I(cw_Gpp^6Sg5Pbnk; z50rg7O^UMCHHUTu{K;Y|a-z~+Mt*OUv{Rn?G@w30n{_nT| zz*Fds0qtkO%Fk5cPgnleLw&9-o~CzZtdIO*kV9N>b)J z*?E(k%S)v^RN4~cW`u&y)jlhfubm&9QIl@b1zw31e2iI+#s)PtO8%$SFL^}v20wMx zr)mug+sPj~?Ho6D!3BV$KG=*`JJ-T^bG?xSb>sT+#wqGxr+sb8vypt^qle~mSisf} zr8^SFqJbqkEB`OVKl}{HC#v5`d>}1cS7sm%MSP9Fiav3#rfY;a>eYMM+Tn_=IBM+_ zUij@*R*m66*5Vi~uWNku;G!9`Y*gvx#VCo7S1F{mxuASl!re$V1=oxH=2K+|;ACD5 z{HnO^)#3bX$5|!U)m(vjPs>>J2#JCmp^ zAWd*Q3$Se>{QZ{4!u&i6tfBrfExq_xv4Xh|r(~QH&-OC2K6pR{|dlkW*mUC*(?{4Xau#~&v77XCRztMbJ- zzQ2Z8P66{5XnViZKHAR7ZHq%KR>Dno(({NF?or5fjNR5(XRB*`Gv)$9LU5E~**M8yg!QUhco0yaQYic&?2QW79Q=-G;jNEeVAB4DLU=%GrJ8ju=#4-k52 z0g~JmaJ%3DZyy^3`?$!Tw))DuYM3xh zXppLcQb?}5g^!NJc5xfN`|+p%FXeQ=oW_%bamU{H_Etv0K9ZS|XKJ~$aZfq~JG*Tvyf9X4k zTJt`8v|;0PlpKD$JQCbbvI}`r<7mYJh*_}>ZF*_9dIV5EY>Bv8-fGOjZ4mOuIp#|u zD6i;$;7gft#m4Z-s>w_)bW~ph3_B`()MO}CfWI`AUz>AcI-8JU*vx(G_vaW}lv$w8 zFr1!E-1h<^YTpeJ_4%BA=0F&;<-|Ta3EeW~cGI7yTzfnfsi_*yE#7{*>yy~VCk0yt#0#!Z)PgVETu zBxdBTM+jxFu=wJ;y$1?f(1$ZD<}EH6f|KE#3~-KE%w2RYVrdIpJ{uPQ?~Q*DG`6$0 zwhSZ`(p{=5M^ZTJ2@Nz3jR5YQoIgHus28>7AU!jcdPsEttsDPp*rT2EXfaRP^n&-~ z#fNOfH^ikcDzT|Uuej>DnAcw`IO+=UZ*uEm0y$@NiSwy+!nuk%tXjYRbem|rVJ7cs z(%XFPN#p*zQ?l*X9Whr7w6eMyU-4h@%47lh74AS^z?d7uMe0B;{+6331})DcZK&X3 zSh~0aC-Z4Y!-nR=sfU{Q{&exSpXNUsLR$KGTA8pkt)ce~8yw%(ZydTV1O25|<7Ias zTx}}fV|2;G@f$URaLmA#zD~ZkIzO~toY$akq_8$$(IaMbpx7)>L=dZ;7Azl&U^LY( zEa+Hp5`|k27WahJVf)tRNTp))6owq{mpSf0RPn0UF?o6M;$GM}?BdGFYgoCJ63>FR zG}Re)5`p-nqiW=}V3s_uyeCJL-aPnnze#|*J|ZvMudw7LAk6>i1y=boqkEs-UAWH) z2i_0+!Hym(fF%}xyfZ@J4iU_>(&?6K#=iS`0enA>9VON_7n zYOBt2qRl)k>b+^*hsMxIA|$TYsI1~2;zZx(k^YyXN~T5_}p1Ma)nWV zLMo3p(GxUzjk+(Chs1k53^nRqF7#~&frk|t0yp9wG+w)Ml5E^1;i%5&X!w|0T^Z0I zQo3~F2`kjwl=W;}vy5$&9x7&cU&_V!g9@yA;zWm(3(E_2o)X#F7)w4_2QI}L&hBb~ z0Ijuptx>t=ed;a52RQ%e$0Y8{v_i!OjpTUdu0{3=x}d(*H>Aa`=XI_umB#ucq+}9( z5-hGXa`&Q#62i^K?RhSu-J@bXhDijq$;lR2@ybM`&)fPXmmd;!<;lDo+5!0w-C*eK zZCW|~F2*$6gBf2VH?O(Y5kl_(bdfMaTS1QL&ilza`?;*h;nxAbw?#DKWfD**KTmSb zF)Pfo5@k$CX}5V)s@f!rsIhwcF5EVde%Y3Ke4aEYc!H$u=Xm;&WA##^X&EE+K&K`j z^d#D8`QEYkQMWPe7kulvZLs>OkNPFW>1S%OIO0ikR^r>*XL%8<=*#ZQN;+rFBKRUy z+9kyI)+$t8oVRdL0I&X~S1^oJ5vbPeeG!|EyJ($Uqf;vt${oCg!#P?>O>gJ(bPMo%}cV(a~a)_E|2ZT8Gk-@!*?O?bwx$>Js+Gi!Ae@&wS zt5ySK&JC(owzi{d35f&9)OGi2Xew%ibMxGzDSz-48<3fi_A$oxpxaG^(9i%UzT z$!ka3w^zkLe(-4O{&{pN!qqIi!jNML-5Um5&i+lnm7#b>XU@qCCCd?0KTKH4jCgIH z#6T|QMzVfX&D7C+Jb|SZ@!72+E{Unq{Y)NnKpH&Jrr5kf4{9PIBKs~QMhZRMlw?7; zOhxwYkVWtmrmVYM0X~L3Mo0HsaSI_0x9K||MDM=)Y!*VoiTIp)))1|JNQ;W3tMAM{c8dE*v?mf}Fbgp|@ppA-a z#S5FTXZ}htso3upVubtDMVuHKdZTax&~z?U$8@+Jp`K2B9+wWTss$c?&%Znl zK0i~qoX{iO8JN+t^T9`FT~M$Yzk&@JSR@EW{HkC+2Q;W#^w0k|+Nmt{1ve6hMh5Mh z^v7H0=0Ew1tzI>`+Egl(;b#2mzW6N=a-_&QyEvpmAhKLhTX1-mtYQW-PTMD$KQQ9A zODo2mNKQqu)$Fq2*(QTGbb^8S;~Z3W#%F8D6uh@Bw9|~F+8TP$vZ%$#y%ZK>rgb61 z2m`k;G4~$1#mPB&KIK~Po3$gcT6Yb=ikzmglHX4*(!2szN!D7K4P=**dgyV`M453; zR*uA#skam}bL_Iv!ZR1&2o1w7&DqH&9fo_#wCDQUI;`M~{CUO9ai*Z#DHz$if0bUs zEnB?cIPI>@s3FMTecf7}t z&zQ*pt@guwF;x1elaEEwlM}_7BLvXK)tfFH{+@wrwGp1F2o6^=5*r%JLkZ{~K|AFe zF4SfU_kO-;W^=qUFi>6ZapIlBQ{7DMHtY6maxK<(Jmo|jV&cB0`(pRE3cy-!u`S&= z%bK2cW_y_#92|e2YP%=Jh`S$Lx#?D6m@DnmG5suIZFlm!RETQ4r?t4|8d#@P_NbrA zlJ_g2Z&Pj0OQJNzlZdH$Wr zux{BrcEL~!yhyZ)sR{rnfPY4}S4ej#a77idVx-n6u_li9&ucuse@S6yLyl$)nETq90y4>C>I~#%WJ|E0|*j{Sz(g`QV**0k|$pTyx?} z?G$vXR*znKXsb$D1J)nNvmfCHdYJO;=`&B@%5Q}yuwIdtss-JhHuFQ8Z`&6p_4Wir zwcfrk)OUg@&(^l(k0Wl#vr7hl%=87ty4TbiNPRTv3u`+v({7fvJ zxvop--dX>9%nCxdgZnq4;Xh+2R?M7fF4wt?N?H0Jh;WDab}u}uD+ZeXcE?qb%+AAi z`xbJFr^tPXR0^~>Mf8`H@Ljdt6R8usnp!R2-uUo&bh|_dGSjFKo`g+rPeM-4O0$k^ zjw7X1ah_DM;W8G{#r|^})amQdXDZVAF!Ue;^W8#S7rPYNzBN1QUx=64oC6ivLzV}~ zz2*%KLHK!+3bE43m2Z-zJF>pb?M!T|M?$9D_H6q7tjsBE@{~ot)(>WQQFc0>om4BF z6?nl-Xn7<vzZ_bK<;}~=-nu9NFAbnACQNmU0atg5QEyrwrL9>&Mht#ka6M^ z&A0fnlICb(j^678zRMIH#`Gte;Pvdx7s!oy1a@0&%(OFE2u&wD1B5I2$;+gFNUJMl zbyb-xu_?~+#Cb_3ORNd%2bR^&c$us@cA?C!Cv_a#AK@@e$VzsdX~}!uoa&Fm`odf^ z=HULM9rN2Zk)3w74VIXg^oXpt_xbv|jD}JD<#y!9yass^^pb|%Qk#S;ASpw7i}ZT5 z2ut&%qwWyS6LKp{#uGY%7grQg2AFcN~sb zUg+_fX+GTWw~HfrAl@qDC$eaj>7_MloY8mDB&%4(!!d4^6uTh2@NpvR{&OVh4NRv{ zqH~cjI^qrl5-f;>Xd{?Ig0{D34RNnM(oz>>dCrf)^t80NoxyDZ4R z78tEF-hkZ}(#&%NRj;IK)f_jt0ascvnc<$(eH_oeG_N9d6OlMGbY&M7hH|I9qq-sJ z-93@-c%1sNTPSJO3H+_?h4;&3uF_+=bH6y7@P#nZl`cWp3T?1-bhX-i{54@Jljo4z zs~;F^`U~IG>YtEq>Ssv6H|(8d3lZ8&Er#4D`wstr!mmTALXJRat>^RnloQ;dzpc(s zey7nUtfc192rs{I9GxnKI~W~A#t3&g#SVhcn{mj|i&77d9DG5EzE z*w6(nboC_X9ClA`vxS_fMlmm+~VaF{m zqvcncy2@%dhz9Bz+x18wM1L6Q(olh(tL6HIT^qqpwrnWpnD8sV3%qdd3c(a&a* zq<=jl!x}PN+=p48T@2axI710Ey$oNSq7W#1)y7r$q~NCB=g+x|E;8Q?K!bXg2f2K$ z)iWX^4;I27!byaZPj`SChY7=bg#idH0{L%X9IIR}Pr4&Oft9 z03ZkYkON(JV&wc#cN5CtSGrvCd!!cmQD4d2Y{_QC=V!Fih}p6YwMy&F>OJ!HHB{vAxqw%6;N=uCN0`hK;eWzfU$hvgFspu#-19 zUm^b$m9UR*_g#rTPsXP(7$+i7U*St@366i=wXZ3AoA<@%(}BS~6Vg^Oh7IBc?{OXl zWu~idqze@jZ6BM~8=l(4<5Z-_%(I=E{XTH3rbntQRs^Nec|B-n@|Pz+;%SN6r>)%Z zLO9xKAuaZ79iJ)pdnYb=qH>%?1hBh5%;1 z6~&&RfZMer@5#=A31kkYFM6yK$2c{R%GO@=-ue_-9FG~P!klqptV{*&=+Vh(Bk&9$ zYh(b?bMEiB7h!()Oi~XnEr)^ZAIFQo3MuOv-8F7@_j}kD)KvZ2VdoY2Z`&xO2E6Ok zEzGX0JHd_Zb>j^8$RFXv|1m7fUx=@NwR-+SeEt89i26Tgiin**`ylUOilSM906ZI% za;}=f9e83tH9;>?*#vU;%$#ffBIV~_@7A9 z|4hq9Rqci;!~b*BazlD$9IBIAR1_jL1M{RWOh@bVQOiA6Mb;{?8CVJ+e2X2IqX#wm zy3s>5bnmvxz?s6uRXjF7P1iaI;gYq|++f!R0tLhP&Q{*#SW$T2Wys~5f7V3*)2hJT zqEEia?`ioZgVOIkW0)d5#_faAM2!+ggRO@~-&1J%k4L)Nu&aAVPp}j}+xRsMV0{(Z z@e`tUZ9`t%wg<9Dj%@iAlpFu^Z|l<6uNhwDtMR0SCa`;wuM*W>Q)-5RmWGO3j#m!G z@!H|3POQU(J?ucYc>{7k$%so@$0~t_{IcrkZZA^v23TOc-1_G_g&#ZbU^2R)>_Ks5 z?%6LmU-AZ5>rG74zG^}upr+0l^yV%&qI&?r!U}b`AA+)es?QkWa|$7^1ohA+kv;zvfVYKAZgY1069-95El~pN#cMXqwm)oiE`!F|J~zWtmo~v z*DHLRQv7C-pv@pvQPo}NNt23czK^XQ3g(m`j=&i~H-?Us10xxtpO-up`DLq)Ab|)& zcu7bDOE7m6J`8xhvjWzMCEe=xEL7;6fPY{Xy=-Li!t&0Wr?AD`dLA3L_M~vyuTDqD z5V5_EQT83Vb-<|j-Cm53lFH3Py zxCL#Gwe=sNQs(V0P;rpDsZhrkAlCk{_XpMcj`hd=bT$gceZ0yk&w%SlF>+>n$h_A0 zkO|}S$3HW@<^0bgz$MgW*Ep_i$^iac(*U6t1TO02jn@EM*7!6C;{Uono&q~+Hw17m z*I1(Mm%7`!-XH?NYTY^9smE~6Wa|YkKHT`83}9|}2wW<-Q+$0V15ynloV3h_sDogxG4ge^CZ4_a>Iu|Kc%dneJo z1~;tXu4ZPn_*GcW%Sf0WMw8Zsa51{ySG4iF;PSu6WYTMyOuFp(oI7niOv3&;AnZq# z+Zpur^{$~AT&w4jaQYE)3BIEpYsdW z|1XK)vKj$G4r9#Bbu|g+JsE82+c$lEl*tBCjFFyntc9>7eQ<7C2Oae8qs3_Z+Q$(b zAXvvkSOq%*+gBII)3=aKKo%()`@a+`NcHfv{(s(fd{?&z%CKkv?F|W<>YwX6Y_3ir&e+II`L#g z^C<7+%|{6z(F*cdHvEv z(MyoN&uGt?Dy&k~Ym1iBhjnEn;s_v>e@D^9Vg`E$&GhvPxRR!0!uq-s^S!j_l_{=J zNy~@wm-u%-zz+o#%lF;ZAAjOCVO>>P`zq6mj^X3LkP?<)E{fp#f6OX$&)e(EDvb2Y z{M2$_ccQt{9fmuzY|QaaK$&(HPM=0ubSn;%Aehl(XgOB{ljQPF+h0AL^CYoOf5q2pP?qeXb!sPZUy_N-Rr)&KHZlh%$mH0z@PLIgOxQK6cCTdp zamYFDyR8k{*>bKACGPU?e(lEPil_POq!pb4A_O%V=Tn-f#W=UIH*mVK

4hhbaPMVN~r*ziQAZ8vKh z49o9teWw6N&pTvcZ*&SRYMD(w4@k2Y;Uv;yTzl?AZ31(Ay011k@uMw96U)6BT1IAz zuTwR7t>VbW5rb1sCBgH&RZ;S{SHX7A9_=4_xD9gf7xOW%mQ>1@-RHd`KOO<6H49(C zaB^wsJu31}ox9`A`85}J`q>S&uj5y_V`xv8Hpe}<8D(iY+KWoX>Adfzko#9ja;|FR z+r3WZQ=u!d^4CH{^y;v_P!{cG2_O!KeW$9bfrIh}*9JlPVo>c~68)pQYFi>VV1W03 zg*e$&Z@mfbL@$Wp#q5E8Gst;6+qqJLDKEs(986aoomZ=jq#wAH+D+`5nJl)O%o&xI z?lk?>Fup|n(dAThSxGZs+*5K=yjV>#j7$s zst+&77J#Qj@a=j@y6hWOI1yPCa_D*E5JT$a{~qG8?5TC7B10|5 zB@Gi^yV`U2s+bNN0N8Fgyl z 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%0D8oG{78 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 diff --git a/static/d19faa31f4a04b52f802a465edf50d18.png b/static/d19faa31f4a04b52f802a465edf50d18.png new file mode 100755 index 0000000000000000000000000000000000000000..c85928e37418bdc9ceefdd7a845dd23872b06e2e GIT binary patch literal 768 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 lzoq|uqW_fMMF#->N7Snz4FUPDQNjLc