This commit is contained in:
songchuang 2023-03-18 10:12:41 +08:00
commit 01487ea4c4
30 changed files with 1387 additions and 459 deletions

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/fonchain-artistinfo.iml" filepath="$PROJECT_DIR$/.idea/fonchain-artistinfo.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

128
.idea/workspace.xml Normal file
View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="ALL" />
</component>
<component name="ChangeListManager">
<list default="true" id="853fcb60-a62b-4975-bc33-7fe9b5daba92" name="Changes" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Go File" />
</list>
</option>
</component>
<component name="GOROOT" url="file://$USER_HOME$/.g/go" />
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectId" id="2LrJWBpeAE7xjhfmBJcHGq1aluW" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;DefaultGoTemplateProperty&quot;: &quot;Go File&quot;,
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.go.formatter.settings.were.checked&quot;: &quot;true&quot;,
&quot;RunOnceActivity.go.migrated.go.modules.settings&quot;: &quot;true&quot;,
&quot;RunOnceActivity.go.modules.go.list.on.any.changes.was.set&quot;: &quot;true&quot;,
&quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
&quot;configurable..is.expanded&quot;: &quot;false&quot;,
&quot;configurable.GoLibrariesConfigurable.is.expanded&quot;: &quot;true&quot;,
&quot;go.import.settings.migrated&quot;: &quot;true&quot;,
&quot;go.sdk.automatically.set&quot;: &quot;true&quot;,
&quot;last_opened_file_path&quot;: &quot;D:/jjxu/work/projects/fonchain-artistinfo/pb&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;editing.templates&quot;
}
}</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="D:\jjxu\work\projects\fonchain-artistinfo\pb" />
<recent name="D:\jjxu\work\projects\fonchain-artistinfo\conf" />
<recent name="D:\jjxu\work\projects\fonchain-artistinfo\conf\xjjdev" />
<recent name="D:\jjxu\work\projects\fonchain-artistinfo\conf\test" />
<recent name="D:\jjxu\work\projects\fonchain-artistinfo" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\jjxu\work\projects\fonchain-artistinfo\cmd\model\old" />
<recent name="D:\jjxu\work\projects\fonchain-artistinfo\cmd\model" />
<recent name="D:\jjxu\work\projects\fonchain-artistinfo\pb\old" />
<recent name="D:\jjxu\work\projects\fonchain-artistinfo\pb" />
<recent name="D:\jjxu\work\projects\fonchain-artistinfo\pb\artistinfo" />
</key>
</component>
<component name="RunManager">
<configuration name="go build app.go" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
<module name="fonchain-artistinfo" />
<working_directory value="$PROJECT_DIR$/cmd" />
<kind value="FILE" />
<package value="github.com/fonchain/fonchain-artistinfo/cmd" />
<directory value="$PROJECT_DIR$" />
<filePath value="$PROJECT_DIR$/cmd/app.go" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Go Build.go build app.go" />
</list>
</recent_temporary>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="VgoProject">
<environment>
<map>
<entry key="GOPROXY" value="https://goproxy.cn,direct" />
</map>
</environment>
<settings-migrated>true</settings-migrated>
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/cmd/internal/logic/artistinfo_artshowArtistSupplement.go</url>
<line>58</line>
<option name="timeStamp" value="18" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/cmd/internal/dao/artistInfo_user.go</url>
<line>34</line>
<option name="timeStamp" value="32" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
<watches-manager>
<configuration name="GoApplicationRunConfiguration">
<watch expression="*(*&quot;[]*github.com/fonchain/fonchain-artistinfo/pb/artwork_query.ArtworkPreviewResponse&quot;)(824648763672)" />
</configuration>
</watches-manager>
</component>
</project>

20
.vscode/launch.json vendored Normal file
View File

@ -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":[]
}
]
}

22
.vscode/settings.json vendored Normal file
View File

@ -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"
}

View File

@ -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 {

View File

@ -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)
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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"
}

View File

@ -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

View File

@ -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 # 日志级别

View File

@ -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;

View File

@ -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 (

View File

@ -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
}

View File

@ -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
}

View File

@ -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))
}

View File

@ -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")

View File

@ -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 (

Binary file not shown.

Binary file not shown.

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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("错误格式")
}
}

BIN
pkg/util/excel/img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
pkg/util/excel/img_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

27
pkg/util/excel/options.go Normal file
View File

@ -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)
}

161
pkg/util/excel/readme.md Normal file
View File

@ -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对象
数据类型至此结构体和切片<br/>
`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文件模板来调整更为直观方便所以没做此方面的设计。

41
pkg/util/excel/utils.go Normal file
View File

@ -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)
}