作者 yangfu

refactor: optimize table query

正在显示 60 个修改的文件 包含 1418 行增加167 行删除
... ... @@ -27,4 +27,6 @@ _testmain.go
app.log
go.sum
lastupdate.tmp
*.log
\ No newline at end of file
*.log
public/*
\ No newline at end of file
... ...
... ... @@ -139,16 +139,14 @@
- [ ] 表数据自定义查询 /table/preview where conditions 升序、降序 包含、不包含
- [ ] 表数据字段可选值搜索 /table/field-optional 文本匹配
- [ ] 表数据更新、添加、删除 /table/row-data-mutation
- [ ] 表数据导出
- [ ] 表数据导出 /table/export-table
## 数据验证
- [ ] 文件验证 /data/edit-data-table
- [] 文件验证 /data/edit-data-table
## 底层字库接口
- [ ] 表格编辑
```json
{
"file": {},
... ... @@ -157,7 +155,8 @@
"params": ["产品名2"]
}
```
- [ ] 数据预览
- [ ] 表格编辑
- [ ] 保存校验文件 (文件地址)
- [ ] 生成主表
- [ ] 表复制
... ... @@ -165,4 +164,10 @@
- [ ] 表删除 (主表、副表、分表)
- [ ] 表拆分
- [ ] 更新表结构(分表)
- [ ] 编辑、添加、删除表数据(副表)
\ No newline at end of file
- [ ] 编辑、添加、删除表数据(副表)
- [ ] 取消校验
## 定时作业
- 隔天清理校验中的文件
- 隔天清理public临时文件
\ No newline at end of file
... ...
/*1.初始化索引*/
/*files*/
CREATE INDEX IF NOT EXISTS idx_files_company_id_file_type ON metadata.files USING btree((context->>'companyId'),file_type);
CREATE INDEX IF NOT EXISTS idx_files_source_file_id ON metadata.files USING btree(source_file_id);
/*tables*/
CREATE INDEX IF NOT EXISTS idx_tables_company_id_table_type ON metadata.tables USING btree((context->>'companyId'),table_type);
CREATE INDEX IF NOT EXISTS idx_tables_parent_id ON metadata.tables USING btree(parent_id);
/*logs*/
CREATE INDEX IF NOT EXISTS idx_logs_company_id_log_type_source_id ON metadata.logs USING btree((context->>'companyId'),log_type,source_id);
CREATE INDEX IF NOT EXISTS idx_logs_company_id_object_name ON metadata.logs USING btree((context->>'companyId'),object_name);
CREATE INDEX IF NOT EXISTS idx_logs_company_id_object_type ON metadata.logs USING btree((context->>'companyId'),object_type);
CREATE INDEX IF NOT EXISTS idx_logs_company_id_operation_type ON metadata.logs USING btree((context->>'companyId'),operation_type);
CREATE INDEX IF NOT EXISTS idx_logs_company_id_content ON metadata.logs USING btree((context->>'companyId'),content);
CREATE INDEX IF NOT EXISTS idx_logs_company_id_operator_name ON metadata.logs USING btree((context->>'companyId'),operator_name);
CREATE INDEX IF NOT EXISTS idx_logs_company_id_created_at ON metadata.logs USING btree((context->>'companyId'),created_at);
/*mapping_rules*/
CREATE INDEX IF NOT EXISTS idx_mapping_rules_company_id_table_id_file_id ON metadata.mapping_rules USING btree((context->>'companyId'),table_id,file_id);
\ No newline at end of file
... ...
... ... @@ -45,6 +45,7 @@ require (
golang.org/x/tools v0.1.5 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gorm.io/driver/mysql v1.3.6
gorm.io/driver/postgres v1.3.9
gorm.io/gorm v1.23.8
)
... ...
... ... @@ -16,6 +16,8 @@ import (
_ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/beego"
)
const Version = "v1.0.1"
func main() {
defer func() {
if r := recover(); r != nil {
... ... @@ -31,6 +33,8 @@ func main() {
}
time.Sleep(time.Second)
log.Logger.Info("Service:" + constant.SERVICE_NAME)
log.Logger.Info("Version:" + Version)
log.Logger.Info("server start!")
web.Run()
log.Logger.Info("server stop!")
... ...
... ... @@ -13,7 +13,7 @@ func FastLog(transactionContext application.TransactionContext, logType domain.L
return logService.Log(logType, sourceId, logEntry)
}
func CreateLoadDataTableService(transactionContext application.TransactionContext) (domain.LoadDataTableService, error) {
func CreateLoadDataTableService(transactionContext application.TransactionContext) (domain.PreviewDataTableService, error) {
return domainService.NewLoadDataTableService(transactionContext.(*pg.TransactionContext))
}
... ...
package factory
import (
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
)
func FastError(err error) error {
return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
func FastDataTable(options starrocks.QueryOptions) (*domain.DataTable, error) {
var err error
// 待优化分批下载,压缩
var dataTable *domain.DataTable
dataTable, err = starrocks.Query(options, starrocks.WrapQueryFuncWithDB(starrocks.DB))
if err != nil {
return nil, err
}
dataTable.Total, err = starrocks.WrapQueryCountWithDB(options, starrocks.DB)()
if err != nil {
return nil, err
}
return dataTable, nil
}
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type CancelVerifyingFileCommand struct {
// 文件ID
FileId int `cname:"文件ID" json:"fileId" valid:"Required"`
}
func (cmd *CancelVerifyingFileCommand) Valid(validation *validation.Validation) {
}
func (cmd *CancelVerifyingFileCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(cmd)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(cmd).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
} else {
return fmt.Errorf(validErr.Message)
}
}
}
return nil
}
... ...
... ... @@ -2,7 +2,7 @@ package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/dto"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
... ... @@ -11,11 +11,11 @@ import (
type FlushDataTableCommand struct {
// 文件ID
FileId int `cname:"文件ID" json:"fileId" valid:"Required"`
FileId int `cname:"文件ID" json:"objectId" valid:"Required"`
// 记录数
RowCount int `cname:"记录数" json:"rowCount" valid:"Required"`
// 数据列
DataFields []*dto.Field `cname:"数据列" json:"dataFields" valid:"Required"`
DataFields []*domain.Field `cname:"数据列" json:"fields" valid:"Required"`
}
func (flushDataTableCommand *FlushDataTableCommand) Valid(validation *validation.Validation) {
... ...
... ... @@ -11,7 +11,7 @@ import (
type LoadDataTableCommand struct {
// 文件ID
FileId int `cname:"文件ID" json:"fileId" valid:"Required"`
FileId int `cname:"文件ID" json:"objectId" valid:"Required"`
// 页号
//PageNumber int `cname:"页号" json:"pageNumber"`
// 页号
... ...
... ... @@ -12,6 +12,8 @@ type FileDto struct {
Name string `json:"name"`
// 文件地址
Url string `json:"url"`
// 文件类型
FileType string `json:"fileType"`
// 创建时间
Time string `json:"time"`
}
... ... @@ -20,5 +22,6 @@ func (d *FileDto) Load(f *domain.File) {
d.FileId = f.FileId
d.Name = f.FileInfo.Name
d.Url = f.FileInfo.Url
d.FileType = f.FileType
d.Time = xtime.New(f.CreatedAt).Local().Format("2006-01-02 15:04:05")
}
... ...
... ... @@ -7,8 +7,8 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
)
// 加载表格数据
func (fileService *FileService) LoadDataTable(ctx *domain.Context, loadDataTableCommand *command.LoadDataTableCommand) (interface{}, error) {
// FilePreview 加载表格数据
func (fileService *FileService) FilePreview(ctx *domain.Context, loadDataTableCommand *command.LoadDataTableCommand) (interface{}, error) {
if err := loadDataTableCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
... ... @@ -24,7 +24,7 @@ func (fileService *FileService) LoadDataTable(ctx *domain.Context, loadDataTable
}()
loadDataTableService, _ := factory.CreateLoadDataTableService(transactionContext)
data, err := loadDataTableService.Load(ctx, loadDataTableCommand.FileId, loadDataTableCommand.Where)
data, err := loadDataTableService.Preview(ctx, loadDataTableCommand.FileId, loadDataTableCommand.Where)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
... ... @@ -37,7 +37,7 @@ func (fileService *FileService) LoadDataTable(ctx *domain.Context, loadDataTable
return data, nil
}
// 编辑表格数据
// EditDataTable 编辑表格数据
func (fileService *FileService) EditDataTable(ctx *domain.Context, editDataTableCommand *command.EditDataTableCommand) (interface{}, error) {
if err := editDataTableCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
... ... @@ -59,7 +59,7 @@ func (fileService *FileService) EditDataTable(ctx *domain.Context, editDataTable
return struct{}{}, nil
}
// 持久化表格数据
// FlushDataTable 持久化表格数据
func (fileService *FileService) FlushDataTable(ctx *domain.Context, flushDataTableCommand *command.FlushDataTableCommand) (interface{}, error) {
if err := flushDataTableCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
... ... @@ -79,7 +79,7 @@ func (fileService *FileService) FlushDataTable(ctx *domain.Context, flushDataTab
for _, f := range flushDataTableCommand.DataFields {
fields = append(fields, &domain.Field{
Name: f.Name,
SQLType: f.Type,
SQLType: f.SQLType,
})
}
if _, err := flushDataTableService.Flush(ctx, flushDataTableCommand.FileId, &domain.Table{
... ... @@ -94,7 +94,7 @@ func (fileService *FileService) FlushDataTable(ctx *domain.Context, flushDataTab
return struct{}{}, nil
}
// 生成主表
// GenerateMainTable 生成主表
func (fileService *FileService) GenerateMainTable(ctx *domain.Context, generateMainTableCommand *command.GenerateMainTableCommand) (interface{}, error) {
if err := generateMainTableCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
... ... @@ -121,7 +121,7 @@ func (fileService *FileService) GenerateMainTable(ctx *domain.Context, generateM
return struct{}{}, nil
}
// 生成主表
// AppendDataToTable 追加数据
func (fileService *FileService) AppendDataToTable(ctx *domain.Context, cmd *command.AppendDataToTableCommand) (interface{}, error) {
if err := cmd.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
... ...
... ... @@ -9,6 +9,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/dto"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/query"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain/bytecore"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
"path/filepath"
... ... @@ -210,7 +211,7 @@ func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFile
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeFileCommand.FileId)))
}
deleteFileService, _ := factory.CreateDeleteFileService(transactionContext)
err = deleteFileService.Delete(nil, file)
err = deleteFileService.DeleteFiles(nil, file)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
... ... @@ -263,6 +264,48 @@ func (fileService *FileService) UpdateFile(updateFileCommand *command.UpdateFile
}
}
// 取消校验中的文件
func (fileService *FileService) CancelVerifyingFile(ctx *domain.Context, cmd *command.CancelVerifyingFileCommand) (interface{}, error) {
if err := cmd.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
_, file, err := factory.FastPgFile(transactionContext, cmd.FileId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if file.FileType != domain.TemporaryFile.ToString() {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "校验中的文件才允许取消")
}
deleteFileService, _ := factory.CreateDeleteFileService(transactionContext)
err = deleteFileService.DeleteFiles(nil, file)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
byteCore, _ := factory.CreateByteCoreService(transactionContext)
_, err = byteCore.CancelFile(bytecore.ReqCancelFile{})
if err != nil {
return nil, factory.FastError(err)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
func NewFileService(options map[string]interface{}) *FileService {
newFileService := &FileService{}
return newFileService
... ...
... ... @@ -87,26 +87,15 @@ func (mappingRuleService *MappingRuleService) GetMappingRule(getMappingRuleQuery
defer func() {
transactionContext.RollbackTransaction()
}()
var mappingRuleRepository domain.MappingRuleRepository
if value, err := factory.CreateMappingRuleRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
mappingRuleRepository = value
}
mappingRule, err := mappingRuleRepository.FindOne(map[string]interface{}{"mappingRuleId": getMappingRuleQuery.MappingRuleId})
_, mappingRule, err := factory.FastPgMappingRule(transactionContext, getMappingRuleQuery.MappingRuleId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if mappingRule == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getMappingRuleQuery.MappingRuleId)))
} else {
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return mappingRule, nil
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return mappingRule, nil
}
// 返回匹配规则服务列表
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type FieldOptionalValuesCommand struct {
ObjectType string `cname:"对象类型" json:"objectType" valid:"Required"`
ObjectId int `cname:"对象Id标识" json:"objectId" valid:"Required"`
Field domain.Field `cname:"列" json:"field" valid:"Required"`
Match string `cname:"匹配内容" json:"match"`
PageNumber int `json:"pageNumber"`
PageSize int `json:"pageSize"`
}
func (cmd *FieldOptionalValuesCommand) Valid(validation *validation.Validation) {
}
func (cmd *FieldOptionalValuesCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(cmd)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(cmd).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
} else {
return fmt.Errorf(validErr.Message)
}
}
}
return nil
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type TablePreviewCommand struct {
// 表Id
TableId int `cname:"表Id" json:"objectId" valid:"Required"`
Where domain.Where `json:"where"`
}
func (cmd *TablePreviewCommand) Valid(validation *validation.Validation) {
}
func (cmd *TablePreviewCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(cmd)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(cmd).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
} else {
return fmt.Errorf(validErr.Message)
}
}
}
return nil
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type DBTablePreviewCommand struct {
// 表Id
ObjectId int `cname:"表Id" json:"objectId" valid:"Required"`
//ObjectType string `json:"objectType"`
Where domain.Where `json:"where"`
}
func (cmd *DBTablePreviewCommand) Valid(validation *validation.Validation) {
}
func (cmd *DBTablePreviewCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(cmd)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(cmd).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
} else {
return fmt.Errorf(validErr.Message)
}
}
}
return nil
}
... ...
... ... @@ -13,7 +13,7 @@ type TableDetailDto struct {
ParentId int `json:"parentId"`
// 主表字段
MainTableFields []*domain.Field `json:"mainTableFields"`
// 手动添加的列
// 手动添加字段
ManualFields []*domain.Field `json:"manualFields"`
// 数据列
Fields []*domain.Field `json:"fields"`
... ...
package dto
import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
type TablePreviewDto struct {
// 表Id
TableId int `json:"objectId"`
// 表Id
ObjectType string `json:"objectType"`
// 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表
TableType string `json:"tableType"`
// 名称
Name string `json:"name"`
// 数据
*domain.DataTable
}
func (d *TablePreviewDto) Load(m *domain.Table, dataTable *domain.DataTable, objectType string) *TablePreviewDto {
d.TableId = m.TableId
d.TableType = m.TableType
d.ObjectType = objectType
d.Name = m.Name
d.DataTable = &domain.DataTable{}
d.Fields = dataTable.MatchFields(m.Fields(true))
d.Data = dataTable.Data
d.Total = dataTable.Total
if len(d.Data) == 0 {
d.Data = make([][]string, 0)
}
return d
}
... ...
package service
import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/dto"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
)
func (tableService *TableService) DBTablePreview(ctx *domain.Context, cmd *command.DBTablePreviewCommand) (interface{}, error) {
if err := cmd.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
var table *domain.Table
var ok bool
table, ok = domain.DBTables[cmd.ObjectId]
if !ok {
return nil, factory.FastError(fmt.Errorf("表%v不存在", cmd.ObjectId))
}
var options = starrocks.QueryOptions{
TableName: table.SQLName,
Select: table.Fields(true),
Context: ctx,
}
options.SetCondition(cmd.Where.Conditions)
options.SetOffsetLimit(cmd.Where.PageNumber, cmd.Where.PageSize)
var dataTable *domain.DataTable
switch cmd.ObjectId {
case domain.DBTableTableOperateLog.ToInt():
options.SetCondition([]domain.Condition{{
Field: &domain.Field{
SQLName: "log_type",
SQLType: domain.String.ToString(),
},
In: []interface{}{domain.CommonLog.ToString()},
}})
}
dataTable, err = starrocks.Query(options, starrocks.WrapQueryFuncWithDB(pg.GormDB))
if err != nil {
return nil, factory.FastError(err)
}
dataTable.Total, err = starrocks.WrapQueryCountWithDB(options, pg.GormDB)()
if err != nil {
return nil, factory.FastError(err)
}
response := (&dto.TablePreviewDto{}).Load(table, dataTable, domain.ObjectDBTable)
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return response, nil
}
... ...
package service
import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/excel"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
"time"
)
func (tableService *TableService) ExportDataTable(ctx *domain.Context, cmd *command.TablePreviewCommand) (interface{}, error) {
if err := cmd.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
// TODO:加锁 同一个用户同一个时间点只允许一次下载
var table *domain.Table
var mainTable *domain.Table
_, table, err = factory.FastPgTable(transactionContext, cmd.TableId)
if err != nil {
return nil, factory.FastError(err)
}
if table.TableType == domain.SubTable.ToString() {
_, mainTable, err = factory.FastPgTable(transactionContext, cmd.TableId)
if err != nil {
return nil, factory.FastError(err)
}
} else {
mainTable = table
}
var options = starrocks.QueryOptions{
TableName: mainTable.SQLName,
Select: table.Fields(true),
}
// 待优化分批下载,压缩
var dataTable *domain.DataTable
dataTable, err = starrocks.Query(options, starrocks.DefaultQueryFunc)
if err != nil {
return nil, factory.FastError(err)
}
count, err := starrocks.QueryCount(options)
if err != nil {
return nil, factory.FastError(err)
}
filename := fmt.Sprintf("%v_%v.xlsx", table.Name, time.Now().Format("060102150405"))
path := fmt.Sprintf("public/%v", filename)
excelWriter := excel.NewXLXSWriterTo(domain.Fields(table.Fields(false)).NameArrayString(), dataTable.Data) //
if err = excelWriter.Save(path); err != nil {
return nil, factory.FastError(err)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return map[string]interface{}{
"url": domain.DownloadUrl(filename),
"count": count,
}, nil
}
... ...
package service
import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
"gorm.io/gorm"
)
func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd *command.FieldOptionalValuesCommand) (interface{}, error) {
if err := cmd.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
var dataTable *domain.DataTable
tableRepository, _, _ := factory.FastPgTable(transactionContext, 0)
var table *domain.Table
var db *gorm.DB
switch cmd.ObjectType {
case domain.ObjectFile:
table, err = tableRepository.FindOne(map[string]interface{}{"ctx": ctx, "tableId": cmd.ObjectId})
if err != nil {
return nil, factory.FastError(err)
}
case domain.ObjectMetaTable:
table, err = tableRepository.FindOne(map[string]interface{}{"ctx": ctx, "tableId": cmd.ObjectId})
if err != nil {
return nil, factory.FastError(err)
}
db = starrocks.DB
case domain.ObjectDBTable:
table = domain.DBTables[cmd.ObjectId]
db = pg.GormDB
}
field, ok := table.MatchField(&cmd.Field)
if !ok {
return nil, factory.FastError(fmt.Errorf("列:%v 不存在", cmd.Field.Name))
}
options := &starrocks.QueryOptions{
TableName: table.SQLName,
Select: []*domain.Field{field},
Where: []starrocks.Condition{
{
Condition: domain.Condition{
Field: field,
Like: cmd.Match,
Order: "ASC",
},
Distinct: true,
},
},
}
options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize)
dataTable, err = starrocks.Query(*options, starrocks.WrapQueryFuncWithDB(db))
if err != nil {
return nil, factory.FastError(err)
}
dataTable.Total, err = starrocks.WrapQueryCountWithDB(*options, db)()
if err != nil {
return nil, factory.FastError(err)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return map[string]interface{}{
"values": dataTable.OptionalValue(),
"total": dataTable.Total,
}, nil
}
... ...
... ... @@ -348,31 +348,6 @@ func (tableService *TableService) AddTableStruct(ctx *domain.Context, cmd *comma
return struct{}{}, nil
}
func (tableService *TableService) PreviewDataTable(ctx *domain.Context, cmd *command.AddTableStructCommand) (interface{}, error) {
if err := cmd.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
AddTableStructService, _ := factory.CreateAddTableStructService(transactionContext)
if _, err := AddTableStructService.AddTableStruct(ctx, cmd.TableId, cmd.Fields, cmd.Name); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
func NewTableService(options map[string]interface{}) *TableService {
newTableService := &TableService{}
return newTableService
... ...
package service
import (
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/dto"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
)
func (tableService *TableService) TablePreview(ctx *domain.Context, cmd *command.TablePreviewCommand) (interface{}, error) {
if err := cmd.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
var table *domain.Table
_, table, err = factory.FastPgTable(transactionContext, cmd.TableId)
if err != nil {
return nil, factory.FastError(err)
}
var options = starrocks.QueryOptions{
TableName: table.SQLName,
Select: table.Fields(true),
}
options.SetCondition(cmd.Where.Conditions)
options.SetOffsetLimit(cmd.Where.PageNumber, cmd.Where.PageSize)
var dataTable *domain.DataTable
dataTable, err = factory.FastDataTable(options)
if err != nil {
return nil, factory.FastError(err)
}
response := (&dto.TablePreviewDto{}).Load(table, dataTable, domain.ObjectMetaTable)
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return response, nil
}
... ...
... ... @@ -23,6 +23,10 @@ var ALLIED_CREATION_USER_HOST = "http://localhost:8081" //"http://allied-creatio
var MMM_BYTE_BANK_HOST = "http://220.250.41.79:8301"
var METADATA_BASTION_HOST = "http://127.0.0.1:8080"
var BYTE_CORE_HOST = "http://127.0.0.1:8080"
//var CUSTOMER_ACCOUNT = []int64{3129687560814592, 3129687690100739, 3492238958608384}
//const CUSTOMER_ACCOUNT_DELIMITER = ","
... ... @@ -39,6 +43,7 @@ func init() {
ALLIED_CREATION_USER_HOST = Configurator.DefaultString("ALLIED_CREATION_USER_HOST", ALLIED_CREATION_USER_HOST)
//ALLIED_CREATION_COOPERATION_HOST = Configurator.DefaultString("ALLIED_CREATION_COOPERATION_HOST", ALLIED_CREATION_COOPERATION_HOST)
MMM_BYTE_BANK_HOST = Configurator.DefaultString("MMM_BYTE_BANK_HOST", MMM_BYTE_BANK_HOST)
BYTE_CORE_HOST = Configurator.DefaultString("BYTE_CORE_HOST", BYTE_CORE_HOST)
SERVICE_ENV = Configurator.DefaultString("SERVICE_ENV", SERVICE_ENV)
HTTP_PORT = Configurator.DefaultInt("HTTP_PORT", HTTP_PORT)
SERVICE_NAME = fmt.Sprintf("%v-%v", SERVICE_NAME, SERVICE_ENV)
... ...
... ... @@ -5,6 +5,13 @@ import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastio
type ByteLibService interface {
LoadDataTable(param ReqLoadDataTable) (*DataLoadDataTable, error)
EditTable(param ReqEditDataTable) (*DataEditDataTable, error)
SaveTable(param ReqSaveTable) (*DataSaveTable, error)
GenerateTable(param ReqGenerateTable) (*DataGenerateTable, error)
CopyTable(param ReqCopyTable) (*DataCopyTable, error)
AppendData(param ReqAppendData) (*DataAppendData, error)
DeleteTable(param ReqDeleteTable) (*DataDeleteTable, error)
CancelFile(param ReqCancelFile) (*DataCancelFile, error)
EditTableData(param ReqEditTableData) (*DataEditTableData, error)
}
type (
... ... @@ -17,9 +24,11 @@ type (
}
DataLoadDataTable struct {
FileId int `json:"fileId"`
DataFields []*Field `json:"dataFields"`
DataRows [][]string `json:"dataRows"`
FileId int `json:"objectId"`
ObjectType string `json:"objectType"`
TableType string `json:"tableType"`
Fields []*Field `json:"fields"`
Data [][]string `json:"data"`
Total int `json:"total"`
PageNumber int `json:"pageNumber"`
InValidCells []InValidCell `json:"inValidCells"`
... ... @@ -31,7 +40,7 @@ type (
// 名称
Name string `json:"name"`
// 对应数据库类型
Type string `json:"type"`
Type string `json:"sqlType"`
}
InValidCell struct {
... ... @@ -53,15 +62,15 @@ func (table DataLoadDataTable) Filter(where domain.Where) *DataLoadDataTable {
data := make([][]string, 0)
if begin < table.Total {
if end < table.Total {
data = table.DataRows[begin:end]
data = table.Data[begin:end]
} else {
data = table.DataRows[begin:]
data = table.Data[begin:]
}
}
return &DataLoadDataTable{
FileId: table.FileId,
DataFields: table.DataFields,
DataRows: data,
Fields: table.Fields,
Data: data,
Total: table.Total,
PageNumber: where.PageNumber,
InValidCells: make([]InValidCell, 0),
... ... @@ -83,3 +92,60 @@ type (
DataLoadDataTable
}
)
type (
ReqSaveTable struct {
}
DataSaveTable struct {
Url string `json:"url"`
}
)
type (
ReqGenerateTable struct {
}
DataGenerateTable struct {
}
)
type (
ReqCopyTable struct {
}
DataCopyTable struct {
}
)
type (
ReqAppendData struct {
}
DataAppendData struct {
}
)
type (
ReqDeleteTable struct {
}
DataDeleteTable struct {
}
)
type (
ReqCancelFile struct {
}
DataCancelFile struct {
}
)
type (
ReqEditTableData struct {
}
DataEditTableData struct {
}
)
... ...
package domain
type DataTable struct {
Fields []*Field
Data [][]string
Total int
Fields []*Field `json:"fields"`
Data [][]string `json:"data"`
Total int64 `json:"total"`
}
type Where struct {
PageNumber int `json:"pageNumber"`
PageSize int `json:"pageSize"`
PageNumber int `json:"pageNumber"`
PageSize int `json:"pageSize"`
Conditions []Condition `json:"conditions"`
}
type Condition struct {
Field *Field `json:"field"`
Like string `json:"like"`
In []interface{} `json:"in"`
Ex []interface{} `json:"ex"`
Range []interface{} `json:"range"`
Order string `json:"order"`
}
func (t *DataTable) OptionalValue() []string {
var values = make([]string, 0)
if len(t.Data) > 0 && len(t.Data[0]) == 1 {
for i := range t.Data {
if len(t.Data[i]) == 0 {
continue
}
values = append(values, t.Data[i][0])
}
}
return values
}
func (t *DataTable) MatchFields(from []*Field) []*Field {
return from
}
... ...
package domain
type LoadDataTableService interface {
Load(ctx *Context, fileId int, where Where) (interface{}, error)
GetFileId() int
type FileTableService interface {
Preview(ctx *Context, fileId int, where Where) (interface{}, error)
Edit()
Flush(ctx *Context, fileId int, table *Table) (interface{}, error)
DeleteFiles(ctx *Context, files ...*File) error
GenerateTable(ctx *Context, fileId int, tableName string) (interface{}, error)
}
type EditDataTableService interface {
type TableService interface {
Preview(ctx *Context, tableId int, where Where) (interface{}, error)
CopyTable(ctx *Context, tableId int, tableName string) (interface{}, error)
DeleteTables(ctx *Context, tables ...*Table) error
AppendData(ctx *Context, fileId int, tableId int, mappingFields []*MappingField) (interface{}, error)
UpdateTableStruct(ctx *Context, tableId int, fields []*Field, name string) (interface{}, error)
AddTableStruct(ctx *Context, parentTableId int, fields []*Field, name string) (interface{}, error)
}
type PreviewDataTableService interface {
Preview(ctx *Context, fileId int, where Where) (interface{}, error)
GetFileId() int
}
type EditDataTableService interface{}
type FlushDataTableService interface {
Flush(ctx *Context, fileId int, table *Table) (interface{}, error)
}
type DeleteFileService interface {
Delete(ctx *Context, files ...*File) error
DeleteFiles(ctx *Context, files ...*File) error
}
type GenerateMainTableService interface {
... ... @@ -29,6 +45,12 @@ type DeleteDataTableService interface {
DeleteTables(ctx *Context, tables ...*Table) error
}
type AppendDataToTableService interface {
AppendData(ctx *Context, fileId int, tableId int, mappingFields []*MappingField) (interface{}, error)
}
/************************************/
type UpdateTableStructService interface {
UpdateTableStruct(ctx *Context, tableId int, fields []*Field, name string) (interface{}, error)
}
... ... @@ -36,7 +58,3 @@ type UpdateTableStructService interface {
type AddTableStructService interface {
AddTableStruct(ctx *Context, parentTableId int, fields []*Field, name string) (interface{}, error)
}
type AppendDataToTableService interface {
AppendData(ctx *Context, fileId int, tableId int, mappingFields []*MappingField) (interface{}, error)
}
... ...
package domain
import "fmt"
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant"
)
var (
ErrorNotFound = fmt.Errorf("没有此资源")
... ... @@ -36,9 +39,9 @@ var (
)
var (
PKField int = 0 // 主键字段
MainTableField int = 1 // 主表字段
ManualField int = 2 // 手动添加
PKField int = 1 // 主键字段
MainTableField int = 2 // 主表字段
ManualField int = 3 // 手动添加
)
var (
... ... @@ -60,6 +63,7 @@ var ObjectTypeMap = map[string]string{
SubTable.ToString(): "分表",
SourceFile.ToString(): "源文件",
VerifiedFile.ToString(): "校验文件",
ObjectDBTable: "业务表",
}
var (
... ... @@ -121,3 +125,85 @@ func EnumsDescription(m map[string]string, key string) string {
}
return ""
}
func DownloadUrl(filename string) string {
return fmt.Sprintf("%v/%v/%v", constant.METADATA_BASTION_HOST, "static", filename)
}
var DBTables = map[int]*Table{
DBTableTableOperateLog.ToInt(): &Table{
TableId: 1,
TableType: ObjectDBTable,
Name: "日志信息",
SQLName: "metadata.logs",
DataFieldIndex: 6,
PK: &Field{
Index: 0,
Name: "日志ID",
SQLName: "log_id",
SQLType: Int.ToString(),
Flag: PKField,
},
DataFields: []*Field{
{
Index: 1,
Name: "数据表表名/文件名",
SQLName: "object_name",
SQLType: String.ToString(),
Flag: MainTableField,
},
{
Index: 2,
Name: "类型",
SQLName: "object_type",
SQLType: String.ToString(),
Flag: MainTableField,
},
{
Index: 3,
Name: "操作类型",
SQLName: "operation_type",
SQLType: String.ToString(),
Flag: MainTableField,
},
{
Index: 4,
Name: "日志内容",
SQLName: "content",
SQLType: String.ToString(),
Flag: MainTableField,
},
{
Index: 5,
Name: "操作时间",
SQLName: "created_at",
SQLType: Datetime.ToString(),
Flag: MainTableField,
},
{
Index: 6,
Name: "操作人",
SQLName: "operator_name",
SQLType: String.ToString(),
Flag: MainTableField,
},
},
},
}
type DBTable int
func (t DBTable) ToInt() int {
return int(t)
}
const (
DBTableTableOperateLog DBTable = 1
DBTableBusinessLog DBTable = 2
)
const (
ObjectFile = "File"
ObjectMetaTable = "MetaTable"
ObjectDBTable = "DBTable"
)
... ...
... ... @@ -16,7 +16,7 @@ type Field struct {
SQLType string `json:"sqlType"`
// 描述
Description string `json:"description"`
// 标识 1:主表字段 2:手动添加
// 标识 1.主键 2:主表字段 3:手动添加
Flag int `json:"flag"`
}
... ... @@ -40,6 +40,14 @@ func (fields Fields) ToMap() map[string]*Field {
return m
}
func (fields Fields) NameArrayString() []string {
m := make([]string, 0)
for i := range fields {
m = append(m, fields[i].Name)
}
return m
}
func (fields Fields) Select(options map[string]interface{}) []*Field {
var result []*Field
for _, field := range fields {
... ...
package domain
import "time"
import (
"fmt"
"math/rand"
"time"
)
// Table 表
type Table struct {
... ... @@ -53,6 +57,8 @@ func (table *Table) Identify() interface{} {
}
func (table *Table) WithContext(ctx *Context) *Table {
rand.Seed(time.Now().Unix())
table.SQLName = fmt.Sprintf("%v_t%v_c%v", table.SQLName, rand.Intn(10000), ctx.CompanyId)
table.Context = ctx
return table
}
... ... @@ -63,15 +69,26 @@ func (table *Table) Update(data map[string]interface{}) error {
func (t *Table) Fields(includePK bool) []*Field {
var fields []*Field
if len(t.fields) == 0 {
if includePK {
fields = append(fields, t.PK)
}
fields = append(fields, t.DataFields...)
if t.TableType == SubTable.ToString() {
fields = append(fields, t.ManualFields...)
}
t.fields = fields
if includePK && t.PK != nil {
fields = append(fields, t.PK)
}
fields = append(fields, t.DataFields...)
if t.TableType == SubTable.ToString() {
fields = append(fields, t.ManualFields...)
}
t.fields = fields
return t.fields
}
func (t *Table) MatchField(field *Field) (*Field, bool) {
if len(t.fields) == 0 {
t.fields = t.Fields(true)
}
mField := (Fields)(t.fields).ToMap()
if v, ok := mField[field.Name]; ok {
return v, true
}
return nil, false
}
... ...
... ... @@ -2,7 +2,10 @@ package api
import (
rawjson "encoding/json"
"fmt"
"github.com/linmadan/egglib-go/utils/json"
"net/http"
"strings"
"time"
"github.com/beego/beego/v2/client/httplib"
... ... @@ -23,6 +26,7 @@ type BaseServiceGateway struct {
ConnectTimeout time.Duration
ReadWriteTimeout time.Duration
host string
Interceptor func(msg string)
}
type Request struct {
... ... @@ -33,16 +37,17 @@ type Request struct {
func (gateway BaseServiceGateway) CreateRequest(url string, method string) *httplib.BeegoHTTPRequest {
var request *httplib.BeegoHTTPRequest
method = strings.ToUpper(method)
switch method {
case "get", "GET":
case http.MethodGet:
request = httplib.Get(url)
case "post", "POST":
case http.MethodPost:
request = httplib.Post(url)
case "put", "PUT":
case http.MethodPut:
request = httplib.Put(url)
case "delete", "DELETE":
case http.MethodDelete:
request = httplib.Delete(url)
case "head", "HEADER":
case http.MethodHead:
request = httplib.Head(url)
default:
request = httplib.Get(url)
... ... @@ -59,7 +64,24 @@ func (gateway BaseServiceGateway) GetResponseData(result Response, data interfac
}
func (gateway BaseServiceGateway) FastDoRequest(url, method string, param interface{}, data interface{}) error {
err := gateway.DoRequest(Request{
begin := time.Now()
var err error
var result = "success"
defer func() {
jsonParam, _ := json.Marshal(param)
jsonData, _ := json.Marshal(data)
if err != nil {
result = err.Error()
}
if gateway.Interceptor != nil {
gateway.Interceptor(fmt.Sprintf("%v | %v | %v : %v \n request:%v \n response:%v", time.Since(begin), url, strings.ToUpper(method),
result,
string(jsonParam),
string(jsonData),
))
}
}()
err = gateway.DoRequest(Request{
Url: url,
Method: method,
Param: param,
... ...
... ... @@ -3,6 +3,7 @@ package bytelib
import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain/bytecore"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/api"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log"
"time"
)
... ... @@ -16,6 +17,9 @@ func NewApiByteLib(host string) *ApiByteLib {
gt := api.NewBaseServiceGateway(host)
gt.ConnectTimeout = 10 * time.Second
gt.ReadWriteTimeout = 10 * time.Second
gt.Interceptor = func(msg string) {
log.Logger.Info(msg)
}
return &ApiByteLib{
BaseServiceGateway: gt,
}
... ... @@ -39,18 +43,90 @@ func (gateway ApiByteLib) EditTable(param bytecore.ReqEditDataTable) (*bytecore.
return &data, nil
}
// 保存校验文件 (文件地址)
// SaveTable 保存校验文件 (文件地址)
func (gateway ApiByteLib) SaveTable(param bytecore.ReqSaveTable) (*bytecore.DataSaveTable, error) {
url := gateway.Host() + "/table/save"
method := "post"
var data bytecore.DataSaveTable
err := gateway.FastDoRequest(url, method, param, &data)
if err != nil {
return nil, err
}
return &data, nil
}
// 生成主表
// GenerateTable 生成主表
func (gateway ApiByteLib) GenerateTable(param bytecore.ReqGenerateTable) (*bytecore.DataGenerateTable, error) {
url := gateway.Host() + "/table/generate"
method := "post"
var data bytecore.DataGenerateTable
err := gateway.FastDoRequest(url, method, param, &data)
if err != nil {
return nil, err
}
return &data, nil
}
// 表复制
// CopyTable 表复制
func (gateway ApiByteLib) CopyTable(param bytecore.ReqCopyTable) (*bytecore.DataCopyTable, error) {
url := gateway.Host() + "/table/copy"
method := "post"
var data bytecore.DataCopyTable
err := gateway.FastDoRequest(url, method, param, &data)
if err != nil {
return nil, err
}
return &data, nil
}
// 追加数据
// AppendData 追加数据
func (gateway ApiByteLib) AppendData(param bytecore.ReqAppendData) (*bytecore.DataAppendData, error) {
url := gateway.Host() + "/table/append"
method := "post"
var data bytecore.DataAppendData
err := gateway.FastDoRequest(url, method, param, &data)
if err != nil {
return nil, err
}
return &data, nil
}
// 表删除 (主表、副表、分表)
// DeleteTable 表删除 (主表、副表、分表)
func (gateway ApiByteLib) DeleteTable(param bytecore.ReqDeleteTable) (*bytecore.DataDeleteTable, error) {
url := gateway.Host() + "/table/delete"
method := "post"
var data bytecore.DataDeleteTable
err := gateway.FastDoRequest(url, method, param, &data)
if err != nil {
return nil, err
}
return &data, nil
}
// CancelFile 表删除 (主表、副表、分表)
func (gateway ApiByteLib) CancelFile(param bytecore.ReqCancelFile) (*bytecore.DataCancelFile, error) {
url := gateway.Host() + "/table/cancel-file"
method := "post"
var data bytecore.DataCancelFile
err := gateway.FastDoRequest(url, method, param, &data)
if err != nil {
return nil, err
}
return &data, nil
}
// 表拆分
// 更新表结构(分表)
// 编辑、添加、删除表数据(副表)
// EditTableData 编辑、添加、删除表数据(副表)
func (gateway ApiByteLib) EditTableData(param bytecore.ReqEditTableData) (*bytecore.DataEditTableData, error) {
url := gateway.Host() + "/table/cancel-file"
method := "post"
var data bytecore.DataEditTableData
err := gateway.FastDoRequest(url, method, param, &data)
if err != nil {
return nil, err
}
return &data, nil
}
... ...
... ... @@ -14,6 +14,8 @@ type ByteCoreService struct {
var ByteCore = &ByteCoreService{} //bytecore.ByteLibService
var _ bytecore.ByteLibService = (*ByteCoreService)(nil)
func (ptr *ByteCoreService) LoadDataTable(param bytecore.ReqLoadDataTable) (*bytecore.DataLoadDataTable, error) {
if v, ok := ptr.load(param.FileId); ok {
return v.Filter(param.Where), nil
... ... @@ -37,8 +39,8 @@ func (ptr *ByteCoreService) LoadDataTable(param bytecore.ReqLoadDataTable) (*byt
var response = &bytecore.DataLoadDataTable{
FileId: param.FileId,
DataFields: columnToField(cols),
DataRows: data,
Fields: columnToField(cols),
Data: data,
Total: len(data),
PageNumber: param.PageNumber,
InValidCells: make([]bytecore.InValidCell, 0),
... ... @@ -77,6 +79,34 @@ func columnToField(cols []string) []*bytecore.Field {
return fields
}
func (ptr *ByteCoreService) SaveTable(param bytecore.ReqSaveTable) (*bytecore.DataSaveTable, error) {
return nil, nil
}
func (ptr *ByteCoreService) GenerateTable(param bytecore.ReqGenerateTable) (*bytecore.DataGenerateTable, error) {
return nil, nil
}
func (ptr *ByteCoreService) CopyTable(param bytecore.ReqCopyTable) (*bytecore.DataCopyTable, error) {
return nil, nil
}
func (ptr *ByteCoreService) AppendData(param bytecore.ReqAppendData) (*bytecore.DataAppendData, error) {
return nil, nil
}
func (ptr *ByteCoreService) DeleteTable(param bytecore.ReqDeleteTable) (*bytecore.DataDeleteTable, error) {
return nil, nil
}
func (ptr *ByteCoreService) CancelFile(param bytecore.ReqCancelFile) (*bytecore.DataCancelFile, error) {
return nil, nil
}
func (ptr *ByteCoreService) EditTableData(param bytecore.ReqEditTableData) (*bytecore.DataEditTableData, error) {
return nil, nil
}
//////////////
// 字库核心
//////////////
... ...
package domainService
import pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
type DeleteTableService struct {
transactionContext *pgTransaction.TransactionContext
}
func (ptr *DeleteTableService) Delete(tableIds ...int) error {
// delete table
// delete log
return nil
}
... ... @@ -21,7 +21,8 @@ func NewDeleteFileService(transactionContext *pgTransaction.TransactionContext)
}
}
func (ptr *DeleteFileService) Delete(ctx *domain.Context, files ...*domain.File) error {
// DeleteFiles 文件删除
func (ptr *DeleteFileService) DeleteFiles(ctx *domain.Context, files ...*domain.File) error {
for _, file := range files {
if err := ptr.delete(file); err != nil {
return err
... ...
... ... @@ -11,6 +11,7 @@ type EditDataTableService struct {
transactionContext *pgTransaction.TransactionContext
}
// Edit 表结构编辑 【data-table】
func (ptr *EditDataTableService) Edit(ctx *domain.Context, fileId int, tableId int, mappingFields []*domain.MappingField) (interface{}, error) {
fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
... ...
... ... @@ -4,6 +4,7 @@ import (
"fmt"
"github.com/google/uuid"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"github.com/linmadan/egglib-go/utils/tool_funs"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/dao"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
... ... @@ -15,6 +16,7 @@ type FlushDataTableService struct {
transactionContext *pgTransaction.TransactionContext
}
// Flush 保存表 【data-table】
func (ptr *FlushDataTableService) Flush(ctx *domain.Context, fileId int, table *domain.Table) (interface{}, error) {
fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
... ... @@ -69,7 +71,7 @@ func (ptr *FlushDataTableService) flushSourceFile(ctx *domain.Context, table *do
return err
}
deleteFileService, _ := NewDeleteFileService(ptr.transactionContext)
if err = deleteFileService.Delete(ctx, files...); err != nil {
if err = deleteFileService.DeleteFiles(ctx, files...); err != nil {
return err
}
return nil
... ... @@ -119,7 +121,7 @@ func NewTable(tableType domain.TableType, fileName string, dataFields []*domain.
// New Table
table.TableType = tableType.ToString()
table.Name = fileName
table.SQLName = SQLTableName()
table.SQLName = pin(fileName) //SQLTableName()
table.PK = PK()
table.DataFieldIndex = len(dataFields)
for i, field := range dataFields {
... ... @@ -144,7 +146,7 @@ func PK() *domain.Field {
SQLName: "id",
SQLType: domain.Int.ToString(),
Description: "主键",
Flag: 0,
Flag: domain.PKField,
}
}
... ... @@ -152,13 +154,13 @@ func DataField(name string, sqlType string, flag int, index int) *domain.Field {
return &domain.Field{
Index: index,
Name: name,
SQLName: fieldName(index),
SQLName: fmt.Sprintf("%v_c%d", pin(name), index), //fieldName(index),
SQLType: sqlType,
Description: "",
Flag: flag,
}
}
func fieldName(index int) string {
return fmt.Sprintf("col%d", index)
func pin(name string) string {
return tool_funs.ToPinYin(name, "_")
}
... ...
... ... @@ -11,6 +11,7 @@ type GenerateMainTableService struct {
transactionContext *pgTransaction.TransactionContext
}
// GenerateTable 主表生成 【data-table】
func (ptr *GenerateMainTableService) GenerateTable(ctx *domain.Context, fileId int, tableName string) (interface{}, error) {
fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
... ... @@ -23,7 +24,7 @@ func (ptr *GenerateMainTableService) GenerateTable(ctx *domain.Context, fileId i
if err != nil {
return nil, fmt.Errorf("文件未校验")
}
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableType": domain.MainTable.ToString(), "tableName": tableName})
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableName": tableName})
if err == nil && duplicateTable != nil {
return nil, fmt.Errorf("表名称重复")
}
... ...
... ... @@ -8,12 +8,13 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
)
type LoadDataTableService struct {
type PreviewDataTableService struct {
FileId int
transactionContext *pgTransaction.TransactionContext
}
func (ptr *LoadDataTableService) Load(ctx *domain.Context, fileId int, where domain.Where) (interface{}, error) {
// Preview 预览 【data-table】
func (ptr *PreviewDataTableService) Preview(ctx *domain.Context, fileId int, where domain.Where) (interface{}, error) {
fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
if err != nil {
... ... @@ -42,19 +43,27 @@ func (ptr *LoadDataTableService) Load(ctx *domain.Context, fileId int, where dom
if err != nil {
return nil, err
}
response.ObjectType = domain.ObjectFile
response.TableType = domain.ExcelTable.ToString()
return response, nil
}
func (ptr *LoadDataTableService) GetFileId() int {
//func convert(from *bytecore.DataLoadDataTable)(to *domain.DataTable){
// to = &domain.DataTable{
//
// }
// return
//}
func (ptr *PreviewDataTableService) GetFileId() int {
return ptr.FileId
}
func NewLoadDataTableService(transactionContext *pgTransaction.TransactionContext) (*LoadDataTableService, error) {
func NewLoadDataTableService(transactionContext *pgTransaction.TransactionContext) (*PreviewDataTableService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &LoadDataTableService{
return &PreviewDataTableService{
transactionContext: transactionContext,
}, nil
}
... ...
... ... @@ -32,7 +32,7 @@ func (ptr *AddTableStructService) AddTableStruct(ctx *domain.Context, parentTabl
}
// 验证表名是否重复
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"tableType": domain.SubTable.ToString(), "tableName": name})
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableName": name})
if err == nil && duplicateTable != nil {
return nil, fmt.Errorf("表名称重复")
}
... ...
... ... @@ -5,12 +5,14 @@ import (
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
"time"
)
type AppendDataToTableService struct {
transactionContext *pgTransaction.TransactionContext
}
// AppendData 追加数据 【data-table】
func (ptr *AppendDataToTableService) AppendData(ctx *domain.Context, fileId int, tableId int, mappingFields []*domain.MappingField) (interface{}, error) {
fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
... ... @@ -38,6 +40,13 @@ func (ptr *AppendDataToTableService) AppendData(ctx *domain.Context, fileId int,
return nil, err
}
// 更新表数据
table.RowCount += excelTable.RowCount
table.UpdatedAt = time.Now()
if _, err = tableRepository.Save(table); err != nil {
return nil, err
}
// 日志
if err = FastLog(ptr.transactionContext, domain.CommonLog, table.TableId, &AppendDataToTableLog{
LogEntry: domain.NewLogEntry(table.Name, domain.MainTable.ToString(), domain.AppendData, ctx),
... ...
... ... @@ -21,14 +21,18 @@ func NewCopyDataTableService(transactionContext *pgTransaction.TransactionContex
}
}
// CopyTable 表复制 【data-table】
func (ptr *CopyDataTableService) CopyTable(ctx *domain.Context, tableId int, tableName string) (interface{}, error) {
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
table, err := tableRepository.FindOne(map[string]interface{}{"tableId": tableId})
if err != nil {
return nil, err
}
if table.TableType != domain.MainTable.ToString() {
return nil, fmt.Errorf("主表才允许复制")
}
// 验证表名是否重复
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"tableType": domain.SideTable.ToString(), "tableName": tableName})
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableName": tableName})
if err == nil && duplicateTable != nil {
return nil, fmt.Errorf("表名称重复")
}
... ...
... ... @@ -21,6 +21,7 @@ func NewDeleteDataTableService(transactionContext *pgTransaction.TransactionCont
}
}
// DeleteTable 表删除 【data-table】
func (ptr *DeleteDataTableService) DeleteTable(ctx *domain.Context, tableId int) (interface{}, error) {
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
table, err := tableRepository.FindOne(map[string]interface{}{"tableId": tableId})
... ...
... ... @@ -8,6 +8,7 @@ import (
"github.com/xuri/excelize/v2"
"io"
"os"
"path/filepath"
)
type XLXSWriterTo struct {
... ... @@ -27,6 +28,9 @@ func (wt *XLXSWriterTo) WriteTo(w io.Writer) (n int64, err error) {
func (wt *XLXSWriterTo) Save(fileName string) error {
var file *excelize.File
var err error
if err = checkPath(fileName); err != nil {
return err
}
file, err = wt.newFile()
if err != nil {
return nil
... ... @@ -34,6 +38,27 @@ func (wt *XLXSWriterTo) Save(fileName string) error {
return file.SaveAs(fileName)
}
func checkPath(fileName string) error {
dir := filepath.Dir(fileName)
if !Exists(dir) {
if err := os.Mkdir(dir, os.ModePerm); err != nil {
return err
}
}
return nil
}
func Exists(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息
if err != nil {
if os.IsExist(err) {
return true
}
return false
}
return true
}
func (wt *XLXSWriterTo) newFile() (*excelize.File, error) {
sheet := "Sheet1"
file := excelize.NewFile()
... ... @@ -94,6 +119,9 @@ func (xw *CSVWriterTo) WriteTo(w io.Writer) (n int64, err error) {
}
func (xw *CSVWriterTo) Save(fileName string) error {
if err := checkPath(fileName); err != nil {
return err
}
csvFile, err := os.Create(fileName)
if err != nil {
return err
... ... @@ -143,10 +171,13 @@ func (xw *XlSWriterTo) WriteTo(w io.Writer) (n int64, err error) {
}
func (xw *XlSWriterTo) Save(fileName string) error {
if err := checkPath(fileName); err != nil {
return err
}
option := excel.Option{"Visible": true, "DisplayAlerts": true, "ScreenUpdating": true}
xl, err := excel.New(option) //xl, _ := excel.Open("test_excel.xls", option)
if err != nil {
return err
}
defer xl.Quit()
... ...
... ... @@ -8,10 +8,16 @@ import (
"github.com/go-pg/pg/v10/orm"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg/models"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"log"
"os"
"time"
)
var DB *pg.DB
var GormDB *gorm.DB
func Init() {
DB = pg.Connect(&pg.Options{
... ... @@ -41,6 +47,30 @@ func Init() {
//comment.AddComments(DB, model)
}
}
var err error
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
Colorful: false, // Disable color
},
)
dsn := fmt.Sprintf("host=%v user=%v password=%v dbname=%v port=%v sslmode=disable TimeZone=Asia/Shanghai",
constant.POSTGRESQL_HOST, constant.POSTGRESQL_USER, constant.POSTGRESQL_PASSWORD, constant.POSTGRESQL_DB_NAME, constant.POSTGRESQL_PORT)
GormDB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: newLogger,
//NamingStrategy: schema.NamingStrategy{
// TablePrefix: "metadata.", // schema name
// SingularTable: false,
//},
})
if err != nil {
newLogger.Error(context.Background(), err.Error())
}
}
type SqlGeneratePrintHook struct{}
... ...
... ... @@ -2,7 +2,11 @@ package starrocks
import (
"database/sql"
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gorm.io/gorm"
"reflect"
"strings"
)
func Query(params QueryOptions, queryFunc func(params QueryOptions) (*sql.Rows, error)) (*domain.DataTable, error) {
... ... @@ -10,24 +14,172 @@ func Query(params QueryOptions, queryFunc func(params QueryOptions) (*sql.Rows,
if err != nil {
return nil, err
}
defer rows.Close()
dataTable := &domain.DataTable{}
dataTable.Data, _ = ScanRows(rows)
return nil, nil
dataTable.Data, err = ScanRows(rows)
//rows.Columns()
return dataTable, err
}
type QueryOptions struct {
TableName string
Select []*domain.Field
Where []string
Order []string
Where []Condition
Offset int
Limit int
Context *domain.Context
}
func (o *QueryOptions) SetOffsetLimit(pageNumber, pageSize int) {
if pageNumber == 0 {
pageNumber = 1
}
if pageSize == 0 {
pageSize = 20
}
o.Offset = (pageNumber - 1) * pageSize
o.Limit = pageSize
}
func (o *QueryOptions) SetCondition(conditions []domain.Condition) {
for _, c := range conditions {
o.Where = append(o.Where, Condition{
Condition: c,
})
}
}
type Condition struct {
Field *domain.Field
In []interface{}
Ex []interface{}
Range []interface{}
Order []interface{}
domain.Condition
Distinct bool
}
func (c Condition) SetWhere(q *gorm.DB) {
if len(c.Like) > 0 {
q.Where(fmt.Sprintf("%v like '%%%v%%'", c.Field.SQLName, c.Like))
}
if len(c.In) > 0 {
q.Where(fmt.Sprintf("%v in %v", c.Field.SQLName, c.InArgs(c.In)))
}
if len(c.Ex) > 0 {
in := c.InArgs(c.Ex)
q.Where(fmt.Sprintf("%v not in %v", c.Field.SQLName, in))
}
if c.Distinct {
q.Distinct(c.Field.SQLName)
}
if len(c.Order) > 0 {
q.Order(fmt.Sprintf("%v %v", c.Field.SQLName, c.Order))
}
}
func (c Condition) InArgs(args interface{}) string {
bytes := make([]byte, 0)
bytes = appendIn(bytes, reflect.ValueOf(args))
return string(bytes)
}
func appendIn(b []byte, slice reflect.Value) []byte {
sliceLen := slice.Len()
b = append(b, '(')
for i := 0; i < sliceLen; i++ {
if i > 0 {
b = append(b, ',')
}
elem := slice.Index(i)
if elem.Kind() == reflect.Interface {
elem = elem.Elem()
}
if elem.Kind() == reflect.Slice {
//b = appendIn(b, elem)
} else {
b = appendValue(b, elem)
}
}
b = append(b, ')')
return b
}
func appendValue(b []byte, v reflect.Value) []byte {
if v.Kind() == reflect.Ptr && v.IsNil() {
return append(b, "NULL"...)
}
if v.Kind() == reflect.Int || v.Kind() == reflect.Int64 || v.Kind() == reflect.Float64 {
return append(b, []byte(v.String())...)
}
b = append(b, []byte("'")...)
b = append(b, []byte(v.String())...)
b = append(b, []byte("'")...)
return b
}
func DefaultQueryFunc(params QueryOptions) (*sql.Rows, error) {
query := DB.Table(params.TableName)
rows, err := query.Rows()
if err != nil {
return nil, err
}
return rows, nil
}
func WrapQueryFuncWithDB(db *gorm.DB) func(QueryOptions) (*sql.Rows, error) {
return func(params QueryOptions) (*sql.Rows, error) {
query := db.Table(params.TableName)
queryWithoutLimitOffset(query, params)
if params.Offset > 0 {
query.Offset(params.Offset)
}
if params.Limit > 0 {
query.Limit(params.Limit)
}
if params.Context != nil {
query.Where(fmt.Sprintf("context->>'companyId'='%v'", params.Context.CompanyId))
//query.Where("context->>'companyId'='?'", params.Context.CompanyId)
}
rows, err := query.Rows()
if err != nil {
return nil, err
}
return rows, nil
}
}
func SetTable(query *gorm.DB, tableName string) {
query.Statement.Table = tableName
}
func queryWithoutLimitOffset(query *gorm.DB, params QueryOptions) {
if len(params.Select) > 0 {
fields := make([]string, 0)
for _, f := range params.Select {
fields = append(fields, f.SQLName)
}
query.Select(strings.Join(fields, ","))
}
if len(params.Where) > 0 {
for _, w := range params.Where {
w.SetWhere(query)
}
}
}
func QueryCount(params QueryOptions) (int64, error) {
var total int64
query := DB.Table(params.TableName)
queryWithoutLimitOffset(query, params)
query.Count(&total)
return total, query.Error
}
func WrapQueryCountWithDB(params QueryOptions, db *gorm.DB) func() (int64, error) {
return func() (int64, error) {
var total int64
query := db.Table(params.TableName)
queryWithoutLimitOffset(query, params)
query.Count(&total)
return total, query.Error
}
}
... ...
... ... @@ -8,7 +8,6 @@ import (
)
func ScanRows(rows *sql.Rows) ([][]string, error) {
defer rows.Close()
var results [][]string
cols, err := rows.Columns()
if err != nil {
... ...
... ... @@ -7,14 +7,27 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
rawlog "log"
"os"
"reflect"
"time"
)
var DB *gorm.DB
func Init() error {
var err error
DB, err = gorm.Open(mysql.Open(constant.STARROCKS_MYSQL_DATA_SOURCE), &gorm.Config{})
newLogger := logger.New(
rawlog.New(os.Stdout, "\r\n", rawlog.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
Colorful: false, // Disable color
},
)
DB, err = gorm.Open(mysql.Open(constant.STARROCKS_MYSQL_DATA_SOURCE), &gorm.Config{Logger: newLogger})
//Test1()
return err
... ...
... ... @@ -26,7 +26,7 @@ func init() {
web.BConfig.Listen.HTTPPort = port
}
}
web.InsertFilter("/*", web.BeforeExec, filters.AllowCors())
web.InsertFilter("/*", web.BeforeRouter, filters.AllowCors())
web.InsertFilter("/*", web.BeforeExec, filters.CreateRequstLogFilter(Logger))
web.InsertFilter("/*", web.AfterExec, filters.CreateResponseLogFilter(Logger), web.WithReturnOnOutput(false))
}
... ...
package controllers
import (
"github.com/linmadan/egglib-go/web/beego"
"path/filepath"
)
type DownloadFileController struct {
beego.BaseController
}
func (controller *DownloadFileController) DownloadHandle() {
filename := filepath.Base(controller.GetString(":filename"))
controller.Ctx.Output.Download("public/" + filename)
}
... ...
... ... @@ -90,11 +90,11 @@ func (controller *FileController) SearchVerifiedFile() {
controller.Response(data, err)
}
func (controller *FileController) LoadDataTable() {
func (controller *FileController) FilePreview() {
fileService := service.NewFileService(nil)
loadDataTableCommand := &command.LoadDataTableCommand{}
controller.Unmarshal(loadDataTableCommand)
data, err := fileService.LoadDataTable(ParseContext(controller.BaseController), loadDataTableCommand)
data, err := fileService.FilePreview(ParseContext(controller.BaseController), loadDataTableCommand)
controller.Response(data, err)
}
... ... @@ -124,8 +124,16 @@ func (controller *FileController) GenerateMainTable() {
func (controller *FileController) AppendDataToTable() {
fileService := service.NewFileService(nil)
cmdd := &command.AppendDataToTableCommand{}
controller.Unmarshal(cmdd)
data, err := fileService.AppendDataToTable(ParseContext(controller.BaseController), cmdd)
cmd := &command.AppendDataToTableCommand{}
controller.Unmarshal(cmd)
data, err := fileService.AppendDataToTable(ParseContext(controller.BaseController), cmd)
controller.Response(data, err)
}
func (controller *FileController) CancelVerifyingFile() {
fileService := service.NewFileService(nil)
cmd := &command.CancelVerifyingFileCommand{}
controller.Unmarshal(cmd)
data, err := fileService.CancelVerifyingFile(ParseContext(controller.BaseController), cmd)
controller.Response(data, err)
}
... ...
... ... @@ -71,7 +71,9 @@ func (controller *MappingRuleController) SearchMappingRule() {
func (controller *MappingRuleController) PrepareMappingRule() {
mappingRuleService := service.NewMappingRuleService(nil)
prepareCommand := &command.PrepareCommand{}
controller.Unmarshal(prepareCommand)
//controller.Unmarshal(prepareCommand)
prepareCommand.TableId, _ = controller.GetInt("tableId")
prepareCommand.FileId, _ = controller.GetInt("fileId")
data, err := mappingRuleService.Prepare(prepareCommand)
controller.Response(data, err)
}
... ...
... ... @@ -6,6 +6,9 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/query"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/service"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
filecommand "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/command"
fileservice "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/service"
)
type TableController struct {
... ... @@ -138,3 +141,63 @@ func (controller *TableController) AddTableStruct() {
data, err := tableService.AddTableStruct(ParseContext(controller.BaseController), batchEditSubTableCommand)
controller.Response(data, err)
}
func (controller *TableController) ExportDataTable() {
tableService := service.NewTableService(nil)
cmd := &command.TablePreviewCommand{}
controller.Unmarshal(cmd)
data, err := tableService.ExportDataTable(ParseContext(controller.BaseController), cmd)
controller.Response(data, err)
}
func (controller *TableController) TablePreview() {
tableService := service.NewTableService(nil)
cmd := &command.TablePreviewCommand{}
controller.Unmarshal(cmd)
data, err := tableService.TablePreview(ParseContext(controller.BaseController), cmd)
controller.Response(data, err)
}
func (controller *TableController) DBTablePreview() {
tableService := service.NewTableService(nil)
cmd := &command.DBTablePreviewCommand{}
controller.Unmarshal(cmd)
data, err := tableService.DBTablePreview(ParseContext(controller.BaseController), cmd)
controller.Response(data, err)
}
func (controller *TableController) FieldOptionalValues() {
tableService := service.NewTableService(nil)
cmd := &command.FieldOptionalValuesCommand{}
controller.Unmarshal(cmd)
data, err := tableService.FieldOptionalValues(ParseContext(controller.BaseController), cmd)
controller.Response(data, err)
}
func (controller *TableController) Preview() {
tableService := service.NewTableService(nil)
fileService := fileservice.NewFileService(nil)
cmd := &struct {
ObjectType string `json:"objectType"`
}{}
controller.Unmarshal(cmd)
var data interface{}
var err error
switch cmd.ObjectType {
case domain.ObjectFile:
cmd := &filecommand.LoadDataTableCommand{}
controller.Unmarshal(cmd)
data, err = fileService.FilePreview(ParseContext(controller.BaseController), cmd)
case domain.ObjectMetaTable:
cmd := &command.TablePreviewCommand{}
controller.Unmarshal(cmd)
data, err = tableService.TablePreview(ParseContext(controller.BaseController), cmd)
case domain.ObjectDBTable:
cmd := &command.DBTablePreviewCommand{}
controller.Unmarshal(cmd)
data, err = tableService.DBTablePreview(ParseContext(controller.BaseController), cmd)
default:
}
controller.Response(data, err)
}
... ...
package routers
import (
"github.com/beego/beego/v2/server/web"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/beego/controllers"
)
func init() {
web.Router("/data/business/db-table-preview", &controllers.TableController{}, "Post:DBTablePreview")
}
... ...
package routers
import (
"github.com/beego/beego/v2/server/web"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/beego/controllers"
)
func init() {
web.Router("/static/:filename", &controllers.DownloadFileController{}, "*:DownloadHandle")
}
... ...
... ... @@ -14,8 +14,9 @@ func init() {
web.Router("/data/files/search", &controllers.FileController{}, "Post:SearchFile")
web.Router("/data/files/search-source-file", &controllers.FileController{}, "Post:SearchSourceFile")
web.Router("/data/files/search-verified-file", &controllers.FileController{}, "Post:SearchVerifiedFile")
web.Router("/data/files/cancel-verifying-file", &controllers.FileController{}, "Post:CancelVerifyingFile")
web.Router("/data/load-data-table", &controllers.FileController{}, "Post:LoadDataTable")
web.Router("/data/file-preview", &controllers.FileController{}, "Post:FilePreview")
web.Router("/data/edit-data-table", &controllers.FileController{}, "Post:EditDataTable")
web.Router("/data/flush-data-table", &controllers.FileController{}, "Post:FlushDataTable")
web.Router("/data/generate-main-table", &controllers.FileController{}, "Post:GenerateMainTable")
... ...
... ... @@ -12,5 +12,5 @@ func init() {
web.Router("/data/mapping-rules/:mappingRuleId", &controllers.MappingRuleController{}, "Delete:RemoveMappingRule")
web.Router("/data/mapping-rules/", &controllers.MappingRuleController{}, "Get:ListMappingRule")
web.Router("/data/mapping-rules/search", &controllers.MappingRuleController{}, "Post:SearchMappingRule")
web.Router("/data/mapping-rules/prepare", &controllers.MappingRuleController{}, "Post:PrepareMappingRule")
web.Router("/data/mapping-rules/prepare", &controllers.MappingRuleController{}, "Get:PrepareMappingRule")
}
... ...
... ... @@ -20,6 +20,13 @@ func init() {
web.Router("/data/tables/batch-edit-sub-table", &controllers.TableController{}, "Post:BatchEditSubTable")
web.Router("/data/tables/copy-data-table", &controllers.TableController{}, "Post:CopyDataTable")
web.Router("/data/tables/update-table-struct", &controllers.TableController{}, "Post:UpdateTableStruct")
web.Router("/data/tables/add-table-struct", &controllers.TableController{}, "Post:AddTableStruct")
// web.Router("/data/tables/preview", &controllers.TableController{}, "Post:PreviewDataTable")
web.Router("/data/tables/add-sub-table", &controllers.TableController{}, "Post:AddTableStruct")
web.Router("/data/tables/export-table", &controllers.TableController{}, "Post:ExportDataTable")
web.Router("/data/tables/table-preview", &controllers.TableController{}, "Post:TablePreview")
web.Router("/data/field-optional-values", &controllers.TableController{}, "Post:FieldOptionalValues")
web.Router("/business/db-table-preview", &controllers.TableController{}, "Post:DBTablePreview")
web.Router("/data/table-preview", &controllers.TableController{}, "Post:Preview")
}
... ...