|
|
package service
|
|
|
|
|
|
import (
|
|
|
"bytes"
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"github.com/beego/beego/v2/client/httplib"
|
|
|
"github.com/linmadan/egglib-go/core/application"
|
|
|
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/command"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/query"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/api/apilib"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/excel"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
|
|
|
"os"
|
|
|
"strings"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
func (fileService *FileService) CreateAppTableFile(ctx *domain.Context, cmd *command.CreateAppTableFileCommand) (*command.CreateFileCommand, error) {
|
|
|
response := &command.CreateFileCommand{}
|
|
|
var (
|
|
|
titles = make([]string, 0)
|
|
|
dataList = make([][]string, 0)
|
|
|
)
|
|
|
for _, filed := range cmd.Fields {
|
|
|
titles = append(titles, filed.Name)
|
|
|
}
|
|
|
for i := range cmd.Data {
|
|
|
row := make([]string, 0)
|
|
|
for _, filed := range titles {
|
|
|
if v, ok := cmd.Data[i][filed]; ok {
|
|
|
row = append(row, v)
|
|
|
} else {
|
|
|
row = append(row, "")
|
|
|
}
|
|
|
}
|
|
|
dataList = append(dataList, row)
|
|
|
}
|
|
|
fileUpload, err := saveFile(cmd.Name, titles, dataList, nil)
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
response.Name = cmd.Name
|
|
|
if !strings.HasSuffix(response.Name, domain.XLSX) {
|
|
|
response.Name = response.Name + domain.XLSX
|
|
|
}
|
|
|
response.Url = fileUpload.Url
|
|
|
response.FileSize = int(fileUpload.FileSize)
|
|
|
response.FileFrom = domain.FileFromDigitalAppClient
|
|
|
return response, nil
|
|
|
}
|
|
|
|
|
|
func saveFile(name string, title []string, dataList [][]string, toInterfaces func([]string) []interface{}) (FileUpload, error) {
|
|
|
var (
|
|
|
response = FileUpload{}
|
|
|
err error
|
|
|
)
|
|
|
var writerTo = excel.NewXLXSWriterTo(title, dataList)
|
|
|
if toInterfaces != nil {
|
|
|
writerTo.ToInterfaces = toInterfaces
|
|
|
}
|
|
|
filename := fmt.Sprintf("%v_%v.xlsx", name, time.Now().Format("060102150405"))
|
|
|
path := fmt.Sprintf("public/%v", filename)
|
|
|
if err = writerTo.Save(path); err != nil {
|
|
|
return response, factory.FastError(err)
|
|
|
}
|
|
|
api := apilib.NewApiAuthLib(constant.OPEN_API_HOST)
|
|
|
uploadResponse, err := api.Upload(apilib.RequestUpload{
|
|
|
UploadFileMap: map[string]string{"file": path},
|
|
|
})
|
|
|
if err != nil {
|
|
|
return response, err
|
|
|
}
|
|
|
if stat, err := os.Stat(path); err == nil {
|
|
|
response.FileSize = stat.Size()
|
|
|
}
|
|
|
response.Url = domain.ConvertInternalFileUrlToPublic(uploadResponse.Path)
|
|
|
response.FileName = name
|
|
|
response.Ext = domain.XLSX
|
|
|
|
|
|
return response, nil
|
|
|
}
|
|
|
|
|
|
func saveCsvFile(name string, title []string, dataList [][]string, toInterfaces func([]string) []interface{}) (FileUpload, error) {
|
|
|
var (
|
|
|
response = FileUpload{}
|
|
|
err error
|
|
|
)
|
|
|
var writerTo = excel.NewCSVWriterTo(title, dataList)
|
|
|
filename := fmt.Sprintf("%v_%v.csv", name, time.Now().Format("060102150405"))
|
|
|
path := fmt.Sprintf("public/%v", filename)
|
|
|
if err = writerTo.Save(path); err != nil {
|
|
|
return response, factory.FastError(err)
|
|
|
}
|
|
|
api := apilib.NewApiAuthLib(constant.OPEN_API_HOST)
|
|
|
uploadResponse, err := api.Upload(apilib.RequestUpload{
|
|
|
UploadFileMap: map[string]string{"file": path},
|
|
|
})
|
|
|
if err != nil {
|
|
|
return response, err
|
|
|
}
|
|
|
if stat, err := os.Stat(path); err == nil {
|
|
|
response.FileSize = stat.Size()
|
|
|
}
|
|
|
response.Url = domain.ConvertInternalFileUrlToPublic(uploadResponse.Path)
|
|
|
response.FileName = name
|
|
|
response.Ext = domain.CSV
|
|
|
|
|
|
return response, nil
|
|
|
}
|
|
|
|
|
|
type FileUpload struct {
|
|
|
Url string `json:"url"`
|
|
|
Ext string `json:"ext"`
|
|
|
FileName string `json:"fileName"`
|
|
|
FileSize int64 `json:"fileSize"`
|
|
|
}
|
|
|
|
|
|
func (fileService *FileService) DeleteAppTableFile(ctx *domain.Context, cmd *command.DeleteAppTableFileCommand) (interface{}, 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()
|
|
|
}()
|
|
|
|
|
|
fileRepository, file, _ := factory.FastPgFile(transactionContext, 0)
|
|
|
file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile})
|
|
|
if err == domain.ErrorNotFound {
|
|
|
return nil, factory.FastError(errors.New("文件不存在"))
|
|
|
}
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
if _, err := fileRepository.Remove(file); 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 (fileService *FileService) AppTableFileAppendData(ctx *domain.Context, cmd *command.AppTableFileAppendDataCommand) (interface{}, 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()
|
|
|
}()
|
|
|
|
|
|
fileRepository, file, _ := factory.FastPgFile(transactionContext, 0)
|
|
|
file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile})
|
|
|
if err == domain.ErrorNotFound {
|
|
|
return nil, factory.FastError(errors.New("文件不存在"))
|
|
|
}
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
|
|
|
// 下载文件
|
|
|
f, err := httplib.Get(domain.ConvertFileUrlToInternal(file.FileInfo.Url)).Bytes()
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
reader := bytes.NewReader(f)
|
|
|
var (
|
|
|
importer *excel.Importer = excel.NewExcelImportByFile(file.FileInfo.Ext)
|
|
|
appendTableDataList = make([][]string, 0)
|
|
|
)
|
|
|
data, err := importer.OpenExcelFromIoReader(reader)
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
titles := importer.Reader().Header().Columns
|
|
|
for _, f := range cmd.Fields {
|
|
|
found := false
|
|
|
for _, column := range titles {
|
|
|
if column == f.Name {
|
|
|
found = true
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
if !found {
|
|
|
titles = append(titles, f.Name)
|
|
|
}
|
|
|
}
|
|
|
// 填充旧数据
|
|
|
// 追加文件
|
|
|
for i := range data {
|
|
|
if len(data[i]) < len(titles) {
|
|
|
for j := 0; j < (len(titles) - len(data[i])); j++ {
|
|
|
data[i] = append(data[i], "")
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
for i := range cmd.Data {
|
|
|
row := make([]string, 0)
|
|
|
for _, filed := range titles {
|
|
|
if v, ok := cmd.Data[i][filed]; ok {
|
|
|
row = append(row, v)
|
|
|
} else {
|
|
|
row = append(row, "")
|
|
|
}
|
|
|
}
|
|
|
data = append(data, row)
|
|
|
if cmd.AppendTableDataFlag {
|
|
|
appendTableDataList = append(appendTableDataList, row)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//if !cmd.AppendTableDataFlag {
|
|
|
// 上传文件
|
|
|
fileUpload, err := saveFile(cmd.Name, titles, data, nil)
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
// 更新文件
|
|
|
file.FileInfo.Url = fileUpload.Url
|
|
|
file.FileInfo.FileSize = int(fileUpload.FileSize)
|
|
|
file.FileInfo.RowCount = len(data)
|
|
|
_, err = fileRepository.Save(file)
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
//}
|
|
|
//else if cmd.AppendTableDataFlag && file.FileInfo.TableId != 0 { // 追加数据到应用表
|
|
|
//var table *domain.Table
|
|
|
//if _, table, err = factory.FastPgTable(transactionContext, file.FileInfo.TableId); err != nil {
|
|
|
// return nil, factory.FastError(err)
|
|
|
//}
|
|
|
//// 上传文件
|
|
|
//fileUpload, err := saveCsvFile(cmd.Name, titles, appendTableDataList, nil)
|
|
|
//if err != nil {
|
|
|
// return nil, factory.FastError(err)
|
|
|
//}
|
|
|
//appendDataToTableService, _ := domainService.NewAppendDataToTableService(transactionContext.(*pgTransaction.TransactionContext))
|
|
|
//var mappingFields = make([]*domain.MappingField, 0)
|
|
|
//for _, f := range cmd.Fields {
|
|
|
// mappingFields = append(mappingFields, &domain.MappingField{
|
|
|
// MainTableField: &domain.Field{Name: f.Name},
|
|
|
// VerifiedFileFieldName: f.Name,
|
|
|
// })
|
|
|
//}
|
|
|
//if _, err = appendDataToTableService.AppendDataDirectly(ctx, fileUpload.Url, table, mappingFields); 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 (fileService *FileService) AppTableAppendData(ctx *domain.Context, cmd *command.AppTableFileAppendDataCommand) (interface{}, 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()
|
|
|
}()
|
|
|
|
|
|
fileRepository, file, _ := factory.FastPgFile(transactionContext, 0)
|
|
|
file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile})
|
|
|
if err == domain.ErrorNotFound {
|
|
|
return nil, factory.FastError(errors.New("文件不存在"))
|
|
|
}
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
if file.FileInfo.TableId == 0 {
|
|
|
return nil, factory.FastError(errors.New("表不存在"))
|
|
|
}
|
|
|
var (
|
|
|
appendTableDataList = make([][]string, 0)
|
|
|
titles = make([]string, 0)
|
|
|
table *domain.Table
|
|
|
)
|
|
|
_, table, err = factory.FastPgTable(transactionContext, file.FileInfo.TableId)
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
for _, f := range table.Fields(false) {
|
|
|
titles = append(titles, f.Name)
|
|
|
}
|
|
|
for _, f := range cmd.Fields {
|
|
|
found := false
|
|
|
for _, column := range titles {
|
|
|
if column == f.Name {
|
|
|
found = true
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
if !found {
|
|
|
titles = append(titles, f.Name)
|
|
|
}
|
|
|
}
|
|
|
for i := range cmd.Data {
|
|
|
row := make([]string, 0)
|
|
|
for _, filed := range titles {
|
|
|
if v, ok := cmd.Data[i][filed]; ok {
|
|
|
row = append(row, v)
|
|
|
} else {
|
|
|
row = append(row, "")
|
|
|
}
|
|
|
}
|
|
|
appendTableDataList = append(appendTableDataList, row)
|
|
|
}
|
|
|
|
|
|
// 上传文件
|
|
|
fileUpload, err := saveCsvFile(cmd.Name, titles, appendTableDataList, nil)
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
appendDataToTableService, _ := domainService.NewAppendDataToTableService(transactionContext.(*pgTransaction.TransactionContext))
|
|
|
var mappingFields = make([]*domain.MappingField, 0)
|
|
|
for _, f := range cmd.Fields {
|
|
|
mappingFields = append(mappingFields, &domain.MappingField{
|
|
|
MainTableField: &domain.Field{Name: f.Name},
|
|
|
VerifiedFileFieldName: f.Name,
|
|
|
})
|
|
|
}
|
|
|
if _, err = appendDataToTableService.AppendDataDirectly(ctx, fileUpload.Url, table, mappingFields); 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 (fileService *FileService) AppTableAppendDataDirect(ctx *domain.Context, cmd *command.AppTableFileAppendDataCommand) (interface{}, 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()
|
|
|
}()
|
|
|
|
|
|
fileRepository, file, _ := factory.FastPgFile(transactionContext, 0)
|
|
|
file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile})
|
|
|
if err == domain.ErrorNotFound {
|
|
|
return nil, factory.FastError(errors.New("文件不存在"))
|
|
|
}
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
if file.FileInfo.TableId == 0 {
|
|
|
return nil, factory.FastError(errors.New("表不存在"))
|
|
|
}
|
|
|
var (
|
|
|
titles = make([]string, 0)
|
|
|
table *domain.Table
|
|
|
)
|
|
|
_, table, err = factory.FastPgTable(transactionContext, file.FileInfo.TableId)
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
for _, f := range table.Fields(false) {
|
|
|
titles = append(titles, f.Name)
|
|
|
}
|
|
|
mapNameField := domain.Fields(table.Fields(false)).ToMap()
|
|
|
for _, f := range cmd.Fields {
|
|
|
found := false
|
|
|
for _, column := range titles {
|
|
|
if column == f.Name {
|
|
|
found = true
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
if !found {
|
|
|
titles = append(titles, f.Name)
|
|
|
}
|
|
|
}
|
|
|
var mapData = make([]map[string]string, 0)
|
|
|
for i := range cmd.Data {
|
|
|
mapItem := make(map[string]string)
|
|
|
for k, v := range cmd.Data[i] {
|
|
|
if f, ok := mapNameField[k]; ok {
|
|
|
mapItem[f.SQLName] = v
|
|
|
}
|
|
|
}
|
|
|
mapData = append(mapData, mapItem)
|
|
|
}
|
|
|
editDataService, _ := factory.CreateTableEditDataService(transactionContext)
|
|
|
_, err = editDataService.BatchAdd(ctx, domain.EditDataRequest{
|
|
|
TableId: table.TableId,
|
|
|
Table: table,
|
|
|
Where: domain.Where{},
|
|
|
UpdateList: nil,
|
|
|
AddList: domainService.MapArrayToFieldValues(mapData, table, nil, false),
|
|
|
RemoveList: nil,
|
|
|
IgnoreTableType: true,
|
|
|
})
|
|
|
if 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 (fileService *FileService) AppTableFileList(ctx *domain.Context, cmd *query.ListAppTableFileCommand) (interface{}, error) {
|
|
|
return fileService.GetAppFile(ctx, cmd.AppKey, cmd.Name)
|
|
|
}
|
|
|
|
|
|
func (fileService *FileService) UpdateAppTableFile(ctx *domain.Context, cmd *command.UpdateAppTableFileCommand) (interface{}, 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()
|
|
|
}()
|
|
|
|
|
|
fileRepository, file, _ := factory.FastPgFile(transactionContext, 0)
|
|
|
file, err = fileRepository.FindOne(map[string]interface{}{"appKey": cmd.AppKey, "fileName": cmd.Name, "fileType": domain.SourceFile})
|
|
|
if err == domain.ErrorNotFound {
|
|
|
return nil, factory.FastError(errors.New("文件不存在"))
|
|
|
}
|
|
|
if err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
if len(cmd.AddFields) == 0 {
|
|
|
return nil, nil
|
|
|
}
|
|
|
tableRepository, table, _ := factory.FastPgTable(transactionContext, file.FileInfo.TableId)
|
|
|
if err == domain.ErrorNotFound {
|
|
|
return nil, factory.FastError(errors.New("文件表不存在"))
|
|
|
}
|
|
|
builder := domainService.NewDataFieldsBuilder()
|
|
|
for i, _ := range cmd.AddFields {
|
|
|
if _, ok := table.MatchField(cmd.AddFields[i]); ok {
|
|
|
return nil, factory.FastError(errors.New("字段已存在"))
|
|
|
}
|
|
|
}
|
|
|
for _, f := range cmd.AddFields {
|
|
|
dataField := builder.NewDataField(f.Name, f.SQLType, domain.MainTableField)
|
|
|
table.DataFields = append(table.DataFields, dataField)
|
|
|
if err = starrocks.AddTableColumn(starrocks.DB, table.SQLName, dataField); err != nil {
|
|
|
return nil, factory.FastError(err)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if table, err = tableRepository.Save(table); 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
|
|
|
} |
...
|
...
|
|