// Package gen // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie // @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package iot import ( "context" "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/handler" "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" "math" "strings" "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 sIotTSimFlowPackagePrice struct{} func NewIotTSimFlowPackagePrice() *sIotTSimFlowPackagePrice { return &sIotTSimFlowPackagePrice{} } func init() { service.RegisterIotTSimFlowPackagePrice(NewIotTSimFlowPackagePrice()) } func (s *sIotTSimFlowPackagePrice) 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.TSimFlowPackagePrice.Ctx(ctx), option...) } func (s *sIotTSimFlowPackagePrice) packageCustomerPriceListModel(ctx context.Context, deptId int64) *gdb.Model { pkgTable := dao.TSimFlowPackageInfo.Table() pkgColumns := dao.TSimFlowPackageInfo.Columns() pcTable := dao.TPackageCustomer.Table() pcColumns := dao.TPackageCustomer.Columns() return handler.Model(dao.TSimFlowPackageInfo.Ctx(ctx), &handler.Option{ FilterTenant: false, FilterAuth: false, }). InnerJoin(pcTable, pkgTable+"."+pkgColumns.PackageCode+" = "+pcTable+"."+pcColumns.PackageCode+" AND "+pkgTable+"."+pkgColumns.TenantId+" = "+pcTable+"."+pcColumns.TenantId). Where(pkgTable+"."+pkgColumns.TenantId, contexts.GetTenantId(ctx)). Where(pcTable+"."+pcColumns.DeptId, deptId). Where(pcTable+"."+pcColumns.TenantId, contexts.GetTenantId(ctx)) } func (s *sIotTSimFlowPackagePrice) AgentTree(ctx context.Context, in *model.TSimFlowPackagePriceAgentTreeParam) (res *model.TSimFlowPackagePriceAgentTreeRes, err error) { items, err := service.AgentDept().SubCompany(ctx) if err != nil { err = gerror.Wrap(err, "获取渠道代理树失败,请稍后重试!") return } if items == nil { items = []*model.SysDeptTreeModel{} } res = &model.TSimFlowPackagePriceAgentTreeRes{Items: items} return } // AgentPackagePriceList 查询指定下级代理套餐生效定价 func (s *sIotTSimFlowPackagePrice) AgentPackagePriceList(ctx context.Context, in *model.TSimFlowPackagePriceAgentPackagePriceListParam) (list []*model.TSimFlowPackagePriceAgentPackagePriceListItem, totalCount int, err error) { if err = s.validateDirectChildAgent(ctx, in.TargetAgentId); err != nil { return } pkgTable := dao.TSimFlowPackageInfo.Table() pkgColumns := dao.TSimFlowPackageInfo.Columns() pcTable := dao.TPackageCustomer.Table() pcColumns := dao.TPackageCustomer.Columns() pkgMod := s.packageCustomerPriceListModel(ctx, in.TargetAgentId) if in.PackageCode != "" { pkgMod = pkgMod.WhereLike(pcTable+"."+pcColumns.PackageCode, "%"+in.PackageCode+"%") } if in.PackageName != "" { pkgMod = pkgMod.WhereLike(pkgTable+"."+pkgColumns.PackageName, "%"+in.PackageName+"%") } totalCount, err = pkgMod.Count() if err != nil { err = gerror.Wrap(err, "查询下级代理套餐定价列表失败,请稍后重试!") return } var packages []*model.TSimFlowPackagePriceAgentDefaultPackagePricePackageItem pkgMod = pkgMod.Fields( pkgTable+"."+pkgColumns.PackageCode, pkgTable+"."+pkgColumns.PackageName, pkgTable+"."+pkgColumns.CostPrice, pkgTable+"."+pkgColumns.TerminalCost, pkgTable+"."+pkgColumns.SysDefaultRatio, pkgTable+"."+pkgColumns.SysDefaultProfit, pkgTable+"."+pkgColumns.SysDefaultTerminalRatio, pkgTable+"."+pkgColumns.SysDefaultTerminalProfit, ) pkgMod = pkgMod.Page(in.Page, in.PageSize) pkgMod = pkgMod.OrderAsc(pkgTable + "." + pkgColumns.SortNo).OrderAsc(pkgTable + "." + pkgColumns.Id) if err = pkgMod.Scan(&packages); err != nil { err = gerror.Wrap(err, "查询下级代理套餐定价列表失败,请稍后重试!") return } if len(packages) == 0 { list = []*model.TSimFlowPackagePriceAgentPackagePriceListItem{} return } packageCodes := make([]string, 0, len(packages)) for _, pkg := range packages { packageCodes = append(packageCodes, pkg.PackageCode) } defaultPrices, err := s.agentDefaultPriceMap(ctx, packageCodes) if err != nil { return } targetPrices, err := s.agentTargetPriceMap(ctx, in.TargetAgentId, packageCodes) if err != nil { return } tenantID := contexts.GetTenantId(ctx) currentDeptID := contexts.GetDeptId(ctx) list = make([]*model.TSimFlowPackagePriceAgentPackagePriceListItem, 0, len(packages)) for _, pkg := range packages { baseCosts, baseErr := resolvePackageEffectiveBaseCosts(ctx, nil, tenantID, currentDeptID, packagePriceSourceFromPriceListItem(pkg)) if baseErr != nil { err = baseErr return } item := &model.TSimFlowPackagePriceAgentPackagePriceListItem{ TargetAgentId: in.TargetAgentId, PackageCode: pkg.PackageCode, PackageName: pkg.PackageName, PriceSource: "system", AgentCost: baseCosts.AgentCost, TerminalCost: baseCosts.TerminalCost, AgentCostRatio: normalizePriceRatio(pkg.SysDefaultRatio), AgentCostProfit: pkg.SysDefaultProfit, TerminalCostRatio: normalizePriceRatio(pkg.SysDefaultTerminalRatio), TerminalCostProfit: pkg.SysDefaultTerminalProfit, } if price, ok := defaultPrices[pkg.PackageCode]; ok { item.AgentDefaultPriceId = price.Id item.PriceSource = "agentDefault" item.AgentCostRatio = normalizePriceRatio(price.AgentCostRatio) item.AgentCostProfit = price.AgentCostProfit item.TerminalCostRatio = normalizePriceRatio(price.UserCostRatio) item.TerminalCostProfit = price.UserCostProfit item.Remark = price.Remark item.UpdatedAt = price.UpdatedAt } if price, ok := targetPrices[pkg.PackageCode]; ok { item.TargetPriceId = price.Id item.PriceSource = "target" item.AgentCostRatio = normalizePriceRatio(price.AgentCostRatio) item.AgentCostProfit = price.AgentCostProfit item.TerminalCostRatio = normalizePriceRatio(price.UserCostRatio) item.TerminalCostProfit = price.UserCostProfit item.Remark = price.Remark item.UpdatedAt = price.UpdatedAt } item.AgentShipmentPrice = roundAmount(item.AgentCost*item.AgentCostRatio + item.AgentCostProfit) item.TerminalSalePrice = roundAmount(item.TerminalCost*item.TerminalCostRatio + item.TerminalCostProfit) list = append(list, item) } return } // AgentDefaultPackagePriceList 查询本级默认套餐生效定价 func (s *sIotTSimFlowPackagePrice) AgentDefaultPackagePriceList(ctx context.Context, in *model.TSimFlowPackagePriceAgentDefaultPackagePriceListParam) (list []*model.TSimFlowPackagePriceAgentDefaultPackagePriceListItem, totalCount int, err error) { pkgTable := dao.TSimFlowPackageInfo.Table() pkgColumns := dao.TSimFlowPackageInfo.Columns() pcTable := dao.TPackageCustomer.Table() pcColumns := dao.TPackageCustomer.Columns() pkgMod := s.packageCustomerPriceListModel(ctx, contexts.GetDeptId(ctx)) if in.PackageCode != "" { pkgMod = pkgMod.WhereLike(pcTable+"."+pcColumns.PackageCode, "%"+in.PackageCode+"%") } if in.PackageName != "" { pkgMod = pkgMod.WhereLike(pkgTable+"."+pkgColumns.PackageName, "%"+in.PackageName+"%") } totalCount, err = pkgMod.Count() if err != nil { err = gerror.Wrap(err, "查询本级默认套餐定价列表失败,请稍后重试!") return } var packages []*model.TSimFlowPackagePriceAgentDefaultPackagePricePackageItem pkgMod = pkgMod.Fields( pkgTable+"."+pkgColumns.PackageCode, pkgTable+"."+pkgColumns.PackageName, pkgTable+"."+pkgColumns.CostPrice, pkgTable+"."+pkgColumns.TerminalCost, pkgTable+"."+pkgColumns.SysDefaultRatio, pkgTable+"."+pkgColumns.SysDefaultProfit, pkgTable+"."+pkgColumns.SysDefaultTerminalRatio, pkgTable+"."+pkgColumns.SysDefaultTerminalProfit, ) pkgMod = pkgMod.Page(in.Page, in.PageSize) pkgMod = pkgMod.OrderAsc(pkgTable + "." + pkgColumns.SortNo).OrderAsc(pkgTable + "." + pkgColumns.Id) if err = pkgMod.Scan(&packages); err != nil { err = gerror.Wrap(err, "查询本级默认套餐定价列表失败,请稍后重试!") return } if len(packages) == 0 { list = []*model.TSimFlowPackagePriceAgentDefaultPackagePriceListItem{} return } packageCodes := make([]string, 0, len(packages)) for _, pkg := range packages { packageCodes = append(packageCodes, pkg.PackageCode) } defaultPrices, err := s.agentDefaultPriceMap(ctx, packageCodes) if err != nil { return } tenantID := contexts.GetTenantId(ctx) currentDeptID := contexts.GetDeptId(ctx) list = make([]*model.TSimFlowPackagePriceAgentDefaultPackagePriceListItem, 0, len(packages)) for _, pkg := range packages { baseCosts, baseErr := resolvePackageEffectiveBaseCosts(ctx, nil, tenantID, currentDeptID, packagePriceSourceFromPriceListItem(pkg)) if baseErr != nil { err = baseErr return } item := &model.TSimFlowPackagePriceAgentDefaultPackagePriceListItem{ PackageCode: pkg.PackageCode, PackageName: pkg.PackageName, PriceSource: "system", AgentCost: baseCosts.AgentCost, TerminalCost: baseCosts.TerminalCost, AgentCostRatio: normalizePriceRatio(pkg.SysDefaultRatio), AgentCostProfit: pkg.SysDefaultProfit, TerminalCostRatio: normalizePriceRatio(pkg.SysDefaultTerminalRatio), TerminalCostProfit: pkg.SysDefaultTerminalProfit, } if price, ok := defaultPrices[pkg.PackageCode]; ok { item.AgentDefaultPriceId = price.Id item.PriceSource = "agentDefault" item.AgentCostRatio = normalizePriceRatio(price.AgentCostRatio) item.AgentCostProfit = price.AgentCostProfit item.TerminalCostRatio = normalizePriceRatio(price.UserCostRatio) item.TerminalCostProfit = price.UserCostProfit item.Remark = price.Remark item.UpdatedAt = price.UpdatedAt } item.AgentShipmentPrice = roundAmount(item.AgentCost*item.AgentCostRatio + item.AgentCostProfit) item.TerminalSalePrice = roundAmount(item.TerminalCost*item.TerminalCostRatio + item.TerminalCostProfit) list = append(list, item) } return } // SaveAgentDefaultPackagePrice 保存本级默认套餐生效定价 func (s *sIotTSimFlowPackagePrice) SaveAgentDefaultPackagePrice(ctx context.Context, in *model.TSimFlowPackagePriceAgentDefaultPackagePriceSaveParam) error { if in == nil || len(in.Items) == 0 { return gerror.New("请至少选择一个套餐") } if err := validateDefaultPriceSaveItems(in.Items); err != nil { return err } return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { for _, item := range in.Items { if err := s.validateAgentOwnsPackage(ctx, tx, contexts.GetDeptId(ctx), item.PackageCode); err != nil { return err } if err := s.validatePackageExists(ctx, tx, item.PackageCode); err != nil { return err } switch item.PriceSource { case "system": if item.AgentDefaultPriceId > 0 { return gerror.Newf("套餐%s来自系统定价,不能携带本级默认定价ID", item.PackageCode) } if err := s.ensurePriceOverrideNotExists(ctx, tx, 0, 0, item.PackageCode); err != nil { return err } if err := s.insertPriceOverride(ctx, tx, item, 0, 0); err != nil { return err } case "agentDefault": if item.AgentDefaultPriceId <= 0 { return gerror.Newf("套餐%s缺少本级默认定价ID", item.PackageCode) } if err := s.validateDefaultPriceRecordOwner(ctx, tx, item.AgentDefaultPriceId, item.PackageCode); err != nil { return err } if err := s.updatePriceOverride(ctx, tx, item.AgentDefaultPriceId, item); err != nil { return err } case "target": return gerror.Newf("本级默认保存不支持下级专属定价:%s", item.PackageCode) default: return gerror.Newf("套餐%s价格来源不合法", item.PackageCode) } } return nil }) } func (s *sIotTSimFlowPackagePrice) SaveAgentPackagePrice(ctx context.Context, in *model.TSimFlowPackagePriceAgentPackagePriceSaveParam) error { if in == nil || len(in.Items) == 0 { return gerror.New("请至少选择一个套餐") } if err := s.validateDirectChildAgent(ctx, in.TargetAgentId); err != nil { return err } if err := validateTargetPriceSaveItems(in.Items); err != nil { return err } return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { for _, item := range in.Items { if err := s.validateAgentOwnsPackage(ctx, tx, in.TargetAgentId, item.PackageCode); err != nil { return err } if err := s.validatePackageExists(ctx, tx, item.PackageCode); err != nil { return err } switch item.PriceSource { case "system", "agentDefault": if item.TargetPriceId > 0 { return gerror.Newf("套餐%s尚未存在下级专属定价,不能携带下级专属定价ID", item.PackageCode) } if err := s.ensurePriceOverrideNotExists(ctx, tx, 1, in.TargetAgentId, item.PackageCode); err != nil { return err } if err := s.insertPriceOverride(ctx, tx, targetSaveItemToDefault(item), 1, in.TargetAgentId); err != nil { return err } case "target": if item.TargetPriceId <= 0 { return gerror.Newf("套餐%s缺少下级专属定价ID", item.PackageCode) } if err := s.validateTargetPriceRecordOwner(ctx, tx, item.TargetPriceId, in.TargetAgentId, item.PackageCode); err != nil { return err } if err := s.updatePriceOverride(ctx, tx, item.TargetPriceId, targetSaveItemToDefault(item)); err != nil { return err } default: return gerror.Newf("套餐%s价格来源不合法", item.PackageCode) } } return nil }) } func (s *sIotTSimFlowPackagePrice) InheritAgentDefaultPackagePrice(ctx context.Context, in *model.TSimFlowPackagePriceAgentDefaultPackagePriceInheritParam) error { if in == nil || len(in.Items) == 0 { return gerror.New("请至少选择一个套餐") } if err := validateDefaultPriceInheritItems(in.Items); err != nil { return err } return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { for _, item := range in.Items { if err := s.validateAgentOwnsPackage(ctx, tx, contexts.GetDeptId(ctx), item.PackageCode); err != nil { return err } if err := s.validateDefaultPriceRecordOwner(ctx, tx, item.AgentDefaultPriceId, item.PackageCode); err != nil { return err } if err := s.deletePriceOverride(ctx, tx, item.AgentDefaultPriceId, 0, 0, item.PackageCode); err != nil { return err } } return nil }) } func (s *sIotTSimFlowPackagePrice) InheritAgentPackagePrice(ctx context.Context, in *model.TSimFlowPackagePriceAgentPackagePriceInheritParam) error { if in == nil || len(in.Items) == 0 { return gerror.New("请至少选择一个套餐") } if err := s.validateDirectChildAgent(ctx, in.TargetAgentId); err != nil { return err } if err := validateTargetPriceInheritItems(in.Items); err != nil { return err } return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { for _, item := range in.Items { if err := s.validateAgentOwnsPackage(ctx, tx, in.TargetAgentId, item.PackageCode); err != nil { return err } if err := s.validateTargetPriceRecordOwner(ctx, tx, item.TargetPriceId, in.TargetAgentId, item.PackageCode); err != nil { return err } if err := s.deletePriceOverride(ctx, tx, item.TargetPriceId, 1, in.TargetAgentId, item.PackageCode); err != nil { return err } } return nil }) } func (s *sIotTSimFlowPackagePrice) agentDefaultPriceMap(ctx context.Context, packageCodes []string) (map[string]*model.TSimFlowPackagePriceAgentDefaultPackagePriceRecord, error) { priceTable := dao.TSimFlowPackagePrice.Table() priceColumns := dao.TSimFlowPackagePrice.Columns() var prices []*model.TSimFlowPackagePriceAgentDefaultPackagePriceRecord if err := s.Model(ctx, &handler.Option{ FilterTenant: true, FilterAuth: false, }). Where(priceTable+"."+priceColumns.DeptId, contexts.GetDeptId(ctx)). Where(priceTable+"."+priceColumns.AgentScopeType, 0). Where(priceTable+"."+priceColumns.TargetAgentId, 0). WhereIn(priceTable+"."+priceColumns.PackageCode, packageCodes). Fields( priceTable+"."+priceColumns.Id, priceTable+"."+priceColumns.PackageCode, priceTable+"."+priceColumns.AgentCostRatio, priceTable+"."+priceColumns.AgentCostProfit, priceTable+"."+priceColumns.UserCostRatio, priceTable+"."+priceColumns.UserCostProfit, priceTable+"."+priceColumns.Remark, priceTable+"."+priceColumns.UpdatedAt, ). Scan(&prices); err != nil { return nil, gerror.Wrap(err, "查询本级默认套餐定价覆盖失败,请稍后重试!") } priceMap := make(map[string]*model.TSimFlowPackagePriceAgentDefaultPackagePriceRecord, len(prices)) for _, price := range prices { priceMap[price.PackageCode] = price } return priceMap, nil } func validateDefaultPriceSaveItems(items []*model.TSimFlowPackagePriceAgentDefaultPackagePriceSaveItem) error { packageCodes := make(map[string]struct{}, len(items)) for i, item := range items { if item == nil { return gerror.Newf("第%d行套餐定价不能为空", i+1) } item.PackageCode = strings.TrimSpace(item.PackageCode) item.PriceSource = strings.TrimSpace(item.PriceSource) if item.PackageCode == "" { return gerror.Newf("第%d行套餐编码不能为空", i+1) } if _, ok := packageCodes[item.PackageCode]; ok { return gerror.Newf("套餐%s重复,请勿在同一批保存中重复提交", item.PackageCode) } packageCodes[item.PackageCode] = struct{}{} if err := validateDefaultPackagePriceNumbers(item); err != nil { return err } if item.PriceSource == "" { return gerror.Newf("套餐%s价格来源不能为空", item.PackageCode) } switch item.PriceSource { case "system": if item.AgentDefaultPriceId > 0 { return gerror.Newf("套餐%s来自系统定价,不能携带本级默认定价ID", item.PackageCode) } case "agentDefault": if item.AgentDefaultPriceId <= 0 { return gerror.Newf("套餐%s缺少本级默认定价ID", item.PackageCode) } default: return gerror.Newf("套餐%s价格来源不合法", item.PackageCode) } } return nil } func validateTargetPriceSaveItems(items []*model.TSimFlowPackagePriceAgentPackagePriceSaveItem) error { packageCodes := make(map[string]struct{}, len(items)) for i, item := range items { if item == nil { return gerror.Newf("第%d行套餐定价不能为空", i+1) } item.PackageCode = strings.TrimSpace(item.PackageCode) item.PriceSource = strings.TrimSpace(item.PriceSource) if item.PackageCode == "" { return gerror.Newf("第%d行套餐编码不能为空", i+1) } if _, ok := packageCodes[item.PackageCode]; ok { return gerror.Newf("套餐%s重复,请勿在同一批保存中重复提交", item.PackageCode) } packageCodes[item.PackageCode] = struct{}{} if err := validateTargetPackagePriceNumbers(item); err != nil { return err } if item.PriceSource == "" { return gerror.Newf("套餐%s价格来源不能为空", item.PackageCode) } switch item.PriceSource { case "system", "agentDefault": if item.TargetPriceId > 0 { return gerror.Newf("套餐%s尚未存在下级专属定价,不能携带下级专属定价ID", item.PackageCode) } case "target": if item.TargetPriceId <= 0 { return gerror.Newf("套餐%s缺少下级专属定价ID", item.PackageCode) } default: return gerror.Newf("套餐%s价格来源不合法", item.PackageCode) } } return nil } func validateDefaultPackagePriceNumbers(item *model.TSimFlowPackagePriceAgentDefaultPackagePriceSaveItem) error { if item == nil { return nil } if err := validatePackagePriceNonNegativeNumber(item.PackageCode, "渠道系数", item.AgentCostRatio); err != nil { return err } if err := validatePackagePriceNonNegativeNumber(item.PackageCode, "渠道利润", item.AgentCostProfit); err != nil { return err } if err := validatePackagePriceNonNegativeNumber(item.PackageCode, "终端系数", item.TerminalCostRatio); err != nil { return err } if err := validatePackagePriceNonNegativeNumber(item.PackageCode, "终端用户成本利润", item.TerminalCostProfit); err != nil { return err } return nil } func validateTargetPackagePriceNumbers(item *model.TSimFlowPackagePriceAgentPackagePriceSaveItem) error { if item == nil { return nil } return validateDefaultPackagePriceNumbers(targetSaveItemToDefault(item)) } func validatePackagePriceNonNegativeNumber(packageCode, label string, value float64) error { if math.IsNaN(value) || math.IsInf(value, 0) { return gerror.Newf("套餐%s%s必须为数字", packageCode, label) } if value < 0 { return gerror.Newf("套餐%s%s不能为负数", packageCode, label) } return nil } func validateDefaultPriceInheritItems(items []*model.TSimFlowPackagePriceAgentDefaultPackagePriceInheritItem) error { packageCodes := make(map[string]struct{}, len(items)) for i, item := range items { if item == nil { return gerror.Newf("第%d行套餐承袭不能为空", i+1) } item.PackageCode = strings.TrimSpace(item.PackageCode) if item.PackageCode == "" { return gerror.Newf("第%d行套餐编码不能为空", i+1) } if item.AgentDefaultPriceId <= 0 { return gerror.Newf("套餐%s不存在本级默认定价,不能承袭", item.PackageCode) } if _, ok := packageCodes[item.PackageCode]; ok { return gerror.Newf("套餐%s重复,请勿在同一批承袭中重复提交", item.PackageCode) } packageCodes[item.PackageCode] = struct{}{} } return nil } func validateTargetPriceInheritItems(items []*model.TSimFlowPackagePriceAgentPackagePriceInheritItem) error { packageCodes := make(map[string]struct{}, len(items)) for i, item := range items { if item == nil { return gerror.Newf("第%d行套餐承袭不能为空", i+1) } item.PackageCode = strings.TrimSpace(item.PackageCode) if item.PackageCode == "" { return gerror.Newf("第%d行套餐编码不能为空", i+1) } if item.TargetPriceId <= 0 { return gerror.Newf("套餐%s不存在下级专属定价,不能承袭", item.PackageCode) } if _, ok := packageCodes[item.PackageCode]; ok { return gerror.Newf("套餐%s重复,请勿在同一批承袭中重复提交", item.PackageCode) } packageCodes[item.PackageCode] = struct{}{} } return nil } func targetSaveItemToDefault(item *model.TSimFlowPackagePriceAgentPackagePriceSaveItem) *model.TSimFlowPackagePriceAgentDefaultPackagePriceSaveItem { if item == nil { return nil } return &model.TSimFlowPackagePriceAgentDefaultPackagePriceSaveItem{ PriceSource: item.PriceSource, AgentDefaultPriceId: item.AgentDefaultPriceId, PackageCode: item.PackageCode, AgentCostRatio: item.AgentCostRatio, AgentCostProfit: item.AgentCostProfit, TerminalCostRatio: item.TerminalCostRatio, TerminalCostProfit: item.TerminalCostProfit, Remark: item.Remark, } } // validatePackageExists 校验套餐是否存在 func (s *sIotTSimFlowPackagePrice) validatePackageExists(ctx context.Context, tx gdb.TX, packageCode string) error { pkgColumns := dao.TSimFlowPackageInfo.Columns() count, err := tx.Ctx(ctx).Model(dao.TSimFlowPackageInfo.Table()). Where(pkgColumns.TenantId, contexts.GetTenantId(ctx)). Where(pkgColumns.PackageCode, packageCode). Count() if err != nil { return gerror.Wrap(err, "校验套餐失败,请稍后重试!") } if count == 0 { return gerror.Newf("套餐%s不存在", packageCode) } return nil } // validateAgentOwnsPackage 校验代理是否拥有套餐 func (s *sIotTSimFlowPackagePrice) validateAgentOwnsPackage(ctx context.Context, tx gdb.TX, deptId int64, packageCode string) error { pcColumns := dao.TPackageCustomer.Columns() count, err := tx.Ctx(ctx).Model(dao.TPackageCustomer.Table()). Where(pcColumns.TenantId, contexts.GetTenantId(ctx)). Where(pcColumns.DeptId, deptId). Where(pcColumns.PackageCode, packageCode). Count() if err != nil { return gerror.Wrap(err, "校验代理套餐归属失败,请稍后重试!") } if count == 0 { return gerror.Newf("代理没有套餐%s", packageCode) } return nil } // validateDefaultPriceRecordOwner 校验本级默认套餐定价记录是否属于当前代理 func (s *sIotTSimFlowPackagePrice) validateDefaultPriceRecordOwner(ctx context.Context, tx gdb.TX, priceId int64, packageCode string) error { price, err := s.priceRecordById(ctx, tx, priceId) if err != nil { return err } if price == nil || price.TenantId != contexts.GetTenantId(ctx) || price.DeptId != contexts.GetDeptId(ctx) || price.PackageCode != packageCode || price.AgentScopeType != 0 || price.TargetAgentId != 0 { return gerror.Newf("套餐%s本级默认定价不存在或不属于当前代理", packageCode) } return nil } // validateTargetPriceRecordOwner 校验下级专属套餐定价记录是否属于当前代理 func (s *sIotTSimFlowPackagePrice) validateTargetPriceRecordOwner(ctx context.Context, tx gdb.TX, priceId int64, targetAgentId int64, packageCode string) error { price, err := s.priceRecordById(ctx, tx, priceId) if err != nil { return err } if price == nil || price.TenantId != contexts.GetTenantId(ctx) || price.DeptId != contexts.GetDeptId(ctx) || price.TargetAgentId != targetAgentId || price.PackageCode != packageCode || price.AgentScopeType != 1 { return gerror.Newf("套餐%s下级专属定价不存在或不属于当前代理", packageCode) } return nil } // priceRecordById 查询套餐定价记录 func (s *sIotTSimFlowPackagePrice) priceRecordById(ctx context.Context, tx gdb.TX, priceId int64) (*entity.TSimFlowPackagePrice, error) { var price *entity.TSimFlowPackagePrice if err := tx.Ctx(ctx).Model(dao.TSimFlowPackagePrice.Table()). Where(dao.TSimFlowPackagePrice.Columns().Id, priceId). Scan(&price); err != nil { return nil, gerror.Wrap(err, "查询套餐定价记录失败,请稍后重试!") } return price, nil } // ensurePriceOverrideNotExists 校验套餐定价覆盖是否存在 func (s *sIotTSimFlowPackagePrice) ensurePriceOverrideNotExists(ctx context.Context, tx gdb.TX, agentScopeType int, targetAgentId int64, packageCode string) error { priceColumns := dao.TSimFlowPackagePrice.Columns() count, err := tx.Ctx(ctx).Model(dao.TSimFlowPackagePrice.Table()). Where(priceColumns.TenantId, contexts.GetTenantId(ctx)). Where(priceColumns.DeptId, contexts.GetDeptId(ctx)). Where(priceColumns.AgentScopeType, agentScopeType). Where(priceColumns.TargetAgentId, targetAgentId). Where(priceColumns.PackageCode, packageCode). Count() if err != nil { return gerror.Wrap(err, "校验套餐定价覆盖失败,请稍后重试!") } if count > 0 { return gerror.Newf("套餐%s定价覆盖已存在,请刷新列表后重试", packageCode) } return nil } // insertPriceOverride 新增套餐定价覆盖 func (s *sIotTSimFlowPackagePrice) insertPriceOverride(ctx context.Context, tx gdb.TX, item *model.TSimFlowPackagePriceAgentDefaultPackagePriceSaveItem, agentScopeType int, targetAgentId int64) error { now := gtime.Now() deptId := contexts.GetDeptId(ctx) data := do.TSimFlowPackagePrice{ PackageCode: item.PackageCode, AgentScopeType: agentScopeType, TargetAgentId: targetAgentId, DeptId: deptId, AgentCostRatio: item.AgentCostRatio, AgentCostProfit: item.AgentCostProfit, UserCostRatio: item.TerminalCostRatio, UserCostProfit: item.TerminalCostProfit, Remark: item.Remark, TenantId: contexts.GetTenantId(ctx), CreatedDept: deptId, CreatedBy: contexts.GetUserId(ctx), CreatedAt: now, UpdatedBy: contexts.GetUserId(ctx), UpdatedAt: now, } if _, err := tx.Ctx(ctx).Model(dao.TSimFlowPackagePrice.Table()).Data(data).OmitNil().Insert(); err != nil { return gerror.Wrap(err, "新增套餐定价覆盖失败,请稍后重试!") } return nil } // updatePriceOverride 更新套餐定价覆盖 func (s *sIotTSimFlowPackagePrice) updatePriceOverride(ctx context.Context, tx gdb.TX, priceId int64, item *model.TSimFlowPackagePriceAgentDefaultPackagePriceSaveItem) error { data := do.TSimFlowPackagePrice{ AgentCostRatio: item.AgentCostRatio, AgentCostProfit: item.AgentCostProfit, UserCostRatio: item.TerminalCostRatio, UserCostProfit: item.TerminalCostProfit, Remark: item.Remark, UpdatedBy: contexts.GetUserId(ctx), UpdatedAt: gtime.Now(), } if _, err := tx.Ctx(ctx).Model(dao.TSimFlowPackagePrice.Table()). Where(dao.TSimFlowPackagePrice.Columns().Id, priceId). Data(data).OmitNil().Update(); err != nil { return gerror.Wrap(err, "更新套餐定价覆盖失败,请稍后重试!") } return nil } func (s *sIotTSimFlowPackagePrice) deletePriceOverride(ctx context.Context, tx gdb.TX, priceId int64, agentScopeType int, targetAgentId int64, packageCode string) error { priceColumns := dao.TSimFlowPackagePrice.Columns() result, err := tx.Ctx(ctx).Model(dao.TSimFlowPackagePrice.Table()). Where(priceColumns.Id, priceId). Where(priceColumns.TenantId, contexts.GetTenantId(ctx)). Where(priceColumns.DeptId, contexts.GetDeptId(ctx)). Where(priceColumns.AgentScopeType, agentScopeType). Where(priceColumns.TargetAgentId, targetAgentId). Where(priceColumns.PackageCode, packageCode). Delete() if err != nil { return gerror.Wrap(err, "承袭套餐定价失败,请稍后重试!") } affected, err := result.RowsAffected() if err != nil { return gerror.Wrap(err, "确认套餐定价承袭结果失败,请稍后重试!") } if affected != 1 { return gerror.Newf("套餐%s定价已变更,请刷新后重试", packageCode) } return nil } // agentTargetPriceMap 查询下级代理专属套餐定价覆盖 func (s *sIotTSimFlowPackagePrice) agentTargetPriceMap(ctx context.Context, targetAgentId int64, packageCodes []string) (map[string]*model.TSimFlowPackagePriceAgentDefaultPackagePriceRecord, error) { priceTable := dao.TSimFlowPackagePrice.Table() priceColumns := dao.TSimFlowPackagePrice.Columns() var prices []*model.TSimFlowPackagePriceAgentDefaultPackagePriceRecord if err := s.Model(ctx, &handler.Option{ FilterTenant: true, FilterAuth: false, }). Where(priceTable+"."+priceColumns.DeptId, contexts.GetDeptId(ctx)). Where(priceTable+"."+priceColumns.AgentScopeType, 1). Where(priceTable+"."+priceColumns.TargetAgentId, targetAgentId). WhereIn(priceTable+"."+priceColumns.PackageCode, packageCodes). Fields( priceTable+"."+priceColumns.Id, priceTable+"."+priceColumns.PackageCode, priceTable+"."+priceColumns.AgentCostRatio, priceTable+"."+priceColumns.AgentCostProfit, priceTable+"."+priceColumns.UserCostRatio, priceTable+"."+priceColumns.UserCostProfit, priceTable+"."+priceColumns.Remark, priceTable+"."+priceColumns.UpdatedAt, ). Scan(&prices); err != nil { return nil, gerror.Wrap(err, "查询下级代理专属套餐定价覆盖失败,请稍后重试!") } priceMap := make(map[string]*model.TSimFlowPackagePriceAgentDefaultPackagePriceRecord, len(prices)) for _, price := range prices { priceMap[price.PackageCode] = price } return priceMap, nil } // validateDirectChildAgent 校验下级代理归属 func (s *sIotTSimFlowPackagePrice) validateDirectChildAgent(ctx context.Context, targetAgentId int64) error { if targetAgentId <= 0 { return gerror.New("请选择下级代理") } deptTable := dao.SysDept.Table() deptColumns := dao.SysDept.Columns() count, err := handler.Model(dao.SysDept.Ctx(ctx), &handler.Option{ FilterTenant: true, FilterAuth: false, }). Where(deptTable+"."+deptColumns.DeptId, targetAgentId). Where(deptTable+"."+deptColumns.ParentId, contexts.GetDeptId(ctx)). Where(deptTable+"."+deptColumns.DeptType, 1). Count() if err != nil { return gerror.Wrap(err, "校验下级代理归属失败,请稍后重试!") } if count == 0 { return gerror.New("下级代理不存在或不属于当前代理") } return nil } // normalizePriceRatio 归一化套餐定价比例 func normalizePriceRatio(ratio float64) float64 { if ratio > 10 { return ratio / 100 } return ratio }