319 lines
11 KiB
Go
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()
|
|
}
|