Files
waf-platform/EdgeAPI/internal/rpc/services/service_plan_plus.go
2026-02-04 20:27:13 +08:00

319 lines
11 KiB
Go

// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build plus
package services
import (
"context"
"encoding/json"
"errors"
"fmt"
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
"github.com/iwind/TeaGo/types"
)
// PlanService 套餐相关服务
type PlanService struct {
BaseService
}
// CreatePlan 创建套餐
func (this *PlanService) CreatePlan(ctx context.Context, req *pb.CreatePlanRequest) (*pb.CreatePlanResponse, error) {
if !teaconst.IsPlus {
return nil, this.NotImplementedYet()
}
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
// check features
if len(req.FeaturesJSON) > 0 {
var featureCodes = []string{}
err = json.Unmarshal(req.FeaturesJSON, &featureCodes)
if err != nil {
return nil, fmt.Errorf("decode features failed: %w", err)
}
for _, featureCode := range featureCodes {
if !userconfigs.CheckUserFeature(featureCode) {
return nil, errors.New("wrong feature code '" + featureCode + "'")
}
}
}
var tx = this.NullTx()
planId, err := models.SharedPlanDAO.CreatePlan(tx, req.Name, req.Description, req.ClusterId, req.TrafficLimitJSON, req.BandwidthLimitPerNodeJSON, req.HasFullFeatures, req.FeaturesJSON, req.PriceType, req.TrafficPriceJSON, req.BandwidthPriceJSON, req.MonthlyPrice, req.SeasonallyPrice, req.YearlyPrice, req.TotalServers, req.TotalServerNames, req.TotalServerNamesPerServer, req.DailyRequests, req.MonthlyRequests, req.DailyWebsocketConnections, req.MonthlyWebsocketConnections, req.MaxUploadSizeJSON)
if err != nil {
return nil, err
}
return &pb.CreatePlanResponse{PlanId: planId}, nil
}
// UpdatePlan 修改套餐
func (this *PlanService) UpdatePlan(ctx context.Context, req *pb.UpdatePlanRequest) (*pb.RPCSuccess, error) {
if !teaconst.IsPlus {
return nil, this.NotImplementedYet()
}
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
// check features
if len(req.FeaturesJSON) > 0 {
var featureCodes = []string{}
err = json.Unmarshal(req.FeaturesJSON, &featureCodes)
if err != nil {
return nil, fmt.Errorf("decode features failed: %w", err)
}
for _, featureCode := range featureCodes {
if !userconfigs.CheckUserFeature(featureCode) {
return nil, errors.New("wrong feature code '" + featureCode + "'")
}
}
}
var tx = this.NullTx()
err = models.SharedPlanDAO.UpdatePlan(tx, req.PlanId, req.Name, req.Description, req.IsOn, req.ClusterId, req.TrafficLimitJSON, req.BandwidthLimitPerNodeJSON, req.HasFullFeatures, req.FeaturesJSON, req.PriceType, req.TrafficPriceJSON, req.BandwidthPriceJSON, req.MonthlyPrice, req.SeasonallyPrice, req.YearlyPrice, req.TotalServers, req.TotalServerNames, req.TotalServerNamesPerServer, req.DailyRequests, req.MonthlyRequests, req.DailyWebsocketConnections, req.MonthlyWebsocketConnections, req.MaxUploadSizeJSON)
if err != nil {
return nil, err
}
return this.Success()
}
// DeletePlan 删除套餐
func (this *PlanService) DeletePlan(ctx context.Context, req *pb.DeletePlanRequest) (*pb.RPCSuccess, error) {
if !teaconst.IsPlus {
return nil, this.NotImplementedYet()
}
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = models.SharedPlanDAO.DisablePlan(tx, req.PlanId)
if err != nil {
return nil, err
}
return this.Success()
}
// FindEnabledPlan 查找单个套餐
func (this *PlanService) FindEnabledPlan(ctx context.Context, req *pb.FindEnabledPlanRequest) (*pb.FindEnabledPlanResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
plan, err := models.SharedPlanDAO.FindEnabledPlan(tx, req.PlanId, nil)
if err != nil {
return nil, err
}
if plan == nil {
return &pb.FindEnabledPlanResponse{Plan: nil}, nil
}
return &pb.FindEnabledPlanResponse{
Plan: &pb.Plan{
Id: int64(plan.Id),
IsOn: plan.IsOn,
Name: plan.Name,
Description: plan.Description,
ClusterId: int64(plan.ClusterId),
TrafficLimitJSON: plan.TrafficLimit,
BandwidthLimitPerNodeJSON: plan.BandwidthLimitPerNode,
HasFullFeatures: plan.HasFullFeatures,
FeaturesJSON: plan.Features,
PriceType: plan.PriceType,
TrafficPriceJSON: plan.TrafficPrice,
BandwidthPriceJSON: plan.BandwidthPrice,
MonthlyPrice: plan.MonthlyPrice,
SeasonallyPrice: plan.SeasonallyPrice,
YearlyPrice: plan.YearlyPrice,
TotalServers: types.Int32(plan.TotalServers),
TotalServerNames: types.Int32(plan.TotalServerNames),
TotalServerNamesPerServer: types.Int32(plan.TotalServerNamesPerServer),
DailyRequests: int64(plan.DailyRequests),
MonthlyRequests: int64(plan.MonthlyRequests),
DailyWebsocketConnections: int64(plan.DailyWebsocketConnections),
MonthlyWebsocketConnections: int64(plan.MonthlyWebsocketConnections),
MaxUploadSizeJSON: plan.MaxUploadSize,
},
}, nil
}
// FindBasicPlan 查找套餐基本信息
func (this *PlanService) FindBasicPlan(ctx context.Context, req *pb.FindBasicPlanRequest) (*pb.FindBasicPlanResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
plan, err := models.SharedPlanDAO.FindBasicPlan(tx, req.PlanId)
if err != nil {
return nil, err
}
if plan == nil {
return &pb.FindBasicPlanResponse{Plan: nil}, nil
}
return &pb.FindBasicPlanResponse{
Plan: &pb.Plan{
Id: int64(plan.Id),
Name: plan.Name,
IsOn: plan.IsOn,
},
}, nil
}
// CountAllEnabledPlans 计算套餐数量
func (this *PlanService) CountAllEnabledPlans(ctx context.Context, req *pb.CountAllEnabledPlansRequest) (*pb.RPCCountResponse, error) {
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
count, err := models.SharedPlanDAO.CountAllEnabledPlans(tx)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}
// ListEnabledPlans 列出单页套餐
func (this *PlanService) ListEnabledPlans(ctx context.Context, req *pb.ListEnabledPlansRequest) (*pb.ListEnabledPlansResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, false)
if err != nil {
return nil, err
}
var tx = this.NullTx()
plans, err := models.SharedPlanDAO.ListEnabledPlans(tx, req.Offset, req.Size)
if err != nil {
return nil, err
}
var pbPlans = []*pb.Plan{}
for _, plan := range plans {
pbPlans = append(pbPlans, &pb.Plan{
Id: int64(plan.Id),
IsOn: plan.IsOn,
Name: plan.Name,
Description: plan.Description,
ClusterId: int64(plan.ClusterId),
TrafficLimitJSON: plan.TrafficLimit,
BandwidthLimitPerNodeJSON: plan.BandwidthLimitPerNode,
HasFullFeatures: plan.HasFullFeatures,
FeaturesJSON: plan.Features,
PriceType: plan.PriceType,
TrafficPriceJSON: plan.TrafficPrice,
BandwidthPriceJSON: plan.BandwidthPrice,
MonthlyPrice: plan.MonthlyPrice,
SeasonallyPrice: plan.SeasonallyPrice,
YearlyPrice: plan.YearlyPrice,
TotalServers: types.Int32(plan.TotalServers),
TotalServerNames: types.Int32(plan.TotalServerNames),
TotalServerNamesPerServer: types.Int32(plan.TotalServerNamesPerServer),
DailyRequests: int64(plan.DailyRequests),
MonthlyRequests: int64(plan.MonthlyRequests),
DailyWebsocketConnections: int64(plan.DailyWebsocketConnections),
MonthlyWebsocketConnections: int64(plan.MonthlyWebsocketConnections),
MaxUploadSizeJSON: plan.MaxUploadSize,
})
}
return &pb.ListEnabledPlansResponse{Plans: pbPlans}, nil
}
// FindAllAvailablePlans 列出所有可用的套餐
func (this *PlanService) FindAllAvailablePlans(ctx context.Context, req *pb.FindAllAvailablePlansRequest) (*pb.FindAllAvailablePlansResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
plans, err := models.SharedPlanDAO.FindAllAvailablePlans(tx)
if err != nil {
return nil, err
}
var pbPlans = []*pb.Plan{}
for _, plan := range plans {
pbPlans = append(pbPlans, &pb.Plan{
Id: int64(plan.Id),
IsOn: plan.IsOn,
Name: plan.Name,
Description: plan.Description,
ClusterId: int64(plan.ClusterId),
TrafficLimitJSON: plan.TrafficLimit,
BandwidthLimitPerNodeJSON: plan.BandwidthLimitPerNode,
HasFullFeatures: plan.HasFullFeatures,
FeaturesJSON: plan.Features,
PriceType: plan.PriceType,
TrafficPriceJSON: plan.TrafficPrice,
BandwidthPriceJSON: plan.BandwidthPrice,
MonthlyPrice: plan.MonthlyPrice,
SeasonallyPrice: plan.SeasonallyPrice,
YearlyPrice: plan.YearlyPrice,
TotalServers: types.Int32(plan.TotalServers),
TotalServerNames: types.Int32(plan.TotalServerNames),
TotalServerNamesPerServer: types.Int32(plan.TotalServerNamesPerServer),
DailyRequests: int64(plan.DailyRequests),
MonthlyRequests: int64(plan.MonthlyRequests),
DailyWebsocketConnections: int64(plan.DailyWebsocketConnections),
MonthlyWebsocketConnections: int64(plan.MonthlyWebsocketConnections),
MaxUploadSizeJSON: plan.MaxUploadSize,
})
}
return &pb.FindAllAvailablePlansResponse{Plans: pbPlans}, nil
}
// FindAllAvailableBasicPlans 列出所有可用的套餐的基本信息
func (this *PlanService) FindAllAvailableBasicPlans(ctx context.Context, req *pb.FindAllAvailableBasicPlansRequest) (*pb.FindAllAvailableBasicPlansResponse, error) {
_, err := this.ValidateNode(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
plans, err := models.SharedPlanDAO.FindAllAvailableBasicPlans(tx)
if err != nil {
return nil, err
}
var pbPlans = []*pb.Plan{}
for _, plan := range plans {
pbPlans = append(pbPlans, &pb.Plan{
Id: int64(plan.Id),
Name: plan.Name,
BandwidthLimitPerNodeJSON: plan.BandwidthLimitPerNode,
TrafficLimitJSON: plan.TrafficLimit,
MaxUploadSizeJSON: plan.MaxUploadSize,
})
}
return &pb.FindAllAvailableBasicPlansResponse{Plans: pbPlans}, nil
}
// SortPlans 对套餐进行排序
func (this *PlanService) SortPlans(ctx context.Context, req *pb.SortPlansRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = models.SharedPlanDAO.SortPlans(tx, req.PlanIds)
if err != nil {
return nil, err
}
return this.Success()
}