package iot import ( "context" "strings" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/iot/simcardbatch/addpackage" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/service" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" ) func (s *sIotTSimCardBindPkg) PrepareInput(ctx context.Context, in *model.TSimCardBindPkgAddPackageInputPrepareParam) (*model.TSimCardBindPkgAddPackageInputPrepareRes, error) { if in == nil { in = &model.TSimCardBindPkgAddPackageInputPrepareParam{} } result, err := addpackage.NewCardSubmitter().PrepareInput(ctx, in.Input, addpackage.SubmitOptions{ PackageCode: in.PackageCode, Remark: in.Remark, EffectiveMode: in.EffectiveMode, }) if err != nil { return nil, err } return (*model.TSimCardBindPkgAddPackageInputPrepareRes)(addPackagePrepareRes(result)), nil } func (s *sIotTSimCardBindPkg) PrepareResult(ctx context.Context, batchNo string) (*model.TSimCardBindPkgAddPackagePrepareResultRes, error) { res, err := loadAddPackagePrepareResult(ctx, batchNo, consts.BatchTypeCardAddPackage) if err != nil { return nil, err } return (*model.TSimCardBindPkgAddPackagePrepareResultRes)(res), nil } func (s *sIotTSimCardBindPkg) ConfirmBatch(ctx context.Context, in *model.TSimCardBindPkgAddPackageBatchConfirmParam) (*model.TSimCardBindPkgAddPackageBatchConfirmRes, error) { res, err := confirmAddPackageBatch(ctx, (*model.TSimAddPackageBatchConfirmParam)(in), consts.BatchTypeCardAddPackage) if err != nil { return nil, err } return (*model.TSimCardBindPkgAddPackageBatchConfirmRes)(res), nil } func (s *sIotTSimPoolBindPackage) PrepareInput(ctx context.Context, in *model.TSimPoolBindPackageAddPackageInputPrepareParam) (*model.TSimPoolBindPackageAddPackageInputPrepareRes, error) { if in == nil { in = &model.TSimPoolBindPackageAddPackageInputPrepareParam{} } result, err := addpackage.NewPoolSubmitter().PrepareInput(ctx, in.Input, addpackage.SubmitOptions{ PackageCode: in.PackageCode, Remark: in.Remark, EffectiveMode: in.EffectiveMode, }) if err != nil { return nil, err } return (*model.TSimPoolBindPackageAddPackageInputPrepareRes)(addPackagePrepareRes(result)), nil } func (s *sIotTSimPoolBindPackage) PrepareResult(ctx context.Context, batchNo string) (*model.TSimPoolBindPackageAddPackagePrepareResultRes, error) { res, err := loadAddPackagePrepareResult(ctx, batchNo, consts.BatchTypePoolAddPackage) if err != nil { return nil, err } return (*model.TSimPoolBindPackageAddPackagePrepareResultRes)(res), nil } func (s *sIotTSimPoolBindPackage) ConfirmBatch(ctx context.Context, in *model.TSimPoolBindPackageAddPackageBatchConfirmParam) (*model.TSimPoolBindPackageAddPackageBatchConfirmRes, error) { res, err := confirmAddPackageBatch(ctx, (*model.TSimAddPackageBatchConfirmParam)(in), consts.BatchTypePoolAddPackage) if err != nil { return nil, err } return (*model.TSimPoolBindPackageAddPackageBatchConfirmRes)(res), nil } func addPackagePrepareRes(result *addpackage.SubmitResult) *model.TSimAddPackagePrepareRes { res := &model.TSimAddPackagePrepareRes{ BatchType: consts.BatchTypePrepare, BatchAsyncStatus: consts.BatchAsyncStatusPending, RunResult: consts.BatchRunResultPending, Status: "pending", } if result == nil { return res } res.BatchNo = result.BatchNo res.BatchType = result.BatchType res.TargetBatchType = result.TargetBatchType res.Total = result.Total res.ValidCount = result.ValidCount res.FailCount = result.FailCount return res } func confirmAddPackageBatch(ctx context.Context, in *model.TSimAddPackageBatchConfirmParam, targetBatchType int) (*model.TSimAddPackageBatchConfirmRes, error) { if in == nil { in = &model.TSimAddPackageBatchConfirmParam{} } in.BatchNo = strings.TrimSpace(in.BatchNo) if in.BatchNo == "" { return nil, gerror.New("批次号不能为空") } if targetBatchType != consts.BatchTypeCardAddPackage && targetBatchType != consts.BatchTypePoolAddPackage { return nil, gerror.New("加油包目标批次类型不正确") } effectiveMode, err := addpackage.NormalizeEffectiveMode(in.EffectiveMode) if err != nil { return nil, err } paymentMode, offlineContractCompleted, err := normalizeAddPackagePaymentMode(ctx, in.PaymentMode, in.OfflineContractCompleted) if err != nil { return nil, err } var converted *addpackage.AsyncConfirmResult err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { var convertErr error converted, convertErr = addpackage.ConvertPrepareToAsync(ctx, tx, &addpackage.AsyncConfirmInput{ BatchNo: in.BatchNo, TargetBatchType: targetBatchType, PackageCode: in.PackageCode, Remark: in.Remark, PaymentMode: paymentMode, OfflineContractCompleted: offlineContractCompleted, EffectiveMode: effectiveMode, Operator: currentOperator(ctx), }) return convertErr }) if err != nil { return nil, err } if converted == nil { return nil, gerror.New("加油包确认结果为空") } publishPendingExecute(ctx, converted.BatchNo, converted.BatchType, contexts.GetTenantId(ctx)) return &model.TSimAddPackageBatchConfirmRes{ BatchNo: converted.BatchNo, BatchType: converted.BatchType, BatchAsyncStatus: converted.BatchAsyncStatus, PackageCode: strings.TrimSpace(in.PackageCode), EffectiveMode: effectiveMode, Status: "pending", }, nil } func loadAddPackagePrepareResult(ctx context.Context, batchNo string, targetBatchType int) (*model.TSimAddPackagePrepareResultRes, error) { batchNo = strings.TrimSpace(batchNo) if batchNo == "" { return nil, gerror.New("批次号不能为空") } columns := dao.BatchMain.Columns() batch := &entity.BatchMain{} if err := dao.BatchMain.Ctx(ctx). Where(columns.BatchNo, batchNo). Where(columns.TenantId, contexts.GetTenantId(ctx)). Where(columns.CreatedDept, contexts.GetDeptId(ctx)). Scan(batch); err != nil { return nil, gerror.Wrap(err, "查询加油包预处理批次失败") } if batch.Id == 0 { return nil, gerror.New("加油包预处理批次不存在或不可见") } if !isAddPackagePrepareOrTarget(batch, targetBatchType) { return nil, gerror.New("批次类型不匹配") } asyncStatus, runResult, status := prepareRuntimeStatus(batch.BatchAsyncStatus, batch.RunResult) res := &model.TSimAddPackagePrepareResultRes{ BatchNo: batch.BatchNo, BatchType: batch.BatchType, TargetBatchType: targetBatchType, Status: status, BatchAsyncStatus: asyncStatus, RunResult: runResult, Total: batch.TotalCount, ValidCount: batch.ValidCount, SuccessCount: batch.SuccessCount, FailCount: batch.FailCount, FailReason: strings.TrimSpace(batch.FailReason), StartTime: batch.StartTime, EndTime: batch.EndTime, } fillAddPackagePrepareFields(res, batch.BatchInfo) if res.Quantity <= 0 { res.Quantity = firstPositive(batch.SuccessCount, batch.ValidCount, batch.TotalCount) } if res.TotalAmount <= 0 && res.UnitPrice > 0 && res.Quantity > 0 { res.TotalAmount = roundAmount(res.UnitPrice * float64(res.Quantity)) } fillAddPackagePaymentView(ctx, res) return res, nil } func isAddPackagePrepareOrTarget(batch *entity.BatchMain, targetBatchType int) bool { if batch == nil { return false } if targetBatchType != consts.BatchTypeCardAddPackage && targetBatchType != consts.BatchTypePoolAddPackage { return false } if batch.BatchInfo != nil && batch.BatchInfo.Get("targetBatchType").Int() == targetBatchType { return true } return batch.BatchType == targetBatchType } func prepareRuntimeStatus(asyncStatusValue int, runResultValue int) (int, int, string) { asyncStatus := consts.BatchAsyncStatusPending runResult := consts.BatchRunResultPending status := "pending" switch { case asyncStatusValue == consts.BatchAsyncStatusProcessing || runResultValue == consts.BatchRunResultRunning: asyncStatus = consts.BatchAsyncStatusProcessing runResult = consts.BatchRunResultRunning status = "processing" case asyncStatusValue == consts.BatchAsyncStatusSuccess && runResultValue == consts.BatchRunResultSuccess: asyncStatus = consts.BatchAsyncStatusSuccess runResult = consts.BatchRunResultSuccess status = "success" case asyncStatusValue == consts.BatchAsyncStatusFailed || runResultValue == consts.BatchRunResultFailed: asyncStatus = consts.BatchAsyncStatusFailed runResult = consts.BatchRunResultFailed status = "failed" case asyncStatusValue == consts.BatchAsyncStatusPartialSuccess || runResultValue == consts.BatchRunResultPartialSuccess: asyncStatus = consts.BatchAsyncStatusFailed runResult = consts.BatchRunResultFailed status = "failed" } return asyncStatus, runResult, status } func fillAddPackagePrepareFields(res *model.TSimAddPackagePrepareResultRes, info *gjson.Json) { if res == nil || info == nil { return } res.PackageCode = jsonString(info, "packageCode", "priceSnapshot.packageCode") res.PackageName = jsonString(info, "packageName", "priceSnapshot.packageName") res.FlowMb = roundAmount(jsonFloat64(info, "flowMb", "priceSnapshot.flowMb")) res.UnitPrice = roundAmount(jsonFloat64(info, "unitPrice", "priceSnapshot.unitPrice")) res.TotalAmount = roundAmount(jsonFloat64(info, "totalAmount")) res.Quantity = jsonInt(info, "quantity") res.EffectiveMode = jsonString(info, "effectiveMode") if res.EffectiveMode == "" { res.EffectiveMode = addpackage.EffectiveModeCurrentMonth } res.EffectiveModeText = jsonString(info, "effectiveModeText") if res.EffectiveModeText == "" { res.EffectiveModeText = addpackage.EffectiveModeText(res.EffectiveMode) } res.EffectiveTime = jsonString(info, "effectiveTime") res.ExpectedExpireTime = jsonString(info, "expectedExpireTime") res.PaymentAccounts = addPackagePaymentAccountsFromInfo(info) res.AvailablePackages = addPackagePackageOptionsFromInfo(info) res.Snapshot = info } func addPackagePaymentAccountsFromInfo(info *gjson.Json) []*model.TSimAddPackagePaymentAccountModel { value := jsonField(info, "paymentAccounts") if value == nil || value.IsNil() { return nil } var accounts []*model.TSimAddPackagePaymentAccountModel if err := gconv.Structs(value.Interfaces(), &accounts); err != nil { return nil } return accounts } func addPackagePackageOptionsFromInfo(info *gjson.Json) []*model.TSimAddPackageOptionModel { value := jsonField(info, "availablePackages", "packageOptions") if value == nil || value.IsNil() { return nil } var options []*model.TSimAddPackageOptionModel if err := gconv.Structs(value.Interfaces(), &options); err != nil { return nil } return options } func fillAddPackagePaymentView(ctx context.Context, res *model.TSimAddPackagePrepareResultRes) { if res == nil { return } isTop, _, err := service.AgentDept().IsTopDept(ctx) if err == nil { res.IsTopDept = isTop res.DefaultPaymentMode = addPackageDefaultPaymentMode(isTop) } balance, err := queryAddPackageAvailableBalance(ctx, contexts.GetDeptId(ctx)) if err == nil { res.AvailableBalance = balance } } func firstPositive(values ...int) int { for _, value := range values { if value > 0 { return value } } return 0 }