正在显示
22 个修改的文件
包含
312 行增加
和
16 行删除
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "github.com/linmadan/egglib-go/core/application" | ||
| 5 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 6 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/event/command" | ||
| 7 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | ||
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 9 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/cache" | ||
| 10 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" | ||
| 11 | +) | ||
| 12 | + | ||
| 13 | +func (tableEventService *TableEventService) DigitalPlatformEventSubscribe(ctx *domain.Context, cmd *command.TableEventCommand) (interface{}, error) { | ||
| 14 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 15 | + if err != nil { | ||
| 16 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 17 | + } | ||
| 18 | + //if err := transactionContext.StartTransaction(); err != nil { | ||
| 19 | + // return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 20 | + //} | ||
| 21 | + //defer func() { | ||
| 22 | + // transactionContext.RollbackTransaction() | ||
| 23 | + //}() | ||
| 24 | + | ||
| 25 | + var ( | ||
| 26 | + dataChanged = true | ||
| 27 | + structChanged = true | ||
| 28 | + ) | ||
| 29 | + | ||
| 30 | + data := cmd.EventTable | ||
| 31 | + tableId := 0 | ||
| 32 | + switch data.Type { | ||
| 33 | + case domain.TableDataImportEvent, domain.TableDataEditEvent, domain.TableDeleteEvent: | ||
| 34 | + // dataChanged = true | ||
| 35 | + tableId = data.Table.TableId | ||
| 36 | + case domain.QuerySetUpdateEvent: | ||
| 37 | + tableId = data.QuerySet.QuerySetInfo.BindTableId | ||
| 38 | + // structChanged = true | ||
| 39 | + } | ||
| 40 | + if tableId == 0 { | ||
| 41 | + return nil, nil | ||
| 42 | + } | ||
| 43 | + var notifyData = struct { | ||
| 44 | + DataChanged bool `json:"dataChanged"` | ||
| 45 | + StructChanged bool `json:"structChanged"` | ||
| 46 | + TableId int `json:"tableId"` | ||
| 47 | + Event string `json:"event"` | ||
| 48 | + TableAffectedList []int `json:"tableAffectedList"` | ||
| 49 | + }{ | ||
| 50 | + DataChanged: dataChanged, | ||
| 51 | + StructChanged: structChanged, | ||
| 52 | + TableId: tableId, | ||
| 53 | + Event: data.Type.ToString(), | ||
| 54 | + } | ||
| 55 | + // tableId 相关联的 | ||
| 56 | + tableRepository, _, _ := factory.FastPgTable(transactionContext, 0) | ||
| 57 | + _, tables, err := tableRepository.Find(map[string]interface{}{"context": data.Context, "tableTypesNotIn": []string{domain.TemporaryTable.ToString(), domain.ExcelTable.ToString()}}) | ||
| 58 | + if err != nil { | ||
| 59 | + return nil, err | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + tableDependencyService, _ := domainService.NewTableDependencyService(transactionContext.(*pgTransaction.TransactionContext)) | ||
| 63 | + tableDependTree := tableDependencyService.TableDependTree(tables, tableId) | ||
| 64 | + tree := tableDependTree.Tree | ||
| 65 | + | ||
| 66 | + //tableService := tableservice.NewTableService(nil) | ||
| 67 | + for i := range tree { | ||
| 68 | + cache.DefaultDataTableCacheService.DeleteDataTable(tree[i]) | ||
| 69 | + // fresh cache | ||
| 70 | + //tableService.TablePreview(data.Context, &tablecommand.TablePreviewCommand{ | ||
| 71 | + // TableId: tree[i], | ||
| 72 | + // ObjectType: domain.ObjectMetaTable, | ||
| 73 | + // PageSize: 10000, | ||
| 74 | + // PageNumber: 0, | ||
| 75 | + // UseCache: true, | ||
| 76 | + //}) | ||
| 77 | + notifyData.TableAffectedList = append(notifyData.TableAffectedList, tree[i]) | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + //if err := transactionContext.CommitTransaction(); err != nil { | ||
| 81 | + // return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 82 | + //} | ||
| 83 | + return nil, nil | ||
| 84 | +} |
| @@ -15,6 +15,7 @@ type EditDataTableCommand struct { | @@ -15,6 +15,7 @@ type EditDataTableCommand struct { | ||
| 15 | // | 15 | // |
| 16 | //Fields []*domain.Field | 16 | //Fields []*domain.Field |
| 17 | domain.EditTableRequest | 17 | domain.EditTableRequest |
| 18 | + HeaderRow int `json:"headerRow"` // 行号 默认:0 | ||
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | func (editDataTableCommand *EditDataTableCommand) Valid(validation *validation.Validation) { | 21 | func (editDataTableCommand *EditDataTableCommand) Valid(validation *validation.Validation) { |
| @@ -30,6 +31,7 @@ func (editDataTableCommand *EditDataTableCommand) Valid(validation *validation.V | @@ -30,6 +31,7 @@ func (editDataTableCommand *EditDataTableCommand) Valid(validation *validation.V | ||
| 30 | validation.Error("文件ID不能为空") | 31 | validation.Error("文件ID不能为空") |
| 31 | return | 32 | return |
| 32 | } | 33 | } |
| 34 | + editDataTableCommand.Where.HeaderRow = domain.SetHeaderRow(editDataTableCommand.HeaderRow) | ||
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | func (editDataTableCommand *EditDataTableCommand) ValidateCommand() error { | 37 | func (editDataTableCommand *EditDataTableCommand) ValidateCommand() error { |
| @@ -23,6 +23,7 @@ func (loadDataTableCommand *LoadDataTableCommand) Valid(validation *validation.V | @@ -23,6 +23,7 @@ func (loadDataTableCommand *LoadDataTableCommand) Valid(validation *validation.V | ||
| 23 | if loadDataTableCommand.PageSize == 0 { | 23 | if loadDataTableCommand.PageSize == 0 { |
| 24 | loadDataTableCommand.PageSize = 20 | 24 | loadDataTableCommand.PageSize = 20 |
| 25 | } | 25 | } |
| 26 | + loadDataTableCommand.HeaderRow = domain.SetHeaderRow(loadDataTableCommand.HeaderRow) | ||
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | func (loadDataTableCommand *LoadDataTableCommand) ValidateCommand() error { | 29 | func (loadDataTableCommand *LoadDataTableCommand) ValidateCommand() error { |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | + "reflect" | ||
| 7 | + "strings" | ||
| 8 | + | ||
| 9 | + "github.com/beego/beego/v2/core/validation" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type ResetTableHeaderCommand struct { | ||
| 13 | + // 文件ID | ||
| 14 | + FileId int `cname:"文件ID" json:"objectId" valid:"Required"` | ||
| 15 | + domain.Where | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +func (loadDataTableCommand *ResetTableHeaderCommand) Valid(validation *validation.Validation) { | ||
| 19 | + loadDataTableCommand.HeaderRow = domain.SetHeaderRow(loadDataTableCommand.HeaderRow) | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +func (loadDataTableCommand *ResetTableHeaderCommand) ValidateCommand() error { | ||
| 23 | + valid := validation.Validation{} | ||
| 24 | + b, err := valid.Valid(loadDataTableCommand) | ||
| 25 | + if err != nil { | ||
| 26 | + return err | ||
| 27 | + } | ||
| 28 | + if !b { | ||
| 29 | + elem := reflect.TypeOf(loadDataTableCommand).Elem() | ||
| 30 | + for _, validErr := range valid.Errors { | ||
| 31 | + field, isExist := elem.FieldByName(validErr.Field) | ||
| 32 | + if isExist { | ||
| 33 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
| 34 | + } else { | ||
| 35 | + return fmt.Errorf(validErr.Message) | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + return nil | ||
| 40 | +} |
| @@ -18,6 +18,8 @@ type FileDto struct { | @@ -18,6 +18,8 @@ type FileDto struct { | ||
| 18 | Ext string `json:"ext"` | 18 | Ext string `json:"ext"` |
| 19 | // 创建时间 | 19 | // 创建时间 |
| 20 | Time string `json:"time"` | 20 | Time string `json:"time"` |
| 21 | + // 行号 | ||
| 22 | + HeaderRow int `json:"headerRow"` | ||
| 21 | } | 23 | } |
| 22 | 24 | ||
| 23 | func (d *FileDto) Load(f *domain.File) *FileDto { | 25 | func (d *FileDto) Load(f *domain.File) *FileDto { |
| @@ -30,5 +32,6 @@ func (d *FileDto) Load(f *domain.File) *FileDto { | @@ -30,5 +32,6 @@ func (d *FileDto) Load(f *domain.File) *FileDto { | ||
| 30 | d.FileType = f.FileType | 32 | d.FileType = f.FileType |
| 31 | d.Ext = f.FileInfo.Ext | 33 | d.Ext = f.FileInfo.Ext |
| 32 | d.Time = xtime.New(f.UpdatedAt).Local().Format("2006-01-02 15:04:05") | 34 | d.Time = xtime.New(f.UpdatedAt).Local().Format("2006-01-02 15:04:05") |
| 35 | + d.HeaderRow = domain.GetHeaderRow(f.FileInfo.HeaderRow) | ||
| 33 | return d | 36 | return d |
| 34 | } | 37 | } |
| @@ -44,6 +44,38 @@ func (fileService *FileService) FilePreview(ctx *domain.Context, loadDataTableCo | @@ -44,6 +44,38 @@ func (fileService *FileService) FilePreview(ctx *domain.Context, loadDataTableCo | ||
| 44 | return data, nil | 44 | return data, nil |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | +func (fileService *FileService) ResetHeaderRow(ctx *domain.Context, loadDataTableCommand *command.ResetTableHeaderCommand) (interface{}, error) { | ||
| 48 | + if err := loadDataTableCommand.ValidateCommand(); err != nil { | ||
| 49 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 50 | + } | ||
| 51 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 52 | + if err != nil { | ||
| 53 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 54 | + } | ||
| 55 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 56 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 57 | + } | ||
| 58 | + defer func() { | ||
| 59 | + transactionContext.RollbackTransaction() | ||
| 60 | + }() | ||
| 61 | + cache := redis.NewFileCacheService() | ||
| 62 | + temporaryFile, err := cache.Get(redis.KeyTemporaryFileInfo(loadDataTableCommand.FileId)) | ||
| 63 | + if err != nil { | ||
| 64 | + return nil, factory.FastError(err) | ||
| 65 | + } | ||
| 66 | + loadDataTableService, _ := factory.CreateLoadDataTableService(transactionContext) | ||
| 67 | + data, err := loadDataTableService.RePreview(ctx, loadDataTableCommand.FileId, temporaryFile.Fields, loadDataTableCommand.Where) | ||
| 68 | + if err != nil { | ||
| 69 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 73 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + return data, nil | ||
| 77 | +} | ||
| 78 | + | ||
| 47 | // PrepareTemporaryFile 准备临时文件 | 79 | // PrepareTemporaryFile 准备临时文件 |
| 48 | func (fileService *FileService) PrepareTemporaryFile(ctx *domain.Context, cmd *command.PrepareTemporaryFileCommand) (interface{}, error) { | 80 | func (fileService *FileService) PrepareTemporaryFile(ctx *domain.Context, cmd *command.PrepareTemporaryFileCommand) (interface{}, error) { |
| 49 | if err := cmd.ValidateCommand(); err != nil { | 81 | if err := cmd.ValidateCommand(); err != nil { |
| @@ -152,6 +184,7 @@ func (fileService *FileService) FlushDataTable(ctx *domain.Context, flushDataTab | @@ -152,6 +184,7 @@ func (fileService *FileService) FlushDataTable(ctx *domain.Context, flushDataTab | ||
| 152 | if _, err := flushDataTableService.Flush(ctx, flushDataTableCommand.ObjectId, &domain.Table{ | 184 | if _, err := flushDataTableService.Flush(ctx, flushDataTableCommand.ObjectId, &domain.Table{ |
| 153 | DataFields: temporaryFile.Fields, | 185 | DataFields: temporaryFile.Fields, |
| 154 | RowCount: temporaryFile.Total, | 186 | RowCount: temporaryFile.Total, |
| 187 | + HeaderRow: temporaryFile.HeaderRow, | ||
| 155 | }); err != nil { | 188 | }); err != nil { |
| 156 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 189 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 157 | } | 190 | } |
| @@ -117,7 +117,9 @@ func (tableService *TableService) RowsDelete(ctx *domain.Context, cmd *command.R | @@ -117,7 +117,9 @@ func (tableService *TableService) RowsDelete(ctx *domain.Context, cmd *command.R | ||
| 117 | if err != nil { | 117 | if err != nil { |
| 118 | return nil, factory.FastError(err) | 118 | return nil, factory.FastError(err) |
| 119 | } | 119 | } |
| 120 | - | 120 | + defer func() { |
| 121 | + domainService.AsyncEvent(domain.NewEventTable(ctx, domain.TableDataEditEvent).WithTable(table)) | ||
| 122 | + }() | ||
| 121 | var options = starrocks.QueryOptions{ | 123 | var options = starrocks.QueryOptions{ |
| 122 | TableName: table.SQLName, | 124 | TableName: table.SQLName, |
| 123 | Select: []*domain.Field{domain.PK()}, //table.Fields(true), | 125 | Select: []*domain.Field{domain.PK()}, //table.Fields(true), |
| @@ -111,6 +111,7 @@ type ( | @@ -111,6 +111,7 @@ type ( | ||
| 111 | ProcessFields []*Field `json:"processFields"` | 111 | ProcessFields []*Field `json:"processFields"` |
| 112 | Action string `json:"action"` | 112 | Action string `json:"action"` |
| 113 | Params map[string]interface{} `json:"params"` | 113 | Params map[string]interface{} `json:"params"` |
| 114 | + HeaderRow int `json:"headerRow"` | ||
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | DataEditDataTable struct { | 117 | DataEditDataTable struct { |
| @@ -11,6 +11,7 @@ type DataTable struct { | @@ -11,6 +11,7 @@ type DataTable struct { | ||
| 11 | type Where struct { | 11 | type Where struct { |
| 12 | PageNumber int `json:"pageNumber"` | 12 | PageNumber int `json:"pageNumber"` |
| 13 | PageSize int `json:"pageSize"` | 13 | PageSize int `json:"pageSize"` |
| 14 | + HeaderRow int `json:"headerRow"` // 行号 默认:0 | ||
| 14 | Conditions []Condition `json:"conditions"` | 15 | Conditions []Condition `json:"conditions"` |
| 15 | } | 16 | } |
| 16 | 17 |
| @@ -19,6 +19,7 @@ type TableService interface { | @@ -19,6 +19,7 @@ type TableService interface { | ||
| 19 | 19 | ||
| 20 | type PreviewDataTableService interface { | 20 | type PreviewDataTableService interface { |
| 21 | Preview(ctx *Context, fileId int, fields []*Field, where Where) (interface{}, error) | 21 | Preview(ctx *Context, fileId int, fields []*Field, where Where) (interface{}, error) |
| 22 | + RePreview(ctx *Context, fileId int, fields []*Field, where Where) (interface{}, error) | ||
| 22 | CreateTemporaryFile(ctx *Context, fileId int) (*File, error) | 23 | CreateTemporaryFile(ctx *Context, fileId int) (*File, error) |
| 23 | GetFileId() int | 24 | GetFileId() int |
| 24 | } | 25 | } |
| @@ -85,3 +85,25 @@ func (file *File) CopyTo(fileType FileType, ctx *Context) *File { | @@ -85,3 +85,25 @@ func (file *File) CopyTo(fileType FileType, ctx *Context) *File { | ||
| 85 | } | 85 | } |
| 86 | return t | 86 | return t |
| 87 | } | 87 | } |
| 88 | + | ||
| 89 | +func (file *File) SetHeaderRow(headerRow int) { | ||
| 90 | + //file.FileInfo.HeaderRow = headerRow | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +func (file *File) GetHeaderRow() int { | ||
| 94 | + return file.FileInfo.HeaderRow | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +func SetHeaderRow(headerRow int) int { | ||
| 98 | + if headerRow-1 < 0 { | ||
| 99 | + return 0 | ||
| 100 | + } | ||
| 101 | + return headerRow - 1 | ||
| 102 | +} | ||
| 103 | + | ||
| 104 | +func GetHeaderRow(headerRow int) int { | ||
| 105 | + if headerRow == 0 { | ||
| 106 | + return 1 | ||
| 107 | + } | ||
| 108 | + return headerRow + 1 | ||
| 109 | +} |
| @@ -45,6 +45,9 @@ type Table struct { | @@ -45,6 +45,9 @@ type Table struct { | ||
| 45 | Context *Context `json:"context"` | 45 | Context *Context `json:"context"` |
| 46 | // 表信息 | 46 | // 表信息 |
| 47 | TableInfo *TableInfo `json:"tableInfo"` | 47 | TableInfo *TableInfo `json:"tableInfo"` |
| 48 | + | ||
| 49 | + // 表头行号 从0开始 | ||
| 50 | + HeaderRow int `json:"-"` | ||
| 48 | } | 51 | } |
| 49 | 52 | ||
| 50 | type TableRepository interface { | 53 | type TableRepository interface { |
| @@ -16,6 +16,7 @@ type RequestCheckoutTablesQuery struct { | @@ -16,6 +16,7 @@ type RequestCheckoutTablesQuery struct { | ||
| 16 | QueryParameters []domain.QueryParameter `json:"queryParameters"` | 16 | QueryParameters []domain.QueryParameter `json:"queryParameters"` |
| 17 | //QueryParameters map[string]interface{} `json:"queryParameters"` | 17 | //QueryParameters map[string]interface{} `json:"queryParameters"` |
| 18 | SortParameters map[string]interface{} `json:"sortParameters"` | 18 | SortParameters map[string]interface{} `json:"sortParameters"` |
| 19 | + HeaderRow int `json:"headerRow"` | ||
| 19 | } | 20 | } |
| 20 | 21 | ||
| 21 | type DataCheckoutTables struct { | 22 | type DataCheckoutTables struct { |
| @@ -37,6 +38,9 @@ func NewRequestCheckoutTablesQuery(param domain.ReqLoadDataTable) RequestCheckou | @@ -37,6 +38,9 @@ func NewRequestCheckoutTablesQuery(param domain.ReqLoadDataTable) RequestCheckou | ||
| 37 | if param.IsFromOriginalTable { | 38 | if param.IsFromOriginalTable { |
| 38 | tableFileUrl = param.TableFileUrl | 39 | tableFileUrl = param.TableFileUrl |
| 39 | } | 40 | } |
| 41 | + if param.HeaderRow > 0 { | ||
| 42 | + isSourceFile = true | ||
| 43 | + } | ||
| 40 | return RequestCheckoutTablesQuery{ | 44 | return RequestCheckoutTablesQuery{ |
| 41 | OriginalTableId: param.OriginalTableId, | 45 | OriginalTableId: param.OriginalTableId, |
| 42 | IsFromOriginalTable: isSourceFile, | 46 | IsFromOriginalTable: isSourceFile, |
| @@ -48,6 +52,7 @@ func NewRequestCheckoutTablesQuery(param domain.ReqLoadDataTable) RequestCheckou | @@ -48,6 +52,7 @@ func NewRequestCheckoutTablesQuery(param domain.ReqLoadDataTable) RequestCheckou | ||
| 48 | QueryParameters: make([]domain.QueryParameter, 0), | 52 | QueryParameters: make([]domain.QueryParameter, 0), |
| 49 | //QueryParameters: make(map[string]interface{}), | 53 | //QueryParameters: make(map[string]interface{}), |
| 50 | SortParameters: param.SortParameters, | 54 | SortParameters: param.SortParameters, |
| 55 | + HeaderRow: param.HeaderRow, | ||
| 51 | } | 56 | } |
| 52 | } | 57 | } |
| 53 | 58 | ||
| @@ -61,6 +66,7 @@ type RequestCheckoutTablesPreProccess struct { | @@ -61,6 +66,7 @@ type RequestCheckoutTablesPreProccess struct { | ||
| 61 | PageSize int `json:"pageSize"` | 66 | PageSize int `json:"pageSize"` |
| 62 | QueryParameters interface{} `json:"queryParameters"` | 67 | QueryParameters interface{} `json:"queryParameters"` |
| 63 | SortParameters map[string]interface{} `json:"sortParameters"` | 68 | SortParameters map[string]interface{} `json:"sortParameters"` |
| 69 | + HeaderRow int `json:"headerRow"` | ||
| 64 | } | 70 | } |
| 65 | 71 | ||
| 66 | func NewRequestCheckoutTablesPreProccess(param domain.ReqEditDataTable) RequestCheckoutTablesPreProccess { | 72 | func NewRequestCheckoutTablesPreProccess(param domain.ReqEditDataTable) RequestCheckoutTablesPreProccess { |
| @@ -73,6 +79,7 @@ func NewRequestCheckoutTablesPreProccess(param domain.ReqEditDataTable) RequestC | @@ -73,6 +79,7 @@ func NewRequestCheckoutTablesPreProccess(param domain.ReqEditDataTable) RequestC | ||
| 73 | PageSize: 20, //param.PageSize, | 79 | PageSize: 20, //param.PageSize, |
| 74 | QueryParameters: []interface{}{}, | 80 | QueryParameters: []interface{}{}, |
| 75 | SortParameters: make(map[string]interface{}), | 81 | SortParameters: make(map[string]interface{}), |
| 82 | + HeaderRow: param.HeaderRow, | ||
| 76 | } | 83 | } |
| 77 | 84 | ||
| 78 | if len(param.Params) == 0 { | 85 | if len(param.Params) == 0 { |
| @@ -31,6 +31,7 @@ func (ptr *EditDataTableService) Edit(ctx *domain.Context, req domain.EditTableR | @@ -31,6 +31,7 @@ func (ptr *EditDataTableService) Edit(ctx *domain.Context, req domain.EditTableR | ||
| 31 | ProcessFields: domain.ToFields(req.ProcessFields), | 31 | ProcessFields: domain.ToFields(req.ProcessFields), |
| 32 | Action: req.Action, | 32 | Action: req.Action, |
| 33 | Params: req.Params, | 33 | Params: req.Params, |
| 34 | + HeaderRow: req.Where.HeaderRow, | ||
| 34 | }) | 35 | }) |
| 35 | if err != nil { | 36 | if err != nil { |
| 36 | return nil, err | 37 | return nil, err |
| @@ -29,6 +29,7 @@ func (ptr *FlushDataTableService) Flush(ctx *domain.Context, fileId int, table * | @@ -29,6 +29,7 @@ func (ptr *FlushDataTableService) Flush(ctx *domain.Context, fileId int, table * | ||
| 29 | if err != nil { | 29 | if err != nil { |
| 30 | return nil, fmt.Errorf("源文件不存在") | 30 | return nil, fmt.Errorf("源文件不存在") |
| 31 | } | 31 | } |
| 32 | + sourceFile.SetHeaderRow(table.HeaderRow) | ||
| 32 | // New Table | 33 | // New Table |
| 33 | table = NewTable(domain.ExcelTable, file.FileInfo.Name, table.DataFields, table.RowCount).WithContext(ctx) | 34 | table = NewTable(domain.ExcelTable, file.FileInfo.Name, table.DataFields, table.RowCount).WithContext(ctx) |
| 34 | // 通知底层保存、进行回调 | 35 | // 通知底层保存、进行回调 |
| @@ -72,9 +73,13 @@ func (ptr *FlushDataTableService) flushSourceFile(ctx *domain.Context, table *do | @@ -72,9 +73,13 @@ func (ptr *FlushDataTableService) flushSourceFile(ctx *domain.Context, table *do | ||
| 72 | if err != nil { | 73 | if err != nil { |
| 73 | return err | 74 | return err |
| 74 | } | 75 | } |
| 76 | + if _, err = fileRepository.Save(sourceFile); err != nil { | ||
| 77 | + return err | ||
| 78 | + } | ||
| 75 | file.FileInfo.TableId = table.TableId | 79 | file.FileInfo.TableId = table.TableId |
| 76 | file.FileType = domain.VerifiedFile.ToString() | 80 | file.FileType = domain.VerifiedFile.ToString() |
| 77 | file.UpdateFileUrl(url) | 81 | file.UpdateFileUrl(url) |
| 82 | + file.SetHeaderRow(sourceFile.FileInfo.HeaderRow) | ||
| 78 | if file, err = fileRepository.Save(file); err != nil { | 83 | if file, err = fileRepository.Save(file); err != nil { |
| 79 | return err | 84 | return err |
| 80 | } | 85 | } |
| @@ -14,6 +14,50 @@ type PreviewDataTableService struct { | @@ -14,6 +14,50 @@ type PreviewDataTableService struct { | ||
| 14 | transactionContext *pgTransaction.TransactionContext | 14 | transactionContext *pgTransaction.TransactionContext |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | +// RePreview 重新预览 | ||
| 18 | +func (ptr *PreviewDataTableService) RePreview(ctx *domain.Context, fileId int, fields []*domain.Field, where domain.Where) (interface{}, error) { | ||
| 19 | + fileRepository, _ := repository.NewFileRepository(ptr.transactionContext) | ||
| 20 | + file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId}) | ||
| 21 | + if err != nil { | ||
| 22 | + return nil, fmt.Errorf("校验文件不存在") | ||
| 23 | + } | ||
| 24 | + isSourceFile := true | ||
| 25 | + fileUrl := file.FileInfo.Url | ||
| 26 | + fileCache := redis.NewFileCacheService() | ||
| 27 | + tempFile, _ := fileCache.Get(redis.KeyTemporaryFileInfo(fileId)) | ||
| 28 | + if tempFile == nil { | ||
| 29 | + return nil, fmt.Errorf("临时文件不存在") | ||
| 30 | + } | ||
| 31 | + // Load Data From Excel(python api) | ||
| 32 | + byteCore, _ := CreateByteCoreService() | ||
| 33 | + response, err := byteCore.LoadDataTable(domain.ReqLoadDataTable{ | ||
| 34 | + FileId: file.FileId, | ||
| 35 | + FileName: file.FileInfo.Name, | ||
| 36 | + Url: file.FileInfo.Url, | ||
| 37 | + Ext: file.FileInfo.Ext, | ||
| 38 | + Where: where, | ||
| 39 | + OriginalTableId: fmt.Sprintf("%v", file.FileId), | ||
| 40 | + IsFromOriginalTable: isSourceFile, | ||
| 41 | + TableFileUrl: fileUrl, | ||
| 42 | + ColumnSchemas: bytelib.DomainFieldsToColumnSchemas(fields), | ||
| 43 | + SortParameters: make(map[string]interface{}), | ||
| 44 | + }) | ||
| 45 | + if err != nil { | ||
| 46 | + return nil, err | ||
| 47 | + } | ||
| 48 | + // 强制刷新列 | ||
| 49 | + fields = response.Fields | ||
| 50 | + | ||
| 51 | + cache := redis.NewFileCacheService() | ||
| 52 | + tempFile, err = cache.Update(redis.KeyTemporaryFileInfo(file.FileId), file, fields, response.Total, redis.WithHeaderRow(where.HeaderRow)) | ||
| 53 | + if err != nil { | ||
| 54 | + return nil, err | ||
| 55 | + } | ||
| 56 | + var responseDto = &FilePreviewDto{} | ||
| 57 | + //responseDto.Load(file.FileId, response, tempFile) | ||
| 58 | + return responseDto, nil | ||
| 59 | +} | ||
| 60 | + | ||
| 17 | // Preview 预览 【data-table】 | 61 | // Preview 预览 【data-table】 |
| 18 | func (ptr *PreviewDataTableService) Preview(ctx *domain.Context, fileId int, fields []*domain.Field, where domain.Where) (interface{}, error) { | 62 | func (ptr *PreviewDataTableService) Preview(ctx *domain.Context, fileId int, fields []*domain.Field, where domain.Where) (interface{}, error) { |
| 19 | fileRepository, _ := repository.NewFileRepository(ptr.transactionContext) | 63 | fileRepository, _ := repository.NewFileRepository(ptr.transactionContext) |
| @@ -98,6 +142,7 @@ type FilePreviewDto struct { | @@ -98,6 +142,7 @@ type FilePreviewDto struct { | ||
| 98 | Data interface{} `json:"grid"` | 142 | Data interface{} `json:"grid"` |
| 99 | PageNumber int `json:"pageNumber"` | 143 | PageNumber int `json:"pageNumber"` |
| 100 | InValidCells []domain.InValidCell `json:"inValidCells"` | 144 | InValidCells []domain.InValidCell `json:"inValidCells"` |
| 145 | + HeaderRow int `json:"headerRow"` | ||
| 101 | } | 146 | } |
| 102 | 147 | ||
| 103 | func (d *FilePreviewDto) Load(fileId int, m *domain.DataLoadDataTable, file *redis.TemporaryFileInfo) { | 148 | func (d *FilePreviewDto) Load(fileId int, m *domain.DataLoadDataTable, file *redis.TemporaryFileInfo) { |
| @@ -137,6 +182,7 @@ func (d *FilePreviewDto) Load(fileId int, m *domain.DataLoadDataTable, file *red | @@ -137,6 +182,7 @@ func (d *FilePreviewDto) Load(fileId int, m *domain.DataLoadDataTable, file *red | ||
| 137 | } | 182 | } |
| 138 | 183 | ||
| 139 | d.InValidCells = domain.NewInValidCells(fields, mapData) | 184 | d.InValidCells = domain.NewInValidCells(fields, mapData) |
| 185 | + d.HeaderRow = domain.GetHeaderRow(file.HeaderRow) | ||
| 140 | } | 186 | } |
| 141 | 187 | ||
| 142 | func (ptr *PreviewDataTableService) GetFileId() int { | 188 | func (ptr *PreviewDataTableService) GetFileId() int { |
| @@ -20,6 +20,7 @@ type TemporaryFileInfo struct { | @@ -20,6 +20,7 @@ type TemporaryFileInfo struct { | ||
| 20 | FileId int `json:"fileId"` | 20 | FileId int `json:"fileId"` |
| 21 | FileType string `json:"fileType"` | 21 | FileType string `json:"fileType"` |
| 22 | Total int `json:"total"` | 22 | Total int `json:"total"` |
| 23 | + HeaderRow int `json:"headerRow"` | ||
| 23 | Fields []*domain.Field `json:"fields"` | 24 | Fields []*domain.Field `json:"fields"` |
| 24 | // 编辑表错误,有错误不允许保存成校验文件 | 25 | // 编辑表错误,有错误不允许保存成校验文件 |
| 25 | // 行记录错误 | 26 | // 行记录错误 |
| @@ -66,6 +67,11 @@ func (f *TemporaryFileInfo) SetTotal(total int) *TemporaryFileInfo { | @@ -66,6 +67,11 @@ func (f *TemporaryFileInfo) SetTotal(total int) *TemporaryFileInfo { | ||
| 66 | return f | 67 | return f |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 70 | +func (f *TemporaryFileInfo) SetHeaderRow(headerRow int) *TemporaryFileInfo { | ||
| 71 | + f.HeaderRow = headerRow | ||
| 72 | + return f | ||
| 73 | +} | ||
| 74 | + | ||
| 69 | func (f *TemporaryFileInfo) AddConvertTypeError(e ConvertTypeError) *TemporaryFileInfo { | 75 | func (f *TemporaryFileInfo) AddConvertTypeError(e ConvertTypeError) *TemporaryFileInfo { |
| 70 | f.RemoveConvertTypeError(e) | 76 | f.RemoveConvertTypeError(e) |
| 71 | f.addConvertTypeError(e) | 77 | f.addConvertTypeError(e) |
| @@ -99,46 +105,52 @@ type ConvertTypeError struct { | @@ -99,46 +105,52 @@ type ConvertTypeError struct { | ||
| 99 | type FileCacheService struct { | 105 | type FileCacheService struct { |
| 100 | } | 106 | } |
| 101 | 107 | ||
| 102 | -func (s *FileCacheService) Update(key string, file *domain.File, fields []*domain.Field, total int, errors ...FileCacheOptionsFunc) (*TemporaryFileInfo, error) { | 108 | +func (s *FileCacheService) Update(key string, file *domain.File, fields []*domain.Field, total int, option ...FileCacheOptionsFunc) (*TemporaryFileInfo, error) { |
| 109 | + options := NewFileCacheOptions(option...) | ||
| 103 | ok, err := ZeroCoreRedis.Exists(key) | 110 | ok, err := ZeroCoreRedis.Exists(key) |
| 104 | - var response = &TemporaryFileInfo{} | 111 | + var tmpFile = &TemporaryFileInfo{} |
| 105 | if err != nil { | 112 | if err != nil { |
| 106 | - return response, err | 113 | + return tmpFile, err |
| 107 | } | 114 | } |
| 108 | if !ok { | 115 | if !ok { |
| 109 | - response.SetFile(file).SetFields(fields).SetTotal(total) | ||
| 110 | - return response, ZeroCoreRedis.Setex(key, json.MarshalToString(response), TemporaryFileExpire) | 116 | + tmpFile.SetFile(file).SetFields(fields).SetTotal(total) |
| 117 | + if options.HasSetHeaderRow { | ||
| 118 | + tmpFile.SetHeaderRow(options.HeaderRow) | ||
| 119 | + } | ||
| 120 | + return tmpFile, ZeroCoreRedis.Setex(key, json.MarshalToString(tmpFile), TemporaryFileExpire) | ||
| 111 | } | 121 | } |
| 112 | data, err := ZeroCoreRedis.Get(key) | 122 | data, err := ZeroCoreRedis.Get(key) |
| 113 | if err != nil { | 123 | if err != nil { |
| 114 | return nil, err | 124 | return nil, err |
| 115 | } | 125 | } |
| 116 | - err = json.UnmarshalFromString(data, response) | 126 | + err = json.UnmarshalFromString(data, tmpFile) |
| 117 | if err != nil { | 127 | if err != nil { |
| 118 | return nil, err | 128 | return nil, err |
| 119 | } | 129 | } |
| 120 | - response.SetFields(fields) | 130 | + tmpFile.SetFields(fields) |
| 131 | + if options.HasSetHeaderRow { | ||
| 132 | + tmpFile.SetHeaderRow(options.HeaderRow) | ||
| 133 | + } | ||
| 121 | 134 | ||
| 122 | - options := NewFileCacheOptions(errors...) | ||
| 123 | for i := range options.AddConvertTypeErrors { | 135 | for i := range options.AddConvertTypeErrors { |
| 124 | - response.AddConvertTypeError(options.AddConvertTypeErrors[i]) | 136 | + tmpFile.AddConvertTypeError(options.AddConvertTypeErrors[i]) |
| 125 | } | 137 | } |
| 126 | for i := range options.RemoveConvertTypeErrors { | 138 | for i := range options.RemoveConvertTypeErrors { |
| 127 | convertType := options.RemoveConvertTypeErrors[i] | 139 | convertType := options.RemoveConvertTypeErrors[i] |
| 128 | - response.RemoveConvertTypeError(options.RemoveConvertTypeErrors[i]) | ||
| 129 | - for j := range response.Fields { | ||
| 130 | - if response.Fields[j].Name == convertType.FieldName { | ||
| 131 | - response.Fields[j].SQLType = convertType.ToType | 140 | + tmpFile.RemoveConvertTypeError(options.RemoveConvertTypeErrors[i]) |
| 141 | + for j := range tmpFile.Fields { | ||
| 142 | + if tmpFile.Fields[j].Name == convertType.FieldName { | ||
| 143 | + tmpFile.Fields[j].SQLType = convertType.ToType | ||
| 132 | break | 144 | break |
| 133 | } | 145 | } |
| 134 | } | 146 | } |
| 135 | } | 147 | } |
| 136 | 148 | ||
| 137 | - err = ZeroCoreRedis.Setex(key, json.MarshalToString(response), TemporaryFileExpire) | 149 | + err = ZeroCoreRedis.Setex(key, json.MarshalToString(tmpFile), TemporaryFileExpire) |
| 138 | if err != nil { | 150 | if err != nil { |
| 139 | return nil, err | 151 | return nil, err |
| 140 | } | 152 | } |
| 141 | - return response, err | 153 | + return tmpFile, err |
| 142 | } | 154 | } |
| 143 | 155 | ||
| 144 | func (s *FileCacheService) UpdateField(key string, file *domain.File, errors ...FileCacheOptionsFunc) (*TemporaryFileInfo, error) { | 156 | func (s *FileCacheService) UpdateField(key string, file *domain.File, errors ...FileCacheOptionsFunc) (*TemporaryFileInfo, error) { |
| @@ -209,6 +221,8 @@ type FileCacheOptions struct { | @@ -209,6 +221,8 @@ type FileCacheOptions struct { | ||
| 209 | //OriginalFileId int | 221 | //OriginalFileId int |
| 210 | RemoveConvertTypeErrors []ConvertTypeError | 222 | RemoveConvertTypeErrors []ConvertTypeError |
| 211 | AddConvertTypeErrors []ConvertTypeError | 223 | AddConvertTypeErrors []ConvertTypeError |
| 224 | + HeaderRow int | ||
| 225 | + HasSetHeaderRow bool | ||
| 212 | } | 226 | } |
| 213 | 227 | ||
| 214 | type FileCacheOptionsFunc func(o *FileCacheOptions) | 228 | type FileCacheOptionsFunc func(o *FileCacheOptions) |
| @@ -225,6 +239,13 @@ func WithAddConvertTypeErrors(errors []ConvertTypeError) FileCacheOptionsFunc { | @@ -225,6 +239,13 @@ func WithAddConvertTypeErrors(errors []ConvertTypeError) FileCacheOptionsFunc { | ||
| 225 | } | 239 | } |
| 226 | } | 240 | } |
| 227 | 241 | ||
| 242 | +func WithHeaderRow(headerRow int) FileCacheOptionsFunc { | ||
| 243 | + return func(o *FileCacheOptions) { | ||
| 244 | + o.HeaderRow = headerRow | ||
| 245 | + o.HasSetHeaderRow = true | ||
| 246 | + } | ||
| 247 | +} | ||
| 248 | + | ||
| 228 | //func WithOriginalFileId(originalFileId int) FileCacheOptionsFunc { | 249 | //func WithOriginalFileId(originalFileId int) FileCacheOptionsFunc { |
| 229 | // return func(o *FileCacheOptions) { | 250 | // return func(o *FileCacheOptions) { |
| 230 | // o.OriginalFileId = originalFileId | 251 | // o.OriginalFileId = originalFileId |
| @@ -368,6 +368,12 @@ func WrapDeleteFuncWithDB(db *gorm.DB) func(QueryOptions) (int64, error) { | @@ -368,6 +368,12 @@ func WrapDeleteFuncWithDB(db *gorm.DB) func(QueryOptions) (int64, error) { | ||
| 368 | continue | 368 | continue |
| 369 | } | 369 | } |
| 370 | idList = append(idList, row[0]) | 370 | idList = append(idList, row[0]) |
| 371 | + if len(idList) > 5000 { | ||
| 372 | + c := Condition{} | ||
| 373 | + sql := fmt.Sprintf("delete from %v where id in %v", params.TableName, c.InArgs(idList)) | ||
| 374 | + query = db.Exec(sql) | ||
| 375 | + idList = make([]string, 0) | ||
| 376 | + } | ||
| 371 | } | 377 | } |
| 372 | if len(idList) == 0 { | 378 | if len(idList) == 0 { |
| 373 | return 0, nil | 379 | return 0, nil |
| @@ -248,6 +248,7 @@ func (controller *TableController) Preview() { | @@ -248,6 +248,7 @@ func (controller *TableController) Preview() { | ||
| 248 | fileService := fileservice.NewFileService(nil) | 248 | fileService := fileservice.NewFileService(nil) |
| 249 | cmd := &struct { | 249 | cmd := &struct { |
| 250 | ObjectType string `json:"objectType"` | 250 | ObjectType string `json:"objectType"` |
| 251 | + Action string `json:"action"` | ||
| 251 | }{} | 252 | }{} |
| 252 | Must(controller.Unmarshal(cmd)) | 253 | Must(controller.Unmarshal(cmd)) |
| 253 | var data interface{} | 254 | var data interface{} |
| @@ -271,6 +272,14 @@ func (controller *TableController) Preview() { | @@ -271,6 +272,14 @@ func (controller *TableController) Preview() { | ||
| 271 | controller.Response(data, err) | 272 | controller.Response(data, err) |
| 272 | } | 273 | } |
| 273 | 274 | ||
| 275 | +func (controller *TableController) TableResetHeaderRow() { | ||
| 276 | + fileService := fileservice.NewFileService(nil) | ||
| 277 | + cmd := &filecommand.ResetTableHeaderCommand{} | ||
| 278 | + Must(controller.Unmarshal(cmd)) | ||
| 279 | + data, err := fileService.ResetHeaderRow(ParseContext(controller.BaseController), cmd) | ||
| 280 | + controller.Response(data, err) | ||
| 281 | +} | ||
| 282 | + | ||
| 274 | func (controller *TableController) RowEdit() { | 283 | func (controller *TableController) RowEdit() { |
| 275 | tableService := service.NewTableService(nil) | 284 | tableService := service.NewTableService(nil) |
| 276 | cmd := &command.RowEditCommandV2{} | 285 | cmd := &command.RowEditCommandV2{} |
| @@ -42,5 +42,7 @@ func init() { | @@ -42,5 +42,7 @@ func init() { | ||
| 42 | web.Router("/business/db-table-preview", tableController, "Post:DBTablePreview") | 42 | web.Router("/business/db-table-preview", tableController, "Post:DBTablePreview") |
| 43 | web.Router("/data/table-preview", tableController, "Post:Preview") | 43 | web.Router("/data/table-preview", tableController, "Post:Preview") |
| 44 | 44 | ||
| 45 | + web.Router("/data/reset-header-row", tableController, "Post:TableResetHeaderRow") | ||
| 46 | + | ||
| 45 | web.Router("/data/tables/exec/:name", tableController, "Get:ExecScript") | 47 | web.Router("/data/tables/exec/:name", tableController, "Get:ExecScript") |
| 46 | } | 48 | } |
| @@ -19,5 +19,9 @@ func tableDataChangeHandler(e event.Event) error { | @@ -19,5 +19,9 @@ func tableDataChangeHandler(e event.Event) error { | ||
| 19 | _, err := svr.Handler(nil, &command.TableEventCommand{ | 19 | _, err := svr.Handler(nil, &command.TableEventCommand{ |
| 20 | EventTable: et, | 20 | EventTable: et, |
| 21 | }) | 21 | }) |
| 22 | + | ||
| 23 | + _, err = svr.DigitalPlatformEventSubscribe(nil, &command.TableEventCommand{ | ||
| 24 | + EventTable: et, | ||
| 25 | + }) | ||
| 22 | return err | 26 | return err |
| 23 | } | 27 | } |
-
请 注册 或 登录 后发表评论