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,36 @@
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/xerr"
"github.com/pkg/errors"
)
type BatchDeleteSubscribeGroupLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Batch delete subscribe group
func NewBatchDeleteSubscribeGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BatchDeleteSubscribeGroupLogic {
return &BatchDeleteSubscribeGroupLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *BatchDeleteSubscribeGroupLogic) BatchDeleteSubscribeGroup(req *types.BatchDeleteSubscribeGroupRequest) error {
err := l.svcCtx.DB.Model(&subscribe.Group{}).Where("id in ?", req.Ids).Delete(&subscribe.Group{}).Error
if err != nil {
l.Logger.Error("[BatchDeleteSubscribeGroup] Delete Database Error: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "batch delete subscribe group failed: %v", err.Error())
}
return nil
}
@@ -0,0 +1,59 @@
package subscribe
import (
"context"
"github.com/perfect-panel/ppanel-server/internal/model/user"
"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 BatchDeleteSubscribeLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Batch delete subscribe
func NewBatchDeleteSubscribeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BatchDeleteSubscribeLogic {
return &BatchDeleteSubscribeLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
var errorIsExistActiveUser = errors.New("subscription ID belongs to an active user subscription")
func (l *BatchDeleteSubscribeLogic) BatchDeleteSubscribe(req *types.BatchDeleteSubscribeRequest) error {
err := l.svcCtx.DB.Transaction(func(tx *gorm.DB) error {
for _, id := range req.Ids {
var count int64
// Validate whether the subscription ID belongs to an active user subscription.
if err := tx.Model(&user.Subscribe{}).Where("subscribe_id = ? AND status = 1", id).Count(&count).Find(&user.Subscribe{}).Error; err != nil {
l.Logger.Error("[BatchDeleteSubscribe] Query Subscribe Error: ", logger.Field("error", err.Error()))
return err
}
if count > 0 {
return errorIsExistActiveUser
}
if err := l.svcCtx.SubscribeModel.Delete(l.ctx, id, tx); err != nil {
return err
}
}
return nil
})
if err != nil {
if errors.Is(err, errorIsExistActiveUser) {
return errors.Wrapf(xerr.NewErrCode(xerr.SubscribeIsUsedError), "subscription ID belongs to an active user subscription")
}
l.Logger.Error("[BatchDeleteSubscribe] Transaction Error: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete subscribe failed: %v", err.Error())
}
return nil
}
@@ -0,0 +1,39 @@
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/xerr"
"github.com/pkg/errors"
)
type CreateSubscribeGroupLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Create subscribe group
func NewCreateSubscribeGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateSubscribeGroupLogic {
return &CreateSubscribeGroupLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateSubscribeGroupLogic) CreateSubscribeGroup(req *types.CreateSubscribeGroupRequest) error {
err := l.svcCtx.DB.Model(&subscribe.Group{}).Create(&subscribe.Group{
Name: req.Name,
Description: req.Description,
}).Error
if err != nil {
l.Logger.Error("[CreateSubscribeGroupLogic] create subscribe group failed: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create subscribe group failed: %v", err.Error())
}
return nil
}
@@ -0,0 +1,68 @@
package subscribe
import (
"context"
"encoding/json"
"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 CreateSubscribeLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// NewCreateSubscribeLogic Create subscribe
func NewCreateSubscribeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateSubscribeLogic {
return &CreateSubscribeLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateSubscribeLogic) CreateSubscribe(req *types.CreateSubscribeRequest) error {
discount := ""
if len(req.Discount) > 0 {
val, _ := json.Marshal(req.Discount)
discount = string(val)
}
sub := &subscribe.Subscribe{
Id: 0,
Name: req.Name,
Description: req.Description,
UnitPrice: req.UnitPrice,
UnitTime: req.UnitTime,
Discount: discount,
Replacement: req.Replacement,
Inventory: req.Inventory,
Traffic: req.Traffic,
SpeedLimit: req.SpeedLimit,
DeviceLimit: req.DeviceLimit,
Quota: req.Quota,
GroupId: req.GroupId,
ServerGroup: tool.Int64SliceToString(req.ServerGroup),
Server: tool.Int64SliceToString(req.Server),
Show: req.Show,
Sell: req.Sell,
Sort: 0,
DeductionRatio: req.DeductionRatio,
AllowDeduction: req.AllowDeduction,
ResetCycle: req.ResetCycle,
RenewalReset: req.RenewalReset,
}
err := l.svcCtx.SubscribeModel.Insert(l.ctx, sub)
if err != nil {
l.Logger.Error("[CreateSubscribeLogic] create subscribe error: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create subscribe error: %v", err.Error())
}
return nil
}
@@ -0,0 +1,36 @@
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/xerr"
"github.com/pkg/errors"
)
type DeleteSubscribeGroupLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Delete subscribe group
func NewDeleteSubscribeGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteSubscribeGroupLogic {
return &DeleteSubscribeGroupLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *DeleteSubscribeGroupLogic) DeleteSubscribeGroup(req *types.DeleteSubscribeGroupRequest) error {
err := l.svcCtx.DB.Model(&subscribe.Group{}).Where("id = ?", req.Id).Delete(&subscribe.Group{}).Error
if err != nil {
l.Logger.Error("[DeleteSubscribeGroupLogic] delete subscribe group failed: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete subscribe group failed: %v", err.Error())
}
return nil
}
@@ -0,0 +1,51 @@
package subscribe
import (
"context"
"github.com/perfect-panel/ppanel-server/internal/model/user"
"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"
"github.com/perfect-panel/ppanel-server/pkg/xerr"
"github.com/pkg/errors"
)
type DeleteSubscribeLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Delete subscribe
func NewDeleteSubscribeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteSubscribeLogic {
return &DeleteSubscribeLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *DeleteSubscribeLogic) DeleteSubscribe(req *types.DeleteSubscribeRequest) error {
// Check if the subscribe exists
var total int64
err := l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error {
return db.Model(&user.Subscribe{}).Where("subscribe_id = ? AND `status` = ?", req.Id, 1).Count(&total).Find(&user.Subscribe{}).Error
})
if err != nil {
l.Logger.Error("[DeleteSubscribeLogic] check subscribe failed: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "check subscribe failed: %v", err.Error())
}
if total != 0 {
return errors.Wrapf(xerr.NewErrCode(xerr.SubscribeIsUsedError), "subscribe is used")
}
err = l.svcCtx.SubscribeModel.Delete(l.ctx, req.Id)
if err != nil {
l.Logger.Error("[DeleteSubscribeLogic] delete subscribe failed: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete subscribe failed: %v", err.Error())
}
return nil
}
@@ -0,0 +1,47 @@
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 GetSubscribeDetailsLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Get subscribe details
func NewGetSubscribeDetailsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSubscribeDetailsLogic {
return &GetSubscribeDetailsLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetSubscribeDetailsLogic) GetSubscribeDetails(req *types.GetSubscribeDetailsRequest) (resp *types.Subscribe, err error) {
sub, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, req.Id)
if err != nil {
l.Logger.Error("[GetSubscribeDetailsLogic] get subscribe details failed: ", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get subscribe details failed: %v", err.Error())
}
resp = &types.Subscribe{}
tool.DeepCopy(resp, sub)
if sub.Discount != "" {
err = json.Unmarshal([]byte(sub.Discount), &resp.Discount)
if err != nil {
l.Logger.Error("[GetSubscribeDetailsLogic] JSON unmarshal failed: ", logger.Field("error", err.Error()), logger.Field("discount", sub.Discount))
}
}
resp.Server = tool.StringToInt64Slice(sub.Server)
resp.ServerGroup = tool.StringToInt64Slice(sub.ServerGroup)
return resp, nil
}
@@ -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 GetSubscribeGroupListLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Get subscribe group list
func NewGetSubscribeGroupListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSubscribeGroupListLogic {
return &GetSubscribeGroupListLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetSubscribeGroupListLogic) GetSubscribeGroupList() (resp *types.GetSubscribeGroupListResponse, 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("[GetSubscribeGroupListLogic] 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.GetSubscribeGroupListResponse{
Total: total,
List: groupList,
}, nil
}
@@ -0,0 +1,72 @@
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 GetSubscribeListLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Get subscribe list
func NewGetSubscribeListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSubscribeListLogic {
return &GetSubscribeListLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetSubscribeListLogic) GetSubscribeList(req *types.GetSubscribeListRequest) (resp *types.GetSubscribeListResponse, err error) {
total, list, err := l.svcCtx.SubscribeModel.QuerySubscribeListByPage(l.ctx, int(req.Page), int(req.Size), req.GroupId, req.Search)
if err != nil {
l.Logger.Error("[GetSubscribeListLogic] get subscribe list failed: ", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get subscribe list failed: %v", err.Error())
}
var (
subscribeIdList = make([]int64, 0, len(list))
resultList = make([]types.SubscribeItem, 0, len(list))
)
for _, item := range list {
subscribeIdList = append(subscribeIdList, item.Id)
var sub types.SubscribeItem
tool.DeepCopy(&sub, item)
if item.Discount != "" {
err = json.Unmarshal([]byte(item.Discount), &sub.Discount)
if err != nil {
l.Logger.Error("[GetSubscribeListLogic] JSON unmarshal failed: ", logger.Field("error", err.Error()), logger.Field("discount", item.Discount))
}
}
sub.Server = tool.StringToInt64Slice(item.Server)
sub.ServerGroup = tool.StringToInt64Slice(item.ServerGroup)
resultList = append(resultList, sub)
}
subscribeMaps, err := l.svcCtx.UserModel.QueryActiveSubscriptions(l.ctx, subscribeIdList...)
if err != nil {
l.Logger.Error("[GetSubscribeListLogic] get user subscribe failed: ", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get user subscribe failed: %v", err.Error())
}
for i, item := range resultList {
if subscribe, ok := subscribeMaps[item.Id]; ok {
resultList[i].Sold = subscribe
}
}
resp = &types.GetSubscribeListResponse{
Total: total,
List: resultList,
}
return
}
@@ -0,0 +1,64 @@
package subscribe
import (
"context"
"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 SubscribeSortLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// NewSubscribeSortLogic Subscribe sort
func NewSubscribeSortLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SubscribeSortLogic {
return &SubscribeSortLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *SubscribeSortLogic) SubscribeSort(req *types.SubscribeSortRequest) error {
var sort = make(map[int64]int64, len(req.Sort))
var ids []int64
for i, v := range req.Sort {
sort[v.Id] = int64(i)
ids = append(ids, v.Id)
}
// query min sort by ids
minSort, err := l.svcCtx.SubscribeModel.QuerySubscribeMinSortByIds(l.ctx, ids)
if err != nil {
l.Logger.Error("[SubscribeSortLogic] query subscribe list by ids error: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query subscribe list by ids error: %v", err.Error())
}
subs, err := l.svcCtx.SubscribeModel.QuerySubscribeListByIds(l.ctx, ids)
if err != nil {
l.Logger.Error("[SubscribeSortLogic] query subscribe list by ids error: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query subscribe list by ids error: %v", err.Error())
}
// reordering
for _, sub := range subs {
if newSort, ok := sort[sub.Id]; ok {
sub.Sort = minSort + newSort
}
}
// update sort
err = l.svcCtx.SubscribeModel.Transaction(l.ctx, func(db *gorm.DB) error {
return db.Save(subs).Error
})
if err != nil {
l.Logger.Error("[SubscribeSortLogic] update subscribe sort error: ", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update subscribe sort error: %v", err.Error())
}
l.Logger.Info("[UpdateSubscribeSort] Successfully updated subscribe sort")
return nil
}
@@ -0,0 +1,40 @@
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/xerr"
"github.com/pkg/errors"
)
type UpdateSubscribeGroupLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Update subscribe group
func NewUpdateSubscribeGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateSubscribeGroupLogic {
return &UpdateSubscribeGroupLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *UpdateSubscribeGroupLogic) UpdateSubscribeGroup(req *types.UpdateSubscribeGroupRequest) error {
err := l.svcCtx.DB.Model(&subscribe.Group{}).Where("id = ?", req.Id).Save(&subscribe.Group{
Id: req.Id,
Name: req.Name,
Description: req.Description,
}).Error
if err != nil {
l.Logger.Error("[UpdateSubscribeGroup] update subscribe group failed", logger.Field("error", err.Error()))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update subscribe group failed: %v", err.Error())
}
return nil
}
@@ -0,0 +1,76 @@
package subscribe
import (
"context"
"encoding/json"
"github.com/perfect-panel/ppanel-server/pkg/device"
"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 UpdateSubscribeLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Update subscribe
func NewUpdateSubscribeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateSubscribeLogic {
return &UpdateSubscribeLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *UpdateSubscribeLogic) UpdateSubscribe(req *types.UpdateSubscribeRequest) error {
// Query the database to get the subscribe information
_, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, req.Id)
if err != nil {
l.Logger.Error("[UpdateSubscribe] Database query error", logger.Field("error", err.Error()), logger.Field("subscribe_id", req.Id))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get subscribe error: %v", err.Error())
}
discount := ""
if len(req.Discount) > 0 {
val, _ := json.Marshal(req.Discount)
discount = string(val)
}
sub := &subscribe.Subscribe{
Id: req.Id,
Name: req.Name,
Description: req.Description,
UnitPrice: req.UnitPrice,
UnitTime: req.UnitTime,
Discount: discount,
Replacement: req.Replacement,
Inventory: req.Inventory,
Traffic: req.Traffic,
SpeedLimit: req.SpeedLimit,
DeviceLimit: req.DeviceLimit,
Quota: req.Quota,
GroupId: req.GroupId,
ServerGroup: tool.Int64SliceToString(req.ServerGroup),
Server: tool.Int64SliceToString(req.Server),
Show: req.Show,
Sell: req.Sell,
Sort: req.Sort,
DeductionRatio: req.DeductionRatio,
AllowDeduction: req.AllowDeduction,
ResetCycle: req.ResetCycle,
RenewalReset: req.RenewalReset,
}
err = l.svcCtx.SubscribeModel.Update(l.ctx, sub)
if err != nil {
l.Logger.Error("[UpdateSubscribe] update subscribe failed", logger.Field("error", err.Error()), logger.Field("subscribe", sub))
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update subscribe error: %v", err.Error())
}
l.svcCtx.DeviceManager.Broadcast(device.SubscribeUpdate)
return nil
}