diff --git a/cmd/internal/dao/artistinfo_statement.go b/cmd/internal/dao/artistinfo_statement.go index b639665..6b544cf 100644 --- a/cmd/internal/dao/artistinfo_statement.go +++ b/cmd/internal/dao/artistinfo_statement.go @@ -137,25 +137,25 @@ func GetStatementDetailList(in *artistinfoStatement.GetStatementDetailListReques res = []model.StatementDetail{} var orm = db.DB.Model(model.StatementDetail{}).Order("created_at desc") if in.Condition.BatchId != 0 { - orm = orm.Where(" batch_id = ?", in.Condition.BatchId) + orm = orm.Where("batch_id = ?", in.Condition.BatchId) } if in.Condition.TfNum != "" { - orm = orm.Where(" tf_num = ?", in.Condition.TfNum) + orm = orm.Where("tf_num = ?", in.Condition.TfNum) } if in.Condition.ArtworkName != "" { - orm = orm.Where(" artwork_name like = ?", "%"+in.Condition.ArtworkName+"%") + orm = orm.Where("artwork_name like = ?", "%"+in.Condition.ArtworkName+"%") } if in.Condition.Ruler != "" { - orm = orm.Where(" = ?", in.Condition.Ruler) + orm = orm.Where("ruler = ?", in.Condition.Ruler) } if in.Condition.SaleNo != "" { - orm = orm.Where(" = ?", in.Condition.SaleNo) + orm = orm.Where("sale_no = ?", in.Condition.SaleNo) } if in.Condition.CompleteDate != "" { - orm = orm.Where(" complete_date = ?", in.Condition.CompleteDate) + orm = orm.Where("complete_date = ?", in.Condition.CompleteDate) } if in.Condition.Id != 0 { - orm = orm.Where(" id = ?", in.Condition.Id) + orm = orm.Where("id = ?", in.Condition.Id) } err = orm.Count(&total).Scopes(db.Pagination(in.Page, in.PageSize)).Find(&res).Error return diff --git a/pb/artistinfoStatement.proto b/pb/artistinfoStatement.proto index c5af79e..bfb321b 100644 --- a/pb/artistinfoStatement.proto +++ b/pb/artistinfoStatement.proto @@ -25,13 +25,13 @@ message StatementPageInfo{ } message StatementBatchRequest{ - int32 StType=1; // 字段注释请查看对账单结构体模型 cmd/model/artworkStatement.go - string ArtistUid=2; - string ArtistRealName=3; - int32 FlowStatus=4; - string BatchTime=5; - float MinPrice=6; - float GuaranteePrice=7; + int32 stType=1; // 字段注释请查看对账单结构体模型 cmd/model/artworkStatement.go + string artistUid=2; + string artistRealName=3; + int32 flowStatus=4; + string batchTime=5; + float minPrice=6; + float guaranteePrice=7; int64 id = 8; string createdAt =9; string updatedAt =10; @@ -47,16 +47,16 @@ message BatchCreateStatementBatchRequest{ message StatementDetailRequest{ - int64 BatchId = 1; //字段注释请查看对账单结构体模型 cmd/model/artworkStatement.go - string TfNum = 2; - string ArtworkName =3; - string Ruler = 4; - string SaleNo = 5; - string CompleteDate = 6; + int64 batchId = 1; //字段注释请查看对账单结构体模型 cmd/model/artworkStatement.go + string tfNum = 2; + string artworkName =3; + string ruler = 4; + string saleNo = 5; + string completeDate = 6; int64 id = 8; - string created_at=9; - string updated_at=10; - int64 deleted_at=11; + string createdAt=9; + string updatedAt=10; + int64 deletedAt=11; } message CreateStatementDetailResponse{ int64 id=1; diff --git a/pb/artistinfoStatement/artistinfoStatement.pb.go b/pb/artistinfoStatement/artistinfoStatement.pb.go index 533f6e8..b18d5d0 100644 --- a/pb/artistinfoStatement/artistinfoStatement.pb.go +++ b/pb/artistinfoStatement/artistinfoStatement.pb.go @@ -94,13 +94,13 @@ type StatementBatchRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - StType int32 `protobuf:"varint,1,opt,name=StType,proto3" json:"StType,omitempty"` // 字段注释请查看对账单结构体模型 cmd/model/artworkStatement.go - ArtistUid string `protobuf:"bytes,2,opt,name=ArtistUid,proto3" json:"ArtistUid,omitempty"` - ArtistRealName string `protobuf:"bytes,3,opt,name=ArtistRealName,proto3" json:"ArtistRealName,omitempty"` - FlowStatus int32 `protobuf:"varint,4,opt,name=FlowStatus,proto3" json:"FlowStatus,omitempty"` - BatchTime string `protobuf:"bytes,5,opt,name=BatchTime,proto3" json:"BatchTime,omitempty"` - MinPrice float32 `protobuf:"fixed32,6,opt,name=MinPrice,proto3" json:"MinPrice,omitempty"` - GuaranteePrice float32 `protobuf:"fixed32,7,opt,name=GuaranteePrice,proto3" json:"GuaranteePrice,omitempty"` + StType int32 `protobuf:"varint,1,opt,name=stType,proto3" json:"stType,omitempty"` // 字段注释请查看对账单结构体模型 cmd/model/artworkStatement.go + ArtistUid string `protobuf:"bytes,2,opt,name=artistUid,proto3" json:"artistUid,omitempty"` + ArtistRealName string `protobuf:"bytes,3,opt,name=artistRealName,proto3" json:"artistRealName,omitempty"` + FlowStatus int32 `protobuf:"varint,4,opt,name=flowStatus,proto3" json:"flowStatus,omitempty"` + BatchTime string `protobuf:"bytes,5,opt,name=batchTime,proto3" json:"batchTime,omitempty"` + MinPrice float32 `protobuf:"fixed32,6,opt,name=minPrice,proto3" json:"minPrice,omitempty"` + GuaranteePrice float32 `protobuf:"fixed32,7,opt,name=guaranteePrice,proto3" json:"guaranteePrice,omitempty"` Id int64 `protobuf:"varint,8,opt,name=id,proto3" json:"id,omitempty"` CreatedAt string `protobuf:"bytes,9,opt,name=createdAt,proto3" json:"createdAt,omitempty"` UpdatedAt string `protobuf:"bytes,10,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` @@ -323,16 +323,16 @@ type StatementDetailRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - BatchId int64 `protobuf:"varint,1,opt,name=BatchId,proto3" json:"BatchId,omitempty"` //字段注释请查看对账单结构体模型 cmd/model/artworkStatement.go - TfNum string `protobuf:"bytes,2,opt,name=TfNum,proto3" json:"TfNum,omitempty"` - ArtworkName string `protobuf:"bytes,3,opt,name=ArtworkName,proto3" json:"ArtworkName,omitempty"` - Ruler string `protobuf:"bytes,4,opt,name=Ruler,proto3" json:"Ruler,omitempty"` - SaleNo string `protobuf:"bytes,5,opt,name=SaleNo,proto3" json:"SaleNo,omitempty"` - CompleteDate string `protobuf:"bytes,6,opt,name=CompleteDate,proto3" json:"CompleteDate,omitempty"` + BatchId int64 `protobuf:"varint,1,opt,name=batchId,proto3" json:"batchId,omitempty"` //字段注释请查看对账单结构体模型 cmd/model/artworkStatement.go + TfNum string `protobuf:"bytes,2,opt,name=tfNum,proto3" json:"tfNum,omitempty"` + ArtworkName string `protobuf:"bytes,3,opt,name=artworkName,proto3" json:"artworkName,omitempty"` + Ruler string `protobuf:"bytes,4,opt,name=ruler,proto3" json:"ruler,omitempty"` + SaleNo string `protobuf:"bytes,5,opt,name=saleNo,proto3" json:"saleNo,omitempty"` + CompleteDate string `protobuf:"bytes,6,opt,name=completeDate,proto3" json:"completeDate,omitempty"` Id int64 `protobuf:"varint,8,opt,name=id,proto3" json:"id,omitempty"` - CreatedAt string `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - UpdatedAt string `protobuf:"bytes,10,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` - DeletedAt int64 `protobuf:"varint,11,opt,name=deleted_at,json=deletedAt,proto3" json:"deleted_at,omitempty"` + CreatedAt string `protobuf:"bytes,9,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt string `protobuf:"bytes,10,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` + DeletedAt int64 `protobuf:"varint,11,opt,name=deletedAt,proto3" json:"deletedAt,omitempty"` } func (x *StatementDetailRequest) Reset() { @@ -847,19 +847,19 @@ var file_pb_artistinfoStatement_proto_rawDesc = []byte{ 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0xfb, 0x02, 0x0a, 0x15, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x53, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x53, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x72, 0x74, 0x69, 0x73, 0x74, 0x55, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x41, 0x72, 0x74, 0x69, 0x73, 0x74, - 0x55, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x41, 0x72, 0x74, 0x69, 0x73, 0x74, 0x52, 0x65, 0x61, - 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x41, 0x72, 0x74, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x46, + 0x06, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x55, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, + 0x55, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x52, 0x65, 0x61, + 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x72, 0x74, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0a, 0x46, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x42, + 0x0a, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x69, 0x6e, - 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x4d, 0x69, 0x6e, - 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, - 0x65, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x47, + 0x62, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x69, 0x6e, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x6d, 0x69, 0x6e, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, + 0x65, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, @@ -877,129 +877,129 @@ var file_pb_artistinfoStatement_proto_rawDesc = []byte{ 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xa9, 0x02, 0x0a, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xa6, 0x02, 0x0a, 0x16, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x42, 0x61, 0x74, 0x63, 0x68, 0x49, - 0x64, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x66, 0x4e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x54, 0x66, 0x4e, 0x75, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x41, 0x72, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x41, 0x72, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x52, 0x75, 0x6c, - 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x52, 0x75, 0x6c, 0x65, 0x72, 0x12, - 0x16, 0x0a, 0x06, 0x53, 0x61, 0x6c, 0x65, 0x4e, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x53, 0x61, 0x6c, 0x65, 0x4e, 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x44, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x62, 0x61, 0x74, 0x63, 0x68, 0x49, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x66, 0x4e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x66, 0x4e, 0x75, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x72, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x75, 0x6c, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x72, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x61, 0x6c, 0x65, 0x4e, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x61, 0x6c, 0x65, 0x4e, 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x44, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 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, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x2f, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, - 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5b, 0x0a, 0x21, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, - 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, - 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xc7, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x72, 0x74, - 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x09, 0x63, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, - 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x03, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x61, - 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0d, 0x62, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x22, 0x89, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x21, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x04, 0x70, 0x61, 0x67, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, - 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x61, - 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x22, 0x91, 0x01, 0x0a, - 0x1d, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, - 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 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, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x2f, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, - 0x70, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, - 0x22, 0x8b, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x04, 0x70, - 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x72, 0x74, 0x69, - 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x50, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x22, 0x38, - 0x0a, 0x22, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x65, 0x6e, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0x85, 0x06, 0x0a, 0x09, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x65, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, - 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, - 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2c, 0x2e, 0x61, 0x72, 0x74, - 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, - 0x68, 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, 0x00, 0x12, 0x6e, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x2e, 0x61, 0x72, - 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, - 0x66, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x78, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x65, 0x6e, 0x75, 0x73, - 0x12, 0x28, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x47, 0x65, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x61, 0x72, 0x74, - 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x65, 0x6e, - 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x15, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x22, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, - 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x72, 0x74, 0x69, - 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x1a, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5b, 0x0a, 0x21, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x12, 0x2d, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, - 0x6f, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 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, 0x00, 0x12, 0x71, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x29, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, + 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x72, 0x74, 0x69, + 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x22, 0xc7, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, + 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x61, 0x67, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x03, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x54, 0x69, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, + 0x62, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x89, 0x01, + 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x35, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, + 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x67, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x22, 0x91, 0x01, 0x0a, 0x1d, 0x47, 0x65, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x09, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x61, 0x67, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x8b, 0x01, + 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x36, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, + 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x67, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x22, 0x38, 0x0a, 0x22, 0x47, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x65, 0x6e, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0x85, 0x06, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x65, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, 0x2e, 0x61, 0x72, + 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, + 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x19, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2c, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, + 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 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, 0x00, 0x12, + 0x6e, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, + 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x78, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x65, 0x6e, 0x75, 0x73, 0x12, 0x28, 0x2e, + 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x42, 0x18, 0x5a, 0x16, 0x2e, 0x2f, 0x3b, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, - 0x6f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x65, 0x6e, 0x75, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x15, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x12, 0x22, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, + 0x6e, 0x66, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x1a, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x12, 0x2d, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 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, 0x00, 0x12, 0x71, 0x0a, 0x16, 0x47, 0x65, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x29, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, + 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2a, 0x2e, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x18, 0x5a, + 0x16, 0x2e, 0x2f, 0x3b, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/pkg/db/dto.go b/pkg/db/dto.go index 12e9513..1f75e1f 100644 --- a/pkg/db/dto.go +++ b/pkg/db/dto.go @@ -9,6 +9,10 @@ package model import "gorm.io/gorm" func Pagination[T int | int32 | int64](page T, pageSize T) func(db *gorm.DB) *gorm.DB { + if page == 0 || pageSize == 0 { + page = 1 + pageSize = 15 + } return func(db *gorm.DB) *gorm.DB { return db.Limit(int(pageSize)).Offset(int((page - 1) * pageSize)) } diff --git a/pkg/util/excel/example/demo.xlsx b/pkg/util/excel/example/demo.xlsx new file mode 100644 index 0000000..bfaaf7e Binary files /dev/null and b/pkg/util/excel/example/demo.xlsx differ diff --git a/pkg/util/excel/example/demo_1671435052.xlsx b/pkg/util/excel/example/demo_1671435052.xlsx new file mode 100644 index 0000000..3176299 Binary files /dev/null and b/pkg/util/excel/example/demo_1671435052.xlsx differ diff --git a/pkg/util/excel/example/exportExample_test.go b/pkg/util/excel/example/exportExample_test.go new file mode 100644 index 0000000..f852823 --- /dev/null +++ b/pkg/util/excel/example/exportExample_test.go @@ -0,0 +1,70 @@ +// Package excel ----------------------------- +// @file : templateInter_test.go +// @author : JJXu +// @contact : wavingbear@163.com +// @time : 2022/7/23 15:59 +// ------------------------------------------- +package example + +import ( + "fmt" + "gingogo2/utils/excel" + "path/filepath" + "strings" + "testing" + "time" +) + +//定义sheet表结构 +type sheet1Define struct { + Xid int `json:"xid" form:"xid" db:"column:xid;comment: "` + Name string `json:"name" form:"name" db:"column:name;comment: "` + Age int `json:"age" form:"age" db:"column:age;comment: "` +} + +func TestExcelTpl_WriteToExcel(t *testing.T) { + var sheet1Data = []sheet1Define{ + {1, "张三", 16}, + {2, "黑猫警长", 18}, + } + + var sheet1 = excel.NewSheet("Sheet1", sheet1Data) + //var suffixFunc = func() string { return fmt.Sprintf("%v", time.Now().Unix()) } + exCreator, err := excel.NewExcelTemplate("demo.xlsx", "./", "./demo.xlsx", sheet1) + if err != nil { + t.Log(err) + } + exCreator.UseOption(func(excel *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) + }) + path, name, err := exCreator.WriteToFile() + if err != nil { + t.Log(err) + } else { + t.Log(path, name) + } +} + +func TestReadExcel(t *testing.T) { + var file = "demo_1671435052.xlsx" + ex := excel.Excel{OriginFilePath: file} + var datas []sheet1Define + err := ex.ReadSheetData("Sheet1", func(rowIndex int, rows []string) { + if rowIndex == 0 { + //跳过首行 + return + } + datas = append(datas, sheet1Define{ + Xid: excel.Int[int](rows[0]), + Name: rows[1], + Age: excel.Int[int](rows[2]), + }) + }) + if err != nil { + t.Error(err.Error()) + } + fmt.Println(datas) + +} diff --git a/pkg/util/excel/excelInter.go b/pkg/util/excel/excelInter.go new file mode 100644 index 0000000..1070e6a --- /dev/null +++ b/pkg/util/excel/excelInter.go @@ -0,0 +1,253 @@ +// Package excel ----------------------------- +// @file : templateInter.go +// @author : JJXu +// @contact : wavingbear@163.com +// @time : 2022/7/23 15:34 +// ------------------------------------------- +package excel + +import ( + "errors" + "fmt" + "github.com/xuri/excelize/v2" + "io" + "log" + "path/filepath" + "reflect" + "sync" +) + +var ( + ErrSheetNotExist = errors.New("sheet does not exist") + ErrSheetDataFrormat = errors.New("sheet data format must be slice or struct") + //ErrSheetNameNotInTemplate = errors.New("sheet name not in emailTemplate") +) + +//====================================================================================================================== +// Sheet define + +// 抽象工作簿 +type Sheet interface { + GetData() any + SheetName() string +} + +// 实例化工作簿 +func NewSheet(sheetName string, datas any) Sheet { + return &newSheetDefine{ + Datas: datas, + Name: sheetName, + } +} + +// 定义一个能够通用的工作簿结构,此结构必须遵循Sheet接口规范 +type newSheetDefine struct { + Datas any + Name string +} + +func (s *newSheetDefine) GetData() any { + return s.Datas +} +func (s *newSheetDefine) SheetName() string { + return s.Name +} + +//====================================================================================================================== +// 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 = NewExcelTemplate(fileName, fileRoot, templatePath, sheets...) + if err != nil { + return + } + 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, rows []string)) error { + exce, err := excelize.OpenReader(file) + if err != nil { + return err + } + var ex = Excel{ex: exce} + return ex.ReadSheetData(sheetName, handler) +} + +// 新建工作表实例 +func NewExcelTemplate(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 +} + +type Excel struct { + ex *excelize.File + SaveRoot string + SaveName string + OriginFilePath string + Sheets map[string]Sheet + rwLock sync.RWMutex + Opts []Option +} + +// UseOption 使用可选项 +func (s *Excel) UseOption(opts ...Option) { + if opts != nil { + s.Opts = append(s.Opts, opts...) + } +} + +// 添加工作簿 +// 注意如果添加相同的工作簿,之前的会被覆盖 +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, rows []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, rows := range datas { + handler(i, rows) + } + return nil +} + +// 写入到文件 +func (s *Excel) WriteToFile() (path string, fileName string, err error) { + if s.ex == nil { + s.ex, err = excelize.OpenFile(s.OriginFilePath) + if err != nil { + return + } + } + if s.Opts != nil { + for _, opt := range s.Opts { + opt(s) + } + } + //插入数据 + var cellNameList []string + for sheetName, st := range s.Sheets { + var firstRow = s.getFirstEmptyRowIndex(s.ex, sheetName) + var SheetData = reflect.ValueOf(st.GetData()) + var SheetType = reflect.TypeOf(st.GetData()) + switch SheetData.Kind() { + case reflect.Slice: + cellNameList = s.getJsonFieldList(SheetType) + var rowLen = SheetData.Len() + for i := 0; i < rowLen; i++ { + var dataMap = s.dataToMap(SheetData.Index(i), SheetType) + for column, v := range cellNameList { + var axis = GetCellIndex(i+firstRow+1, column+1) + err = s.ex.SetCellValue(sheetName, axis, dataMap[v]) + if err != nil { + fmt.Println(err.Error()) + } + } + } + case reflect.Struct: + cellNameList = s.getJsonFieldList(SheetType) + var dataMap = s.dataToMap(SheetData, SheetType) + for column, v := range cellNameList { + var axis = GetCellIndex(firstRow+1, column+1) + err = s.ex.SetCellValue(sheetName, axis, dataMap[v]) + if err != nil { + fmt.Println(err.Error()) + } + } + default: + return "", "", ErrSheetDataFrormat + } + + } + //保存 + path = filepath.ToSlash(filepath.Join(s.SaveRoot, 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() + for i := 0; i < t.NumField(); i++ { + tagList = append(tagList, t.Field(i).Tag.Get("json")) + } + return +} + +// dataToMap 数据转字典 +func (s *Excel) dataToMap(sheet reflect.Value, sheetType reflect.Type) (dataMap map[string]any) { + dataMap = make(map[string]any) + t := sheetType.Elem() + for i := 0; i < t.NumField(); i++ { + 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) +} diff --git a/pkg/util/excel/excel_test.go b/pkg/util/excel/excel_test.go new file mode 100644 index 0000000..c333e35 --- /dev/null +++ b/pkg/util/excel/excel_test.go @@ -0,0 +1,38 @@ +// Package excel ----------------------------- +// @file : excel_test.go +// @author : JJXu +// @contact : wavingBear@163.com +// @time : 2022/12/19 16:52:11 +// ------------------------------------------- +package excel + +import ( + "reflect" + "testing" +) + +//定义sheet表结构 +type sheet1Define struct { + Xid int `json:"xid" form:"xid" db:"column:xid;comment: "` + Name string `json:"name" form:"name" db:"column:name;comment: "` + Age int `json:"age" form:"age" db:"column:age;comment: "` +} + +func TestSlice(t *testing.T) { + var sheet1Datas = []sheet1Define{ + {1, "张三", 16}, + {2, "黑猫警长", 18}, + } + + var sheet1 = NewSheet("Sheet1", &sheet1Datas) + d := sheet1.GetData() + v := reflect.ValueOf(d) + switch v.Kind() { + case reflect.Slice: + t.Log(v.Index(0)) + case reflect.Struct: + t.Log(v) + default: + t.Log("错误格式") + } +} diff --git a/pkg/util/excel/img.png b/pkg/util/excel/img.png new file mode 100644 index 0000000..e20fe42 Binary files /dev/null and b/pkg/util/excel/img.png differ diff --git a/pkg/util/excel/img_1.png b/pkg/util/excel/img_1.png new file mode 100644 index 0000000..fbf06bd Binary files /dev/null and b/pkg/util/excel/img_1.png differ diff --git a/pkg/util/excel/options.go b/pkg/util/excel/options.go new file mode 100644 index 0000000..87cf606 --- /dev/null +++ b/pkg/util/excel/options.go @@ -0,0 +1,27 @@ +// 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) +} diff --git a/pkg/util/excel/readme.md b/pkg/util/excel/readme.md new file mode 100644 index 0000000..d8a18d6 --- /dev/null +++ b/pkg/util/excel/readme.md @@ -0,0 +1,161 @@ +# excel文件生成器 +## excel文件生成器简介 +此模块提供了通过`.xlsx`格式的excel模板文件,创建文件并自动添加数据的方法。 +此模块通过设计模式,在"github.com/xuri/excelize/v2"的基础上封装了`ExcelCreator`这一泛型的方法。适用于快速开发报表导出功能。 + +### 基本使用示例 +```go +package main +import ( + "fmt" + "github.com/flipped-aurora/gin-vue-admin/server/utils/excel" + "github.com/flipped-aurora/gin-vue-admin/server/utils/simpletime" + "sync" + "time" +) + +//读写锁 +var exportEpidemicPreventStaticStaticLock sync.RWMutex + +//定义sheet1数据结构 +type EpidemicPreventStaticReport struct { + Xid int `json:"xid" form:"xid" db:"column:xid;comment:序号"` + Time string `json:"time" form:"time" db:"column:time;comment:日期"` + Name string `json:"name" form:"name" db:"column:name;comment:项目名称"` + Code string `json:"code" form:"code" db:"column:code;comment:监督备案号"` + Street string `json:"street" form:"street" db:"column:street;comment:街道"` + State string `json:"state" form:"state" db:"column:state;comment:状态:未完成、已完成"` +} + +//导出数据 +func (m EpidemicPreventStaticReport) WriteToExcel(datas []EpidemicPreventStaticReport) (path string, filename string, err error) { + defer exportEpidemicPreventStaticStaticLock.Unlock() + //实例化sheet1,载入数据 + st1 := excel.NewSheet("Sheet1", datas) + var suffixName = func() string { + return fmt.Sprintf("%v", simpletime.TimeToString(time.Now(), simpletime.TimeFormat.NoSpacer_YMDhms)) + } + //实例化excelCreator + exc, err := excel.NewExcelCreator("防疫日报日完成项目数统计.xlsx", &suffixName, "uploads/template2/file", "uploads/template2/防疫日报日完成项目数统计.xlsx", st1) + if err != nil { + fmt.Println(err.error()) + } + exportEpidemicPreventStaticStaticLock.Lock() + // 导出数据 + return exc.WriteToExcel() +} + +func main(){ + var ( + reportData []EpidemicPreventStaticReport + excel EpidemicPreventStaticReport + ) + + //do something + //.. + //.. + + path,filename,err:=excel.WriteToExcel(reportData) + if err!=nil{ + fmt.Println(err.Error()) + }else{ + fmt.Printf("path:%v\nfilename:%v\n",path,filename) + } +} +``` + +## 使用说明 +此模块的使用流程如下 +### 1. 创建excel模板,定义好工作簿名称和表头 +请注意,程序默认数据都是一行行连续的。如果两条数据之间间隔了一个或多个空行,导出的数据可能会出现错误。 +![img.png](img.png) +### 2. 定义工作簿数据结构 +注意事项: +1. 结构体字段顺序要与工作簿的表头顺序一一对应、命名规则随意; +2. json标签用于数据的转换,同时也便于将结构体直接作为接口请求参数来使用;没有json标签时,数据将会被忽略; +```go +type Sheet1 struct { + Xid int `json:"xid"` + Name string `json:"name"` + Age int `json:"age"` +} +``` +### 3. 准备数据,实例化sheet对象 +数据类型至此结构体和切片
+`NewSheet`方法的第一个参数是工作簿名称,需要与模板文件中的对应,不然导出数据时会报错 +```go +//准备数据 +var sheet1Data = []Sheet1Define{ +{1, "张三", 16}, +{2, "黑猫警长", 18}, +} +//实例化sheet对象 +var sheet1 = excel.NewSheet("Sheet1", &sheet1Data) +``` +### 4 生成excel文件 +### 4.1 直接生成文件 +如果你不需要什么额外操作,只想直接生成excel文件,那么可以直接调用这个方法 +```go +//定义后缀名生成器,如果不需要可以传nil +var suffixFunc = func() string { return fmt.Sprintf("%v", time.Now().Unix()) } +//导出文件 +path,err:=excel.WriteToExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx", sheet_1) +``` +#### 生成效果: +![img_1.png](img_1.png) + +### 4.2 `ExcelCreator` +ExcelCreator可以用来对工作簿和工作簿中的数据进行增删改查,以及生成文件。 +#### 4.2.1 实例化`ExcelCreator` +```go + +var suffixFunc = func() string { return fmt.Sprintf("%v", time.Now().Unix()) } //文件后缀名生成方法 +exCreator,err := excel.NewExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx", sheet_1) +if err!=nil{ + fmt.Println(err.Error()) +} +//可连续添加多个工作簿或者不传,当然也支持一张工作簿数据的多次传入 +//exCreator,err := excel.NewExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx", sheet_1,sheet_2,sheet_3) +//exCreator,err := excel.NewExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx") +//exCreator,err := excel.NewExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx", sheet_1_1,sheet_1_2,sheet_1_3) + +//不使用文件后缀名 +//exCreator,err := excel.NewExcelCreator("demo.xlsx", nil, "./", "./demo.xlsx", sheet_1) +//exCreator,err := excel.NewExcelCreatorWithoutSuffix("demo.xlsx","./", "./demo.xlsx", sheet_1) +``` +#### `FileName` 和 `filesSuffix`参数的说明 +当设置了`filesSuffix`参数后,创建excel文件时会自动生成文件后缀名。 +如`FileName`设置为"demo.xlsx"、`filesSuffix`返回值为"20200723",那么最终文件名为"demo20200723.xlsx" + +### 4.2.2 新增工作簿 +如果工作簿已存在,数据会组合而不是覆盖 +```go +var err = exCreator.SheetsAdd(sheet_2) +``` +### 4.2.3 删除工作簿 +```go +var err = exCreator.SheetsDelete(sheet_2.SheetName()) +``` + +### 4.2.5 取出工作簿map和缓存数据 +工作簿存储在`ExcelCreator.Sheets`中,存储结构为`map[string][]sheet`。string即工作簿名称。取出后可以进行任意的操作 +```go +var sheets = exCreator.Sheets +datas:= sheets["Sheet1"].GetDatas +//do somthing... +``` + +### 4.2.6 将数据生成到文件 +```go +path,fileName, err := exCreator.WriteToExcel() +if err != nil { + fmt.Println(err.Error()) +} else { + fmt.Println(path) + fmt.Println(fileName) +} +``` + +## 相关问题 +### 1. 为什么不支持通过代码直接生成表头? +鉴于在部分场景下,表头格式比较复杂,且通过代码生成灵活较度差,单元格格式通过代码设置比较繁琐。相比较下,没有直接创建excel文件模板来调整更为直观方便,所以没做此方面的设计。 diff --git a/pkg/util/excel/utils.go b/pkg/util/excel/utils.go new file mode 100644 index 0000000..ca93311 --- /dev/null +++ b/pkg/util/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 | int | 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) +}