Files
iotlcm/server/internal/logic/iot/t_sim_flow_package_info.go
T
2026-10-29 14:36:49 +08:00

709 lines
26 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 iot
import (
"context"
"math"
"strings"
"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/exportcenter"
"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/packageduration"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/packagecustomer"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/do"
"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"
"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/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
type sIotTSimFlowPackageInfo struct{}
func NewIotTSimFlowPackageInfo() *sIotTSimFlowPackageInfo {
return &sIotTSimFlowPackageInfo{}
}
func init() {
service.RegisterIotTSimFlowPackageInfo(NewIotTSimFlowPackageInfo())
}
func (s *sIotTSimFlowPackageInfo) 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.TSimFlowPackageInfo.Ctx(ctx), option...)
}
func (s *sIotTSimFlowPackageInfo) packageListModel(ctx context.Context) (*gdb.Model, error) {
mainTable := dao.TSimFlowPackageInfo.Table()
pcTable := dao.TPackageCustomer.Table()
pcColumns := dao.TPackageCustomer.Columns()
mod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false})
isTop, _, err := service.AgentDept().IsTopDept(ctx)
if err != nil {
return nil, err
}
if isTop {
return mod, nil
}
return mod.
InnerJoin(pcTable, pcTable+"."+pcColumns.PackageCode+" = "+mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageCode).
Where(pcTable+"."+pcColumns.DeptId, contexts.GetDeptId(ctx)).
Where(pcTable+"."+pcColumns.TenantId, contexts.GetTenantId(ctx)), nil
}
func (s *sIotTSimFlowPackageInfo) applyListFilter(mod *gdb.Model, mainTable string, in *model.TSimFlowPackageInfoListParam) *gdb.Model {
if in.PackageCode != "" {
mod = mod.WhereLike(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageCode, "%"+in.PackageCode+"%")
}
if in.CategoryCode != "" {
mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().CategoryCode, in.CategoryCode)
}
if in.PackageType != "" {
mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageType, in.PackageType)
}
if in.PackageName != "" {
mod = mod.WhereLike(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageName, "%"+in.PackageName+"%")
}
if in.Enabled != nil {
mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().Enabled, *in.Enabled)
}
if len(in.CreatedAt) == 2 {
mod = mod.WhereBetween(mainTable+"."+dao.TSimFlowPackageInfo.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1].EndOfDay())
}
return mod
}
func (s *sIotTSimFlowPackageInfo) buildPackageCustomer(ctx context.Context, dept *entity.SysDept, packageCode, packageName string, now *gtime.Time) do.TPackageCustomer {
userId := contexts.GetUserId(ctx)
return do.TPackageCustomer{
PackageCode: packageCode,
PackageName: packageName,
DeptId: dept.DeptId,
DeptName: dept.DeptName,
TenantId: contexts.GetTenantId(ctx),
CreatedDept: contexts.GetDeptId(ctx),
CreatedBy: userId,
CreatedAt: now,
UpdatedBy: userId,
UpdatedAt: now,
}
}
func (s *sIotTSimFlowPackageInfo) List(ctx context.Context, in *model.TSimFlowPackageInfoListParam) (list []*model.TSimFlowPackageInfoListModel, totalCount int, err error) {
mainTable := dao.TSimFlowPackageInfo.Table()
catTable := dao.TSimPackageCategory.Table()
countBaseMod, err := s.packageListModel(ctx)
if err != nil {
return nil, 0, err
}
countMod := s.applyListFilter(countBaseMod, mainTable, in)
totalCount, err = countMod.Count()
if err != nil {
err = gerror.Wrap(err, "获取SIM流量套餐管理列表失败,请稍后重试")
return
}
mod, err := s.packageListModel(ctx)
if err != nil {
return nil, 0, err
}
mod = mod.LeftJoin(catTable, mainTable+"."+dao.TSimFlowPackageInfo.Columns().CategoryCode+" = "+catTable+"."+dao.TSimPackageCategory.Columns().CategoryCode)
mod = s.applyListFilter(mod, mainTable, in)
mod = mod.FieldsPrefix(mainTable, model.TSimFlowPackageInfoListModel{})
mod = mod.Fields(catTable + "." + dao.TSimPackageCategory.Columns().CategoryName + " as categoryName")
mod = mod.Page(in.Page, in.PageSize)
mod = mod.OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().SortNo)
mod = mod.Hook(hook.MemberSummary)
if err = mod.Scan(&list); err != nil {
err = gerror.Wrap(err, "获取SIM流量套餐管理列表失败,请稍后重试")
return
}
if err = s.fillPackageListPrices(ctx, list); err != nil {
return nil, 0, err
}
normalizePackageListRows(list)
return
}
// 可配置池列表(PackageType=102)
func (s *sIotTSimFlowPackageInfo) FlowPackageList(ctx context.Context, in *model.TSimFlowPackageInfoFlowPackageListParam) (list []*model.TSimFlowPackageInfoListModel, err error) {
mainTable := dao.TSimFlowPackageInfo.Table()
mod := dao.TSimFlowPackageInfo.Ctx(ctx)
// 该接口只供流量池套餐配置弹窗使用,返回套餐编码和名称即可。
// pool_package_code 是字符串编码,旧列表模型仍为整数类型,这里不查询该字段,
// 避免编辑已有池配置时发生字符串转整数的扫描错误。
mod = mod.Fields(
mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageCode,
mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageName,
mainTable+"."+dao.TSimFlowPackageInfo.Columns().SortNo,
)
currentPoolPackageCode := ""
if in != nil {
currentPoolPackageCode = strings.TrimSpace(in.PoolPackageCode)
}
mod = applyPoolFlowPackageBaseFilter(mod, mainTable, currentPoolPackageCode)
// 根据流量套餐过滤(格式:100.000,102400.000,前边是GB后边是MB)
if in != nil && in.Flow != "" {
flow := strings.Trim(in.Flow, "\"")
parts := strings.Split(flow, ",")
if len(parts) == 2 {
flowGb := strings.TrimSpace(parts[0])
flowMb := strings.TrimSpace(parts[1])
if flowGb == "" {
mod = mod.Where(mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowGb + " IS NULL")
} else {
mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().FlowGb+" = ?", flowGb)
}
mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().FlowMb+" = ?", flowMb)
}
}
mod = mod.OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().SortNo)
mod = mod.Hook(hook.MemberSummary)
if err = mod.Scan(&list); err != nil {
err = gerror.Wrap(err, "获取SIM流量套餐管理列表失败,请稍后重试")
return
}
normalizePackageListRows(list)
return
}
// 可配置池加油包列表(PackageType=104)
func (s *sIotTSimFlowPackageInfo) FlowPackageAddList(ctx context.Context) (list []*model.TSimFlowPackageInfoListModel, err error) {
mainTable := dao.TSimFlowPackageInfo.Table()
mod := dao.TSimFlowPackageInfo.Ctx(ctx)
// 弹窗只使用套餐编码和名称,不查询字符串类型的池编码字段。
mod = mod.Fields(
mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageCode,
mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageName,
mainTable+"."+dao.TSimFlowPackageInfo.Columns().SortNo,
)
mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageType, "104")
mod = mod.OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().SortNo)
mod = mod.Hook(hook.MemberSummary)
if err = mod.Scan(&list); err != nil {
err = gerror.Wrap(err, "获取SIM流量套餐管理列表失败,请稍后重试")
return
}
normalizePackageListRows(list)
return
}
// GetFlowPackageOptions 获取流量套餐GB+MB组合选项
func (s *sIotTSimFlowPackageInfo) RenewablePackageOptions(ctx context.Context, in *model.TSimFlowPackageInfoRenewablePackageOptionsParam) (list []*model.TSimFlowPackageInfoListModel, err error) {
if in == nil {
in = &model.TSimFlowPackageInfoRenewablePackageOptionsParam{}
}
mainTable := dao.TSimFlowPackageInfo.Table()
columns := dao.TSimFlowPackageInfo.Columns()
mod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}).
Fields(model.TSimFlowPackageInfoListModel{}).
Where(mainTable+"."+columns.Enabled, 1)
if packageType := strings.TrimSpace(in.PackageType); packageType != "" {
mod = mod.Where(mainTable+"."+columns.PackageType, packageType)
}
if packageCode := strings.TrimSpace(in.ExcludePackageCode); packageCode != "" {
mod = mod.WhereNot(mainTable+"."+columns.PackageCode, packageCode)
}
mod = mod.OrderAsc(mainTable + "." + columns.SortNo)
if err = mod.Scan(&list); err != nil {
return nil, gerror.Wrap(err, "获取可续费套餐候选列表失败,请稍后重试")
}
normalizePackageListRows(list)
return list, nil
}
func (s *sIotTSimFlowPackageInfo) GetFlowPackageOptions(ctx context.Context, in *model.TSimFlowPackageInfoFlowPackageOptionsParam) ([]string, error) {
var results []string
mainTable := dao.TSimFlowPackageInfo.Table()
currentPoolPackageCode := ""
if in != nil {
currentPoolPackageCode = strings.TrimSpace(in.PoolPackageCode)
}
var rows []*struct {
FlowGb string
FlowMb string
}
g.Log().Info(ctx, "获取流量套餐选项")
mod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}).
Fields(mainTable+"."+dao.TSimFlowPackageInfo.Columns().FlowGb, mainTable+"."+dao.TSimFlowPackageInfo.Columns().FlowMb).
Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageType, "102").
Distinct().
Where("(" + mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowGb + " <> '' OR " + mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowMb + " <> '')").
OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowGb).
OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowMb)
if currentPoolPackageCode == "" {
mod = mod.Where("(" + mainTable + "." + dao.TSimFlowPackageInfo.Columns().PoolPackageCode + " IS NULL OR " + mainTable + "." + dao.TSimFlowPackageInfo.Columns().PoolPackageCode + " = '')")
} else {
mod = mod.Where("("+mainTable+"."+dao.TSimFlowPackageInfo.Columns().PoolPackageCode+" IS NULL OR "+mainTable+"."+dao.TSimFlowPackageInfo.Columns().PoolPackageCode+" = '' OR "+mainTable+"."+dao.TSimFlowPackageInfo.Columns().PoolPackageCode+" = ?)", currentPoolPackageCode)
}
if err := mod.Scan(&rows); err != nil {
return nil, gerror.Wrap(err, "获取流量套餐选项失败")
}
for _, row := range rows {
results = append(results, row.FlowGb+","+row.FlowMb)
}
return results, nil
}
func normalizePackageListRows(list []*model.TSimFlowPackageInfoListModel) {
for _, item := range list {
if item == nil {
continue
}
if item.RenewableDurationConfig == nil {
continue
}
if normalized, normalizeErr := packageduration.NormalizeRenewableDurationConfig(item.RenewableDurationConfig); normalizeErr == nil {
item.RenewableDurationConfig = normalized
}
}
}
func (s *sIotTSimFlowPackageInfo) fillPackageListPrices(ctx context.Context, list []*model.TSimFlowPackageInfoListModel) error {
if len(list) == 0 {
return nil
}
tenantID := contexts.GetTenantId(ctx)
currentDeptID := contexts.GetDeptId(ctx)
ownerDeptID, err := loadPackagePriceParentDeptID(ctx, nil, tenantID, currentDeptID)
if err != nil {
return gerror.Wrap(err, "get package price owner department failed")
}
for _, item := range list {
if item == nil {
continue
}
salePrice, err := resolvePackageEffectiveSalePrice(
ctx,
nil,
tenantID,
ownerDeptID,
currentDeptID,
packagePriceSourceFromListModel(item),
)
if err != nil {
return gerror.Wrapf(err, "calculate effective price for package %s failed", item.PackageCode)
}
item.AgentShipmentPrice = salePrice.AgentShipmentPrice
item.TerminalSalePrice = salePrice.TerminalSalePrice
}
return nil
}
func packagePriceSourceFromListModel(pkg *model.TSimFlowPackageInfoListModel) packagePriceSource {
if pkg == nil {
return packagePriceSource{}
}
return packagePriceSource{
PackageCode: strings.TrimSpace(pkg.PackageCode),
CostPrice: pkg.CostPrice,
TerminalCost: pkg.TerminalCost,
SysDefaultRatio: pkg.SysDefaultRatio,
SysDefaultProfit: pkg.SysDefaultProfit,
SysDefaultTerminalRatio: pkg.SysDefaultTerminalRatio,
SysDefaultTerminalProfit: pkg.SysDefaultTerminalProfit,
}
}
func applyPoolFlowPackageBaseFilter(mod *gdb.Model, mainTable, currentPoolPackageCode string) *gdb.Model {
columns := dao.TSimFlowPackageInfo.Columns()
poolPackageColumn := mainTable + "." + columns.PoolPackageCode
if currentPoolPackageCode == "" {
return mod.
Where("("+poolPackageColumn+" IS NULL OR "+poolPackageColumn+" = '')").
Where(mainTable+"."+columns.PackageType, "102")
}
return mod.
Where("("+poolPackageColumn+" IS NULL OR "+poolPackageColumn+" = '' OR "+poolPackageColumn+" = ?)", currentPoolPackageCode).
Where(mainTable+"."+columns.PackageType, "102")
}
// Export 导出SIM流量套餐(异步:提交任务后到下载中心取文件)
func (s *sIotTSimFlowPackageInfo) Export(ctx context.Context, in *model.TSimFlowPackageInfoListParam) (err error) {
_, err = exportcenter.Submit(ctx, &exportcenter.Request{
BizKey: "tSimFlowPackageInfo",
BizName: "SIM流量套餐",
PermCode: "cpm:iot:tSimFlowPackageInfo:export",
QueryParam: in,
Tags: func() ([]string, error) {
return convert.GetEntityDescTags(model.TSimFlowPackageInfoListModel{})
},
Fetch: func(ctx context.Context, page, pageSize int) (rows []interface{}, total int, err error) {
query := *in
query.Page = page
query.PageSize = pageSize
list, count, err := s.List(ctx, &query)
if err != nil {
return nil, 0, err
}
rows = make([]interface{}, 0, len(list))
for _, item := range list {
rows = append(rows, item)
}
return rows, count, nil
},
})
return err
}
func (s *sIotTSimFlowPackageInfo) Edit(ctx context.Context, in *model.TSimFlowPackageInfoEditParam) (err error) {
if in == nil {
return gerror.New("package information cannot be empty")
}
if err = validateFlowMb(in); err != nil {
return err
}
if in.BillingMethod == nil || strings.TrimSpace(*in.BillingMethod) == "" {
billingMethod := packageduration.MonthBillingMethodValue()
in.BillingMethod = &billingMethod
}
if in.RenewableDurationConfig != nil {
in.RenewableDurationConfig, err = packageduration.NormalizeRenewableDurationConfig(in.RenewableDurationConfig)
if err != nil {
return err
}
}
packageCode := gconv.String(in.PackageCode)
normalizeFlowPackageRenewableCodes(in, packageCode)
if packageCode != "" {
uniqueMod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}).
Where(dao.TSimFlowPackageInfo.Columns().PackageCode, packageCode)
if in.Id > 0 {
uniqueMod = uniqueMod.WhereNot(dao.TSimFlowPackageInfo.Columns().Id, in.Id)
}
count, countErr := uniqueMod.Count()
if countErr != nil {
return countErr
}
if count > 0 {
return gerror.New("套餐编码已存在")
}
}
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
now := gtime.Now()
userId := contexts.GetUserId(ctx)
if in.Id > 0 {
var oldPackage entity.TSimFlowPackageInfo
if err = s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}).WherePri(in.Id).Scan(&oldPackage); err != nil {
return gerror.Wrap(err, "获取套餐信息失败,请稍后重试")
}
if oldPackage.Id == 0 {
return gerror.New("套餐不存在")
}
in.UpdatedBy = &userId
in.UpdatedAt = now
if _, err = tx.Ctx(ctx).Model(dao.TSimFlowPackageInfo.Table()).
Fields(model.TSimFlowPackageInfoUpdateFields{}).
WherePri(in.Id).
Where(dao.TSimFlowPackageInfo.Columns().TenantId, contexts.GetTenantId(ctx)).
Data(in).Update(); err != nil {
return gerror.Wrap(err, "修改SIM流量套餐管理失败,请稍后重试")
}
newPackageCode := oldPackage.PackageCode
if in.PackageCode != nil {
newPackageCode = *in.PackageCode
}
newPackageName := oldPackage.PackageName
if in.PackageName != nil {
newPackageName = *in.PackageName
}
if newPackageCode != oldPackage.PackageCode || newPackageName != oldPackage.PackageName {
updateCustomer := do.TPackageCustomer{
PackageCode: newPackageCode,
PackageName: newPackageName,
UpdatedBy: userId,
UpdatedAt: now,
}
if _, err = tx.Ctx(ctx).Model(dao.TPackageCustomer.Table()).
Where(dao.TPackageCustomer.Columns().TenantId, contexts.GetTenantId(ctx)).
Where(dao.TPackageCustomer.Columns().PackageCode, oldPackage.PackageCode).
Data(updateCustomer).Update(); err != nil {
return gerror.Wrap(err, "同步套餐客户关联失败,请稍后重试")
}
}
return nil
}
// 新增套餐
tenantId := contexts.GetTenantId(ctx)
in.TenantId = &tenantId
createdDept := contexts.GetDeptId(ctx)
in.CreatedDept = &createdDept
in.CreatedBy = &userId
in.CreatedAt = now
if _, err = tx.Ctx(ctx).Model(dao.TSimFlowPackageInfo.Table()).
Fields(model.TSimFlowPackageInfoInsertFields{}).
Data(in).Insert(); err != nil {
return gerror.Wrap(err, "新增SIM流量套餐管理失败,请稍后重试")
}
_, dept, err := service.AgentDept().IsTopDept(ctx)
if err != nil {
return err
}
packageName := gconv.String(in.PackageName)
customer := s.buildPackageCustomer(ctx, dept, packageCode, packageName, now)
if _, err = tx.Ctx(ctx).Model(dao.TPackageCustomer.Table()).Data(customer).Insert(); err != nil {
return gerror.Wrap(err, "新增套餐客户关联失败,请稍后重试")
}
return nil
})
}
func validateFlowMb(in *model.TSimFlowPackageInfoEditParam) error {
if in == nil {
return gerror.New("package information cannot be empty")
}
if in.Id <= 0 && in.FlowMb == nil {
return gerror.New("套餐流量(MB)不能为空")
}
if in.FlowMb != nil && (*in.FlowMb <= 0 || math.IsNaN(*in.FlowMb) || math.IsInf(*in.FlowMb, 0)) {
return gerror.New("套餐流量(MB)必须大于0")
}
return nil
}
func normalizeFlowPackageRenewableCodes(in *model.TSimFlowPackageInfoEditParam, packageCode string) {
if in == nil || in.RenewablePackageCodes == nil {
return
}
codes := make([]string, 0)
_ = in.RenewablePackageCodes.Scan(&codes)
in.RenewablePackageCodes = gjson.New(uniquePackageCodes(codes))
}
func uniquePackageCodes(codes []string) []string {
result := make([]string, 0, len(codes))
seen := make(map[string]struct{}, len(codes))
for _, code := range codes {
code = strings.TrimSpace(code)
if code == "" {
continue
}
if _, ok := seen[code]; ok {
continue
}
seen[code] = struct{}{}
result = append(result, code)
}
return result
}
func (s *sIotTSimFlowPackageInfo) Delete(ctx context.Context, in *model.TSimFlowPackageInfoDeleteParam) (err error) {
var packageInfo entity.TSimFlowPackageInfo
if err = s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}).WherePri(in.Id).Scan(&packageInfo); err != nil {
return gerror.Wrap(err, "获取套餐信息失败,请稍后重试")
}
if packageInfo.Id == 0 {
return gerror.New("套餐不存在")
}
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
if _, err = tx.Ctx(ctx).Model(dao.TSimFlowPackageInfo.Table()).
WherePri(in.Id).
Where(dao.TSimFlowPackageInfo.Columns().TenantId, contexts.GetTenantId(ctx)).
Unscoped().Delete(); err != nil {
return gerror.Wrap(err, "删除SIM流量套餐管理失败,请稍后重试")
}
if _, err = tx.Ctx(ctx).Model(dao.TPackageCustomer.Table()).
Where(dao.TPackageCustomer.Columns().TenantId, contexts.GetTenantId(ctx)).
Where(dao.TPackageCustomer.Columns().PackageCode, packageInfo.PackageCode).
Delete(); err != nil {
return gerror.Wrap(err, "清理套餐客户关联失败,请稍后重试")
}
return nil
})
}
func (s *sIotTSimFlowPackageInfo) View(ctx context.Context, in *model.TSimFlowPackageInfoViewParam) (res *model.TSimFlowPackageInfoViewModel, err error) {
mainTable := dao.TSimFlowPackageInfo.Table()
catTable := dao.TSimPackageCategory.Table()
mod, err := s.packageListModel(ctx)
if err != nil {
return nil, err
}
mod = mod.LeftJoin(catTable, mainTable+"."+dao.TSimFlowPackageInfo.Columns().CategoryCode+" = "+catTable+"."+dao.TSimPackageCategory.Columns().CategoryCode)
mod = mod.Fields(
mainTable+".*",
catTable+"."+dao.TSimPackageCategory.Columns().CategoryName+" as categoryName",
)
if err = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().Id, in.Id).Hook(hook.MemberSummary).Scan(&res); err != nil {
return nil, gerror.Wrap(err, "获取SIM流量套餐管理信息失败,请稍后重试")
}
if res == nil || res.Id == 0 {
return nil, gerror.New("套餐不存在或无权限")
}
if res.RenewableDurationConfig != nil {
if normalized, normalizeErr := packageduration.NormalizeRenewableDurationConfig(res.RenewableDurationConfig); normalizeErr == nil {
res.RenewableDurationConfig = normalized
}
}
if err = s.fillPackageRelationNames(ctx, res); err != nil {
return nil, err
}
return
}
func (s *sIotTSimFlowPackageInfo) fillPackageRelationNames(ctx context.Context, res *model.TSimFlowPackageInfoViewModel) error {
if res == nil {
return nil
}
renewableCodes := packageCodesFromJSON(res.RenewablePackageCodes)
changeableCodes := packageCodesFromJSON(res.ChangeablePackageCodes)
topupCodes := packageCodesFromJSON(res.TopupPackageCodes)
allCodes := uniquePackageCodes(append(append(renewableCodes, changeableCodes...), topupCodes...))
if len(allCodes) == 0 {
return nil
}
nameMap, err := s.packageNamesByCode(ctx, res.TenantId, allCodes)
if err != nil {
return err
}
res.RenewablePackageNames = gjson.New(packageNamesForCodes(renewableCodes, nameMap))
res.ChangeablePackageNames = gjson.New(packageNamesForCodes(changeableCodes, nameMap))
res.TopupPackageNames = gjson.New(packageNamesForCodes(topupCodes, nameMap))
return nil
}
func packageCodesFromJSON(value *gjson.Json) []string {
if value == nil {
return nil
}
var codes []string
_ = value.Scan(&codes)
return uniquePackageCodes(codes)
}
func (s *sIotTSimFlowPackageInfo) packageNamesByCode(ctx context.Context, tenantId string, codes []string) (map[string]string, error) {
result := make(map[string]string, len(codes))
if len(codes) == 0 {
return result, nil
}
columns := dao.TSimFlowPackageInfo.Columns()
var packages []struct {
PackageCode string `orm:"package_code"`
PackageName string `orm:"package_name"`
}
mod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}).
Fields(columns.PackageCode, columns.PackageName).
WhereIn(columns.PackageCode, codes)
if tenantId != "" {
mod = mod.Where(columns.TenantId, tenantId)
}
if err := mod.Scan(&packages); err != nil {
return nil, gerror.Wrap(err, "查询套餐名称失败")
}
for _, pkg := range packages {
code := strings.TrimSpace(pkg.PackageCode)
name := strings.TrimSpace(pkg.PackageName)
if code == "" || name == "" {
continue
}
result[code] = name
}
return result, nil
}
func packageNamesForCodes(codes []string, nameMap map[string]string) []string {
names := make([]string, 0, len(codes))
for _, code := range codes {
if name := strings.TrimSpace(nameMap[code]); name != "" {
names = append(names, name)
}
}
return names
}
// GetPoolPackagesByCardPackages 根据卡套餐编码列表获取对应的池套餐编码列表
func (s *sIotTSimFlowPackageInfo) GetPoolPackagesByCardPackages(ctx context.Context, cardPackageCodes []string) (poolPackageMap102 map[string]int64, poolPackageMap104 map[string]int64, err error) {
poolPackageMap102 = make(map[string]int64)
poolPackageMap104 = make(map[string]int64)
if len(cardPackageCodes) == 0 {
return
}
g.Log().Info(ctx, "GetPoolPackagesByCardPackages cardPackageCodes:", cardPackageCodes) //这些不存在 104
mod := s.Model(ctx)
mod = mod.Where(dao.TSimFlowPackageInfo.Columns().PackageCode+" IN (?)", cardPackageCodes)
// 查询 102 池套餐
mod102 := mod.Where(dao.TSimFlowPackageInfo.Columns().PackageType, 102)
var packages102 []*model.TSimFlowPackageInfoListModel
var poolPackageCodes []int64
if err = mod102.Scan(&packages102); err != nil {
return nil, nil, gerror.Wrap(err, "获取102池套餐列表失败,请稍后重试!")
}
g.Log().Info(ctx, "获取102池套餐列表:%v", packages102)
for _, pkg := range packages102 {
poolPackageMap102[pkg.PackageCode] = pkg.PoolPackageCode
poolPackageCodes = append(poolPackageCodes, pkg.PoolPackageCode)
}
// 查询 104 池套餐
mod104 := s.Model(ctx).Where(dao.TSimFlowPackageInfo.Columns().PackageType, 104).Where(dao.TSimFlowPackageInfo.Columns().PoolPackageCode+" IN (?)", poolPackageCodes)
var packages104 []*model.TSimFlowPackageInfoListModel
if err = mod104.Scan(&packages104); err != nil {
return nil, nil, gerror.Wrap(err, "获取104池套餐列表失败,请稍后重试!")
}
g.Log().Info(ctx, "GetPoolPackagesByCardPackages packages104:", packages104)
for _, pkg := range packages104 {
poolPackageMap104[pkg.PackageCode] = pkg.PoolPackageCode
}
g.Log().Info(ctx, "GetPoolPackagesByCardPackages poolPackageMap102:", poolPackageMap102)
g.Log().Info(ctx, "GetPoolPackagesByCardPackages poolPackageMap104:", poolPackageMap104)
return poolPackageMap102, poolPackageMap104, nil
}
func (s *sIotTSimFlowPackageInfo) SyncDeptPackages(ctx context.Context) (err error) {
_, dept, err := service.AgentDept().IsTopDept(ctx)
if err != nil {
return
}
return packagecustomer.PublishSync(ctx, model.PackageCustomerSyncMessage{
TenantId: contexts.GetTenantId(ctx),
DeptId: dept.DeptId,
UserId: contexts.GetUserId(ctx),
Trigger: "manual_sync",
})
}
func (s *sIotTSimFlowPackageInfo) SyncDeptPackagesByDept(ctx context.Context, tenantId string, deptId int64, userId int64) error {
return packagecustomer.SyncDeptPackagesByDept(ctx, tenantId, deptId, userId)
}