作者 yangfu

feat: file header row

  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 +}
@@ -14,4 +14,6 @@ type FileInfo struct { @@ -14,4 +14,6 @@ type FileInfo struct {
14 RowCount int `json:"rowCount"` 14 RowCount int `json:"rowCount"`
15 // 表结构ID 15 // 表结构ID
16 TableId int `json:"tableId"` 16 TableId int `json:"tableId"`
  17 + // 行号
  18 + HeaderRow int `json:"headerRow"`
17 } 19 }
@@ -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 }