init: 1.0.0

This commit is contained in:
Chang lue Tsen
2025-04-25 12:08:29 +09:00
commit 8addcc584b
1031 changed files with 76472 additions and 0 deletions
@@ -0,0 +1,115 @@
package subscribe
import (
"context"
"github.com/perfect-panel/ppanel-server/internal/model/application"
"github.com/perfect-panel/ppanel-server/pkg/xerr"
"github.com/pkg/errors"
"gorm.io/gorm"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/logger"
)
type QueryApplicationConfigLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Get application config
func NewQueryApplicationConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryApplicationConfigLogic {
return &QueryApplicationConfigLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *QueryApplicationConfigLogic) QueryApplicationConfig() (resp *types.ApplicationResponse, err error) {
resp = &types.ApplicationResponse{}
var applications []*application.Application
err = l.svcCtx.ApplicationModel.Transaction(l.ctx, func(tx *gorm.DB) (err error) {
return tx.Model(applications).Preload("ApplicationVersions").Find(&applications).Error
})
if err != nil {
l.Errorw("[QueryApplicationConfig] get application error: ", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get application error: %v", err.Error())
}
if len(applications) == 0 {
return resp, nil
}
for _, app := range applications {
applicationResponse := types.ApplicationResponseInfo{
Id: app.Id,
Name: app.Name,
Icon: app.Icon,
Description: app.Description,
SubscribeType: app.SubscribeType,
}
applicationVersions := app.ApplicationVersions
if len(applicationVersions) != 0 {
for _, applicationVersion := range applicationVersions {
/*if !applicationVersion.IsDefault {
continue
}*/
switch applicationVersion.Platform {
case "ios":
applicationResponse.Platform.IOS = append(applicationResponse.Platform.IOS, &types.ApplicationVersion{
Id: applicationVersion.Id,
Url: applicationVersion.Url,
Version: applicationVersion.Version,
IsDefault: applicationVersion.IsDefault,
Description: applicationVersion.Description,
})
case "macos":
applicationResponse.Platform.MacOS = append(applicationResponse.Platform.MacOS, &types.ApplicationVersion{
Id: applicationVersion.Id,
Url: applicationVersion.Url,
Version: applicationVersion.Version,
IsDefault: applicationVersion.IsDefault,
Description: applicationVersion.Description,
})
case "linux":
applicationResponse.Platform.Linux = append(applicationResponse.Platform.Linux, &types.ApplicationVersion{
Id: applicationVersion.Id,
Url: applicationVersion.Url,
Version: applicationVersion.Version,
IsDefault: applicationVersion.IsDefault,
Description: applicationVersion.Description,
})
case "android":
applicationResponse.Platform.Android = append(applicationResponse.Platform.Android, &types.ApplicationVersion{
Id: applicationVersion.Id,
Url: applicationVersion.Url,
Version: applicationVersion.Version,
IsDefault: applicationVersion.IsDefault,
Description: applicationVersion.Description,
})
case "windows":
applicationResponse.Platform.Windows = append(applicationResponse.Platform.Windows, &types.ApplicationVersion{
Id: applicationVersion.Id,
Url: applicationVersion.Url,
Version: applicationVersion.Version,
IsDefault: applicationVersion.IsDefault,
Description: applicationVersion.Description,
})
case "harmony":
applicationResponse.Platform.Harmony = append(applicationResponse.Platform.Harmony, &types.ApplicationVersion{
Id: applicationVersion.Id,
Url: applicationVersion.Url,
Version: applicationVersion.Version,
IsDefault: applicationVersion.IsDefault,
Description: applicationVersion.Description,
})
}
}
}
resp.Applications = append(resp.Applications, applicationResponse)
}
return
}
@@ -0,0 +1,44 @@
package subscribe
import (
"context"
"github.com/perfect-panel/ppanel-server/internal/model/subscribe"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/ppanel-server/pkg/tool"
"github.com/perfect-panel/ppanel-server/pkg/xerr"
"github.com/pkg/errors"
)
type QuerySubscribeGroupListLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Get subscribe group list
func NewQuerySubscribeGroupListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QuerySubscribeGroupListLogic {
return &QuerySubscribeGroupListLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *QuerySubscribeGroupListLogic) QuerySubscribeGroupList() (resp *types.QuerySubscribeGroupListResponse, err error) {
var list []*subscribe.Group
var total int64
err = l.svcCtx.DB.Model(&subscribe.Group{}).Count(&total).Find(&list).Error
if err != nil {
l.Logger.Error("[QuerySubscribeGroupListLogic] get subscribe group list failed: ", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get subscribe group list failed: %v", err.Error())
}
groupList := make([]types.SubscribeGroup, 0)
tool.DeepCopy(&groupList, list)
return &types.QuerySubscribeGroupListResponse{
Total: total,
List: groupList,
}, nil
}
@@ -0,0 +1,55 @@
package subscribe
import (
"context"
"encoding/json"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/ppanel-server/pkg/tool"
"github.com/perfect-panel/ppanel-server/pkg/xerr"
"github.com/pkg/errors"
)
type QuerySubscribeListLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Get subscribe list
func NewQuerySubscribeListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QuerySubscribeListLogic {
return &QuerySubscribeListLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *QuerySubscribeListLogic) QuerySubscribeList() (resp *types.QuerySubscribeListResponse, err error) {
data, err := l.svcCtx.SubscribeModel.QuerySubscribeList(l.ctx)
if err != nil {
l.Errorw("[QuerySubscribeListLogic] Database Error", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "QuerySubscribeList error: %v", err.Error())
}
resp = &types.QuerySubscribeListResponse{
List: make([]types.Subscribe, 0),
Total: int64(len(data)),
}
for _, v := range data {
var sub types.Subscribe
tool.DeepCopy(&sub, v)
if v.Discount != "" {
if err = json.Unmarshal([]byte(v.Discount), &sub.Discount); err != nil {
l.Errorw("[QuerySubscribeListLogic] json.Unmarshal Error", logger.Field("error", err.Error()), logger.Field("value", v.Discount))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "json.Unmarshal error: %v", err.Error())
}
} else {
sub.Discount = make([]types.SubscribeDiscount, 0)
}
resp.List = append(resp.List, sub)
}
return
}
@@ -0,0 +1,67 @@
package subscribe
import (
"context"
"github.com/perfect-panel/ppanel-server/internal/model/order"
"github.com/perfect-panel/ppanel-server/internal/model/user"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/constant"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/ppanel-server/pkg/xerr"
"github.com/pkg/errors"
"gorm.io/gorm"
)
type QueryUserAlreadySubscribeLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Get Already subscribed to package
func NewQueryUserAlreadySubscribeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryUserAlreadySubscribeLogic {
return &QueryUserAlreadySubscribeLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *QueryUserAlreadySubscribeLogic) QueryUserAlreadySubscribe() (resp *types.QueryUserSubscribeResp, err error) {
resp = &types.QueryUserSubscribeResp{
Data: make([]types.UserSubscribeData, 0),
}
userInfo := l.ctx.Value(constant.CtxKeyUser).(*user.User)
var orderIds []int64
var subscribes []user.Subscribe
err = l.svcCtx.OrderModel.Transaction(context.Background(), func(tx *gorm.DB) error {
if err := tx.Model(&order.Order{}).Where("user_id = ? AND status in ?", userInfo.Id, []int64{2, 5}).Select("id").Find(&orderIds).Error; err != nil {
return err
}
if len(orderIds) == 0 {
return nil
}
return tx.Model(&user.Subscribe{}).Where("user_id = ? AND order_id in ?", userInfo.Id, orderIds).Order("created_at desc").Find(&subscribes).Error
})
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find order error: %v", err.Error())
}
if len(subscribes) == 0 {
return
}
userAlreadySubscribe := make(map[int64]int64)
for _, subscribe := range subscribes {
userAlreadySubscribe[subscribe.SubscribeId] = subscribe.Id
}
for k, v := range userAlreadySubscribe {
resp.Data = append(resp.Data, types.UserSubscribeData{
SubscribeId: k,
UserSubscribeId: v,
})
}
return
}
@@ -0,0 +1,107 @@
package subscribe
import (
"context"
"strconv"
"strings"
"time"
"github.com/perfect-panel/ppanel-server/internal/model/user"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/constant"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/ppanel-server/pkg/xerr"
"github.com/pkg/errors"
)
type QueryUserAvailableUserSubscribeLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Get Available subscriptions for users
func NewQueryUserAvailableUserSubscribeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryUserAvailableUserSubscribeLogic {
return &QueryUserAvailableUserSubscribeLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *QueryUserAvailableUserSubscribeLogic) QueryUserAvailableUserSubscribe(req *types.AppUserSubscribeRequest) (resp *types.AppUserSubscbribeResponse, err error) {
resp = &types.AppUserSubscbribeResponse{List: make([]types.AppUserSubcbribe, 0)}
userInfo := l.ctx.Value(constant.CtxKeyUser).(*user.User)
//查询用户订阅
subscribeDetails, err := l.svcCtx.UserModel.QueryUserSubscribe(l.ctx, userInfo.Id, 1, 2)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get query user subscribe error: %v", err.Error())
}
userSubscribeMap := make(map[int64]types.AppUserSubcbribe)
for _, sd := range subscribeDetails {
userSubscribeInfo := types.AppUserSubcbribe{
Id: sd.Id,
Name: sd.Subscribe.Name,
Traffic: sd.Traffic,
Upload: sd.Upload,
Download: sd.Download,
ExpireTime: sd.ExpireTime.Format(time.DateTime),
StartTime: sd.StartTime.Format(time.DateTime),
DeviceLimit: sd.Subscribe.DeviceLimit,
}
//不需要查询节点
if req.ContainsNodes == nil || !*req.ContainsNodes {
resp.List = append(resp.List, userSubscribeInfo)
continue
}
//拿到所有订阅下的服务组id
var ids []int64
for _, idStr := range strings.Split(sd.Subscribe.ServerGroup, ",") {
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
continue
}
ids = append(ids, id)
}
//根据服务组id拿到所有节点
servers, err := l.svcCtx.ServerModel.FindServerListByGroupIds(l.ctx, ids)
if err != nil {
l.Logger.Errorf("FindServerListByGroupIds error: %v", err.Error())
continue
}
for _, server := range servers {
userSubscribeInfo.List = append(userSubscribeInfo.List, types.AppUserSubscbribeNode{
Id: server.Id,
Uuid: sd.UUID,
Traffic: sd.Traffic,
Upload: sd.Upload,
Download: sd.Download,
RelayNode: server.RelayNode,
RelayMode: server.RelayMode,
Longitude: server.Longitude,
Latitude: server.Latitude,
Tags: strings.Split(server.Tags, ","),
Config: server.Config,
ServerAddr: server.ServerAddr,
Protocol: server.Protocol,
SpeedLimit: server.SpeedLimit,
City: server.City,
Country: server.Country,
Name: server.Name,
})
}
resp.List = append(resp.List, userSubscribeInfo)
userSubscribeMap[userSubscribeInfo.Id] = userSubscribeInfo
}
for _, userSubscribeInfo := range userSubscribeMap {
resp.List = append(resp.List, userSubscribeInfo)
}
return resp, nil
}
@@ -0,0 +1,60 @@
package subscribe
import (
"context"
"time"
"github.com/perfect-panel/ppanel-server/internal/model/user"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/constant"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/ppanel-server/pkg/xerr"
"github.com/pkg/errors"
)
type ResetUserSubscribePeriodLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewResetUserSubscribePeriodLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ResetUserSubscribePeriodLogic {
return &ResetUserSubscribePeriodLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *ResetUserSubscribePeriodLogic) ResetUserSubscribePeriod(req *types.UserSubscribeResetPeriodRequest) (resp *types.UserSubscribeResetPeriodResponse, err error) {
resp = &types.UserSubscribeResetPeriodResponse{}
userInfo := l.ctx.Value(constant.CtxKeyUser).(*user.User)
subscribe, err := l.svcCtx.UserModel.FindOneSubscribe(l.ctx, req.UserSubscribeId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find order error: %v", err.Error())
}
if userInfo.Id != subscribe.UserId {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SubscribeNotAvailable), "user not authorized,subscribe not available")
}
if time.Now().After(subscribe.ExpireTime) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SubscribeExpired), "subscribe expired")
}
if subscribe.Traffic < 1 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ExistAvailableTraffic), "Unlimited data plan.")
}
if (subscribe.Download + subscribe.Upload + 10240) < subscribe.Traffic {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ExistAvailableTraffic), "There is still available traffic.")
}
subscribe.ExpireTime = subscribe.ExpireTime.AddDate(0, -1, 0)
err = l.svcCtx.UserModel.UpdateSubscribe(l.ctx, subscribe)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update subscribe error: %v", err.Error())
}
resp.Status = true
return
}