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

871 lines
32 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"
"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
}