668 lines
23 KiB
Go
668 lines
23 KiB
Go
// Package gen
|
|
// @Link https://github.com/xiujiecn/xiu-admin
|
|
// @Copyright Copyright (c) 2026 LiXiujie
|
|
// @Author Lxj <xxx@example.com>
|
|
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
|
|
// @AutoGenerate Version
|
|
package iot
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"sort"
|
|
"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/library/xgorm"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/handler"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/hook"
|
|
"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"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/utility/convert"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/utility/excel"
|
|
|
|
"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/net/ghttp"
|
|
"github.com/gogf/gf/v2/os/gctx"
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
)
|
|
|
|
type sIotTSimCardBindPkg struct{}
|
|
|
|
func NewIotTSimCardBindPkg() *sIotTSimCardBindPkg {
|
|
return &sIotTSimCardBindPkg{}
|
|
}
|
|
|
|
func init() {
|
|
service.RegisterIotTSimCardBindPkg(NewIotTSimCardBindPkg())
|
|
}
|
|
|
|
// Model 订购表ORM模型
|
|
func (s *sIotTSimCardBindPkg) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
|
|
if len(option) == 0 {
|
|
option = append(option, &handler.Option{
|
|
FilterTenant: true,
|
|
FilterAuth: true,
|
|
})
|
|
}
|
|
return handler.Model(dao.TSimCardBindPkg.Ctx(ctx), option...)
|
|
}
|
|
|
|
// List 获取订购表列表
|
|
func (s *sIotTSimCardBindPkg) List(ctx context.Context, in *model.TSimCardBindPkgListParam) (list []*model.TSimCardBindPkgListModel, totalCount int, err error) {
|
|
mod := s.Model(ctx)
|
|
bindPackage := dao.TSimCardBindPkg.Table()
|
|
packageInfo := dao.TSimFlowPackageInfo.Table()
|
|
|
|
// 先构建 Join
|
|
mod = mod.LeftJoin(packageInfo, bindPackage+"."+dao.TSimCardBindPkg.Columns().PackageCode+" = "+packageInfo+"."+dao.TSimFlowPackageInfo.Columns().PackageCode)
|
|
|
|
// 字段过滤(包含主表字段 + joined 表字段)
|
|
mod = mod.FieldsPrefix(bindPackage, model.TSimCardBindPkgListModel{})
|
|
mod = mod.Fields(packageInfo + ".package_name as packageName")
|
|
mod = mod.WhereIn(dao.TSimCardBindPkg.Columns().PackageType, []int{101, 102})
|
|
|
|
// 查询主键ID
|
|
if in.Id > 0 {
|
|
mod = mod.Where(dao.TSimCardBindPkg.Columns().Id, in.Id)
|
|
}
|
|
// 查询ICCID
|
|
if in.Iccid != "" {
|
|
mod = mod.Where(dao.TSimCardBindPkg.Columns().Iccid, in.Iccid)
|
|
}
|
|
|
|
// 查询订购状态 枚举
|
|
if in.EffectiveStatus > 0 {
|
|
mod = mod.Where(dao.TSimCardBindPkg.Columns().EffectiveStatus, in.EffectiveStatus)
|
|
}
|
|
// 查询类型 枚举
|
|
if in.BusinessType != nil {
|
|
mod = mod.Where(dao.TSimCardBindPkg.Columns().BusinessType, *in.BusinessType)
|
|
}
|
|
|
|
// 查询创建时间
|
|
if len(in.CreatedAt) == 2 {
|
|
in.CreatedAt[1] = in.CreatedAt[1].EndOfDay()
|
|
}
|
|
if len(in.CreatedAt) == 2 {
|
|
mod = mod.WhereBetween(dao.TSimCardBindPkg.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
|
|
}
|
|
|
|
// 分页
|
|
mod = mod.Page(in.Page, in.PageSize)
|
|
|
|
// 排序
|
|
mod = mod.OrderDesc(dao.TSimCardBindPkg.Columns().Id)
|
|
|
|
// 操作人摘要信息
|
|
mod = mod.Hook(hook.MemberSummary)
|
|
|
|
// 查询数据
|
|
if err = mod.ScanAndCount(&list, &totalCount, false); err != nil {
|
|
err = gerror.Wrap(err, "获取订购表列表失败,请稍后重试!")
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// Export 导出订购表
|
|
func (s *sIotTSimCardBindPkg) Export(ctx context.Context, in *model.TSimCardBindPkgListParam) (err error) {
|
|
list, totalCount, err := s.List(ctx, in)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// 字段的排序是依据tags的字段顺序,如果你不想使用默认的排序方式,可以直接定义 tags = []string{"字段名称", "字段名称2", ...}
|
|
tags, err := convert.GetEntityDescTags(model.TSimCardBindPkgExportModel{})
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var (
|
|
fileName = "导出订购表-" + gctx.CtxId(ctx)
|
|
sheetName = fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, (totalCount+in.PageSize-1)/in.PageSize, in.Page, len(list))
|
|
exports []model.TSimCardBindPkgExportModel
|
|
)
|
|
|
|
if err = gconv.Scan(list, &exports); err != nil {
|
|
return
|
|
}
|
|
|
|
err = excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
|
|
return
|
|
}
|
|
|
|
// Edit 修改/新增订购表
|
|
func (s *sIotTSimCardBindPkg) Edit(ctx context.Context, in *model.TSimCardBindPkgEditParam) (err error) {
|
|
// 验证'SubscriptionNo'唯一
|
|
if err = xgorm.IsUnique(ctx, &dao.TSimCardBindPkg, g.Map{dao.TSimCardBindPkg.Columns().SubscriptionNo: in.SubscriptionNo}, "订购记录编号已存在", in.Id); err != nil {
|
|
return
|
|
}
|
|
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
|
|
|
|
// 修改
|
|
if in.Id > 0 {
|
|
updatedBy := contexts.GetUserId(ctx)
|
|
in.UpdatedBy = &updatedBy
|
|
in.UpdatedAt = gtime.Now()
|
|
if _, err = s.Model(ctx).
|
|
Fields(model.TSimCardBindPkgUpdateFields{}).
|
|
WherePri(in.Id).Data(in).Update(); err != nil {
|
|
err = gerror.Wrap(err, "修改订购表失败,请稍后重试!")
|
|
}
|
|
return
|
|
}
|
|
|
|
// 新增
|
|
tenantId := contexts.GetTenantId(ctx)
|
|
in.TenantId = &tenantId
|
|
createdDept := contexts.GetDeptId(ctx)
|
|
in.CreatedDept = &createdDept
|
|
createdBy := contexts.GetUserId(ctx)
|
|
in.CreatedBy = &createdBy
|
|
in.CreatedAt = gtime.Now()
|
|
if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).
|
|
Fields(model.TSimCardBindPkgInsertFields{}).
|
|
Data(in).Insert(); err != nil {
|
|
err = gerror.Wrap(err, "新增订购表失败,请稍后重试!")
|
|
}
|
|
return
|
|
})
|
|
}
|
|
|
|
// Delete 删除订购表
|
|
func (s *sIotTSimCardBindPkg) Delete(ctx context.Context, in *model.TSimCardBindPkgDeleteParam) (err error) {
|
|
|
|
if _, err = s.Model(ctx).WherePri(in.Id).Unscoped().Delete(); err != nil {
|
|
err = gerror.Wrap(err, "删除订购表失败,请稍后重试!")
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// View 获取订购表指定信息
|
|
func (s *sIotTSimCardBindPkg) View(ctx context.Context, in *model.TSimCardBindPkgViewParam) (res *model.TSimCardBindPkgViewModel, err error) {
|
|
if err = s.Model(ctx).WherePri(in.Id).Hook(hook.MemberSummary).Scan(&res); err != nil {
|
|
err = gerror.Wrap(err, "获取订购表信息,请稍后重试!")
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// AddPackagePaymentContext 获取当前组织的加油包支付上下文。
|
|
func (s *sIotTSimCardBindPkg) AddPackagePaymentContext(ctx context.Context) (*model.TSimAddPackageOptionsRes, error) {
|
|
return queryAddPackagePaymentContext(ctx)
|
|
}
|
|
|
|
// AddPackageOptions 获取当前卡共同可订购的加油包套餐。
|
|
func (s *sIotTSimCardBindPkg) AddPackageOptions(ctx context.Context, in *model.TSimCardAddPackageOptionsParam) (*model.TSimAddPackageOptionsRes, error) {
|
|
if in == nil || len(in.Iccids) == 0 {
|
|
return nil, gerror.New("ICCID不能为空")
|
|
}
|
|
iccids := uniqueNonEmptyStrings(in.Iccids)
|
|
if len(iccids) == 0 {
|
|
return nil, gerror.New("ICCID不能为空")
|
|
}
|
|
|
|
cardColumns := dao.TSimCardInfo.Columns()
|
|
var cards []struct {
|
|
Iccid string `orm:"iccid"`
|
|
PackageStatus int `orm:"package_status"`
|
|
DeptId int64 `orm:"dept_id"`
|
|
}
|
|
if err := handler.Model(dao.TSimCardInfo.Ctx(ctx), &handler.Option{FilterTenant: true, FilterAuth: true}).
|
|
Fields(cardColumns.Iccid, cardColumns.PackageStatus, cardColumns.TenantId, cardColumns.DeptId, cardColumns.CreatedDept, cardColumns.CreatedBy).
|
|
WhereIn(cardColumns.Iccid, iccids).
|
|
Scan(&cards); err != nil {
|
|
return nil, gerror.Wrap(err, "查询卡信息失败")
|
|
}
|
|
cardMap := make(map[string]int64, len(cards))
|
|
for _, card := range cards {
|
|
code := strings.TrimSpace(card.Iccid)
|
|
if code == "" {
|
|
continue
|
|
}
|
|
if card.PackageStatus != consts.PackageStatusEffective {
|
|
return nil, gerror.Newf("ICCID %s 当前套餐未生效,不能订购加油包", code)
|
|
}
|
|
if card.DeptId <= 0 {
|
|
return nil, gerror.Newf("ICCID %s 未绑定客户组织", code)
|
|
}
|
|
cardMap[code] = card.DeptId
|
|
}
|
|
for _, code := range iccids {
|
|
if _, ok := cardMap[code]; !ok {
|
|
return nil, gerror.Newf("ICCID %s 不存在或无权限", code)
|
|
}
|
|
}
|
|
if err := ensureNoActiveCardTopupPackages(ctx, iccids); err != nil {
|
|
return nil, err
|
|
}
|
|
isTopDept, _, err := service.AgentDept().IsTopDept(ctx)
|
|
if err != nil {
|
|
return nil, gerror.Wrap(err, "判断当前组织类型失败")
|
|
}
|
|
availableBalance, err := queryAddPackageAvailableBalance(ctx, contexts.GetDeptId(ctx))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bindColumns := dao.TSimCardBindPkg.Columns()
|
|
var binds []struct {
|
|
Iccid string `orm:"iccid"`
|
|
PackageCode string `orm:"package_code"`
|
|
ExpectedExpireTime *gtime.Time `orm:"expected_expire_time"`
|
|
}
|
|
if err := handler.Model(dao.TSimCardBindPkg.Ctx(ctx), &handler.Option{FilterTenant: true, FilterAuth: true}).
|
|
Fields(bindColumns.Iccid, bindColumns.PackageCode, bindColumns.ExpectedExpireTime, bindColumns.TenantId, bindColumns.DeptId, bindColumns.CreatedDept, bindColumns.CreatedBy).
|
|
WhereIn(bindColumns.Iccid, iccids).
|
|
WhereIn(bindColumns.PackageType, []int{consts.PackageTypeCard, consts.PackageTypePool}).
|
|
Where(bindColumns.EffectiveStatus, consts.EffectiveStatusEffective).
|
|
OrderDesc(bindColumns.ExpectedExpireTime).
|
|
OrderDesc(bindColumns.Id).
|
|
Scan(&binds); err != nil {
|
|
return nil, gerror.Wrap(err, "查询卡基础套餐失败")
|
|
}
|
|
baseCodes := make(map[string]string, len(iccids))
|
|
for _, bind := range binds {
|
|
iccid := strings.TrimSpace(bind.Iccid)
|
|
if _, exists := baseCodes[iccid]; exists {
|
|
continue
|
|
}
|
|
if bind.ExpectedExpireTime != nil && !bind.ExpectedExpireTime.After(gtime.Now()) {
|
|
continue
|
|
}
|
|
baseCodes[iccid] = strings.TrimSpace(bind.PackageCode)
|
|
}
|
|
for _, code := range iccids {
|
|
if baseCodes[code] == "" {
|
|
return nil, gerror.Newf("ICCID %s 当前没有正在生效中的基础套餐", code)
|
|
}
|
|
}
|
|
|
|
packageCodes := make([]string, 0, len(baseCodes))
|
|
for _, code := range baseCodes {
|
|
packageCodes = append(packageCodes, code)
|
|
}
|
|
packageColumns := dao.TSimFlowPackageInfo.Columns()
|
|
var packages []*entity.TSimFlowPackageInfo
|
|
if err := handler.Model(dao.TSimFlowPackageInfo.Ctx(ctx), &handler.Option{FilterTenant: true, FilterAuth: false}).
|
|
Fields(packageColumns.PackageCode, packageColumns.TopupPackageCodes).
|
|
WhereIn(packageColumns.PackageCode, uniqueNonEmptyStrings(packageCodes)).
|
|
Scan(&packages); err != nil {
|
|
return nil, gerror.Wrap(err, "查询基础套餐配置失败")
|
|
}
|
|
packageMap := make(map[string]*entity.TSimFlowPackageInfo, len(packages))
|
|
for _, pkg := range packages {
|
|
if pkg != nil {
|
|
packageMap[strings.TrimSpace(pkg.PackageCode)] = pkg
|
|
}
|
|
}
|
|
|
|
var commonCodes map[string]struct{}
|
|
for _, code := range iccids {
|
|
base := packageMap[baseCodes[code]]
|
|
if base == nil {
|
|
return nil, gerror.Newf("基础套餐不存在:%s", baseCodes[code])
|
|
}
|
|
allowed := make(map[string]struct{})
|
|
for _, topupCode := range packageCodesFromJSON(base.TopupPackageCodes) {
|
|
allowed[topupCode] = struct{}{}
|
|
}
|
|
if len(allowed) == 0 {
|
|
return nil, gerror.Newf("基础套餐未配置可购加油包:%s", baseCodes[code])
|
|
}
|
|
if commonCodes == nil {
|
|
commonCodes = allowed
|
|
continue
|
|
}
|
|
for candidate := range commonCodes {
|
|
if _, ok := allowed[candidate]; !ok {
|
|
delete(commonCodes, candidate)
|
|
}
|
|
}
|
|
}
|
|
if len(commonCodes) == 0 {
|
|
return nil, gerror.New("所选卡没有共同可购的加油包套餐")
|
|
}
|
|
|
|
var addPackages []*entity.TSimFlowPackageInfo
|
|
if err := handler.Model(dao.TSimFlowPackageInfo.Ctx(ctx), &handler.Option{FilterTenant: true, FilterAuth: false}).
|
|
Fields(
|
|
packageColumns.PackageCode,
|
|
packageColumns.PackageName,
|
|
packageColumns.FlowMb,
|
|
packageColumns.CostPrice,
|
|
packageColumns.TerminalCost,
|
|
packageColumns.SysDefaultRatio,
|
|
packageColumns.SysDefaultProfit,
|
|
packageColumns.SysDefaultTerminalRatio,
|
|
packageColumns.SysDefaultTerminalProfit,
|
|
).
|
|
WhereIn(packageColumns.PackageCode, mapKeys(commonCodes)).
|
|
Where(packageColumns.PackageType, consts.PackageTypeCardAddPackage).
|
|
Where(packageColumns.Enabled, 1).
|
|
OrderAsc(packageColumns.SortNo).
|
|
Scan(&addPackages); err != nil {
|
|
return nil, gerror.Wrap(err, "查询单卡加油包套餐失败")
|
|
}
|
|
items := make([]*model.TSimAddPackageOptionModel, 0, len(addPackages))
|
|
for _, pkg := range addPackages {
|
|
if pkg == nil {
|
|
continue
|
|
}
|
|
var totalAmount float64
|
|
var unitPrice float64
|
|
priceAvailable := true
|
|
uniformPrice := true
|
|
paymentAccounts := make(map[int64]*model.TSimAddPackagePaymentAccountModel)
|
|
for index, iccid := range iccids {
|
|
customerDeptID := cardMap[iccid]
|
|
priceOwnerDeptID, err := loadPackagePriceParentDeptID(ctx, nil, contexts.GetTenantId(ctx), customerDeptID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
salePrice, err := resolvePackageEffectiveSalePrice(
|
|
ctx,
|
|
nil,
|
|
contexts.GetTenantId(ctx),
|
|
priceOwnerDeptID,
|
|
customerDeptID,
|
|
packagePriceSourceFromEntity(pkg),
|
|
)
|
|
if err != nil {
|
|
priceAvailable = false
|
|
break
|
|
}
|
|
if index == 0 {
|
|
unitPrice = salePrice.AgentShipmentPrice
|
|
} else if math.Abs(unitPrice-salePrice.AgentShipmentPrice) > 0.0001 {
|
|
uniformPrice = false
|
|
}
|
|
totalAmount = roundAmount(totalAmount + salePrice.AgentShipmentPrice)
|
|
account := paymentAccounts[customerDeptID]
|
|
if account == nil {
|
|
balance, err := queryAddPackageAvailableBalance(ctx, customerDeptID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
account = &model.TSimAddPackagePaymentAccountModel{
|
|
PayerDeptId: customerDeptID,
|
|
AvailableBalance: balance,
|
|
}
|
|
paymentAccounts[customerDeptID] = account
|
|
}
|
|
account.TargetCount++
|
|
account.RequiredAmount = roundAmount(account.RequiredAmount + salePrice.AgentShipmentPrice)
|
|
}
|
|
paymentAccountItems := make([]*model.TSimAddPackagePaymentAccountModel, 0, len(paymentAccounts))
|
|
for _, account := range paymentAccounts {
|
|
account.BalanceEnough = account.AvailableBalance+0.0001 >= account.RequiredAmount
|
|
paymentAccountItems = append(paymentAccountItems, account)
|
|
}
|
|
if !uniformPrice {
|
|
unitPrice = 0
|
|
}
|
|
items = append(items, &model.TSimAddPackageOptionModel{
|
|
PackageCode: strings.TrimSpace(pkg.PackageCode),
|
|
PackageName: strings.TrimSpace(pkg.PackageName),
|
|
FlowMb: pkg.FlowMb,
|
|
UnitPrice: unitPrice,
|
|
TotalAmount: totalAmount,
|
|
PriceAvailable: priceAvailable,
|
|
PaymentAccounts: paymentAccountItems,
|
|
})
|
|
}
|
|
return &model.TSimAddPackageOptionsRes{
|
|
Items: items,
|
|
IsTopDept: isTopDept,
|
|
DefaultPaymentMode: addPackageDefaultPaymentMode(isTopDept),
|
|
AvailableBalance: availableBalance,
|
|
}, nil
|
|
}
|
|
|
|
func uniqueNonEmptyStrings(values []string) []string {
|
|
seen := make(map[string]struct{}, len(values))
|
|
result := make([]string, 0, len(values))
|
|
for _, value := range values {
|
|
value = strings.TrimSpace(value)
|
|
if value == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[value]; ok {
|
|
continue
|
|
}
|
|
seen[value] = struct{}{}
|
|
result = append(result, value)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func mapKeys(values map[string]struct{}) []string {
|
|
keys := make([]string, 0, len(values))
|
|
for key := range values {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
return keys
|
|
}
|
|
|
|
func ensureNoActiveCardTopupPackages(ctx context.Context, iccids []string) error {
|
|
iccids = uniqueNonEmptyStrings(iccids)
|
|
if len(iccids) == 0 {
|
|
return nil
|
|
}
|
|
c := dao.TSimCardBindPkg.Columns()
|
|
var row struct {
|
|
Iccid string `orm:"iccid"`
|
|
}
|
|
if err := handler.Model(dao.TSimCardBindPkg.Ctx(ctx), &handler.Option{FilterTenant: true, FilterAuth: true}).
|
|
Fields(c.Iccid).
|
|
WhereIn(c.Iccid, iccids).
|
|
Where(c.PackageType, consts.PackageTypeCardAddPackage).
|
|
WhereIn(c.EffectiveStatus, []int{consts.EffectiveStatusPending, consts.EffectiveStatusEffective}).
|
|
Where(fmt.Sprintf("(%s IS NULL OR %s > ?)", c.ExpectedExpireTime, c.ExpectedExpireTime), gtime.Now()).
|
|
OrderAsc(c.Id).
|
|
Limit(1).
|
|
Scan(&row); err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
return gerror.Wrap(err, "查询未过期单卡加油包失败")
|
|
}
|
|
if iccid := strings.TrimSpace(row.Iccid); iccid != "" {
|
|
return gerror.Newf("ICCID %s 存在未过期加油包,不能重复订购", iccid)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func ensureNoActivePoolTopupPackages(ctx context.Context, poolCodes []string) error {
|
|
poolCodes = uniqueNonEmptyStrings(poolCodes)
|
|
if len(poolCodes) == 0 {
|
|
return nil
|
|
}
|
|
c := dao.TSimPoolBindPackage.Columns()
|
|
var row struct {
|
|
PoolNo string `orm:"pool_no"`
|
|
}
|
|
if err := handler.Model(dao.TSimPoolBindPackage.Ctx(ctx), &handler.Option{FilterTenant: true, FilterAuth: true}).
|
|
Fields(c.PoolNo).
|
|
WhereIn(c.PoolNo, poolCodes).
|
|
Where(c.PackageType, consts.PackageTypePoolAddPackage).
|
|
WhereIn(c.EffectiveStatus, []int{consts.EffectiveStatusPending, consts.EffectiveStatusEffective}).
|
|
Where(fmt.Sprintf("(%s IS NULL OR %s > ?)", c.ExpectedExpireTime, c.ExpectedExpireTime), gtime.Now()).
|
|
OrderAsc(c.Id).
|
|
Limit(1).
|
|
Scan(&row); err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
return gerror.Wrap(err, "查询未过期流量池加油包失败")
|
|
}
|
|
if poolNo := strings.TrimSpace(row.PoolNo); poolNo != "" {
|
|
return gerror.Newf("流量池 %s 存在未过期加油包,不能重复订购", poolNo)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 套餐详情查询
|
|
func (s *sIotTSimCardBindPkg) GetPkgInfo(ctx context.Context, in *model.TSimCardBindPkgInfoParam) (list []*model.TSimCardBindPkgListModel, totalCount int, err error) {
|
|
mod := s.Model(ctx)
|
|
bindPackage := dao.TSimCardBindPkg.Table()
|
|
packageInfo := dao.TSimFlowPackageInfo.Table()
|
|
orderTable := dao.TOrder.Table()
|
|
|
|
// 先构建 Join
|
|
mod = mod.LeftJoin(packageInfo, bindPackage+"."+dao.TSimCardBindPkg.Columns().PackageCode+" = "+packageInfo+"."+dao.TSimFlowPackageInfo.Columns().PackageCode)
|
|
mod = mod.LeftJoin(orderTable, "CONVERT("+bindPackage+"."+dao.TSimCardBindPkg.Columns().OrderCode+" USING utf8mb4) = "+orderTable+"."+dao.TOrder.Columns().OrderSn)
|
|
|
|
// 字段过滤(包含主表字段 + joined 表字段)
|
|
mod = mod.FieldsPrefix(bindPackage, model.TSimCardBindPkgListModel{})
|
|
mod = mod.Fields(packageInfo + ".package_name as packageName")
|
|
mod = mod.Fields(packageInfo + ".flow_mb as packageFlowMb")
|
|
mod = mod.Fields(packageInfo + ".flow_gb as packageFlowGb")
|
|
mod = mod.Fields(orderTable + ".pay_type as payType")
|
|
mod = mod.Fields(orderTable + ".pay_status as payStatus")
|
|
mod = mod.Fields(orderTable + ".pay_time as payTime")
|
|
mod = mod.Fields(orderTable + ".total_amount as totalAmount")
|
|
mod = mod.Fields(orderTable + ".paid_amount as paidAmount")
|
|
mod = mod.Fields(orderTable + ".balance as balance")
|
|
|
|
// 查询ICCID
|
|
if in.Iccid != "" {
|
|
mod = mod.Where(dao.TSimCardBindPkg.Columns().Iccid, in.Iccid)
|
|
}
|
|
mod = mod.Where(dao.TSimCardBindPkg.Columns().PackageType, 103)
|
|
|
|
// 分页
|
|
mod = mod.Page(in.Page, in.PageSize)
|
|
|
|
// 排序
|
|
mod = mod.OrderDesc(dao.TSimCardBindPkg.Columns().Id)
|
|
|
|
// 操作人摘要信息
|
|
mod = mod.Hook(hook.MemberSummary)
|
|
|
|
// 查询数据
|
|
if err = mod.ScanAndCount(&list, &totalCount, false); err != nil {
|
|
err = gerror.Wrap(err, "获取订购表列表失败,请稍后重试!")
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// 变更套餐
|
|
func (s *sIotTSimCardBindPkg) GetChangePkg(ctx context.Context, in *model.TSimCardBindPkgInfoParam) (list []*model.TSimCardBindPkgListModel, totalCount int, err error) {
|
|
mod := s.Model(ctx)
|
|
bindPackage := dao.TSimCardBindPkg.Table()
|
|
packageInfo := dao.TSimFlowPackageInfo.Table()
|
|
|
|
// 构建 Join - 关联当前套餐信息(变更后)
|
|
mod = mod.LeftJoin(packageInfo+" as curr_pkg", bindPackage+"."+dao.TSimCardBindPkg.Columns().PackageCode+" = curr_pkg."+dao.TSimFlowPackageInfo.Columns().PackageCode)
|
|
// 构建 Join - 关联变更前套餐信息
|
|
mod = mod.LeftJoin(packageInfo+" as prev_pkg", bindPackage+"."+dao.TSimCardBindPkg.Columns().PreviousPackageCode+" = prev_pkg."+dao.TSimFlowPackageInfo.Columns().PackageCode)
|
|
|
|
// 字段过滤(包含主表字段 + joined 表字段)
|
|
mod = mod.FieldsPrefix(bindPackage, model.TSimCardBindPkgListModel{})
|
|
mod = mod.Fields("curr_pkg.package_name as packageName")
|
|
mod = mod.Fields("prev_pkg.package_name as previousPackageName")
|
|
|
|
// 查询ICCID
|
|
mod = mod.Where(bindPackage+"."+dao.TSimCardBindPkg.Columns().Iccid, in.Iccid)
|
|
mod = mod.Where("("+bindPackage+"."+dao.TSimCardBindPkg.Columns().BusinessType+" = ? OR "+bindPackage+"."+dao.TSimCardBindPkg.Columns().BatchNo+" LIKE ?)", consts.PackageBusinessTypeChange, "CHG%")
|
|
// 分页
|
|
mod = mod.Page(in.Page, in.PageSize)
|
|
|
|
// 排序
|
|
mod = mod.OrderDesc(dao.TSimCardBindPkg.Columns().Id)
|
|
|
|
// 操作人摘要信息
|
|
mod = mod.Hook(hook.MemberSummary)
|
|
|
|
// 查询数据
|
|
if err = mod.ScanAndCount(&list, &totalCount, false); err != nil {
|
|
err = gerror.Wrap(err, "获取订购表列表失败,请稍后重试!")
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *sIotTSimCardBindPkg) DownloadExcelTemplate(ctx context.Context) error {
|
|
return addpackage.NewCardSubmitter().DownloadTemplate(ctx)
|
|
}
|
|
|
|
func (s *sIotTSimCardBindPkg) SubmitExcel(ctx context.Context, in *model.TSimCardBindPkgAddPackageExcelSubmitParam) (*model.TSimCardBindPkgAddPackageExcelSubmitRes, error) {
|
|
if in == nil {
|
|
in = &model.TSimCardBindPkgAddPackageExcelSubmitParam{}
|
|
}
|
|
file, err := cardAddPackageUploadFile(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
paymentMode, offlineContractCompleted, err := normalizeAddPackagePaymentMode(ctx, in.PaymentMode, in.OfflineContractCompleted)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result, err := addpackage.NewCardSubmitter().SubmitExcel(ctx, file, addpackage.SubmitOptions{
|
|
PaymentMode: paymentMode,
|
|
OfflineContractCompleted: offlineContractCompleted,
|
|
ManualConfirm: in.ManualConfirm,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return cardAddPackageSubmitRes(result), nil
|
|
}
|
|
|
|
func (s *sIotTSimCardBindPkg) SubmitInput(ctx context.Context, in *model.TSimCardBindPkgAddPackageInputSubmitParam) (*model.TSimCardBindPkgAddPackageInputSubmitRes, error) {
|
|
if in == nil {
|
|
in = &model.TSimCardBindPkgAddPackageInputSubmitParam{}
|
|
}
|
|
paymentMode, offlineContractCompleted, err := normalizeAddPackagePaymentMode(ctx, in.PaymentMode, in.OfflineContractCompleted)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result, err := addpackage.NewCardSubmitter().SubmitInput(ctx, in.Input, addpackage.SubmitOptions{
|
|
PackageCode: in.PackageCode,
|
|
Remark: in.Remark,
|
|
PaymentMode: paymentMode,
|
|
OfflineContractCompleted: offlineContractCompleted,
|
|
EffectiveMode: in.EffectiveMode,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return (*model.TSimCardBindPkgAddPackageInputSubmitRes)(cardAddPackageSubmitRes(result)), nil
|
|
}
|
|
|
|
func cardAddPackageUploadFile(ctx context.Context) (*ghttp.UploadFile, error) {
|
|
r := g.RequestFromCtx(ctx)
|
|
if r == nil {
|
|
return nil, gerror.New("当前上下文不是HTTP请求")
|
|
}
|
|
file := r.GetUploadFile("file")
|
|
if file == nil {
|
|
return nil, gerror.New("请选择上传文件")
|
|
}
|
|
return file, nil
|
|
}
|
|
|
|
func cardAddPackageSubmitRes(result *addpackage.SubmitResult) *model.TSimCardBindPkgAddPackageBatchSubmitRes {
|
|
res := &model.TSimCardBindPkgAddPackageBatchSubmitRes{}
|
|
if result == nil {
|
|
return res
|
|
}
|
|
res.BatchNo = result.BatchNo
|
|
res.BatchType = result.BatchType
|
|
res.TargetBatchType = result.TargetBatchType
|
|
res.BatchAsyncStatus = result.BatchAsyncStatus
|
|
res.Total = result.Total
|
|
res.ValidCount = result.ValidCount
|
|
res.FailCount = result.FailCount
|
|
return res
|
|
}
|