diff --git a/.idea/fonchain-artistinfo.iml b/.idea/fonchain-artistinfo.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/fonchain-artistinfo.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2b361cd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..e2757d7 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + { + "keyToString": { + "DefaultGoTemplateProperty": "Go File", + "RunOnceActivity.OpenProjectViewOnStart": "true", + "RunOnceActivity.ShowReadmeOnStart": "true", + "RunOnceActivity.go.formatter.settings.were.checked": "true", + "RunOnceActivity.go.migrated.go.modules.settings": "true", + "RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true", + "WebServerToolWindowFactoryState": "false", + "configurable..is.expanded": "false", + "configurable.GoLibrariesConfigurable.is.expanded": "true", + "go.import.settings.migrated": "true", + "go.sdk.automatically.set": "true", + "last_opened_file_path": "D:/jjxu/work/projects/fonchain-artistinfo/pb", + "node.js.detected.package.eslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "nodejs_package_manager_path": "npm", + "settings.editor.selected.configurable": "editing.templates" + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + file://$PROJECT_DIR$/cmd/internal/logic/artistinfo_artshowArtistSupplement.go + 58 + + + file://$PROJECT_DIR$/cmd/internal/dao/artistInfo_user.go + 34 + + + + + + + + + + \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3335ed8 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "env": { + "GOPATH":"C:\\Users\\lenovo\\go", + "GOOS":"windows" + }, + "program": "${workspaceFolder}\\cmd", + "args":[] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4fe3b60 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,22 @@ +{ + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#fa1b49", + "activityBar.background": "#fa1b49", + "activityBar.foreground": "#e7e7e7", + "activityBar.inactiveForeground": "#e7e7e799", + "activityBarBadge.background": "#155e02", + "activityBarBadge.foreground": "#e7e7e7", + "commandCenter.border": "#e7e7e799", + "sash.hoverBorder": "#fa1b49", + "statusBar.background": "#dd0531", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.hoverBackground": "#fa1b49", + "statusBarItem.remoteBackground": "#dd0531", + "statusBarItem.remoteForeground": "#e7e7e7", + "titleBar.activeBackground": "#dd0531", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveBackground": "#dd053199", + "titleBar.inactiveForeground": "#e7e7e799" + }, + "peacock.color": "#dd0531" +} \ No newline at end of file diff --git a/cmd/app.go b/cmd/app.go index 665b39d..4183fa3 100644 --- a/cmd/app.go +++ b/cmd/app.go @@ -21,7 +21,7 @@ func main() { config.SetProviderService(&controller.ArtistInfoArtworkProvider{}) config.SetProviderService(&controller.ArtistInfoArtshowProvider{}) config.SetProviderService(&controller.ArtistInfoContractProvider{}) - config.SetConsumerService(&controller.StatementServerProvider{}) + // config.SetConsumerService(&controller.StatementServerProvider{}) db.Init(m.SERVER_CONFIG) cache.InitRedis(m.SERVER_CONFIG) if err := config.Load(); err != nil { diff --git a/cmd/internal/controller/artistinfo_statement.go b/cmd/internal/controller/artistinfo_statement.go index 933a924..495832c 100644 --- a/cmd/internal/controller/artistinfo_statement.go +++ b/cmd/internal/controller/artistinfo_statement.go @@ -1,44 +1,44 @@ package controller -import ( - "context" +// import ( +// "context" - "github.com/fonchain/fonchain-artistinfo/cmd/internal/logic" - "github.com/fonchain/fonchain-artistinfo/pb/artistinfoStatement" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) +// "github.com/fonchain/fonchain-artistinfo/cmd/internal/logic" +// "github.com/fonchain/fonchain-artistinfo/pb/artistinfoStatement" +// emptypb "google.golang.org/protobuf/types/known/emptypb" +// ) -//go:generate mockgen -destination .\artistinfoStatement_triple.pb.go -package controller -source ..\..\..\pb\artistinfoStatement\artistinfoStatement_triple.pb.go StatementServer +// //go:generate mockgen -destination .\artistinfoStatement_triple.pb.go -package controller -source ..\..\..\pb\artistinfoStatement\artistinfoStatement_triple.pb.go StatementServer -type StatementServerProvider struct { - artistinfoStatement.UnimplementedStatementServer - logic logic.StatementServerLogic -} +// type StatementServerProvider struct { +// artistinfoStatement.UnimplementedStatementServer +// logic logic.StatementServerLogic +// } -func (s *StatementServerProvider) CreateStatementBatch(ctx context.Context, in *artistinfoStatement.StatementBatchRequest) (res *artistinfoStatement.CreateStatementBatchResponse, err error) { - return s.logic.CreateStatementBatch(in) -} +// func (s *StatementServerProvider) CreateStatementBatch(ctx context.Context, in *artistinfoStatement.StatementBatchRequest) (res *artistinfoStatement.CreateStatementBatchResponse, err error) { +// return s.logic.CreateStatementBatch(in) +// } -func (s *StatementServerProvider) BatchCreateStatementBatch(ctx context.Context, in *artistinfoStatement.BatchCreateStatementBatchRequest) (*emptypb.Empty, error) { - return s.logic.BatchCreateStatementBatch(in) -} +// func (s *StatementServerProvider) BatchCreateStatementBatch(ctx context.Context, in *artistinfoStatement.BatchCreateStatementBatchRequest) (*emptypb.Empty, error) { +// return s.logic.BatchCreateStatementBatch(in) +// } -func (s *StatementServerProvider) GetStatementBatchList(ctx context.Context, in *artistinfoStatement.GetStatementBatchListRequest) (*artistinfoStatement.GetStatementBatchListResponse, error) { - return s.logic.GetStatementBatchList(in) -} +// func (s *StatementServerProvider) GetStatementBatchList(ctx context.Context, in *artistinfoStatement.GetStatementBatchListRequest) (*artistinfoStatement.GetStatementBatchListResponse, error) { +// return s.logic.GetStatementBatchList(in) +// } -func (s *StatementServerProvider) CreateStatementDetail(ctx context.Context, in *artistinfoStatement.StatementDetailRequest) (*artistinfoStatement.CreateStatementDetailResponse, error) { - return s.logic.CreateStatementDetail(in) -} +// func (s *StatementServerProvider) CreateStatementDetail(ctx context.Context, in *artistinfoStatement.StatementDetailRequest) (*artistinfoStatement.CreateStatementDetailResponse, error) { +// return s.logic.CreateStatementDetail(in) +// } -func (s *StatementServerProvider) BatchCreateStatementDetail(ctx context.Context, in *artistinfoStatement.BatchCreateStatementDetailRequest) (*emptypb.Empty, error) { - return s.logic.BatchCreateStatementDetail(in) -} +// func (s *StatementServerProvider) BatchCreateStatementDetail(ctx context.Context, in *artistinfoStatement.BatchCreateStatementDetailRequest) (*emptypb.Empty, error) { +// return s.logic.BatchCreateStatementDetail(in) +// } -func (s *StatementServerProvider) GetStatementDetailList(ctx context.Context, in *artistinfoStatement.GetStatementDetailListRequest) (*artistinfoStatement.GetStatementDetailListResponse, error) { - return s.logic.GetStatementDetailList(in) -} +// func (s *StatementServerProvider) GetStatementDetailList(ctx context.Context, in *artistinfoStatement.GetStatementDetailListRequest) (*artistinfoStatement.GetStatementDetailListResponse, error) { +// return s.logic.GetStatementDetailList(in) +// } -func (s *StatementServerProvider) GetStatementBatchTimeMenus(ctx context.Context, in *artistinfoStatement.GetStatementBatchListRequest) (*artistinfoStatement.GetStatementBatchTimeMenusResponse, error) { - return s.logic.GetStatementBatchTimeMenus(in) -} +// func (s *StatementServerProvider) GetStatementBatchTimeMenus(ctx context.Context, in *artistinfoStatement.GetStatementBatchListRequest) (*artistinfoStatement.GetStatementBatchTimeMenusResponse, error) { +// return s.logic.GetStatementBatchTimeMenus(in) +// } diff --git a/cmd/internal/dao/artistinfo_statement.go b/cmd/internal/dao/artistinfo_statement.go index b639665..29a5de2 100644 --- a/cmd/internal/dao/artistinfo_statement.go +++ b/cmd/internal/dao/artistinfo_statement.go @@ -1,162 +1,162 @@ package dao -import ( - "github.com/fonchain/fonchain-artistinfo/cmd/model" - "github.com/fonchain/fonchain-artistinfo/pb/artistinfoStatement" - db "github.com/fonchain/fonchain-artistinfo/pkg/db" - "gorm.io/gorm/clause" -) - -// ===================================== +// import ( +// "github.com/fonchain/fonchain-artistinfo/cmd/model" +// "github.com/fonchain/fonchain-artistinfo/pb/artistinfoStatement" +// db "github.com/fonchain/fonchain-artistinfo/pkg/db" +// "gorm.io/gorm/clause" +// ) // -// 对账单批次 -func CreateStatementBatch(in *artistinfoStatement.StatementBatchRequest) (res model.StatementBatch, err error) { - res = model.StatementBatch{ - StType: in.StType, - ArtistUid: in.ArtistUid, - ArtistRealName: in.ArtistRealName, - FlowStatus: in.FlowStatus, - BatchTime: in.BatchTime, - MinPrice: in.MinPrice, - GuaranteePrice: in.GuaranteePrice, - FileUrl: in.FileUrl, - } - err = db.DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "st_type"}, {Name: "artist_uid"}, {Name: "batch_time"}}, - UpdateAll: true, - }).Create(&res).Error - return -} +// // ===================================== +// // +// // 对账单批次 +// func CreateStatementBatch(in *artistinfoStatement.StatementBatchRequest) (res model.StatementBatch, err error) { +// res = model.StatementBatch{ +// StType: in.StType, +// ArtistUid: in.ArtistUid, +// ArtistRealName: in.ArtistRealName, +// FlowStatus: in.FlowStatus, +// BatchTime: in.BatchTime, +// MinPrice: in.MinPrice, +// GuaranteePrice: in.GuaranteePrice, +// FileUrl: in.FileUrl, +// } +// err = db.DB.Clauses(clause.OnConflict{ +// Columns: []clause.Column{{Name: "st_type"}, {Name: "artist_uid"}, {Name: "batch_time"}}, +// UpdateAll: true, +// }).Create(&res).Error +// return +// } -func BatchCreateStatementBatch(in *artistinfoStatement.BatchCreateStatementBatchRequest) error { - var datas = []model.StatementBatch{} - for _, in := range in.Data { - datas = append(datas, model.StatementBatch{ - StType: in.StType, - ArtistUid: in.ArtistUid, - ArtistRealName: in.ArtistRealName, - FlowStatus: in.FlowStatus, - BatchTime: in.BatchTime, - MinPrice: in.MinPrice, - GuaranteePrice: in.GuaranteePrice, - FileUrl: in.FileUrl, - }) - } - err := db.DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "st_type"}, {Name: "artist_uid"}, {Name: "batch_time"}}, - UpdateAll: true, - }).Create(&datas).Error - return err -} +// func BatchCreateStatementBatch(in *artistinfoStatement.BatchCreateStatementBatchRequest) error { +// var datas = []model.StatementBatch{} +// for _, in := range in.Data { +// datas = append(datas, model.StatementBatch{ +// StType: in.StType, +// ArtistUid: in.ArtistUid, +// ArtistRealName: in.ArtistRealName, +// FlowStatus: in.FlowStatus, +// BatchTime: in.BatchTime, +// MinPrice: in.MinPrice, +// GuaranteePrice: in.GuaranteePrice, +// FileUrl: in.FileUrl, +// }) +// } +// err := db.DB.Clauses(clause.OnConflict{ +// Columns: []clause.Column{{Name: "st_type"}, {Name: "artist_uid"}, {Name: "batch_time"}}, +// UpdateAll: true, +// }).Create(&datas).Error +// return err +// } -func GetStatementBatchList(in *artistinfoStatement.GetStatementBatchListRequest) (res []model.StatementBatch, total int64, err error) { - res = []model.StatementBatch{} - var orm = db.DB.Model(model.StatementBatch{}).Order("created_at desc").Preload("ArtworkList") - if in.Condition.StType != 0 { - orm = orm.Where("st_type = ?", in.Condition.StType) - } - if in.Condition.ArtistUid != "" { - orm = orm.Where("artist_uid = ?", in.Condition.ArtistUid) - } - if in.Condition.ArtistRealName != "" { - orm = orm.Where("artist_real_name = ?", in.Condition.ArtistRealName) - } - if in.Condition.FlowStatus != 0 { - orm = orm.Where("flow_status = ?", in.Condition.FlowStatus) - } - if in.Condition.BatchTime != "" { - orm = orm.Where("batch_time = ?", in.Condition.BatchTime) - } - if in.Condition.MinPrice != 0 { - orm = orm.Where("min_price = ?", in.Condition.MinPrice) - } - if in.Condition.GuaranteePrice != 0 { - orm = orm.Where("guarantee_price = ?", in.Condition.GuaranteePrice) - } - if in.Condition.Id != 0 { - orm = orm.Where("id = ?", in.Condition.Id) - } - if in.Condition.FileUrl != "" { - orm = orm.Where("file_url = ?", in.Condition.FileUrl) - } - if len(in.Ids) > 0 { - orm = orm.Where("id in ?", in.Ids) - } - if len(in.BatchTimeList) > 0 { - orm = orm.Where("batch_time in ?", in.BatchTimeList) - } - err = orm.Count(&total).Scopes(db.Pagination(in.Page, in.PageSize)).Find(&res).Error - return -} +// func GetStatementBatchList(in *artistinfoStatement.GetStatementBatchListRequest) (res []model.StatementBatch, total int64, err error) { +// res = []model.StatementBatch{} +// var orm = db.DB.Model(model.StatementBatch{}).Order("created_at desc").Preload("ArtworkList") +// if in.Condition.StType != 0 { +// orm = orm.Where("st_type = ?", in.Condition.StType) +// } +// if in.Condition.ArtistUid != "" { +// orm = orm.Where("artist_uid = ?", in.Condition.ArtistUid) +// } +// if in.Condition.ArtistRealName != "" { +// orm = orm.Where("artist_real_name = ?", in.Condition.ArtistRealName) +// } +// if in.Condition.FlowStatus != 0 { +// orm = orm.Where("flow_status = ?", in.Condition.FlowStatus) +// } +// if in.Condition.BatchTime != "" { +// orm = orm.Where("batch_time = ?", in.Condition.BatchTime) +// } +// if in.Condition.MinPrice != 0 { +// orm = orm.Where("min_price = ?", in.Condition.MinPrice) +// } +// if in.Condition.GuaranteePrice != 0 { +// orm = orm.Where("guarantee_price = ?", in.Condition.GuaranteePrice) +// } +// if in.Condition.Id != 0 { +// orm = orm.Where("id = ?", in.Condition.Id) +// } +// if in.Condition.FileUrl != "" { +// orm = orm.Where("file_url = ?", in.Condition.FileUrl) +// } +// if len(in.Ids) > 0 { +// orm = orm.Where("id in ?", in.Ids) +// } +// if len(in.BatchTimeList) > 0 { +// orm = orm.Where("batch_time in ?", in.BatchTimeList) +// } +// err = orm.Count(&total).Scopes(db.Pagination(in.Page, in.PageSize)).Find(&res).Error +// return +// } -func GetStatementBatchTimeMenus(in *artistinfoStatement.GetStatementBatchListRequest) (res []string, err error) { - res = []string{} - err = db.DB.Model(model.StatementBatch{}).Pluck("batch_time", &res).Error - return -} +// func GetStatementBatchTimeMenus(in *artistinfoStatement.GetStatementBatchListRequest) (res []string, err error) { +// res = []string{} +// err = db.DB.Model(model.StatementBatch{}).Pluck("batch_time", &res).Error +// return +// } -//===================================== -// 对账单详情 +// //===================================== +// // 对账单详情 -func CreateStatementDetail(in *artistinfoStatement.StatementDetailRequest) (res model.StatementDetail, err error) { - res = model.StatementDetail{ - BatchId: in.BatchId, - TfNum: in.TfNum, - ArtworkName: in.ArtworkName, - Ruler: in.Ruler, - SaleNo: in.SaleNo, - CompleteDate: in.CompleteDate, - } - err = db.DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "tf_num"}, {Name: "batch_id"}}, - UpdateAll: true, - }).Create(&res).Error - return -} +// func CreateStatementDetail(in *artistinfoStatement.StatementDetailRequest) (res model.StatementDetail, err error) { +// res = model.StatementDetail{ +// BatchId: in.BatchId, +// TfNum: in.TfNum, +// ArtworkName: in.ArtworkName, +// Ruler: in.Ruler, +// SaleNo: in.SaleNo, +// CompleteDate: in.CompleteDate, +// } +// err = db.DB.Clauses(clause.OnConflict{ +// Columns: []clause.Column{{Name: "tf_num"}, {Name: "batch_id"}}, +// UpdateAll: true, +// }).Create(&res).Error +// return +// } -func BatchCreateStatementDetail(in *artistinfoStatement.BatchCreateStatementDetailRequest) error { - var datas = []model.StatementDetail{} - for _, in := range in.Data { - datas = append(datas, model.StatementDetail{ - BatchId: in.BatchId, - TfNum: in.TfNum, - ArtworkName: in.ArtworkName, - Ruler: in.Ruler, - SaleNo: in.SaleNo, - CompleteDate: in.CompleteDate, - }) - } - err := db.DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "tf_num"}, {Name: "batch_id"}}, - UpdateAll: true, - }).Create(&datas).Error - return err -} +// func BatchCreateStatementDetail(in *artistinfoStatement.BatchCreateStatementDetailRequest) error { +// var datas = []model.StatementDetail{} +// for _, in := range in.Data { +// datas = append(datas, model.StatementDetail{ +// BatchId: in.BatchId, +// TfNum: in.TfNum, +// ArtworkName: in.ArtworkName, +// Ruler: in.Ruler, +// SaleNo: in.SaleNo, +// CompleteDate: in.CompleteDate, +// }) +// } +// err := db.DB.Clauses(clause.OnConflict{ +// Columns: []clause.Column{{Name: "tf_num"}, {Name: "batch_id"}}, +// UpdateAll: true, +// }).Create(&datas).Error +// return err +// } -func GetStatementDetailList(in *artistinfoStatement.GetStatementDetailListRequest) (res []model.StatementDetail, total int64, err error) { - 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) - } - if in.Condition.TfNum != "" { - orm = orm.Where(" tf_num = ?", in.Condition.TfNum) - } - if in.Condition.ArtworkName != "" { - orm = orm.Where(" artwork_name like = ?", "%"+in.Condition.ArtworkName+"%") - } - if in.Condition.Ruler != "" { - orm = orm.Where(" = ?", in.Condition.Ruler) - } - if in.Condition.SaleNo != "" { - orm = orm.Where(" = ?", in.Condition.SaleNo) - } - if in.Condition.CompleteDate != "" { - orm = orm.Where(" complete_date = ?", in.Condition.CompleteDate) - } - if in.Condition.Id != 0 { - orm = orm.Where(" id = ?", in.Condition.Id) - } - err = orm.Count(&total).Scopes(db.Pagination(in.Page, in.PageSize)).Find(&res).Error - return -} +// func GetStatementDetailList(in *artistinfoStatement.GetStatementDetailListRequest) (res []model.StatementDetail, total int64, err error) { +// 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) +// } +// if in.Condition.TfNum != "" { +// orm = orm.Where("tf_num = ?", in.Condition.TfNum) +// } +// if in.Condition.ArtworkName != "" { +// orm = orm.Where("artwork_name like = ?", "%"+in.Condition.ArtworkName+"%") +// } +// if in.Condition.Ruler != "" { +// orm = orm.Where("ruler = ?", in.Condition.Ruler) +// } +// if in.Condition.SaleNo != "" { +// orm = orm.Where("sale_no = ?", in.Condition.SaleNo) +// } +// if in.Condition.CompleteDate != "" { +// orm = orm.Where("complete_date = ?", in.Condition.CompleteDate) +// } +// if in.Condition.Id != 0 { +// 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/cmd/internal/logic/artistinfo_statement.go b/cmd/internal/logic/artistinfo_statement.go index 224fd75..9725855 100644 --- a/cmd/internal/logic/artistinfo_statement.go +++ b/cmd/internal/logic/artistinfo_statement.go @@ -1,95 +1,95 @@ package logic -import ( - "github.com/fonchain/fonchain-artistinfo/cmd/internal/dao" - "github.com/fonchain/fonchain-artistinfo/pb/artistinfoStatement" - "github.com/fonchain/fonchain-artistinfo/pkg/util/stime" - "google.golang.org/protobuf/types/known/emptypb" -) +// import ( +// "github.com/fonchain/fonchain-artistinfo/cmd/internal/dao" +// "github.com/fonchain/fonchain-artistinfo/pb/artistinfoStatement" +// "github.com/fonchain/fonchain-artistinfo/pkg/util/stime" +// "google.golang.org/protobuf/types/known/emptypb" +// ) -type StatementServerLogic struct{} +// type StatementServerLogic struct{} -func (s *StatementServerLogic) CreateStatementBatch(in *artistinfoStatement.StatementBatchRequest) (res *artistinfoStatement.CreateStatementBatchResponse, err error) { - res = &artistinfoStatement.CreateStatementBatchResponse{} - data, err := dao.CreateStatementBatch(in) - res.Id = data.ID - return -} +// func (s *StatementServerLogic) CreateStatementBatch(in *artistinfoStatement.StatementBatchRequest) (res *artistinfoStatement.CreateStatementBatchResponse, err error) { +// res = &artistinfoStatement.CreateStatementBatchResponse{} +// data, err := dao.CreateStatementBatch(in) +// res.Id = data.ID +// return +// } -func (s *StatementServerLogic) BatchCreateStatementBatch(in *artistinfoStatement.BatchCreateStatementBatchRequest) (*emptypb.Empty, error) { - return nil, dao.BatchCreateStatementBatch(in) -} +// func (s *StatementServerLogic) BatchCreateStatementBatch(in *artistinfoStatement.BatchCreateStatementBatchRequest) (*emptypb.Empty, error) { +// return nil, dao.BatchCreateStatementBatch(in) +// } -func (s *StatementServerLogic) GetStatementBatchList(in *artistinfoStatement.GetStatementBatchListRequest) (res *artistinfoStatement.GetStatementBatchListResponse, err error) { - datas, total, err := dao.GetStatementBatchList(in) +// func (s *StatementServerLogic) GetStatementBatchList(in *artistinfoStatement.GetStatementBatchListRequest) (res *artistinfoStatement.GetStatementBatchListResponse, err error) { +// datas, total, err := dao.GetStatementBatchList(in) - res = &artistinfoStatement.GetStatementBatchListResponse{ - Page: &artistinfoStatement.StatementPageInfo{ - Page: in.Page, - PageSize: in.PageSize, - Total: total, - }, - Data: []*artistinfoStatement.StatementBatchRequest{}, - } - for _, v := range datas { - res.Data = append(res.Data, &artistinfoStatement.StatementBatchRequest{ - StType: v.StType, - ArtistUid: v.ArtistUid, - ArtistRealName: v.ArtistRealName, - FlowStatus: v.FlowStatus, - BatchTime: v.BatchTime, - MinPrice: v.MinPrice, - GuaranteePrice: v.GuaranteePrice, - Id: v.ID, - CreatedAt: stime.TimeToString(v.CreatedAt, stime.Format_Normal_YMDhms), - UpdatedAt: stime.TimeToString(v.UpdatedAt, stime.Format_Normal_YMDhms), - DeletedAt: int64(v.DeletedAt), - FileUrl: v.FileUrl, - }) - } - return -} +// res = &artistinfoStatement.GetStatementBatchListResponse{ +// Page: &artistinfoStatement.StatementPageInfo{ +// Page: in.Page, +// PageSize: in.PageSize, +// Total: total, +// }, +// Data: []*artistinfoStatement.StatementBatchRequest{}, +// } +// for _, v := range datas { +// res.Data = append(res.Data, &artistinfoStatement.StatementBatchRequest{ +// StType: v.StType, +// ArtistUid: v.ArtistUid, +// ArtistRealName: v.ArtistRealName, +// FlowStatus: v.FlowStatus, +// BatchTime: v.BatchTime, +// MinPrice: v.MinPrice, +// GuaranteePrice: v.GuaranteePrice, +// Id: v.ID, +// CreatedAt: stime.TimeToString(v.CreatedAt, stime.Format_Normal_YMDhms), +// UpdatedAt: stime.TimeToString(v.UpdatedAt, stime.Format_Normal_YMDhms), +// DeletedAt: int64(v.DeletedAt), +// FileUrl: v.FileUrl, +// }) +// } +// return +// } -func (s *StatementServerLogic) CreateStatementDetail(in *artistinfoStatement.StatementDetailRequest) (res *artistinfoStatement.CreateStatementDetailResponse, err error) { - res = &artistinfoStatement.CreateStatementDetailResponse{} - data, err := dao.CreateStatementDetail(in) - res.Id = data.ID - return -} +// func (s *StatementServerLogic) CreateStatementDetail(in *artistinfoStatement.StatementDetailRequest) (res *artistinfoStatement.CreateStatementDetailResponse, err error) { +// res = &artistinfoStatement.CreateStatementDetailResponse{} +// data, err := dao.CreateStatementDetail(in) +// res.Id = data.ID +// return +// } -func (s *StatementServerLogic) BatchCreateStatementDetail(in *artistinfoStatement.BatchCreateStatementDetailRequest) (*emptypb.Empty, error) { - return nil, dao.BatchCreateStatementDetail(in) -} +// func (s *StatementServerLogic) BatchCreateStatementDetail(in *artistinfoStatement.BatchCreateStatementDetailRequest) (*emptypb.Empty, error) { +// return nil, dao.BatchCreateStatementDetail(in) +// } -func (s *StatementServerLogic) GetStatementDetailList(in *artistinfoStatement.GetStatementDetailListRequest) (res *artistinfoStatement.GetStatementDetailListResponse, err error) { - datas, total, err := dao.GetStatementDetailList(in) - res = &artistinfoStatement.GetStatementDetailListResponse{ - Data: []*artistinfoStatement.StatementDetailRequest{}, - Page: &artistinfoStatement.StatementPageInfo{ - Page: in.Page, - PageSize: in.PageSize, - Total: total, - }, - } - for _, v := range datas { - res.Data = append(res.Data, &artistinfoStatement.StatementDetailRequest{ - BatchId: v.BatchId, - TfNum: v.TfNum, - ArtworkName: v.ArtworkName, - Ruler: v.Ruler, - SaleNo: v.SaleNo, - CompleteDate: v.CompleteDate, - Id: v.ID, - CreatedAt: stime.TimeToString(v.CreatedAt, stime.Format_Normal_YMDhms), - UpdatedAt: stime.TimeToString(v.UpdatedAt, stime.Format_Normal_YMDhms), - DeletedAt: int64(v.DeletedAt), - }) - } - return -} +// func (s *StatementServerLogic) GetStatementDetailList(in *artistinfoStatement.GetStatementDetailListRequest) (res *artistinfoStatement.GetStatementDetailListResponse, err error) { +// datas, total, err := dao.GetStatementDetailList(in) +// res = &artistinfoStatement.GetStatementDetailListResponse{ +// Data: []*artistinfoStatement.StatementDetailRequest{}, +// Page: &artistinfoStatement.StatementPageInfo{ +// Page: in.Page, +// PageSize: in.PageSize, +// Total: total, +// }, +// } +// for _, v := range datas { +// res.Data = append(res.Data, &artistinfoStatement.StatementDetailRequest{ +// BatchId: v.BatchId, +// TfNum: v.TfNum, +// ArtworkName: v.ArtworkName, +// Ruler: v.Ruler, +// SaleNo: v.SaleNo, +// CompleteDate: v.CompleteDate, +// Id: v.ID, +// CreatedAt: stime.TimeToString(v.CreatedAt, stime.Format_Normal_YMDhms), +// UpdatedAt: stime.TimeToString(v.UpdatedAt, stime.Format_Normal_YMDhms), +// DeletedAt: int64(v.DeletedAt), +// }) +// } +// return +// } -func (s *StatementServerLogic) GetStatementBatchTimeMenus(in *artistinfoStatement.GetStatementBatchListRequest) (res *artistinfoStatement.GetStatementBatchTimeMenusResponse, err error) { - res = &artistinfoStatement.GetStatementBatchTimeMenusResponse{} - res.Data, err = dao.GetStatementBatchTimeMenus(in) - return -} +// func (s *StatementServerLogic) GetStatementBatchTimeMenus(in *artistinfoStatement.GetStatementBatchListRequest) (res *artistinfoStatement.GetStatementBatchTimeMenusResponse, err error) { +// res = &artistinfoStatement.GetStatementBatchTimeMenusResponse{} +// res.Data, err = dao.GetStatementBatchTimeMenus(in) +// return +// } diff --git a/cmd/model/artworkStatement.go b/cmd/model/artworkStatement.go index 8afa5aa..d9a0784 100644 --- a/cmd/model/artworkStatement.go +++ b/cmd/model/artworkStatement.go @@ -1,25 +1,42 @@ package model -// 对账单批次 +// 对账单委托画作批次 type StatementBatch struct { Model - StType int32 `gorm:"column:st_type;unqiueIndex:sttype_uid_batchtime_idx;comment:对账单类型 1=版权 2=物权;"` - ArtistUid string `gorm:"column:artist_uid;unqiueIndex:sttype_uid_batchtime_idx;comment:画家uid"` - ArtistRealName string `gorm:"column:artist_real_name;comment:画家真实姓名;"` - FlowStatus int32 `gorm:"column:flow_status;comment:流程状态 1=未生成 2=已生成未签署 3=已签署"` - BatchTime string `gorm:"column:batch_time;unqiueIndex:sttype_uid_batchtime_idx;comment:批次时间;"` - MinPrice float32 `gorm:"column:min_price;comment:委托销售底价"` - GuaranteePrice float32 `gorm:"column:guarantee_price;comment:以收取保证金;"` - FileUrl string `gorm:"column:file_url,comment:对账单文件地址;"` - ArtworkList []StatementDetail `gorm:"foreignKey:BatchId"` + // StType int32 `gorm:"column:st_type;unqiueIndex:sttype_uid_batchtime_idx;comment:对账单类型 1=版权 2=物权;"` + ArtistUid string `gorm:"column:artist_uid;unqiueIndex:sttype_uid_batchtime_idx;comment:画家uid"` + // ArtistRealName string `gorm:"column:artist_real_name;comment:画家真实姓名;"` + BatchTime string `gorm:"column:batch_time;unqiueIndex:sttype_uid_batchtime_idx;comment:批次时间;"` + FlowStatus int32 `gorm:"column:flow_status;default:1;comment:流程状态 1=未生成 2=已生成未签署 3=已签署"` + FileUrl string `gorm:"column:file_url,comment:对账单文件地址;"` + + EntrustList []ArtworkEntrustDetail `gorm:"foreignKey:BatchId"` + SalesList []ArtworkSalesDetail `gorm:"foreignKey:BatchId"` } func (StatementBatch) TableName() string { return "statement_batch" } -// 对账单批次详情 -type StatementDetail struct { +// 对账单画作委托详情 +type ArtworkEntrustDetail struct { + Model + BatchId int64 `gorm:"column:batch_id;unqiueIndex:batchid_tfnum_idx;comment:批次id;"` + TfNum string `gorm:"column:tf_num;unqiueIndex:batchid_tfnum_idx;comment:"泰丰画作编号"` + ArtworkName string `gorm:"column:artwork_name;comment:画作名称"` + Ruler string `gorm:"column:ruler;comment:平尺"` + SaleNo string `gorm:"column:sale_no;comment:销售单号"` + CompleteDate string `gorm:"column:complete_date;comment:成交日期"` + MinPrice float32 `gorm:"column:min_price;comment:委托销售底价"` + GuaranteePrice float32 `gorm:"column:guarantee_price;comment:已收取保证金;"` +} + +func (ArtworkEntrustDetail) TableName() string { + return "artwork_entrust_detail" +} + +//对账单画作销售详情 +type ArtworkSalesDetail struct { Model BatchId int64 `gorm:"column:batch_id;unqiueIndex:batchid_tfnum_idx;comment:批次id;"` TfNum string `gorm:"column:tf_num;unqiueIndex:batchid_tfnum_idx;comment:"泰丰画作编号"` @@ -29,6 +46,6 @@ type StatementDetail struct { CompleteDate string `gorm:"column:complete_date;comment:成交日期"` } -func (StatementDetail) TableName() string { - return "statement_detail" +func (ArtworkSalesDetail) TableName() string { + return "artwork_sales_detail" } diff --git a/conf/prod/conf.ini b/conf/prod/conf.ini index 3650b5a..6d20e5a 100644 --- a/conf/prod/conf.ini +++ b/conf/prod/conf.ini @@ -3,11 +3,11 @@ mode = prod #正式prod #测试dev [mysql] Db = mysql -DbHost = mysql +DbHost = 172.16.100.30 DbPort = 3306 -DbUser = fonchain -DbPassWord = C250PflXIWv2SQm -DbName = artistmgmt +DbUser = root +DbPassWord = "IhQmhg8HZjDmU=Ove5PnA^D" +DbName = artistmgmtProd [redis] RedisDB = 2 diff --git a/conf/prod/dubbogo.yaml b/conf/prod/dubbogo.yaml index c697f56..d8a1955 100644 --- a/conf/prod/dubbogo.yaml +++ b/conf/prod/dubbogo.yaml @@ -19,18 +19,51 @@ dubbo: port: 20050 provider: services: - ArtistInfoProvider: + ArtistInfoUserProvider: + interface: com.fontree.microservices.common.ArtistInfoUser + retries: 100 + ArtistInfoArtworkProvider: + interface: com.fontree.microservices.common.ArtistInfoArtwork + retries: 100 + ArtistInfoArtshowProvider: + interface: com.fontree.microservices.common.ArtistInfoArtshow + retries: 100 + ArtistInfoContractProvider: + interface: com.fontree.microservices.common.ArtistInfoContract + retries: 100 + consumer: + request-timeout: 120s + references: + AccountClientImpl: + protocol: tri + interface: com.fontree.microservices.common.Account + filter: cshutdown,sign,fonDomainFilter,fonValidateFilter + params: + .accessKeyId: "Accountksl" + .secretAccessKey: "BSDY-FDF1-Fontree_account" + ArtistClientImpl: + protocol: tri + interface: com.fontree.microservices.common.Artist + ArtistInfoClientImpl: + protocol: tri interface: com.fontree.microservices.common.ArtistInfo - retries: 0 - ContractProvider: - interface: com.fontree.microservices.common.Contract - retries: 0 - ArtWorkProvider: - interface: com.fontree.microservices.common.ArtWork - retries: 0 - SupplyProvider: + ContractClientImpl: + timeout: 15s + protocol: tri + interface: com.fontree.microservices.common.contract + filter: cshutdown,sign + params: + .accessKeyId: "SYD8-Chain-04" + .secretAccessKey: "Al-Chain-FDF112" + ArtworkClientImpl: + protocol: tri + interface: com.fontree.microservices.common.Artwork + ArtworkQueryClientImpl: + protocol: tri + interface: com.fontree.microservices.common.ArtworkQuery + SupplyClientImpl: + protocol: tri interface: com.fontree.microservices.common.Supply - retries: 0 logger: zap-config: level: info # 日志级别 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/common/filter/domain.go b/pkg/common/filter/domain.go new file mode 100644 index 0000000..61d9ef2 --- /dev/null +++ b/pkg/common/filter/domain.go @@ -0,0 +1,38 @@ +package filter + +import ( + "context" + + "dubbo.apache.org/dubbo-go/v3/common/extension" + "dubbo.apache.org/dubbo-go/v3/filter" + "dubbo.apache.org/dubbo-go/v3/protocol" +) + +func init() { + extension.SetFilter("fonDomainFilter", NewDomainFonFilter) +} + +func NewDomainFonFilter() filter.Filter { + return &DomainFonFilter{} +} + +type DomainFonFilter struct { +} + +func (f *DomainFonFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + // if len(invocation.Arguments()) > 0 { + // req := invocation.Arguments()[0] + // pp := reflect.ValueOf(req) + // field := pp.Elem().FieldByName("Domain") + + // if field.IsValid() && field.String() == "" { + // field.SetString(config.Domain) + // } + // } + + return invoker.Invoke(ctx, invocation) +} + +func (f *DomainFonFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, protocol protocol.Invocation) protocol.Result { + return result +} diff --git a/pkg/common/filter/validate.go b/pkg/common/filter/validate.go new file mode 100644 index 0000000..9b203b3 --- /dev/null +++ b/pkg/common/filter/validate.go @@ -0,0 +1,51 @@ +package filter + +import ( + "context" + "regexp" + "strconv" + + "dubbo.apache.org/dubbo-go/v3/common/extension" + "dubbo.apache.org/dubbo-go/v3/filter" + "dubbo.apache.org/dubbo-go/v3/protocol" + perrors "github.com/pkg/errors" +) + +type validator interface { + Validate() error +} + +func init() { + extension.SetFilter("fonValidateFilter", NewClientFonValidateFilter) +} + +func NewClientFonValidateFilter() filter.Filter { + return &ClientFonValidateFilter{} +} + +type ClientFonValidateFilter struct { +} + +func (f *ClientFonValidateFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + + if len(invocation.Arguments()) > 0 { + if v, ok := invocation.Arguments()[0].(validator); ok { + if err := v.Validate(); err != nil { + errMsg := err.Error() + re3, _ := regexp.Compile(`^invalid(.*): `) + rep := re3.ReplaceAllString(errMsg, "") + if errCode, err := strconv.ParseInt(rep, 10, 64); err == nil { + return &protocol.RPCResult{Err: perrors.Errorf("%v", int(errCode))} + } + + return &protocol.RPCResult{Err: perrors.Errorf("%v", rep)} + } + } + } + + return invoker.Invoke(ctx, invocation) +} + +func (f *ClientFonValidateFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, protocol protocol.Invocation) protocol.Result { + return result +} 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/db/init.go b/pkg/db/init.go index 544bb30..1e4dac8 100644 --- a/pkg/db/init.go +++ b/pkg/db/init.go @@ -124,7 +124,8 @@ func migration() { &model.ArtshowArtistSupplement{}, //画展-画家补充信息 &model.Contract{}, //合同 &model.StatementBatch{}, //对账单批次 - &model.StatementDetail{}, //对账单详情 + &model.ArtworkEntrustDetail{}, // + &model.ArtworkSalesDetail{}, // ) if err != nil { fmt.Println("register table fail") diff --git a/pkg/service/init.go b/pkg/service/init.go index 1cae9b1..f2ef451 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -9,6 +9,7 @@ import ( "github.com/fonchain/fonchain-artistinfo/pb/account" "github.com/fonchain/fonchain-artistinfo/pb/artist" contractMicroservice "github.com/fonchain/fonchain-artistinfo/pb/contract_microservice" + _ "github.com/fonchain/fonchain-artistinfo/pkg/common/filter" ) var ( 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) +}