From cb395d19c2331ca487a42a60f04e5e982c0f6412 Mon Sep 17 00:00:00 2001 From: JNG <365252428@qq.com> Date: Thu, 8 Jan 2026 11:39:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/supplier/supplier.pb.go | 240 ++++++++++------ api/supplier/supplier.proto | 6 + api/supplier/supplier.validator.pb.go | 3 + api/supplier/supplier_triple.pb.go | 90 ++++++ pkg/logic/supplier.go | 178 ++++++++++++ pkg/router/supplier.go | 4 +- pkg/service/init.go | 2 +- pkg/service/supplier/supplier.go | 148 +++++++++- pkg/service/upload/upload.go | 43 ++- pkg/utils/excel/excelInter.go | 381 ++++++++++++++++++++++++++ pkg/utils/excel/options.go | 52 ++++ pkg/utils/excel/style.go | 54 ++++ pkg/utils/excel/utils.go | 41 +++ pkg/utils/excel/writer.go | 81 ++++++ 14 files changed, 1223 insertions(+), 100 deletions(-) create mode 100644 pkg/logic/supplier.go create mode 100644 pkg/utils/excel/excelInter.go create mode 100644 pkg/utils/excel/options.go create mode 100644 pkg/utils/excel/style.go create mode 100644 pkg/utils/excel/utils.go create mode 100644 pkg/utils/excel/writer.go diff --git a/api/supplier/supplier.pb.go b/api/supplier/supplier.pb.go index d8012ad..952f057 100644 --- a/api/supplier/supplier.pb.go +++ b/api/supplier/supplier.pb.go @@ -405,6 +405,50 @@ func (x *CountryRegion) GetCode() string { return "" } +type GetCountryRegionInfoRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ZhAndCode string `protobuf:"bytes,1,opt,name=zhAndCode,proto3" json:"zhAndCode"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetCountryRegionInfoRequest) Reset() { + *x = GetCountryRegionInfoRequest{} + mi := &file_api_supplier_supplier_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetCountryRegionInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCountryRegionInfoRequest) ProtoMessage() {} + +func (x *GetCountryRegionInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_supplier_supplier_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetCountryRegionInfoRequest.ProtoReflect.Descriptor instead. +func (*GetCountryRegionInfoRequest) Descriptor() ([]byte, []int) { + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{6} +} + +func (x *GetCountryRegionInfoRequest) GetZhAndCode() string { + if x != nil { + return x.ZhAndCode + } + return "" +} + type GetCountryRegionListRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Page uint64 `protobuf:"varint,1,opt,name=page,proto3" json:"page"` @@ -418,7 +462,7 @@ type GetCountryRegionListRequest struct { func (x *GetCountryRegionListRequest) Reset() { *x = GetCountryRegionListRequest{} - mi := &file_api_supplier_supplier_proto_msgTypes[6] + mi := &file_api_supplier_supplier_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -430,7 +474,7 @@ func (x *GetCountryRegionListRequest) String() string { func (*GetCountryRegionListRequest) ProtoMessage() {} func (x *GetCountryRegionListRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[6] + mi := &file_api_supplier_supplier_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -443,7 +487,7 @@ func (x *GetCountryRegionListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCountryRegionListRequest.ProtoReflect.Descriptor instead. func (*GetCountryRegionListRequest) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{6} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{7} } func (x *GetCountryRegionListRequest) GetPage() uint64 { @@ -491,7 +535,7 @@ type OrganizeDictionary struct { func (x *OrganizeDictionary) Reset() { *x = OrganizeDictionary{} - mi := &file_api_supplier_supplier_proto_msgTypes[7] + mi := &file_api_supplier_supplier_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -503,7 +547,7 @@ func (x *OrganizeDictionary) String() string { func (*OrganizeDictionary) ProtoMessage() {} func (x *OrganizeDictionary) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[7] + mi := &file_api_supplier_supplier_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -516,7 +560,7 @@ func (x *OrganizeDictionary) ProtoReflect() protoreflect.Message { // Deprecated: Use OrganizeDictionary.ProtoReflect.Descriptor instead. func (*OrganizeDictionary) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{7} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{8} } func (x *OrganizeDictionary) GetId() uint64 { @@ -545,7 +589,7 @@ type GetOrganizeDictionaryListResponse struct { func (x *GetOrganizeDictionaryListResponse) Reset() { *x = GetOrganizeDictionaryListResponse{} - mi := &file_api_supplier_supplier_proto_msgTypes[8] + mi := &file_api_supplier_supplier_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -557,7 +601,7 @@ func (x *GetOrganizeDictionaryListResponse) String() string { func (*GetOrganizeDictionaryListResponse) ProtoMessage() {} func (x *GetOrganizeDictionaryListResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[8] + mi := &file_api_supplier_supplier_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -570,7 +614,7 @@ func (x *GetOrganizeDictionaryListResponse) ProtoReflect() protoreflect.Message // Deprecated: Use GetOrganizeDictionaryListResponse.ProtoReflect.Descriptor instead. func (*GetOrganizeDictionaryListResponse) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{8} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{9} } func (x *GetOrganizeDictionaryListResponse) GetData() []*OrganizeDictionary { @@ -610,7 +654,7 @@ type CreateOrganizeDictionaryRequest struct { func (x *CreateOrganizeDictionaryRequest) Reset() { *x = CreateOrganizeDictionaryRequest{} - mi := &file_api_supplier_supplier_proto_msgTypes[9] + mi := &file_api_supplier_supplier_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -622,7 +666,7 @@ func (x *CreateOrganizeDictionaryRequest) String() string { func (*CreateOrganizeDictionaryRequest) ProtoMessage() {} func (x *CreateOrganizeDictionaryRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[9] + mi := &file_api_supplier_supplier_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -635,7 +679,7 @@ func (x *CreateOrganizeDictionaryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateOrganizeDictionaryRequest.ProtoReflect.Descriptor instead. func (*CreateOrganizeDictionaryRequest) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{9} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{10} } func (x *CreateOrganizeDictionaryRequest) GetName() string { @@ -654,7 +698,7 @@ type CreateOrganizeDictionaryResponse struct { func (x *CreateOrganizeDictionaryResponse) Reset() { *x = CreateOrganizeDictionaryResponse{} - mi := &file_api_supplier_supplier_proto_msgTypes[10] + mi := &file_api_supplier_supplier_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -666,7 +710,7 @@ func (x *CreateOrganizeDictionaryResponse) String() string { func (*CreateOrganizeDictionaryResponse) ProtoMessage() {} func (x *CreateOrganizeDictionaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[10] + mi := &file_api_supplier_supplier_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -679,7 +723,7 @@ func (x *CreateOrganizeDictionaryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateOrganizeDictionaryResponse.ProtoReflect.Descriptor instead. func (*CreateOrganizeDictionaryResponse) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{10} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{11} } func (x *CreateOrganizeDictionaryResponse) GetId() uint64 { @@ -700,7 +744,7 @@ type GetOrganizeDictionaryListRequest struct { func (x *GetOrganizeDictionaryListRequest) Reset() { *x = GetOrganizeDictionaryListRequest{} - mi := &file_api_supplier_supplier_proto_msgTypes[11] + mi := &file_api_supplier_supplier_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -712,7 +756,7 @@ func (x *GetOrganizeDictionaryListRequest) String() string { func (*GetOrganizeDictionaryListRequest) ProtoMessage() {} func (x *GetOrganizeDictionaryListRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[11] + mi := &file_api_supplier_supplier_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -725,7 +769,7 @@ func (x *GetOrganizeDictionaryListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetOrganizeDictionaryListRequest.ProtoReflect.Descriptor instead. func (*GetOrganizeDictionaryListRequest) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{11} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{12} } func (x *GetOrganizeDictionaryListRequest) GetPage() uint64 { @@ -782,7 +826,7 @@ type GetSupplierListRequest struct { func (x *GetSupplierListRequest) Reset() { *x = GetSupplierListRequest{} - mi := &file_api_supplier_supplier_proto_msgTypes[12] + mi := &file_api_supplier_supplier_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -794,7 +838,7 @@ func (x *GetSupplierListRequest) String() string { func (*GetSupplierListRequest) ProtoMessage() {} func (x *GetSupplierListRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[12] + mi := &file_api_supplier_supplier_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -807,7 +851,7 @@ func (x *GetSupplierListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSupplierListRequest.ProtoReflect.Descriptor instead. func (*GetSupplierListRequest) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{12} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{13} } func (x *GetSupplierListRequest) GetPage() uint64 { @@ -997,7 +1041,7 @@ type GetSupplierListResponse struct { func (x *GetSupplierListResponse) Reset() { *x = GetSupplierListResponse{} - mi := &file_api_supplier_supplier_proto_msgTypes[13] + mi := &file_api_supplier_supplier_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1009,7 +1053,7 @@ func (x *GetSupplierListResponse) String() string { func (*GetSupplierListResponse) ProtoMessage() {} func (x *GetSupplierListResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[13] + mi := &file_api_supplier_supplier_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1022,7 +1066,7 @@ func (x *GetSupplierListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSupplierListResponse.ProtoReflect.Descriptor instead. func (*GetSupplierListResponse) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{13} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{14} } func (x *GetSupplierListResponse) GetTotal() uint64 { @@ -1086,7 +1130,7 @@ type SupplierInfo struct { func (x *SupplierInfo) Reset() { *x = SupplierInfo{} - mi := &file_api_supplier_supplier_proto_msgTypes[14] + mi := &file_api_supplier_supplier_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1098,7 +1142,7 @@ func (x *SupplierInfo) String() string { func (*SupplierInfo) ProtoMessage() {} func (x *SupplierInfo) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[14] + mi := &file_api_supplier_supplier_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1111,7 +1155,7 @@ func (x *SupplierInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use SupplierInfo.ProtoReflect.Descriptor instead. func (*SupplierInfo) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{14} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{15} } func (x *SupplierInfo) GetId() uint64 { @@ -1319,7 +1363,7 @@ type UpdateSupplierRequest struct { func (x *UpdateSupplierRequest) Reset() { *x = UpdateSupplierRequest{} - mi := &file_api_supplier_supplier_proto_msgTypes[15] + mi := &file_api_supplier_supplier_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1331,7 +1375,7 @@ func (x *UpdateSupplierRequest) String() string { func (*UpdateSupplierRequest) ProtoMessage() {} func (x *UpdateSupplierRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[15] + mi := &file_api_supplier_supplier_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1344,7 +1388,7 @@ func (x *UpdateSupplierRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateSupplierRequest.ProtoReflect.Descriptor instead. func (*UpdateSupplierRequest) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{15} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{16} } func (x *UpdateSupplierRequest) GetId() uint64 { @@ -1530,7 +1574,7 @@ type CreateSupplierRequest struct { func (x *CreateSupplierRequest) Reset() { *x = CreateSupplierRequest{} - mi := &file_api_supplier_supplier_proto_msgTypes[16] + mi := &file_api_supplier_supplier_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1542,7 +1586,7 @@ func (x *CreateSupplierRequest) String() string { func (*CreateSupplierRequest) ProtoMessage() {} func (x *CreateSupplierRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[16] + mi := &file_api_supplier_supplier_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1555,7 +1599,7 @@ func (x *CreateSupplierRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateSupplierRequest.ProtoReflect.Descriptor instead. func (*CreateSupplierRequest) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{16} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{17} } func (x *CreateSupplierRequest) GetOwningEntityId() uint64 { @@ -1716,7 +1760,7 @@ type Attachment struct { func (x *Attachment) Reset() { *x = Attachment{} - mi := &file_api_supplier_supplier_proto_msgTypes[17] + mi := &file_api_supplier_supplier_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1728,7 +1772,7 @@ func (x *Attachment) String() string { func (*Attachment) ProtoMessage() {} func (x *Attachment) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[17] + mi := &file_api_supplier_supplier_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1741,7 +1785,7 @@ func (x *Attachment) ProtoReflect() protoreflect.Message { // Deprecated: Use Attachment.ProtoReflect.Descriptor instead. func (*Attachment) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{17} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{18} } func (x *Attachment) GetUrl() string { @@ -1768,13 +1812,14 @@ func (x *Attachment) GetName() string { type CreateSupplierResponse struct { state protoimpl.MessageState `protogen:"open.v1"` Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id"` + SupplierCode string `protobuf:"bytes,2,opt,name=supplierCode,proto3" json:"supplierCode"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *CreateSupplierResponse) Reset() { *x = CreateSupplierResponse{} - mi := &file_api_supplier_supplier_proto_msgTypes[18] + mi := &file_api_supplier_supplier_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1786,7 +1831,7 @@ func (x *CreateSupplierResponse) String() string { func (*CreateSupplierResponse) ProtoMessage() {} func (x *CreateSupplierResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[18] + mi := &file_api_supplier_supplier_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1799,7 +1844,7 @@ func (x *CreateSupplierResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateSupplierResponse.ProtoReflect.Descriptor instead. func (*CreateSupplierResponse) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{18} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{19} } func (x *CreateSupplierResponse) GetId() uint64 { @@ -1809,6 +1854,13 @@ func (x *CreateSupplierResponse) GetId() uint64 { return 0 } +func (x *CreateSupplierResponse) GetSupplierCode() string { + if x != nil { + return x.SupplierCode + } + return "" +} + type GetSupplierRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id"` @@ -1818,7 +1870,7 @@ type GetSupplierRequest struct { func (x *GetSupplierRequest) Reset() { *x = GetSupplierRequest{} - mi := &file_api_supplier_supplier_proto_msgTypes[19] + mi := &file_api_supplier_supplier_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1830,7 +1882,7 @@ func (x *GetSupplierRequest) String() string { func (*GetSupplierRequest) ProtoMessage() {} func (x *GetSupplierRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_supplier_supplier_proto_msgTypes[19] + mi := &file_api_supplier_supplier_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1843,7 +1895,7 @@ func (x *GetSupplierRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSupplierRequest.ProtoReflect.Descriptor instead. func (*GetSupplierRequest) Descriptor() ([]byte, []int) { - return file_api_supplier_supplier_proto_rawDescGZIP(), []int{19} + return file_api_supplier_supplier_proto_rawDescGZIP(), []int{20} } func (x *GetSupplierRequest) GetId() uint64 { @@ -1888,7 +1940,9 @@ const file_api_supplier_supplier_proto_rawDesc = "" + "\x02id\x18\x01 \x01(\x04R\x02id\x12\x16\n" + "\x06nameEN\x18\x02 \x01(\tR\x06nameEN\x12\x16\n" + "\x06nameCN\x18\x03 \x01(\tR\x06nameCN\x12\x12\n" + - "\x04code\x18\x04 \x01(\tR\x04code\"\x91\x01\n" + + "\x04code\x18\x04 \x01(\tR\x04code\";\n" + + "\x1bGetCountryRegionInfoRequest\x12\x1c\n" + + "\tzhAndCode\x18\x01 \x01(\tR\tzhAndCode\"\x91\x01\n" + "\x1bGetCountryRegionListRequest\x12\x12\n" + "\x04page\x18\x01 \x01(\x04R\x04page\x12\x1a\n" + "\bpageSize\x18\x02 \x01(\x04R\bpageSize\x12\x16\n" + @@ -2021,19 +2075,22 @@ const file_api_supplier_supplier_proto_rawDesc = "" + "attachment\x12\x10\n" + "\x03url\x18\x01 \x01(\tR\x03url\x12\x12\n" + "\x04type\x18\x02 \x01(\tR\x04type\x12\x12\n" + - "\x04name\x18\x03 \x01(\tR\x04name\"(\n" + + "\x04name\x18\x03 \x01(\tR\x04name\"L\n" + "\x16CreateSupplierResponse\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x04R\x02id\"$\n" + + "\x02id\x18\x01 \x01(\x04R\x02id\x12\"\n" + + "\fsupplierCode\x18\x02 \x01(\tR\fsupplierCode\"$\n" + "\x12GetSupplierRequest\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x04R\x02id2\xf9\x06\n" + + "\x02id\x18\x01 \x01(\x04R\x02id2\xbb\b\n" + "\bSupplier\x12N\n" + "\vGetSupplier\x12\x1c.supplier.GetSupplierRequest\x1a\x1f.supplier.UpdateSupplierRequest\"\x00\x12U\n" + "\x0eCreateSupplier\x12\x1f.supplier.CreateSupplierRequest\x1a .supplier.CreateSupplierResponse\"\x00\x12U\n" + "\x0eUpdateSupplier\x12\x1f.supplier.UpdateSupplierRequest\x1a .supplier.CreateSupplierResponse\"\x00\x12X\n" + "\x0fGetSupplierList\x12 .supplier.GetSupplierListRequest\x1a!.supplier.GetSupplierListResponse\"\x00\x12s\n" + "\x18CreateOrganizeDictionary\x12).supplier.CreateOrganizeDictionaryRequest\x1a*.supplier.CreateOrganizeDictionaryResponse\"\x00\x12v\n" + - "\x19GetOrganizeDictionaryList\x12*.supplier.GetOrganizeDictionaryListRequest\x1a+.supplier.GetOrganizeDictionaryListResponse\"\x00\x12g\n" + - "\x14GetCountryRegionList\x12%.supplier.GetCountryRegionListRequest\x1a&.supplier.GetCountryRegionListResponse\"\x00\x12a\n" + + "\x19GetOrganizeDictionaryList\x12*.supplier.GetOrganizeDictionaryListRequest\x1a+.supplier.GetOrganizeDictionaryListResponse\"\x00\x12f\n" + + "\x19GetOrganizeDictionaryInfo\x12).supplier.CreateOrganizeDictionaryRequest\x1a\x1c.supplier.OrganizeDictionary\"\x00\x12g\n" + + "\x14GetCountryRegionList\x12%.supplier.GetCountryRegionListRequest\x1a&.supplier.GetCountryRegionListResponse\"\x00\x12X\n" + + "\x14GetCountryRegionInfo\x12%.supplier.GetCountryRegionInfoRequest\x1a\x17.supplier.CountryRegion\"\x00\x12a\n" + "\x12CreateImportRecord\x12#.supplier.CreateImportRecordRequest\x1a$.supplier.CreateImportRecordResponse\"\x00\x12\\\n" + "\x13GetImportRecordInfo\x12 .supplier.GetImportRecordRequest\x1a!.supplier.GetImportRecordResponse\"\x00B\rZ\v./;supplierb\x06proto3" @@ -2049,7 +2106,7 @@ func file_api_supplier_supplier_proto_rawDescGZIP() []byte { return file_api_supplier_supplier_proto_rawDescData } -var file_api_supplier_supplier_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_api_supplier_supplier_proto_msgTypes = make([]protoimpl.MessageInfo, 21) var file_api_supplier_supplier_proto_goTypes = []any{ (*GetImportRecordRequest)(nil), // 0: supplier.GetImportRecordRequest (*GetImportRecordResponse)(nil), // 1: supplier.GetImportRecordResponse @@ -2057,48 +2114,53 @@ var file_api_supplier_supplier_proto_goTypes = []any{ (*CreateImportRecordResponse)(nil), // 3: supplier.CreateImportRecordResponse (*GetCountryRegionListResponse)(nil), // 4: supplier.GetCountryRegionListResponse (*CountryRegion)(nil), // 5: supplier.CountryRegion - (*GetCountryRegionListRequest)(nil), // 6: supplier.GetCountryRegionListRequest - (*OrganizeDictionary)(nil), // 7: supplier.OrganizeDictionary - (*GetOrganizeDictionaryListResponse)(nil), // 8: supplier.GetOrganizeDictionaryListResponse - (*CreateOrganizeDictionaryRequest)(nil), // 9: supplier.CreateOrganizeDictionaryRequest - (*CreateOrganizeDictionaryResponse)(nil), // 10: supplier.CreateOrganizeDictionaryResponse - (*GetOrganizeDictionaryListRequest)(nil), // 11: supplier.GetOrganizeDictionaryListRequest - (*GetSupplierListRequest)(nil), // 12: supplier.GetSupplierListRequest - (*GetSupplierListResponse)(nil), // 13: supplier.GetSupplierListResponse - (*SupplierInfo)(nil), // 14: supplier.SupplierInfo - (*UpdateSupplierRequest)(nil), // 15: supplier.UpdateSupplierRequest - (*CreateSupplierRequest)(nil), // 16: supplier.CreateSupplierRequest - (*Attachment)(nil), // 17: supplier.attachment - (*CreateSupplierResponse)(nil), // 18: supplier.CreateSupplierResponse - (*GetSupplierRequest)(nil), // 19: supplier.GetSupplierRequest + (*GetCountryRegionInfoRequest)(nil), // 6: supplier.GetCountryRegionInfoRequest + (*GetCountryRegionListRequest)(nil), // 7: supplier.GetCountryRegionListRequest + (*OrganizeDictionary)(nil), // 8: supplier.OrganizeDictionary + (*GetOrganizeDictionaryListResponse)(nil), // 9: supplier.GetOrganizeDictionaryListResponse + (*CreateOrganizeDictionaryRequest)(nil), // 10: supplier.CreateOrganizeDictionaryRequest + (*CreateOrganizeDictionaryResponse)(nil), // 11: supplier.CreateOrganizeDictionaryResponse + (*GetOrganizeDictionaryListRequest)(nil), // 12: supplier.GetOrganizeDictionaryListRequest + (*GetSupplierListRequest)(nil), // 13: supplier.GetSupplierListRequest + (*GetSupplierListResponse)(nil), // 14: supplier.GetSupplierListResponse + (*SupplierInfo)(nil), // 15: supplier.SupplierInfo + (*UpdateSupplierRequest)(nil), // 16: supplier.UpdateSupplierRequest + (*CreateSupplierRequest)(nil), // 17: supplier.CreateSupplierRequest + (*Attachment)(nil), // 18: supplier.attachment + (*CreateSupplierResponse)(nil), // 19: supplier.CreateSupplierResponse + (*GetSupplierRequest)(nil), // 20: supplier.GetSupplierRequest } var file_api_supplier_supplier_proto_depIdxs = []int32{ 5, // 0: supplier.GetCountryRegionListResponse.data:type_name -> supplier.CountryRegion - 7, // 1: supplier.GetOrganizeDictionaryListResponse.data:type_name -> supplier.OrganizeDictionary - 14, // 2: supplier.GetSupplierListResponse.data:type_name -> supplier.SupplierInfo - 17, // 3: supplier.SupplierInfo.attachments:type_name -> supplier.attachment - 17, // 4: supplier.UpdateSupplierRequest.attachments:type_name -> supplier.attachment - 17, // 5: supplier.CreateSupplierRequest.attachments:type_name -> supplier.attachment - 19, // 6: supplier.Supplier.GetSupplier:input_type -> supplier.GetSupplierRequest - 16, // 7: supplier.Supplier.CreateSupplier:input_type -> supplier.CreateSupplierRequest - 15, // 8: supplier.Supplier.UpdateSupplier:input_type -> supplier.UpdateSupplierRequest - 12, // 9: supplier.Supplier.GetSupplierList:input_type -> supplier.GetSupplierListRequest - 9, // 10: supplier.Supplier.CreateOrganizeDictionary:input_type -> supplier.CreateOrganizeDictionaryRequest - 11, // 11: supplier.Supplier.GetOrganizeDictionaryList:input_type -> supplier.GetOrganizeDictionaryListRequest - 6, // 12: supplier.Supplier.GetCountryRegionList:input_type -> supplier.GetCountryRegionListRequest - 2, // 13: supplier.Supplier.CreateImportRecord:input_type -> supplier.CreateImportRecordRequest - 0, // 14: supplier.Supplier.GetImportRecordInfo:input_type -> supplier.GetImportRecordRequest - 15, // 15: supplier.Supplier.GetSupplier:output_type -> supplier.UpdateSupplierRequest - 18, // 16: supplier.Supplier.CreateSupplier:output_type -> supplier.CreateSupplierResponse - 18, // 17: supplier.Supplier.UpdateSupplier:output_type -> supplier.CreateSupplierResponse - 13, // 18: supplier.Supplier.GetSupplierList:output_type -> supplier.GetSupplierListResponse - 10, // 19: supplier.Supplier.CreateOrganizeDictionary:output_type -> supplier.CreateOrganizeDictionaryResponse - 8, // 20: supplier.Supplier.GetOrganizeDictionaryList:output_type -> supplier.GetOrganizeDictionaryListResponse - 4, // 21: supplier.Supplier.GetCountryRegionList:output_type -> supplier.GetCountryRegionListResponse - 3, // 22: supplier.Supplier.CreateImportRecord:output_type -> supplier.CreateImportRecordResponse - 1, // 23: supplier.Supplier.GetImportRecordInfo:output_type -> supplier.GetImportRecordResponse - 15, // [15:24] is the sub-list for method output_type - 6, // [6:15] is the sub-list for method input_type + 8, // 1: supplier.GetOrganizeDictionaryListResponse.data:type_name -> supplier.OrganizeDictionary + 15, // 2: supplier.GetSupplierListResponse.data:type_name -> supplier.SupplierInfo + 18, // 3: supplier.SupplierInfo.attachments:type_name -> supplier.attachment + 18, // 4: supplier.UpdateSupplierRequest.attachments:type_name -> supplier.attachment + 18, // 5: supplier.CreateSupplierRequest.attachments:type_name -> supplier.attachment + 20, // 6: supplier.Supplier.GetSupplier:input_type -> supplier.GetSupplierRequest + 17, // 7: supplier.Supplier.CreateSupplier:input_type -> supplier.CreateSupplierRequest + 16, // 8: supplier.Supplier.UpdateSupplier:input_type -> supplier.UpdateSupplierRequest + 13, // 9: supplier.Supplier.GetSupplierList:input_type -> supplier.GetSupplierListRequest + 10, // 10: supplier.Supplier.CreateOrganizeDictionary:input_type -> supplier.CreateOrganizeDictionaryRequest + 12, // 11: supplier.Supplier.GetOrganizeDictionaryList:input_type -> supplier.GetOrganizeDictionaryListRequest + 10, // 12: supplier.Supplier.GetOrganizeDictionaryInfo:input_type -> supplier.CreateOrganizeDictionaryRequest + 7, // 13: supplier.Supplier.GetCountryRegionList:input_type -> supplier.GetCountryRegionListRequest + 6, // 14: supplier.Supplier.GetCountryRegionInfo:input_type -> supplier.GetCountryRegionInfoRequest + 2, // 15: supplier.Supplier.CreateImportRecord:input_type -> supplier.CreateImportRecordRequest + 0, // 16: supplier.Supplier.GetImportRecordInfo:input_type -> supplier.GetImportRecordRequest + 16, // 17: supplier.Supplier.GetSupplier:output_type -> supplier.UpdateSupplierRequest + 19, // 18: supplier.Supplier.CreateSupplier:output_type -> supplier.CreateSupplierResponse + 19, // 19: supplier.Supplier.UpdateSupplier:output_type -> supplier.CreateSupplierResponse + 14, // 20: supplier.Supplier.GetSupplierList:output_type -> supplier.GetSupplierListResponse + 11, // 21: supplier.Supplier.CreateOrganizeDictionary:output_type -> supplier.CreateOrganizeDictionaryResponse + 9, // 22: supplier.Supplier.GetOrganizeDictionaryList:output_type -> supplier.GetOrganizeDictionaryListResponse + 8, // 23: supplier.Supplier.GetOrganizeDictionaryInfo:output_type -> supplier.OrganizeDictionary + 4, // 24: supplier.Supplier.GetCountryRegionList:output_type -> supplier.GetCountryRegionListResponse + 5, // 25: supplier.Supplier.GetCountryRegionInfo:output_type -> supplier.CountryRegion + 3, // 26: supplier.Supplier.CreateImportRecord:output_type -> supplier.CreateImportRecordResponse + 1, // 27: supplier.Supplier.GetImportRecordInfo:output_type -> supplier.GetImportRecordResponse + 17, // [17:28] is the sub-list for method output_type + 6, // [6:17] is the sub-list for method input_type 6, // [6:6] is the sub-list for extension type_name 6, // [6:6] is the sub-list for extension extendee 0, // [0:6] is the sub-list for field type_name @@ -2115,7 +2177,7 @@ func file_api_supplier_supplier_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_supplier_supplier_proto_rawDesc), len(file_api_supplier_supplier_proto_rawDesc)), NumEnums: 0, - NumMessages: 20, + NumMessages: 21, NumExtensions: 0, NumServices: 1, }, diff --git a/api/supplier/supplier.proto b/api/supplier/supplier.proto index ec96d75..3c5e291 100644 --- a/api/supplier/supplier.proto +++ b/api/supplier/supplier.proto @@ -13,8 +13,10 @@ service Supplier { //组织字典 rpc CreateOrganizeDictionary(CreateOrganizeDictionaryRequest) returns (CreateOrganizeDictionaryResponse) {} rpc GetOrganizeDictionaryList(GetOrganizeDictionaryListRequest) returns (GetOrganizeDictionaryListResponse) {} + rpc GetOrganizeDictionaryInfo(CreateOrganizeDictionaryRequest) returns (OrganizeDictionary) {} //国家组织 rpc GetCountryRegionList(GetCountryRegionListRequest) returns (GetCountryRegionListResponse) {} + rpc GetCountryRegionInfo(GetCountryRegionInfoRequest) returns (CountryRegion) {} //导入 rpc CreateImportRecord(CreateImportRecordRequest) returns (CreateImportRecordResponse) {} rpc GetImportRecordInfo(GetImportRecordRequest) returns (GetImportRecordResponse) {} @@ -52,6 +54,9 @@ message CountryRegion{ string nameCN = 3; string code = 4; } +message GetCountryRegionInfoRequest{ + string zhAndCode = 1; +} message GetCountryRegionListRequest{ uint64 page = 1; uint64 pageSize = 2; @@ -194,6 +199,7 @@ message attachment{ } message CreateSupplierResponse{ uint64 id = 1; + string supplierCode = 2; } message GetSupplierRequest{ uint64 id = 1; diff --git a/api/supplier/supplier.validator.pb.go b/api/supplier/supplier.validator.pb.go index 31ef842..12a318a 100644 --- a/api/supplier/supplier.validator.pb.go +++ b/api/supplier/supplier.validator.pb.go @@ -40,6 +40,9 @@ func (this *GetCountryRegionListResponse) Validate() error { func (this *CountryRegion) Validate() error { return nil } +func (this *GetCountryRegionInfoRequest) Validate() error { + return nil +} func (this *GetCountryRegionListRequest) Validate() error { return nil } diff --git a/api/supplier/supplier_triple.pb.go b/api/supplier/supplier_triple.pb.go index b25469f..c4aa33a 100644 --- a/api/supplier/supplier_triple.pb.go +++ b/api/supplier/supplier_triple.pb.go @@ -36,8 +36,10 @@ type SupplierClient interface { // 组织字典 CreateOrganizeDictionary(ctx context.Context, in *CreateOrganizeDictionaryRequest, opts ...grpc_go.CallOption) (*CreateOrganizeDictionaryResponse, common.ErrorWithAttachment) GetOrganizeDictionaryList(ctx context.Context, in *GetOrganizeDictionaryListRequest, opts ...grpc_go.CallOption) (*GetOrganizeDictionaryListResponse, common.ErrorWithAttachment) + GetOrganizeDictionaryInfo(ctx context.Context, in *CreateOrganizeDictionaryRequest, opts ...grpc_go.CallOption) (*OrganizeDictionary, common.ErrorWithAttachment) // 国家组织 GetCountryRegionList(ctx context.Context, in *GetCountryRegionListRequest, opts ...grpc_go.CallOption) (*GetCountryRegionListResponse, common.ErrorWithAttachment) + GetCountryRegionInfo(ctx context.Context, in *GetCountryRegionInfoRequest, opts ...grpc_go.CallOption) (*CountryRegion, common.ErrorWithAttachment) // 导入 CreateImportRecord(ctx context.Context, in *CreateImportRecordRequest, opts ...grpc_go.CallOption) (*CreateImportRecordResponse, common.ErrorWithAttachment) GetImportRecordInfo(ctx context.Context, in *GetImportRecordRequest, opts ...grpc_go.CallOption) (*GetImportRecordResponse, common.ErrorWithAttachment) @@ -54,7 +56,9 @@ type SupplierClientImpl struct { GetSupplierList func(ctx context.Context, in *GetSupplierListRequest) (*GetSupplierListResponse, error) CreateOrganizeDictionary func(ctx context.Context, in *CreateOrganizeDictionaryRequest) (*CreateOrganizeDictionaryResponse, error) GetOrganizeDictionaryList func(ctx context.Context, in *GetOrganizeDictionaryListRequest) (*GetOrganizeDictionaryListResponse, error) + GetOrganizeDictionaryInfo func(ctx context.Context, in *CreateOrganizeDictionaryRequest) (*OrganizeDictionary, error) GetCountryRegionList func(ctx context.Context, in *GetCountryRegionListRequest) (*GetCountryRegionListResponse, error) + GetCountryRegionInfo func(ctx context.Context, in *GetCountryRegionInfoRequest) (*CountryRegion, error) CreateImportRecord func(ctx context.Context, in *CreateImportRecordRequest) (*CreateImportRecordResponse, error) GetImportRecordInfo func(ctx context.Context, in *GetImportRecordRequest) (*GetImportRecordResponse, error) } @@ -107,12 +111,24 @@ func (c *supplierClient) GetOrganizeDictionaryList(ctx context.Context, in *GetO return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetOrganizeDictionaryList", in, out) } +func (c *supplierClient) GetOrganizeDictionaryInfo(ctx context.Context, in *CreateOrganizeDictionaryRequest, opts ...grpc_go.CallOption) (*OrganizeDictionary, common.ErrorWithAttachment) { + out := new(OrganizeDictionary) + interfaceKey := ctx.Value(constant.InterfaceKey).(string) + return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetOrganizeDictionaryInfo", in, out) +} + func (c *supplierClient) GetCountryRegionList(ctx context.Context, in *GetCountryRegionListRequest, opts ...grpc_go.CallOption) (*GetCountryRegionListResponse, common.ErrorWithAttachment) { out := new(GetCountryRegionListResponse) interfaceKey := ctx.Value(constant.InterfaceKey).(string) return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetCountryRegionList", in, out) } +func (c *supplierClient) GetCountryRegionInfo(ctx context.Context, in *GetCountryRegionInfoRequest, opts ...grpc_go.CallOption) (*CountryRegion, common.ErrorWithAttachment) { + out := new(CountryRegion) + interfaceKey := ctx.Value(constant.InterfaceKey).(string) + return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetCountryRegionInfo", in, out) +} + func (c *supplierClient) CreateImportRecord(ctx context.Context, in *CreateImportRecordRequest, opts ...grpc_go.CallOption) (*CreateImportRecordResponse, common.ErrorWithAttachment) { out := new(CreateImportRecordResponse) interfaceKey := ctx.Value(constant.InterfaceKey).(string) @@ -137,8 +153,10 @@ type SupplierServer interface { // 组织字典 CreateOrganizeDictionary(context.Context, *CreateOrganizeDictionaryRequest) (*CreateOrganizeDictionaryResponse, error) GetOrganizeDictionaryList(context.Context, *GetOrganizeDictionaryListRequest) (*GetOrganizeDictionaryListResponse, error) + GetOrganizeDictionaryInfo(context.Context, *CreateOrganizeDictionaryRequest) (*OrganizeDictionary, error) // 国家组织 GetCountryRegionList(context.Context, *GetCountryRegionListRequest) (*GetCountryRegionListResponse, error) + GetCountryRegionInfo(context.Context, *GetCountryRegionInfoRequest) (*CountryRegion, error) // 导入 CreateImportRecord(context.Context, *CreateImportRecordRequest) (*CreateImportRecordResponse, error) GetImportRecordInfo(context.Context, *GetImportRecordRequest) (*GetImportRecordResponse, error) @@ -168,9 +186,15 @@ func (UnimplementedSupplierServer) CreateOrganizeDictionary(context.Context, *Cr func (UnimplementedSupplierServer) GetOrganizeDictionaryList(context.Context, *GetOrganizeDictionaryListRequest) (*GetOrganizeDictionaryListResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetOrganizeDictionaryList not implemented") } +func (UnimplementedSupplierServer) GetOrganizeDictionaryInfo(context.Context, *CreateOrganizeDictionaryRequest) (*OrganizeDictionary, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetOrganizeDictionaryInfo not implemented") +} func (UnimplementedSupplierServer) GetCountryRegionList(context.Context, *GetCountryRegionListRequest) (*GetCountryRegionListResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetCountryRegionList not implemented") } +func (UnimplementedSupplierServer) GetCountryRegionInfo(context.Context, *GetCountryRegionInfoRequest) (*CountryRegion, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCountryRegionInfo not implemented") +} func (UnimplementedSupplierServer) CreateImportRecord(context.Context, *CreateImportRecordRequest) (*CreateImportRecordResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateImportRecord not implemented") } @@ -379,6 +403,35 @@ func _Supplier_GetOrganizeDictionaryList_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _Supplier_GetOrganizeDictionaryInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateOrganizeDictionaryRequest) + if err := dec(in); err != nil { + return nil, err + } + base := srv.(dubbo3.Dubbo3GrpcService) + args := []interface{}{} + args = append(args, in) + md, _ := metadata.FromIncomingContext(ctx) + invAttachment := make(map[string]interface{}, len(md)) + for k, v := range md { + invAttachment[k] = v + } + invo := invocation.NewRPCInvocation("GetOrganizeDictionaryInfo", args, invAttachment) + if interceptor == nil { + result := base.XXX_GetProxyImpl().Invoke(ctx, invo) + return result, result.Error() + } + info := &grpc_go.UnaryServerInfo{ + Server: srv, + FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string), + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + result := base.XXX_GetProxyImpl().Invoke(ctx, invo) + return result, result.Error() + } + return interceptor(ctx, in, info, handler) +} + func _Supplier_GetCountryRegionList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) { in := new(GetCountryRegionListRequest) if err := dec(in); err != nil { @@ -408,6 +461,35 @@ func _Supplier_GetCountryRegionList_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } +func _Supplier_GetCountryRegionInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) { + in := new(GetCountryRegionInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + base := srv.(dubbo3.Dubbo3GrpcService) + args := []interface{}{} + args = append(args, in) + md, _ := metadata.FromIncomingContext(ctx) + invAttachment := make(map[string]interface{}, len(md)) + for k, v := range md { + invAttachment[k] = v + } + invo := invocation.NewRPCInvocation("GetCountryRegionInfo", args, invAttachment) + if interceptor == nil { + result := base.XXX_GetProxyImpl().Invoke(ctx, invo) + return result, result.Error() + } + info := &grpc_go.UnaryServerInfo{ + Server: srv, + FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string), + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + result := base.XXX_GetProxyImpl().Invoke(ctx, invo) + return result, result.Error() + } + return interceptor(ctx, in, info, handler) +} + func _Supplier_CreateImportRecord_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) { in := new(CreateImportRecordRequest) if err := dec(in); err != nil { @@ -497,10 +579,18 @@ var Supplier_ServiceDesc = grpc_go.ServiceDesc{ MethodName: "GetOrganizeDictionaryList", Handler: _Supplier_GetOrganizeDictionaryList_Handler, }, + { + MethodName: "GetOrganizeDictionaryInfo", + Handler: _Supplier_GetOrganizeDictionaryInfo_Handler, + }, { MethodName: "GetCountryRegionList", Handler: _Supplier_GetCountryRegionList_Handler, }, + { + MethodName: "GetCountryRegionInfo", + Handler: _Supplier_GetCountryRegionInfo_Handler, + }, { MethodName: "CreateImportRecord", Handler: _Supplier_CreateImportRecord_Handler, diff --git a/pkg/logic/supplier.go b/pkg/logic/supplier.go new file mode 100644 index 0000000..663a954 --- /dev/null +++ b/pkg/logic/supplier.go @@ -0,0 +1,178 @@ +package logic + +import ( + "crypto/sha256" + "errors" + "fmt" + "strconv" + "strings" + "time" + + "github.com/tealeg/xlsx" +) + +type SupplierLogic struct { + OwningEntityName string `json:"owningEntityName"` + LegalName string `json:"legalName"` + LocalName string `json:"localName"` + AbbreviationName string `json:"abbreviationName"` + CountryOrRegionName string `json:"countryOrRegionName"` + CompanyRegistrationNumber string `json:"companyRegistrationNumber"` + SupplierType string `json:"supplierType"` + ApprovalStatus string `json:"approvalStatus"` + ApprovalDate string `json:"approvalDate"` + LastReviewDate string `json:"lastReviewDate"` + LegalEntityType string `json:"legalEntityType"` + SanctionsCountryScreeningResult string `json:"sanctionsCountryScreeningResult"` + KeyFinancial string `json:"keyFinancial"` + CompanyAddress string `json:"companyAddress"` + PrimaryContact string `json:"primaryContact"` + DataOwnerDepartment string `json:"dataOwnerDepartment"` + BasicCompanyInformation string `json:"basicCompanyInformation"` + SupplementaryText string `json:"supplementaryText"` +} +type ErrSupplierRes struct { + ID int `json:"id"` + LegalName string `json:"legalName"` + Remark string `json:"remark"` +} + +func ImportSupplier(filePath string) ([]*SupplierLogic, error) { + xlFile, err := xlsx.OpenFile(filePath) + if err != nil { + return nil, err + } + //开辟除表头外的行数的数组内存 + //遍历sheet + for sheetIndex, sheet := range xlFile.Sheets { + var resourceArr []map[int]string + //遍历每一行 + //for rowIndex, row := range sheet.Rows { + for _, row := range sheet.Rows { + //开辟除表头外的行数的数组内存 + objMap := make(map[int]string) + + if len(row.Cells) <= 0 || row.Cells[0].String() == "" { + continue + } + for cellIndex, cell := range row.Cells { + text := cell.String() + //如果是每一行的第一个单元格 + objMap[cellIndex] = text + } + resourceArr = append(resourceArr, objMap) + } + if len(resourceArr) >= 2 { + suppliers, err := getListFromRaw(resourceArr) + if err != nil { + return nil, errors.New(fmt.Sprintf("页码:%d,文件读取错误信息%s", sheetIndex+1, err.Error())) + } + if len(suppliers) > 0 { + return suppliers, nil + } + } + break + } + + return nil, nil +} +func getListFromRaw(list []map[int]string) ([]*SupplierLogic, error) { + var entrusts []*SupplierLogic + kkMap := map[string]string{ + "*使用组织/Owning Entity": "owningEntityName", + "*供应商法定全称/Legal Name": "legalName", + "供应商本地名称(如有)/Local Name (if applicable)": "localName", + "供应商简称(如有)/Abbreviation/Trade Name (if applicable)": "abbreviationName", + "*所在国家或地区/Country or Region": "countryOrRegionName", + "*公司注册编号/Company Registration Number": "companyRegistrationNumber", + "*供应商类型/Supplier Type": "supplierType", + "*准入状态/Approval Status": "approvalStatus", + "准入日期/Approval Date": "approvalDate", + "法律实体形式/Legal Entity Type": "legalEntityType", + "制裁与高风险国家筛查结果/Sanctions & High-Risk Country Screening Result": "sanctionsCountryScreeningResult", + "关键财务与付款信息/Key Financial & Payment Information": "keyFinancial", + "公司地址/Company Address": "companyAddress", + "主要联系人、职位及联系方式/Primary Contact, Position&Details": "primaryContact", + "数据维护部门&人员/Data Owner Department/Personnel": "dataOwnerDepartment", + "公司信息概要/Summary of Basic Company Information": "basicCompanyInformation", + "其他补充信息/Other Supplementary Information": "supplementaryText", + } + keyMap := list[0] + for index, tt := range list { + if index == 0 { + continue + } + temp := &SupplierLogic{} + for i, r := range tt { + t := strings.TrimSpace(r) + if _, ok := keyMap[i]; !ok { + continue + } + keyString := strings.TrimSpace(keyMap[i]) + if _, ok := kkMap[keyString]; !ok { + fmt.Println(fmt.Sprintf("行数:%d字段信息(%s)没有匹配,请以模版为准", i, keyString)) + continue + } + switch kkMap[keyString] { + case "owningEntityName": + temp.OwningEntityName = t + case "legalName": + temp.LegalName = t + case "localName": + temp.LocalName = t + case "abbreviationName": + temp.AbbreviationName = t + case "countryOrRegionName": + temp.CountryOrRegionName = t + case "companyRegistrationNumber": + temp.CompanyRegistrationNumber = t + case "supplierType": + temp.SupplierType = t + case "approvalStatus": + temp.ApprovalStatus = t + case "approvalDate": + temp.ApprovalDate = ParseExcelDate(t) + //temp.ApprovalDate = t + case "legalEntityType": + temp.LegalEntityType = t + case "sanctionsCountryScreeningResult": + temp.SanctionsCountryScreeningResult = t + case "keyFinancial": + temp.KeyFinancial = t + case "companyAddress": + temp.CompanyAddress = t + case "primaryContact": + temp.PrimaryContact = t + case "dataOwnerDepartment": + temp.DataOwnerDepartment = t + case "basicCompanyInformation": + temp.BasicCompanyInformation = t + case "supplementaryText": + temp.SupplementaryText = t + + } + } + entrusts = append(entrusts, temp) + } + sha256.New() + return entrusts, nil +} +func ParseExcelDate(v string) string { + if v == "" { + return "" + } + + // 非数字,直接认为是 yyyy-mm-dd + if _, err := strconv.ParseFloat(v, 64); err != nil { + t, err := time.Parse("2006-01-02", v) + if err != nil { + return "" + } + return t.Format("2006-01-02") + } + + // Excel 序列号 + f, _ := strconv.ParseFloat(v, 64) + base := time.Date(1899, 12, 30, 0, 0, 0, 0, time.Local) + return base.AddDate(0, 0, int(f)).Format("2006-01-02") +} diff --git a/pkg/router/supplier.go b/pkg/router/supplier.go index 28fa90f..8878b6a 100644 --- a/pkg/router/supplier.go +++ b/pkg/router/supplier.go @@ -1,6 +1,8 @@ package router import ( + "fonchain-fiee/pkg/middleware" + "fonchain-fiee/pkg/service" "fonchain-fiee/pkg/service/supplier" "github.com/gin-gonic/gin" @@ -10,7 +12,7 @@ func SupplierRouter(r *gin.RouterGroup) { supplierRoute := r.Group("supplier/web") - //supplierRoute.Use(middleware.CheckWebLogin(service.AccountProvider)) + supplierRoute.Use(middleware.CheckWebLogin(service.AccountProvider)) { supplierRoute.POST("info", supplier.GetSupplier) supplierRoute.POST("create", supplier.CreateSupplier) diff --git a/pkg/service/init.go b/pkg/service/init.go index e8a25b6..da1b23b 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -41,7 +41,7 @@ var SupplierProvider = new(supplier.SupplierClientImpl) func init() { //config.SetConsumerService(BundleProvider) //config.SetConsumerService(OrderProvider) - //config.SetConsumerService(AccountProvider) + config.SetConsumerService(AccountProvider) //config.SetConsumerService(PaymentProvider) //config.SetConsumerService(AccountFieeProvider) //config.SetConsumerService(CastProvider) diff --git a/pkg/service/supplier/supplier.go b/pkg/service/supplier/supplier.go index 86c6c84..87e3169 100644 --- a/pkg/service/supplier/supplier.go +++ b/pkg/service/supplier/supplier.go @@ -2,11 +2,19 @@ package supplier import ( "errors" + "fmt" "fonchain-fiee/api/supplier" + "fonchain-fiee/pkg/logic" + "fonchain-fiee/pkg/model/login" "fonchain-fiee/pkg/service" + "fonchain-fiee/pkg/service/upload" + "fonchain-fiee/pkg/utils/excel" + "os" + "time" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" + "github.com/google/uuid" ) func GetSupplier(c *gin.Context) { @@ -127,17 +135,149 @@ func GetCountryRegionList(c *gin.Context) { } func CreateImportRecord(c *gin.Context) { - req := &supplier.CreateImportRecordRequest{} - if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil { + file, err := c.FormFile("file") + if err != nil { + service.Error(c, err) + } + safeFilename := fmt.Sprintf("%d", time.Now().Unix()) + "_" + file.Filename + userInfo := login.GetUserInfoFromC(c) + fileDir := fmt.Sprintf("/fiee/supplier/%s/%s_%s", time.Now().Format("2006-01-02"), userInfo.Name, safeFilename) + // 保存上传的文件到本地 + if err = c.SaveUploadedFile(file, safeFilename); err != nil { service.Error(c, err) return } - res, err := service.SupplierProvider.CreateImportRecord(c, req) + defer func() { + if err := os.Remove(safeFilename); err != nil { + // 处理删除文件失败的情况 + fmt.Println("Failed to delete file:", err) + } + }() + inputUrl, err := upload.PutBosWithName(safeFilename, false, fileDir) if err != nil { service.Error(c, err) return } - service.Success(c, res) + supplierList, err := logic.ImportSupplier(safeFilename) + if err != nil { + service.Error(c, err) + return + } + if len(supplierList) == 0 { + service.Error(c, errors.New("导入数据为空")) + return + } + uuid, _ := uuid.NewUUID() + var SuccessNum uint64 + var SupplierCodes []string + var ErrSupplierRes []*logic.ErrSupplierRes + for idx, i := range supplierList { + rowNum := idx + 1 + if i.OwningEntityName == "" || i.LegalName == "" || i.CountryOrRegionName == "" || i.CompanyRegistrationNumber == "" || i.SupplierType == "" || i.ApprovalStatus == "" { + ErrSupplierRes = append(ErrSupplierRes, &logic.ErrSupplierRes{ + ID: rowNum, + LegalName: i.LegalName, + Remark: "必填项存在空值", + }) + continue + } + OwningEntityRes, _ := service.SupplierProvider.GetOrganizeDictionaryInfo(c, &supplier.CreateOrganizeDictionaryRequest{Name: i.OwningEntityName}) + if OwningEntityRes == nil || OwningEntityRes.Id == 0 { + ErrSupplierRes = append(ErrSupplierRes, &logic.ErrSupplierRes{ + ID: rowNum, + LegalName: i.LegalName, + Remark: "所属组织不存在", + }) + continue + } + countryRegionRes, _ := service.SupplierProvider.GetCountryRegionInfo(c, &supplier.GetCountryRegionInfoRequest{ZhAndCode: i.CountryOrRegionName}) + if countryRegionRes == nil || countryRegionRes.Id == 0 { + ErrSupplierRes = append(ErrSupplierRes, &logic.ErrSupplierRes{ + ID: rowNum, + LegalName: i.LegalName, + Remark: "所属国家或地区不存在", + }) + continue + } + var LastReviewDate string + if i.ApprovalDate != "" { + t, err := time.Parse("2006-01-02", i.ApprovalDate) + if err != nil { + LastReviewDate = "" + i.ApprovalDate = "" + } else { + LastReviewDate = t.AddDate(0, 1, 0).Format("2006-01-02") + } + } + createRes, err := service.SupplierProvider.CreateSupplier(c, &supplier.CreateSupplierRequest{ + OwningEntityId: OwningEntityRes.Id, + LegalName: i.LegalName, + LocalName: i.LocalName, + AbbreviationName: i.AbbreviationName, + CountryOrRegionId: countryRegionRes.Id, + CompanyRegistrationNumber: i.CompanyRegistrationNumber, + SupplierType: i.SupplierType, + ApprovalStatus: i.ApprovalStatus, + ApprovalDate: i.ApprovalDate, + LastReviewDate: LastReviewDate, + LegalEntityType: i.LegalEntityType, + SanctionsCountryScreeningResult: i.SanctionsCountryScreeningResult, + KeyFinancial: i.KeyFinancial, + CompanyAddress: i.CompanyAddress, + PrimaryContact: i.PrimaryContact, + DataOwnerDepartment: i.DataOwnerDepartment, + BasicCompanyInformation: i.BasicCompanyInformation, + SupplementaryText: i.SupplementaryText, + Status: 1, + }) + if err != nil { + ErrSupplierRes = append(ErrSupplierRes, &logic.ErrSupplierRes{ + ID: rowNum, + LegalName: i.LegalName, + Remark: err.Error(), + }) + continue + } else { + SupplierCodes = append(SupplierCodes, createRes.SupplierCode) + SuccessNum++ + } + + } + status := 2 + outUrl := "" + if len(ErrSupplierRes) == 0 { + status = 1 + } else { + var sheet1Columns = []string{"行数", "供应商法定全称", "错误信息"} + var sheet1 = excel.NewSheet("Sheet1", ErrSupplierRes, sheet1Columns) + ex, err := excel.NewExcelCreatorFromTemplate("./mistake.xlsx", "./", "", sheet1) + ex.UseOption(excel.OptionFileNameSuffixWithUnixTime) + path, _, err := ex.WriteToFile() + outUrl, err = upload.PutBos(path, "", false) + if err != nil { + service.Error(c, err) + return + } + defer func() { + os.Remove(path) + }() + } + req := &supplier.CreateImportRecordRequest{ + SupplierCodes: SupplierCodes, + Status: uint64(status), + UserId: userInfo.ID, + ToLeadUrl: inputUrl, + DeriveUrl: outUrl, + Uuid: uuid.String(), + SuccessNum: SuccessNum, + FailNum: uint64(len(ErrSupplierRes)), + } + _, err = service.SupplierProvider.CreateImportRecord(c, req) + if err != nil { + service.Error(c, err) + return + } + service.Success(c, req) return } diff --git a/pkg/service/upload/upload.go b/pkg/service/upload/upload.go index a15b8dd..4798fa4 100644 --- a/pkg/service/upload/upload.go +++ b/pkg/service/upload/upload.go @@ -12,14 +12,13 @@ import ( "fonchain-fiee/pkg/model" "fonchain-fiee/pkg/service" "fonchain-fiee/pkg/utils" + "io" + "github.com/disintegration/imaging" "github.com/fonchain_enterprise/utils/objstorage" "github.com/gin-gonic/gin" uuid "github.com/satori/go.uuid" - "io" - ffmpeg "github.com/u2takey/ffmpeg-go" - "go.uber.org/zap" "io/ioutil" "mime/multipart" "net/url" @@ -28,6 +27,9 @@ import ( "path/filepath" "strconv" "strings" + + ffmpeg "github.com/u2takey/ffmpeg-go" + "go.uber.org/zap" ) const ( @@ -266,7 +268,8 @@ func BaiduCheckImage(imageByte []byte) (err error) { return nil } func PutBos(filePath string, mediaType string, needRemove bool) (url string, err error) { - BOSClient, err := objstorage.NewOSS(os.Getenv(config.ConfigData.Oss.AccessKeyId), os.Getenv(config.ConfigData.Oss.AccessKeySecret), os.Getenv(config.ConfigData.Oss.Endpoint)) + //BOSClient, err := objstorage.NewOSS(os.Getenv(config.ConfigData.Oss.AccessKeyId), os.Getenv(config.ConfigData.Oss.AccessKeySecret), os.Getenv(config.ConfigData.Oss.Endpoint)) + BOSClient, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) if err != nil { fmt.Println("=== PutBos NewOss err ", err) //logger.Errorf("PutBos NewOss err ", err) @@ -290,8 +293,10 @@ func PutBos(filePath string, mediaType string, needRemove bool) (url string, err } } filePath = strings.Replace(filePath, model.MediaPath, "", 1) + //var objectName string = fmt.Sprintf("%s/%s%s", os.Getenv(config.ConfigData.Oss.BaseDir), config.Env, filePath) var objectName string = fmt.Sprintf("%s/%s%s", config.ConfigData.Oss.BaseDir, config.Env, filePath) _, err = BOSClient.PutObjectFromBytes(os.Getenv(config.ConfigData.Oss.BucketName), objectName, fileBytes) + _, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, objectName, fileBytes) if err != nil { fmt.Println("=== PutBos PutObject err ", err) //logger.Errorf("PutBos PutObject err %+v", err.Error()) @@ -299,7 +304,8 @@ func PutBos(filePath string, mediaType string, needRemove bool) (url string, err return } //url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName) - url = fmt.Sprintf("%s/%s", os.Getenv(config.ConfigData.Oss.CdnHost), objectName) + //url = fmt.Sprintf("%s/%s", os.Getenv(config.ConfigData.Oss.CdnHost), objectName) + url = fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, objectName) return } func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string, err error) { @@ -347,3 +353,30 @@ func getEnvDir(cloudStoreSubPath string) (ep string) { ep, _ = url.JoinPath("fiee", cloudStoreSubPath) return ep } +func PutBosWithName(filePath string, needRemove bool, ossPath string) (url string, err error) { + //BOSClient, err := objstorage.NewOSS(os.Getenv(config.ConfigData.Oss.AccessKeyId), os.Getenv(config.ConfigData.Oss.AccessKeySecret), os.Getenv(config.ConfigData.Oss.Endpoint)) + BOSClient, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) + if err != nil { + //logger.Errorf("PutBosWithName err1 ", err) + err = errors.New(e.GetMsg(e.ErrorUploadBos)) + return + } + if ossPath == "" { + ossPath = filePath[1:] + } + var objectName string = fmt.Sprintf("%s/%s%s", config.ConfigData.Oss.BaseDir, config.Env, ossPath) + //_, err = BOSClient.PutObject(os.Getenv(config.ConfigData.Oss.BucketName), objectName, filePath) + _, err = BOSClient.PutObject(config.ConfigData.Oss.BucketName, objectName, filePath) + if err != nil { + //logger.Errorf("PutBosWithName err2 ", err) + err = errors.New(e.GetMsg(e.ErrorUploadBos)) + return + } + //删除本地文件 + if needRemove { + _ = os.Remove(filePath) + } + //url = fmt.Sprintf("%s/%s", os.Getenv(config.ConfigData.Oss.CdnHost), objectName) + url = fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, objectName) + return +} diff --git a/pkg/utils/excel/excelInter.go b/pkg/utils/excel/excelInter.go new file mode 100644 index 0000000..99f6d81 --- /dev/null +++ b/pkg/utils/excel/excelInter.go @@ -0,0 +1,381 @@ +// Package excel ----------------------------- +// @file : templateInter.go +// @author : JJXu +// @contact : wavingbear@163.com +// @time : 2022/7/23 15:34 +// ------------------------------------------- +package excel + +import ( + "bytes" + "errors" + "fmt" + "io" + "log" + "os" + "path/filepath" + "reflect" + "sync" + + "github.com/tealeg/xlsx" + "github.com/xuri/excelize/v2" +) + +var ( + ErrSheetNotExist = errors.New("sheet does not exist") + ErrSheetDataFormatNotSupport = errors.New("sheet data format not support") + //ErrSheetNameNotInTemplate = errors.New("sheet name not in emailTemplate") +) + +// ====================================================================================================================== +// +// Sheet define +type HeaderRow struct { + RowNum int //行号 + Values []string +} + +// 抽象工作簿 +type Sheet interface { + GetData() any //数据,支持struct、[]struct、[]*struct三种类型 + SheetName() string //表名称 + SheetHeaders() []string //表头名称,没有则跳过插入表头的步骤 + GetJsonFiledList() []string //指定字段的排列顺序,默认按照结构体中的顺序排列(表头与数据没有关联,使用这个指定字段插入顺序) +} + +// 实例化工作簿,使用模板生成excel的话用这个 +func NewTemplateSheet(sheetName string, datas any) Sheet { + return &newSheetDefine{ + Datas: datas, + Name: sheetName, + } +} + +// 实例化工作簿,不通过模板生成excel的话用这个 +func NewSheet(sheetName string, datas any, headers []string, jsonFiledList ...[]string) Sheet { + st := &newSheetDefine{ + Datas: datas, + Name: sheetName, + Headers: headers, + } + if jsonFiledList != nil { + st.JsonFiledList = jsonFiledList[0] + } + return st +} + +// 定义一个能够通用的工作簿结构,此结构必须遵循Sheet接口规范 +type newSheetDefine struct { + Datas any + Name string + Headers []string + JsonFiledList []string +} + +func (s *newSheetDefine) GetData() any { + return s.Datas +} +func (s *newSheetDefine) SheetName() string { + return s.Name +} +func (s *newSheetDefine) SheetHeaders() []string { + return s.Headers +} +func (s *newSheetDefine) GetJsonFiledList() []string { + return s.JsonFiledList +} + +//====================================================================================================================== +// Sheet define + +// WriteToExcel 通过模板文件写入数据并另存为 +// param fileName : 文件名 +// param filesSuffix : 文件后缀名生成函数 +// param fileRoot : 导出目录 +// param templatePath : 模板文件路径 +// param sheets : Sheet类型的数据,类型为[]Sheet +// return path : 文件路径 +// return exfileName : 导出后的文件名 +// return err +func WriteToExcel(fileName string, fileRoot string, templatePath string, sheets ...Sheet) (path string, exFileName string, err error) { + var exc *Excel + exc, err = NewExcelCreatorFromTemplate(fileName, fileRoot, templatePath, sheets...) + if err != nil { + return + } + exc.UseOption(OptionFileNameSuffixWithUnixTime) + return exc.WriteToFile() +} + +// ReadDataFromExcel 从excel文件读取数据 +func ReadDataFromExcel(filepath string, sheetName string, handler func(rowIndex int, rows []string)) error { + ex := Excel{OriginFilePath: filepath} + return ex.ReadSheetData(sheetName, handler) +} + +// ReadDataFromBytes 从io口读取数据,用户http上传的附件 +func ReadDataFromBytes(file io.Reader, sheetName string, handler func(rowIndex int, row []string)) error { + exce, err := excelize.OpenReader(file) + if err != nil { + return err + } + var ex = Excel{ex: exce} + return ex.ReadSheetData(sheetName, handler) +} + +// 读取模板并创建工作表生成器 +func NewExcelCreatorFromTemplate(fileName string, fileRoot string, templatePath string, sheets ...Sheet) (exc *Excel, err error) { + exc = &Excel{ + SaveRoot: fileRoot, + SaveName: fileName, + OriginFilePath: templatePath, + rwLock: sync.RWMutex{}, + } + if sheets != nil { + err = exc.AddSheets(sheets...) + if err != nil { + return + } + } + return exc, nil +} + +// 新建文件并创建工作表生成器 +func NewExcelCreatorWithNewFile(fileName string, fileRoot string, sheets ...Sheet) (exc *Excel, err error) { + return NewExcelCreatorFromTemplate(fileName, fileRoot, "", sheets...) +} + +type Excel struct { + ex *excelize.File + SaveRoot string + SaveName string + OriginFilePath string + Sheets map[string]Sheet + rwLock sync.RWMutex + Opts []Option + After []Option +} + +// UseOption 使用可选项 +func (s *Excel) UseOption(opts ...Option) { + if opts != nil { + s.Opts = append(s.Opts, opts...) + } +} +func (s *Excel) AfterAddData(after ...Option) { + if after != nil { + s.After = append(s.After, after...) + } +} + +// 添加工作簿 +// 注意如果添加相同的工作簿,之前的会被覆盖 +func (s *Excel) AddSheets(sheets ...Sheet) (err error) { + if s.Sheets == nil { + s.Sheets = make(map[string]Sheet, 0) + } + for _, sheet := range sheets { + var sheetName = sheet.SheetName() + s.Sheets[sheetName] = sheet + } + return +} + +// 删除工作簿 +func (s *Excel) DeleteSheets(sheetName string) error { + if s.Sheets == nil { + return nil + } else if s.Sheets[sheetName] != nil { + delete(s.Sheets, sheetName) + } else { + return ErrSheetNotExist + } + return nil +} + +// 读取工作簿 +func (s *Excel) ReadSheetData(sheetName string, handler func(rowIndex int, row []string)) (err error) { + if s.ex == nil { + s.ex, err = excelize.OpenFile(s.OriginFilePath) + if err != nil { + return + } + } + datas, err := s.ex.GetRows(sheetName) + for i, row := range datas { + handler(i, row) + } + return nil +} + +// 写入到文件 +func (s *Excel) WriteToFile() (path string, fileName string, err error) { + if s.ex == nil { + if s.OriginFilePath == "" { + s.ex = excelize.NewFile() + } else { + s.ex, err = excelize.OpenFile(s.OriginFilePath) + if err != nil { + return + } + } + } + if s.Opts != nil { + for _, opt := range s.Opts { + opt(s) + } + } + //插入数据 + for sheetName, st := range s.Sheets { + //添加表头,没有定义则不插入 + if st.SheetHeaders() != nil { + for i, c := range st.SheetHeaders() { + err = s.ex.SetCellValue(sheetName, GetCellIndex(1, i+1), c) + if err != nil { + fmt.Println(err.Error()) + return + } + } + headerStyleID, errs := s.ex.NewStyle(NewDefaultHeaderStyle()) + if errs != nil { + fmt.Println(errs) + err = errs + return + } + //表头设置为默认样式,边框加粗、字体加粗 + if err = s.ex.SetCellStyle(st.SheetName(), "A1", GetCellIndex(1, len(st.SheetHeaders())), headerStyleID); err != nil { + return + } + } + //添加数据 + var firstRow = s.getFirstEmptyRowIndex(s.ex, sheetName) + var SheetData = reflect.ValueOf(st.GetData()) + var SheetType = reflect.TypeOf(st.GetData()) + writerFunc, exists := writerMap[SheetData.Kind()] + if exists { + err = writerFunc(s, st, SheetData, SheetType, firstRow) + } else { + return "", "", ErrSheetDataFormatNotSupport + } + } + if s.After != nil { + for _, after := range s.After { + after(s) + } + } + //检测并生成目录 + _ = os.MkdirAll(s.SaveRoot, os.ModePerm) + //保存 + path = filepath.ToSlash(filepath.Join(s.SaveRoot, s.SaveName)) + fileName = s.SaveName + s.rwLock.Lock() + if err = s.ex.SaveAs(path); err != nil { + log.Println(fmt.Sprintf("save file error :%v", err)) + s.rwLock.Unlock() + return + } + s.rwLock.Unlock() + return +} + +// getJsonFieldList 获取json字段列表 +func (s *Excel) getJsonFieldList(sheetType reflect.Type) (tagList []string) { + t := sheetType.Elem() + if t.Kind() == reflect.Ptr { + t = t.Elem() + if t.Kind() != reflect.Struct { + return + } + } + for i := 0; i < t.NumField(); i++ { + var tag = t.Field(i).Tag.Get("json") + if tag != "" { + tagList = append(tagList, tag) + } + } + return +} + +// dataToMap 数据转字典 +func (s *Excel) dataToMap(sheet reflect.Value, sheetType reflect.Type) (dataMap map[string]any) { + dataMap = make(map[string]any) + t := sheetType.Elem() + //指针类型结构体拿真实的对象 + if t.Kind() == reflect.Ptr { + t = t.Elem() + sheet = sheet.Elem() + } + for i := 0; i < t.NumField(); i++ { + var tag = t.Field(i).Tag.Get("json") + if tag != "" { + dataMap[t.Field(i).Tag.Get("json")] = sheet.Field(i).Interface() + } + } + return dataMap +} + +// getFirstEmptyRowIndex 获取首个空行的索引位置 +func (s *Excel) getFirstEmptyRowIndex(ex *excelize.File, sheetName string) (index int) { + rows, err := ex.GetRows(sheetName) + if err != nil { + return 1 + } + return len(rows) +} + +func ToExcel(titleList []string, dataList []interface{}) (content io.ReadSeeker) { + // 生成一个新的文件 + file := xlsx.NewFile() + // 添加sheet页 + sheet, _ := file.AddSheet("Sheet1") + // 插入表头 + titleRow := sheet.AddRow() + for _, v := range titleList { + cell := titleRow.AddCell() + cell.Value = v + } + // 插入内容 + for _, v := range dataList { + row := sheet.AddRow() + row.WriteStruct(v, -1) + } + + var buffer bytes.Buffer + _ = file.Write(&buffer) + file.Save("1.xlsx") + content = bytes.NewReader(buffer.Bytes()) + return +} + +// 自动设置单元格宽度 +func (s *Excel) autoResetCellWidth(sheetObj Sheet) { + // 获取最大字符宽度 + maxWidths := make(map[int]int) + var sheetData = reflect.ValueOf(sheetObj.GetData()) + var rowLen = 1 + var columnLen = len(sheetObj.GetJsonFiledList()) + if sheetData.Kind() == reflect.Slice { + rowLen = sheetData.Len() + } + limitWidth := 90 + for col := 1; col <= columnLen; col++ { + var maxWidth int + for row := 0; row < rowLen; row++ { + value, _ := s.ex.GetCellValue(sheetObj.SheetName(), GetCellIndex(row+1, col)) + width := len(value) + if width > limitWidth { + width = limitWidth + } + if width > maxWidth { + maxWidth = width + } + } + maxWidths[col] = maxWidth + } + + // 设置列宽度 + for col, width := range maxWidths { + colChar := GetColumnIndex(col) + s.ex.SetColWidth(sheetObj.SheetName(), colChar, colChar, float64(width+2)) + } +} diff --git a/pkg/utils/excel/options.go b/pkg/utils/excel/options.go new file mode 100644 index 0000000..69a5cd3 --- /dev/null +++ b/pkg/utils/excel/options.go @@ -0,0 +1,52 @@ +// Package excel ----------------------------- +// @file : options.go +// @author : JJXu +// @contact : wavingBear@163.com +// @time : 2022/12/19 12:41:40 +// ------------------------------------------- +package excel + +import ( + "fmt" + "path/filepath" + "strings" + "time" +) + +type Option func(excel *Excel) + +// func AddSaveFileSuffixWithUnixTime(excel *Excel) { +// excel.SaveName +// fmt.Sprintf("%v", time.Now().Unix()) +// } +// +// 时间戳作为文件后缀 +func OptionFileNameSuffixWithUnixTime(excel *Excel) { + ext := filepath.Ext(excel.SaveName) + name := strings.Split(excel.SaveName, ext)[0] + excel.SaveName = fmt.Sprintf("%s_%v%s", name, time.Now().Unix(), ext) +} + +// 为第一行添加表头 +func AfterAddHeader1(sheet Sheet, text string) func(excel *Excel) { + return func(excel *Excel) { + err := excel.ex.InsertRows(sheet.SheetName(), 1, 1) + if err != nil { + panic(err) + } + err = excel.ex.SetCellValue(sheet.SheetName(), GetCellIndex(1, 1), text) + if err != nil { + panic(err) + } + headerStyleID, errs := excel.ex.NewStyle(NewHeaderOneStyle()) + if errs != nil { + fmt.Println(errs) + err = errs + return + } + //表头设置为默认样式,边框加粗、字体加粗 + _ = excel.ex.SetCellStyle(sheet.SheetName(), "A1", GetCellIndex(1, len(sheet.SheetHeaders())), headerStyleID) + _ = excel.ex.MergeCell(sheet.SheetName(), "A1", GetCellIndex(1, len(sheet.SheetHeaders()))) + + } +} diff --git a/pkg/utils/excel/style.go b/pkg/utils/excel/style.go new file mode 100644 index 0000000..e0829db --- /dev/null +++ b/pkg/utils/excel/style.go @@ -0,0 +1,54 @@ +// Package excel ----------------------------- +// @file : style.go +// @author : JJXu +// @contact : wavingbear@163.com +// @time : 2023/9/1 13:50 +// ------------------------------------------- +package excel + +import ( + "github.com/xuri/excelize/v2" +) + +func NewDefaultHeaderStyle() *excelize.Style { + return &excelize.Style{ + Border: []excelize.Border{ + {Type: "left", Color: "000000", Style: 2}, + {Type: "top", Color: "000000", Style: 2}, + {Type: "bottom", Color: "000000", Style: 2}, + {Type: "right", Color: "000000", Style: 2}, + }, + Font: &excelize.Font{Bold: true, Size: 12}, + Alignment: &excelize.Alignment{ + Horizontal: "center", + }, + } +} +func NewDefaultDataStyle() *excelize.Style { + return &excelize.Style{ + Border: []excelize.Border{ + {Type: "left", Color: "000000", Style: 1}, + {Type: "bottom", Color: "000000", Style: 1}, + {Type: "right", Color: "000000", Style: 1}, + }, + Font: &excelize.Font{Size: 12}, + Alignment: &excelize.Alignment{ + Horizontal: "left", + }, + } +} + +func NewHeaderOneStyle() *excelize.Style { + return &excelize.Style{ + Border: []excelize.Border{ + {Type: "left", Color: "000000", Style: 2}, + {Type: "top", Color: "000000", Style: 2}, + {Type: "bottom", Color: "000000", Style: 2}, + {Type: "right", Color: "000000", Style: 2}, + }, + Font: &excelize.Font{Bold: true, Size: 14}, + Alignment: &excelize.Alignment{ + Horizontal: "center", + }, + } +} diff --git a/pkg/utils/excel/utils.go b/pkg/utils/excel/utils.go new file mode 100644 index 0000000..a9ee91a --- /dev/null +++ b/pkg/utils/excel/utils.go @@ -0,0 +1,41 @@ +// Package utils ----------------------------- +// @file : excelHelper.go +// @author : JJXu +// @contact : wavingbear@163.com +// @time : 2022/6/9 13:41 +// ------------------------------------------- +package excel + +import ( + "fmt" + "strconv" +) + +// 行列坐标值转换为excel的坐标。注意row和columnCount的初始值都是1 +func GetCellIndex(row int, columnCount int) string { + var column = GetColumnIndex(columnCount) + return fmt.Sprintf("%s%d", column, row) +} + +// 获取excel的列索引 +var columnIndices = []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"} + +func GetColumnIndex(num int) string { + num-- + var column = columnIndices[num%26] + for num = num / 26; num > 0; num = num / 26 { + column = columnIndices[(num-1)%26] + column + num-- + } + return column +} + +func Int[T int | uint | uint8 | uint32 | uint64 | int32 | int64](value string) T { + v, _ := strconv.Atoi(value) + return T(v) +} + +func Float[T float64 | float32](value string) T { + v, _ := strconv.ParseFloat(value, 64) + return T(v) +} diff --git a/pkg/utils/excel/writer.go b/pkg/utils/excel/writer.go new file mode 100644 index 0000000..0e053d7 --- /dev/null +++ b/pkg/utils/excel/writer.go @@ -0,0 +1,81 @@ +// Package excel ----------------------------- +// @file : writer.go +// @author : JJXu +// @contact : wavingbear@163.com +// @time : 2023/9/1 14:11 +// ------------------------------------------- +package excel + +import ( + "errors" + "fmt" + "reflect" +) + +var writerMap = map[reflect.Kind]func(exc *Excel, sheetObj Sheet, SheetData reflect.Value, SheetType reflect.Type, firstRow int) error{ + reflect.Slice: sliceWriter, + reflect.Struct: structWriter, +} + +func RegisterWriter(dataKind reflect.Kind, function func(exc *Excel, sheetObj Sheet, SheetData reflect.Value, SheetType reflect.Type, firstRow int) error) error { + if _, exists := writerMap[dataKind]; exists { + return errors.New(fmt.Sprintf("dataKind: %v has existed", dataKind)) + } + writerMap[dataKind] = function + return nil +} + +func sliceWriter(exc *Excel, sheetObj Sheet, SheetData reflect.Value, SheetDataType reflect.Type, firstRow int) error { + var cellNameList = sheetObj.GetJsonFiledList() + if cellNameList == nil { + cellNameList = exc.getJsonFieldList(SheetDataType) + } + var rowLen = SheetData.Len() + for i := 0; i < rowLen; i++ { + var dataMap = exc.dataToMap(SheetData.Index(i), SheetDataType) + for column, v := range cellNameList { + var axis = GetCellIndex(i+firstRow+1, column+1) + err := exc.ex.SetCellValue(sheetObj.SheetName(), axis, dataMap[v]) + if err != nil { + return err + } + } + } + //设置数据格式 + dataStyleID, errs := exc.ex.NewStyle(NewDefaultDataStyle()) + if errs != nil { + return errs + } + if err := exc.ex.SetCellStyle(sheetObj.SheetName(), GetCellIndex(firstRow+1, 1), GetCellIndex(rowLen+1, len(sheetObj.SheetHeaders())), dataStyleID); err != nil { + return err + } + //设置默认列宽 + //exc.ex.SetColWidth(sheetObj.SheetName(), GetColumnIndex(1), GetColumnIndex(len(sheetObj.SheetHeaders())), 12.0) + exc.autoResetCellWidth(sheetObj) + return nil +} + +func structWriter(exc *Excel, sheetObj Sheet, SheetData reflect.Value, SheetType reflect.Type, firstRow int) error { + var cellNameList = exc.getJsonFieldList(SheetType) + var dataMap = exc.dataToMap(SheetData, SheetType) + for column, v := range cellNameList { + var axis = GetCellIndex(firstRow+1, column+1) + err := exc.ex.SetCellValue(sheetObj.SheetName(), axis, dataMap[v]) + if err != nil { + fmt.Println(err.Error()) + return err + } + } + //设置数据格式 + dataStyleID, err := exc.ex.NewStyle(NewDefaultDataStyle()) + if err != nil { + return err + } + if err = exc.ex.SetCellStyle(sheetObj.SheetName(), GetCellIndex(firstRow, 1), GetCellIndex(firstRow+1, len(sheetObj.SheetHeaders())), dataStyleID); err != nil { + return err + } + //设置默认列宽 + //exc.ex.SetColWidth(sheetObj.SheetName(), GetColumnIndex(1), GetColumnIndex(len(sheetObj.SheetHeaders())), 12.0) + exc.autoResetCellWidth(sheetObj) + return nil +}