Files
iotlcm/app/server/internal/library/batchimport/async.go
T

178 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package batchimport
import (
"context"
"strings"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/batchmetadata"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/dao"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/do"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/service"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
type PendingOptions struct {
PrepareRows func(ctx context.Context, rows []Row) error
}
func CreatePendingUpload(ctx context.Context, req SubmitRequest, p Processor, options PendingOptions) (*Result, error) {
if err := batchmetadata.ValidateCreation(req.SourceChannel, req.ExecutionMode); err != nil {
return nil, err
}
cfg := p.Config()
if req.File == nil {
return nil, gerror.New("请选择上传文件")
}
if err := service.SysOss().CheckType(ctx, consts.SysUploadFileTypeFile, req.File); err != nil {
return nil, err
}
if req.File.Size > cfg.MaxFileSize {
return nil, gerror.Newf("上传文件大小超过限制,最大为%dM", cfg.MaxFileSize>>20)
}
batchNo, err := NextBatchNoContext(ctx, cfg.BatchNoPrefix)
if err != nil {
return nil, err
}
req.BatchNo = batchNo
content, err := readUploadContent(req.File)
if err != nil {
return nil, err
}
importOss, err := service.SysOss().SaveContent(ctx, &model.SysOssSaveContentParam{
Content: content,
FileName: batchNo + "-import.xlsx",
NewFileType: consts.SysUploadNewFileTypeUserFile,
SubDirName: cfg.ImportDir,
})
if err != nil {
return nil, gerror.Wrap(err, "保存原始Excel失败")
}
rows, err := p.ParseRows(ctx, importOss.Path)
if err != nil {
return nil, err
}
return createPending(ctx, &req, p, rows, importOss, options)
}
func CreatePendingRows(ctx context.Context, req SubmitRequest, p Processor, rows []Row, options PendingOptions) (*Result, error) {
if err := batchmetadata.ValidateCreation(req.SourceChannel, req.ExecutionMode); err != nil {
return nil, err
}
batchNo, err := NextBatchNoContext(ctx, p.Config().BatchNoPrefix)
if err != nil {
return nil, err
}
req.BatchNo = batchNo
return createPending(ctx, &req, p, rows, nil, options)
}
func createPending(ctx context.Context, req *SubmitRequest, p Processor, rows []Row, importOss *model.SysOssSaveContentModel, options PendingOptions) (*Result, error) {
if len(rows) == 0 {
return nil, gerror.New("导入数据为空")
}
if err := p.ValidateRows(ctx, rows); err != nil {
return nil, err
}
if options.PrepareRows != nil {
if err := options.PrepareRows(ctx, rows); err != nil {
return nil, err
}
}
result := &Result{
ImportStatus: consts.ImportStatusSuccess,
BatchNo: req.BatchNo,
BatchType: p.Config().BatchType,
TotalRows: len(rows),
}
if importOss != nil {
result.ImportFileOssId = importOss.OssId
result.ImportFileUrl = importOss.Url
}
if err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
sourceBatchNo := strings.TrimSpace(req.SourceBatchNo)
if sourceBatchNo == "" {
sourceBatchNo = req.BatchNo
}
if _, err := dao.BatchMain.Ctx(ctx).TX(tx).Data(do.BatchMain{
BatchNo: req.BatchNo,
OrderSn: "",
BatchType: p.Config().BatchType,
BatchStatus: consts.BatchAsyncStatusPending,
BatchAsyncStatus: consts.BatchAsyncStatusPending,
SourceType: req.SourceType,
SourceChannel: batchmetadata.Channel(req.SourceChannel),
ExecutionMode: batchmetadata.NormalizeMode(req.ExecutionMode),
SourceBatchNo: sourceBatchNo,
IsCrossDept: 0,
TargetDeptId: req.TargetDeptId,
DeptId: req.Operator.DeptId,
TotalCount: len(rows),
ValidCount: 0,
SuccessCount: 0,
FailCount: 0,
RunResult: consts.BatchRunResultPending,
FailReason: "",
BatchInfo: p.BuildBatchInfo(ctx, *req, result, importOss, nil, 0),
TenantId: req.Operator.TenantId,
CreatedDept: req.Operator.DeptId,
CreatedBy: req.Operator.UserId,
UpdatedBy: req.Operator.UserId,
}).Insert(); err != nil {
return gerror.Wrap(err, "写入待处理批次失败")
}
details := make([]do.BatchDetail, 0, len(rows))
for _, row := range rows {
details = append(details, do.BatchDetail{
BatchNo: req.BatchNo,
BatchType: p.Config().BatchType,
DetailStatus: consts.BatchDetailStatusPending,
BlankOutStatus: consts.BlankOutStatusNo,
RowNo: row.GetRowNo(),
ItemId: row.GetItemID(),
ErrorCode: "",
ErrorReason: strings.Join(row.GetErrorReasons(), ";"),
Snapshot: row.Snapshot(),
TenantId: req.Operator.TenantId,
CreatedDept: req.Operator.DeptId,
CreatedBy: req.Operator.UserId,
UpdatedBy: req.Operator.UserId,
})
}
_, err := dao.BatchDetail.Ctx(ctx).TX(tx).Data(details).Insert()
return gerror.Wrap(err, "写入待处理批次明细失败")
}); err != nil {
return nil, err
}
return result, nil
}
func SaveAsyncResultFiles(
ctx context.Context,
req SubmitRequest,
p Processor,
result *Result,
rows []Row,
importOss *model.SysOssSaveContentModel,
startTime, endTime *gtime.Time,
) (*model.SysOssSaveContentModel, int64, error) {
resultOss, downloadId, err := saveResultExcelAndDownload(ctx, req, p, result, rows, importOss, startTime, endTime)
if err != nil {
return nil, 0, err
}
result.ResultDownloadId = downloadId
result.ResultFileOssId = resultOss.OssId
result.ResultFileUrl = resultOss.Url
return resultOss, downloadId, nil
}