refactor(api): remove deprecated application-related endpoints and types
This commit is contained in:
parent
14a86c50b2
commit
8996a62b54
@ -11,50 +11,6 @@ info (
|
|||||||
import "../types.api"
|
import "../types.api"
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// Update application request
|
|
||||||
UpdateApplicationRequest {
|
|
||||||
Id int64 `json:"id" validate:"required"`
|
|
||||||
Icon string `json:"icon"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
SubscribeType string `json:"subscribe_type"`
|
|
||||||
Platform ApplicationPlatform `json:"platform"`
|
|
||||||
}
|
|
||||||
// Create application request
|
|
||||||
CreateApplicationRequest {
|
|
||||||
Icon string `json:"icon"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
SubscribeType string `json:"subscribe_type"`
|
|
||||||
Platform ApplicationPlatform `json:"platform"`
|
|
||||||
}
|
|
||||||
// Update application request
|
|
||||||
UpdateApplicationVersionRequest {
|
|
||||||
Id int64 `json:"id" validate:"required"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
Version string `json:"version" validate:"required"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Platform string `json:"platform" validate:"required,oneof=windows mac linux android ios harmony"`
|
|
||||||
IsDefault bool `json:"is_default"`
|
|
||||||
ApplicationId int64 `json:"application_id" validate:"required"`
|
|
||||||
}
|
|
||||||
// Create application request
|
|
||||||
CreateApplicationVersionRequest {
|
|
||||||
Url string `json:"url"`
|
|
||||||
Version string `json:"version" validate:"required"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Platform string `json:"platform" validate:"required,oneof=windows mac linux android ios harmony"`
|
|
||||||
IsDefault bool `json:"is_default"`
|
|
||||||
ApplicationId int64 `json:"application_id" validate:"required"`
|
|
||||||
}
|
|
||||||
// Delete application request
|
|
||||||
DeleteApplicationRequest {
|
|
||||||
Id int64 `json:"id" validate:"required"`
|
|
||||||
}
|
|
||||||
// Delete application request
|
|
||||||
DeleteApplicationVersionRequest {
|
|
||||||
Id int64 `json:"id" validate:"required"`
|
|
||||||
}
|
|
||||||
GetNodeMultiplierResponse {
|
GetNodeMultiplierResponse {
|
||||||
Periods []TimePeriod `json:"periods"`
|
Periods []TimePeriod `json:"periods"`
|
||||||
}
|
}
|
||||||
@ -90,42 +46,6 @@ service ppanel {
|
|||||||
@handler GetSubscribeType
|
@handler GetSubscribeType
|
||||||
get /subscribe_type returns (SubscribeType)
|
get /subscribe_type returns (SubscribeType)
|
||||||
|
|
||||||
@doc "update application config"
|
|
||||||
@handler UpdateApplicationConfig
|
|
||||||
put /application_config (ApplicationConfig)
|
|
||||||
|
|
||||||
@doc "get application config"
|
|
||||||
@handler GetApplicationConfig
|
|
||||||
get /application_config returns (ApplicationConfig)
|
|
||||||
|
|
||||||
@doc "Get application"
|
|
||||||
@handler GetApplication
|
|
||||||
get /application returns (ApplicationResponse)
|
|
||||||
|
|
||||||
@doc "Update application"
|
|
||||||
@handler UpdateApplication
|
|
||||||
put /application (UpdateApplicationRequest)
|
|
||||||
|
|
||||||
@doc "Create application"
|
|
||||||
@handler CreateApplication
|
|
||||||
post /application (CreateApplicationRequest)
|
|
||||||
|
|
||||||
@doc "Delete application"
|
|
||||||
@handler DeleteApplication
|
|
||||||
delete /application (DeleteApplicationRequest)
|
|
||||||
|
|
||||||
@doc "Update application version"
|
|
||||||
@handler UpdateApplicationVersion
|
|
||||||
put /application_version (UpdateApplicationVersionRequest)
|
|
||||||
|
|
||||||
@doc "Create application version"
|
|
||||||
@handler CreateApplicationVersion
|
|
||||||
post /application_version (CreateApplicationVersionRequest)
|
|
||||||
|
|
||||||
@doc "Delete application"
|
|
||||||
@handler DeleteApplicationVersion
|
|
||||||
delete /application_version (DeleteApplicationVersionRequest)
|
|
||||||
|
|
||||||
@doc "Get register config"
|
@doc "Get register config"
|
||||||
@handler GetRegisterConfig
|
@handler GetRegisterConfig
|
||||||
get /register_config returns (RegisterConfig)
|
get /register_config returns (RegisterConfig)
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "Announcement API"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
import "../types.api"
|
|
||||||
|
|
||||||
@server (
|
|
||||||
prefix: v1/app/announcement
|
|
||||||
group: app/announcement
|
|
||||||
middleware: AppMiddleware,AuthMiddleware
|
|
||||||
)
|
|
||||||
service ppanel {
|
|
||||||
@doc "Query announcement"
|
|
||||||
@handler QueryAnnouncement
|
|
||||||
get /list (QueryAnnouncementRequest) returns (QueryAnnouncementResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,104 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "App Auth Api"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
import (
|
|
||||||
"../types.api"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
AppAuthCheckRequest {
|
|
||||||
Method string `json:"method" validate:"required" validate:"required,oneof=device email mobile"`
|
|
||||||
Account string `json:"account"`
|
|
||||||
Identifier string `json:"identifier" validate:"required"`
|
|
||||||
UserAgent string `json:"user_agent" validate:"required,oneof=windows mac linux android ios harmony"`
|
|
||||||
AreaCode string `json:"area_code"`
|
|
||||||
}
|
|
||||||
AppAuthCheckResponse {
|
|
||||||
Status bool
|
|
||||||
}
|
|
||||||
AppAuthRequest {
|
|
||||||
Method string `json:"method" validate:"required" validate:"required,oneof=device email mobile"`
|
|
||||||
Account string `json:"account"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Identifier string `json:"identifier" validate:"required"`
|
|
||||||
UserAgent string `json:"user_agent" validate:"required,oneof=windows mac linux android ios harmony"`
|
|
||||||
Code string `json:"code"`
|
|
||||||
Invite string `json:"invite"`
|
|
||||||
AreaCode string `json:"area_code"`
|
|
||||||
CfToken string `json:"cf_token,optional"`
|
|
||||||
}
|
|
||||||
AppAuthRespone {
|
|
||||||
Token string `json:"token"`
|
|
||||||
}
|
|
||||||
AppSendCodeRequest {
|
|
||||||
Method string `json:"method" validate:"required" validate:"required,oneof=email mobile"`
|
|
||||||
Account string `json:"account"`
|
|
||||||
AreaCode string `json:"area_code"`
|
|
||||||
CfToken string `json:"cf_token,optional"`
|
|
||||||
}
|
|
||||||
AppSendCodeRespone {
|
|
||||||
Status bool `json:"status"`
|
|
||||||
Code string `json:"code,omitempty"`
|
|
||||||
}
|
|
||||||
AppConfigRequest {
|
|
||||||
UserAgent string `json:"user_agent" validate:"required,oneof=windows mac linux android ios harmony"`
|
|
||||||
}
|
|
||||||
AppConfigResponse {
|
|
||||||
EncryptionKey string `json:"encryption_key"`
|
|
||||||
EncryptionMethod string `json:"encryption_method"`
|
|
||||||
Domains []string `json:"domains"`
|
|
||||||
StartupPicture string `json:"startup_picture"`
|
|
||||||
StartupPictureSkipTime int64 `json:"startup_picture_skip_time"`
|
|
||||||
Application AppInfo `json:"applications"`
|
|
||||||
OfficialEmail string `json:"official_email"`
|
|
||||||
OfficialWebsite string `json:"official_website"`
|
|
||||||
OfficialTelegram string `json:"official_telegram"`
|
|
||||||
OfficialTelephone string `json:"official_telephone"`
|
|
||||||
InvitationLink string `json:"invitation_link"`
|
|
||||||
KrWebsiteId string `json:"kr_website_id"`
|
|
||||||
}
|
|
||||||
AppInfo {
|
|
||||||
Id int64 `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
VersionDescription string `json:"version_description"`
|
|
||||||
IsDefault bool `json:"is_default"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
@server (
|
|
||||||
prefix: v1/app/auth
|
|
||||||
group: app/auth
|
|
||||||
middleware: AppMiddleware
|
|
||||||
)
|
|
||||||
service ppanel {
|
|
||||||
@doc "Check Account"
|
|
||||||
@handler Check
|
|
||||||
post /check (AppAuthCheckRequest) returns (AppAuthCheckResponse)
|
|
||||||
|
|
||||||
@doc "Login"
|
|
||||||
@handler Login
|
|
||||||
post /login (AppAuthRequest) returns (AppAuthRespone)
|
|
||||||
|
|
||||||
@doc "Register"
|
|
||||||
@handler Register
|
|
||||||
post /register (AppAuthRequest) returns (AppAuthRespone)
|
|
||||||
|
|
||||||
@doc "Reset Password"
|
|
||||||
@handler ResetPassword
|
|
||||||
post /reset_password (AppAuthRequest) returns (AppAuthRespone)
|
|
||||||
|
|
||||||
@doc "GetAppConfig"
|
|
||||||
@handler GetAppConfig
|
|
||||||
post /config (AppConfigRequest) returns (AppConfigResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "Document API"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
import "../types.api"
|
|
||||||
|
|
||||||
@server (
|
|
||||||
prefix: v1/app/document
|
|
||||||
group: app/document
|
|
||||||
middleware: AppMiddleware,AuthMiddleware
|
|
||||||
)
|
|
||||||
service ppanel {
|
|
||||||
@doc "Get document list"
|
|
||||||
@handler QueryDocumentList
|
|
||||||
get /list returns (QueryDocumentListResponse)
|
|
||||||
|
|
||||||
@doc "Get document detail"
|
|
||||||
@handler QueryDocumentDetail
|
|
||||||
get /detail (QueryDocumentDetailRequest) returns (Document)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "App Node Api"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
import "../types.api"
|
|
||||||
|
|
||||||
type (
|
|
||||||
AppRuleGroupListResponse {
|
|
||||||
Total int64 `json:"total"`
|
|
||||||
List []ServerRuleGroup `json:"list"`
|
|
||||||
}
|
|
||||||
AppUserSubscbribeNodeRequest {
|
|
||||||
Id int64 `form:"id" validate:"required"`
|
|
||||||
}
|
|
||||||
AppUserSubscbribeNodeResponse {
|
|
||||||
List []AppUserSubscbribeNode `json:"list"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
@server (
|
|
||||||
prefix: v1/app/node
|
|
||||||
group: app/node
|
|
||||||
middleware: AppMiddleware,AuthMiddleware
|
|
||||||
)
|
|
||||||
service ppanel {
|
|
||||||
@doc "Get Node list"
|
|
||||||
@handler GetNodeList
|
|
||||||
get /list (AppUserSubscbribeNodeRequest) returns (AppUserSubscbribeNodeResponse)
|
|
||||||
|
|
||||||
@doc "Get rule group list"
|
|
||||||
@handler GetRuleGroupList
|
|
||||||
get /rule_group_list returns (AppRuleGroupListResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "Order API"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
import (
|
|
||||||
"../types.api"
|
|
||||||
)
|
|
||||||
|
|
||||||
@server (
|
|
||||||
prefix: v1/app/order
|
|
||||||
group: app/order
|
|
||||||
middleware: AppMiddleware,AuthMiddleware
|
|
||||||
)
|
|
||||||
service ppanel {
|
|
||||||
@doc "Pre create order"
|
|
||||||
@handler PreCreateOrder
|
|
||||||
post /pre (PurchaseOrderRequest) returns (PreOrderResponse)
|
|
||||||
|
|
||||||
@doc "purchase Subscription"
|
|
||||||
@handler Purchase
|
|
||||||
post /purchase (PurchaseOrderRequest) returns (PurchaseOrderResponse)
|
|
||||||
|
|
||||||
@doc "Renewal Subscription"
|
|
||||||
@handler Renewal
|
|
||||||
post /renewal (RenewalOrderRequest) returns (RenewalOrderResponse)
|
|
||||||
|
|
||||||
@doc "Reset traffic"
|
|
||||||
@handler ResetTraffic
|
|
||||||
post /reset (ResetTrafficOrderRequest) returns (ResetTrafficOrderResponse)
|
|
||||||
|
|
||||||
@doc "Recharge"
|
|
||||||
@handler Recharge
|
|
||||||
post /recharge (RechargeOrderRequest) returns (RechargeOrderResponse)
|
|
||||||
|
|
||||||
@doc "Checkout order"
|
|
||||||
@handler CheckoutOrder
|
|
||||||
post /checkout (CheckoutOrderRequest) returns (CheckoutOrderResponse)
|
|
||||||
|
|
||||||
@doc "Close order"
|
|
||||||
@handler CloseOrder
|
|
||||||
post /close (CloseOrderRequest)
|
|
||||||
|
|
||||||
@doc "Get order"
|
|
||||||
@handler QueryOrderDetail
|
|
||||||
get /detail (QueryOrderDetailRequest) returns (OrderDetail)
|
|
||||||
|
|
||||||
@doc "Get order list"
|
|
||||||
@handler QueryOrderList
|
|
||||||
get /list (QueryOrderListRequest) returns (QueryOrderListResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "payment API"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
import "../types.api"
|
|
||||||
|
|
||||||
@server (
|
|
||||||
prefix: v1/app/payment
|
|
||||||
group: app/payment
|
|
||||||
middleware: AppMiddleware,AuthMiddleware
|
|
||||||
)
|
|
||||||
service ppanel {
|
|
||||||
@doc "Get available payment methods"
|
|
||||||
@handler GetAvailablePaymentMethods
|
|
||||||
get /methods returns (GetAvailablePaymentMethodsResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "Subscribe API"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
import "../types.api"
|
|
||||||
|
|
||||||
type (
|
|
||||||
QueryUserSubscribeResp {
|
|
||||||
Data []UserSubscribeData `json:"data"`
|
|
||||||
}
|
|
||||||
UserSubscribeData {
|
|
||||||
SubscribeId int64 `json:"subscribe_id"`
|
|
||||||
UserSubscribeId int64 `json:"user_subscribe_id"`
|
|
||||||
}
|
|
||||||
UserSubscribeResetPeriodRequest {
|
|
||||||
UserSubscribeId int64 `json:"user_subscribe_id"`
|
|
||||||
}
|
|
||||||
UserSubscribeResetPeriodResponse {
|
|
||||||
Status bool `json:"status"`
|
|
||||||
}
|
|
||||||
AppUserSubscribeRequest {
|
|
||||||
ContainsNodes *bool `form:"contains_nodes"`
|
|
||||||
}
|
|
||||||
AppUserSubscbribeResponse {
|
|
||||||
List []AppUserSubcbribe `json:"list"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
@server (
|
|
||||||
prefix: v1/app/subscribe
|
|
||||||
group: app/subscribe
|
|
||||||
middleware: AppMiddleware,AuthMiddleware
|
|
||||||
)
|
|
||||||
service ppanel {
|
|
||||||
@doc "Get subscribe list"
|
|
||||||
@handler QuerySubscribeList
|
|
||||||
get /list returns (QuerySubscribeListResponse)
|
|
||||||
|
|
||||||
@doc "Get subscribe group list"
|
|
||||||
@handler QuerySubscribeGroupList
|
|
||||||
get /group/list returns (QuerySubscribeGroupListResponse)
|
|
||||||
|
|
||||||
@doc "Get application config"
|
|
||||||
@handler QueryApplicationConfig
|
|
||||||
get /application/config returns (ApplicationResponse)
|
|
||||||
|
|
||||||
@doc "Get Already subscribed to package"
|
|
||||||
@handler QueryUserAlreadySubscribe
|
|
||||||
get /user/already_subscribe returns (QueryUserSubscribeResp)
|
|
||||||
|
|
||||||
@doc "Get Available subscriptions for users"
|
|
||||||
@handler QueryUserAvailableUserSubscribe
|
|
||||||
get /user/available_subscribe (AppUserSubscribeRequest) returns (AppUserSubscbribeResponse)
|
|
||||||
|
|
||||||
@doc "Reset user subscription period"
|
|
||||||
@handler ResetUserSubscribePeriod
|
|
||||||
post /reset/period (UserSubscribeResetPeriodRequest) returns (UserSubscribeResetPeriodResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,86 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "App User Api"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
import (
|
|
||||||
"../types.api"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
UserInfoResponse {
|
|
||||||
Id int64 `json:"id"`
|
|
||||||
Balance int64 `json:"balance"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
RefererId int64 `json:"referer_id"`
|
|
||||||
ReferCode string `json:"refer_code"`
|
|
||||||
Avatar string `json:"avatar"`
|
|
||||||
AreaCode string `json:"area_code"`
|
|
||||||
Telephone string `json:"telephone"`
|
|
||||||
Devices []UserDevice `json:"devices"`
|
|
||||||
AuthMethods []UserAuthMethod `json:"auth_methods"`
|
|
||||||
}
|
|
||||||
UpdatePasswordRequeset {
|
|
||||||
Password string `json:"password"`
|
|
||||||
NewPassword string `json:"new_password"`
|
|
||||||
}
|
|
||||||
DeleteAccountRequest {
|
|
||||||
Method string `json:"method" validate:"required" validate:"required,oneof=email telephone device"`
|
|
||||||
Code string `json:"code"`
|
|
||||||
}
|
|
||||||
GetUserOnlineTimeStatisticsResponse {
|
|
||||||
WeeklyStats []WeeklyStat `json:"weekly_stats"`
|
|
||||||
ConnectionRecords ConnectionRecords `json:"connection_records"`
|
|
||||||
}
|
|
||||||
WeeklyStat {
|
|
||||||
Day int `json:"day"`
|
|
||||||
DayName string `json:"day_name"`
|
|
||||||
Hours float64 `json:"hours"`
|
|
||||||
}
|
|
||||||
ConnectionRecords {
|
|
||||||
CurrentContinuousDays int64 `json:"current_continuous_days"`
|
|
||||||
HistoryContinuousDays int64 `json:"history_continuous_days"`
|
|
||||||
LongestSingleConnection int64 `json:"longest_single_connection"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
@server (
|
|
||||||
prefix: v1/app/user
|
|
||||||
group: app/user
|
|
||||||
middleware: AppMiddleware,AuthMiddleware
|
|
||||||
)
|
|
||||||
service ppanel {
|
|
||||||
@doc "query user info"
|
|
||||||
@handler QueryUserInfo
|
|
||||||
get /info returns (UserInfoResponse)
|
|
||||||
|
|
||||||
@doc "Update Password "
|
|
||||||
@handler UpdatePassword
|
|
||||||
put /password (UpdatePasswordRequeset)
|
|
||||||
|
|
||||||
@doc "Delete Account"
|
|
||||||
@handler DeleteAccount
|
|
||||||
delete /account (DeleteAccountRequest)
|
|
||||||
|
|
||||||
@doc "Get user subcribe traffic logs"
|
|
||||||
@handler GetUserSubscribeTrafficLogs
|
|
||||||
get /subscribe/traffic_logs (GetUserSubscribeTrafficLogsRequest) returns (GetUserSubscribeTrafficLogsResponse)
|
|
||||||
|
|
||||||
@doc "Get user online time total"
|
|
||||||
@handler GetUserOnlineTimeStatistics
|
|
||||||
get /online_time/statistics returns (GetUserOnlineTimeStatisticsResponse)
|
|
||||||
|
|
||||||
@doc "Query User Affiliate List"
|
|
||||||
@handler QueryUserAffiliateList
|
|
||||||
get /affiliate/list (QueryUserAffiliateListRequest) returns (QueryUserAffiliateListResponse)
|
|
||||||
|
|
||||||
@doc "Query User Affiliate Count"
|
|
||||||
@handler QueryUserAffiliate
|
|
||||||
get /affiliate/count returns (QueryUserAffiliateCountResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "App Heartbeat Api"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
@server (
|
|
||||||
prefix: v1/app/ws
|
|
||||||
group: app/ws
|
|
||||||
middleware: AuthMiddleware
|
|
||||||
)
|
|
||||||
service ppanel {
|
|
||||||
@doc "App heartbeat"
|
|
||||||
@handler AppWs
|
|
||||||
get /:userid/:identifier
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -35,10 +35,6 @@ type (
|
|||||||
GetTosResponse {
|
GetTosResponse {
|
||||||
TosContent string `json:"tos_content"`
|
TosContent string `json:"tos_content"`
|
||||||
}
|
}
|
||||||
GetAppcationResponse {
|
|
||||||
Config ApplicationConfig `json:"config"`
|
|
||||||
Applications []ApplicationResponseInfo `json:"applications"`
|
|
||||||
}
|
|
||||||
// GetCodeRequest Get code request
|
// GetCodeRequest Get code request
|
||||||
SendCodeRequest {
|
SendCodeRequest {
|
||||||
Email string `json:"email" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
@ -102,10 +98,6 @@ service ppanel {
|
|||||||
@handler GetGlobalConfig
|
@handler GetGlobalConfig
|
||||||
get /site/config returns (GetGlobalConfigResponse)
|
get /site/config returns (GetGlobalConfigResponse)
|
||||||
|
|
||||||
@doc "Get Tos Content"
|
|
||||||
@handler GetApplication
|
|
||||||
get /application returns (GetAppcationResponse)
|
|
||||||
|
|
||||||
@doc "Get Tos Content"
|
@doc "Get Tos Content"
|
||||||
@handler GetTos
|
@handler GetTos
|
||||||
get /site/tos returns (GetTosResponse)
|
get /site/tos returns (GetTosResponse)
|
||||||
|
|||||||
@ -23,9 +23,5 @@ service ppanel {
|
|||||||
@doc "Get subscribe group list"
|
@doc "Get subscribe group list"
|
||||||
@handler QuerySubscribeGroupList
|
@handler QuerySubscribeGroupList
|
||||||
get /group/list returns (QuerySubscribeGroupListResponse)
|
get /group/list returns (QuerySubscribeGroupListResponse)
|
||||||
|
|
||||||
@doc "Get application config"
|
|
||||||
@handler QueryApplicationConfig
|
|
||||||
get /application/config returns (ApplicationResponse)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "App API"
|
|
||||||
desc: "API for ppanel"
|
|
||||||
author: "Tension"
|
|
||||||
email: "tension@ppanel.com"
|
|
||||||
version: "0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
import (
|
|
||||||
"./app/auth.api"
|
|
||||||
"./app/user.api"
|
|
||||||
"./app/node.api"
|
|
||||||
"./app/ws.api"
|
|
||||||
"./app/order.api"
|
|
||||||
"./app/announcement.api"
|
|
||||||
"./app/payment.api"
|
|
||||||
"./app/document.api"
|
|
||||||
"./app/subscribe.api"
|
|
||||||
)
|
|
||||||
|
|
||||||
@ -475,14 +475,6 @@ type (
|
|||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
Prefix string `json:"prefix"`
|
Prefix string `json:"prefix"`
|
||||||
}
|
}
|
||||||
ApplicationConfig {
|
|
||||||
AppId int64 `json:"app_id"`
|
|
||||||
EncryptionKey string `json:"encryption_key"`
|
|
||||||
EncryptionMethod string `json:"encryption_method"`
|
|
||||||
Domains []string `json:"domains" validate:"required"`
|
|
||||||
StartupPicture string `json:"startup_picture"`
|
|
||||||
StartupPictureSkipTime int64 `json:"startup_picture_skip_time"`
|
|
||||||
}
|
|
||||||
UserDevice {
|
UserDevice {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
Ip string `json:"ip"`
|
Ip string `json:"ip"`
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
DROP TABLE IF EXISTS `application`;
|
||||||
|
DROP TABLE IF EXISTS `application_version`;
|
||||||
|
DROP TABLE IF EXISTS `application_config`;
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/system"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Create application
|
|
||||||
func CreateApplicationHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.CreateApplicationRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := system.NewCreateApplicationLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.CreateApplication(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/system"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Create application version
|
|
||||||
func CreateApplicationVersionHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.CreateApplicationVersionRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := system.NewCreateApplicationVersionLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.CreateApplicationVersion(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/system"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Delete application
|
|
||||||
func DeleteApplicationHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.DeleteApplicationRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := system.NewDeleteApplicationLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.DeleteApplication(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/system"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Delete application
|
|
||||||
func DeleteApplicationVersionHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.DeleteApplicationVersionRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := system.NewDeleteApplicationVersionLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.DeleteApplicationVersion(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/system"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// get application config
|
|
||||||
func GetApplicationConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := system.NewGetApplicationConfigLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetApplicationConfig()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/system"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get application
|
|
||||||
func GetApplicationHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := system.NewGetApplicationLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetApplication()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/system"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// update application config
|
|
||||||
func UpdateApplicationConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.ApplicationConfig
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := system.NewUpdateApplicationConfigLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.UpdateApplicationConfig(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/system"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update application
|
|
||||||
func UpdateApplicationHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.UpdateApplicationRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := system.NewUpdateApplicationLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.UpdateApplication(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/system"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update application version
|
|
||||||
func UpdateApplicationVersionHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.UpdateApplicationVersionRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := system.NewUpdateApplicationVersionLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.UpdateApplicationVersion(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package announcement
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/announcement"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Query announcement
|
|
||||||
func QueryAnnouncementHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.QueryAnnouncementRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := announcement.NewQueryAnnouncementLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryAnnouncement(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/auth"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Check Account
|
|
||||||
func CheckHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.AppAuthCheckRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := auth.NewCheckLogic(c, svcCtx)
|
|
||||||
resp, err := l.Check(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/auth"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetAppConfig
|
|
||||||
func GetAppConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.AppConfigRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := auth.NewGetAppConfigLogic(c, svcCtx)
|
|
||||||
resp, err := l.GetAppConfig(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/auth"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
"github.com/perfect-panel/server/pkg/turnstile"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Login
|
|
||||||
func LoginHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.AppAuthRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if svcCtx.Config.Verify.LoginVerify {
|
|
||||||
verifyTurns := turnstile.New(turnstile.Config{
|
|
||||||
Secret: svcCtx.Config.Verify.TurnstileSecret,
|
|
||||||
Timeout: 3 * time.Second,
|
|
||||||
})
|
|
||||||
if verify, err := verifyTurns.Verify(c, req.CfToken, c.ClientIP()); err != nil || !verify {
|
|
||||||
err = errors.Wrapf(xerr.NewErrCode(xerr.TooManyRequests), "error: %v, verify: %v", err, verify)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
l := auth.NewLoginLogic(c, svcCtx)
|
|
||||||
resp, err := l.Login(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/auth"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
"github.com/perfect-panel/server/pkg/turnstile"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Register
|
|
||||||
func RegisterHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.AppAuthRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// get client ip
|
|
||||||
if svcCtx.Config.Verify.RegisterVerify {
|
|
||||||
verifyTurns := turnstile.New(turnstile.Config{
|
|
||||||
Secret: svcCtx.Config.Verify.TurnstileSecret,
|
|
||||||
Timeout: 3 * time.Second,
|
|
||||||
})
|
|
||||||
if verify, err := verifyTurns.Verify(c, req.CfToken, c.ClientIP()); err != nil || !verify {
|
|
||||||
err = errors.Wrapf(xerr.NewErrCode(xerr.TooManyRequests), "error: %v, verify: %v", err, verify)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l := auth.NewRegisterLogic(c, svcCtx)
|
|
||||||
resp, err := l.Register(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/auth"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
"github.com/perfect-panel/server/pkg/turnstile"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reset Password
|
|
||||||
func ResetPasswordHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.AppAuthRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if svcCtx.Config.Verify.ResetPasswordVerify {
|
|
||||||
verifyTurns := turnstile.New(turnstile.Config{
|
|
||||||
Secret: svcCtx.Config.Verify.TurnstileSecret,
|
|
||||||
Timeout: 3 * time.Second,
|
|
||||||
})
|
|
||||||
if verify, err := verifyTurns.Verify(c, req.CfToken, c.ClientIP()); err != nil || !verify {
|
|
||||||
err = errors.Wrapf(xerr.NewErrCode(xerr.TooManyRequests), "error: %v, verify: %v", err, verify)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
l := auth.NewResetPasswordLogic(c, svcCtx)
|
|
||||||
resp, err := l.ResetPassword(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package document
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/document"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get document detail
|
|
||||||
func QueryDocumentDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.QueryDocumentDetailRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := document.NewQueryDocumentDetailLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryDocumentDetail(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package document
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/document"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get document list
|
|
||||||
func QueryDocumentListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := document.NewQueryDocumentListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryDocumentList()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package node
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/node"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get Node list
|
|
||||||
func GetNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.AppUserSubscbribeNodeRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := node.NewGetNodeListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetNodeList(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package node
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/node"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get rule group list
|
|
||||||
func GetRuleGroupListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := node.NewGetRuleGroupListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetRuleGroupList()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/order"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Checkout order
|
|
||||||
func CheckoutOrderHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.CheckoutOrderRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := order.NewCheckoutOrderLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.CheckoutOrder(&req, c.Request.Host)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/order"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Close order
|
|
||||||
func CloseOrderHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.CloseOrderRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := order.NewCloseOrderLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.CloseOrder(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/order"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Pre create order
|
|
||||||
func PreCreateOrderHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.PurchaseOrderRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := order.NewPreCreateOrderLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.PreCreateOrder(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/order"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// purchase Subscription
|
|
||||||
func PurchaseHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.PurchaseOrderRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := order.NewPurchaseLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.Purchase(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/order"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get order
|
|
||||||
func QueryOrderDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.QueryOrderDetailRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := order.NewQueryOrderDetailLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryOrderDetail(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/order"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get order list
|
|
||||||
func QueryOrderListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.QueryOrderListRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := order.NewQueryOrderListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryOrderList(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/order"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Recharge
|
|
||||||
func RechargeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.RechargeOrderRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := order.NewRechargeLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.Recharge(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/order"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Renewal Subscription
|
|
||||||
func RenewalHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.RenewalOrderRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := order.NewRenewalLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.Renewal(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/order"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reset traffic
|
|
||||||
func ResetTrafficHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.ResetTrafficOrderRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := order.NewResetTrafficLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.ResetTraffic(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package payment
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/payment"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get available payment methods
|
|
||||||
func GetAvailablePaymentMethodsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := payment.NewGetAvailablePaymentMethodsLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetAvailablePaymentMethods()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/subscribe"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get application config
|
|
||||||
func QueryApplicationConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := subscribe.NewQueryApplicationConfigLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryApplicationConfig()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/subscribe"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get subscribe group list
|
|
||||||
func QuerySubscribeGroupListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := subscribe.NewQuerySubscribeGroupListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QuerySubscribeGroupList()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/subscribe"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get subscribe list
|
|
||||||
func QuerySubscribeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := subscribe.NewQuerySubscribeListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QuerySubscribeList()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/subscribe"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get Already subscribed to package
|
|
||||||
func QueryUserAlreadySubscribeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := subscribe.NewQueryUserAlreadySubscribeLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryUserAlreadySubscribe()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/subscribe"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get Available subscriptions for users
|
|
||||||
func QueryUserAvailableUserSubscribeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.AppUserSubscribeRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := subscribe.NewQueryUserAvailableUserSubscribeLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryUserAvailableUserSubscribe(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/subscribe"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reset user subscription period
|
|
||||||
func ResetUserSubscribePeriodHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.UserSubscribeResetPeriodRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := subscribe.NewResetUserSubscribePeriodLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.ResetUserSubscribePeriod(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Delete Account
|
|
||||||
func DeleteAccountHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.DeleteAccountRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := user.NewDeleteAccountLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.DeleteAccount(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get user online time total
|
|
||||||
func GetUserOnlineTimeStatisticsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := user.NewGetUserOnlineTimeStatisticsLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetUserOnlineTimeStatistics()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get user subcribe traffic logs
|
|
||||||
func GetUserSubscribeTrafficLogsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.GetUserSubscribeTrafficLogsRequest
|
|
||||||
_ = c.BindQuery(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := user.NewGetUserSubscribeTrafficLogsLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetUserSubscribeTrafficLogs(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// query user info
|
|
||||||
func QueryUserInfoHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := user.NewQueryUserInfoLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryUserInfo()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Query User Affiliate Count
|
|
||||||
func QueryUserAffiliateHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := user.NewQueryUserAffiliateLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryUserAffiliate()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Query User Affiliate List
|
|
||||||
func QueryUserAffiliateListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.QueryUserAffiliateListRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := user.NewQueryUserAffiliateListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryUserAffiliateList(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update Password
|
|
||||||
func UpdatePasswordHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.UpdatePasswordRequeset
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := user.NewUpdatePasswordLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.UpdatePassword(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package ws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/app/ws"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// App heartbeat
|
|
||||||
func AppWsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
ctx := c.Request.Context()
|
|
||||||
|
|
||||||
// Logic: App heartbeat
|
|
||||||
l := ws.NewAppWsLogic(ctx, svcCtx)
|
|
||||||
err := l.AppWs(c.Writer, c.Request, c.Param("userid"), c.Param("identifier"))
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/common"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get Tos Content
|
|
||||||
func GetApplicationHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := common.NewGetApplicationLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetApplication()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/public/subscribe"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get application config
|
|
||||||
func QueryApplicationConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := subscribe.NewQueryApplicationConfigLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.QueryApplicationConfig()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -22,15 +22,6 @@ import (
|
|||||||
adminTicket "github.com/perfect-panel/server/internal/handler/admin/ticket"
|
adminTicket "github.com/perfect-panel/server/internal/handler/admin/ticket"
|
||||||
adminTool "github.com/perfect-panel/server/internal/handler/admin/tool"
|
adminTool "github.com/perfect-panel/server/internal/handler/admin/tool"
|
||||||
adminUser "github.com/perfect-panel/server/internal/handler/admin/user"
|
adminUser "github.com/perfect-panel/server/internal/handler/admin/user"
|
||||||
appAnnouncement "github.com/perfect-panel/server/internal/handler/app/announcement"
|
|
||||||
appAuth "github.com/perfect-panel/server/internal/handler/app/auth"
|
|
||||||
appDocument "github.com/perfect-panel/server/internal/handler/app/document"
|
|
||||||
appNode "github.com/perfect-panel/server/internal/handler/app/node"
|
|
||||||
appOrder "github.com/perfect-panel/server/internal/handler/app/order"
|
|
||||||
appPayment "github.com/perfect-panel/server/internal/handler/app/payment"
|
|
||||||
appSubscribe "github.com/perfect-panel/server/internal/handler/app/subscribe"
|
|
||||||
appUser "github.com/perfect-panel/server/internal/handler/app/user"
|
|
||||||
appWs "github.com/perfect-panel/server/internal/handler/app/ws"
|
|
||||||
auth "github.com/perfect-panel/server/internal/handler/auth"
|
auth "github.com/perfect-panel/server/internal/handler/auth"
|
||||||
authOauth "github.com/perfect-panel/server/internal/handler/auth/oauth"
|
authOauth "github.com/perfect-panel/server/internal/handler/auth/oauth"
|
||||||
common "github.com/perfect-panel/server/internal/handler/common"
|
common "github.com/perfect-panel/server/internal/handler/common"
|
||||||
@ -357,33 +348,6 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
adminSystemGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
adminSystemGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Get application
|
|
||||||
adminSystemGroupRouter.GET("/application", adminSystem.GetApplicationHandler(serverCtx))
|
|
||||||
|
|
||||||
// Update application
|
|
||||||
adminSystemGroupRouter.PUT("/application", adminSystem.UpdateApplicationHandler(serverCtx))
|
|
||||||
|
|
||||||
// Create application
|
|
||||||
adminSystemGroupRouter.POST("/application", adminSystem.CreateApplicationHandler(serverCtx))
|
|
||||||
|
|
||||||
// Delete application
|
|
||||||
adminSystemGroupRouter.DELETE("/application", adminSystem.DeleteApplicationHandler(serverCtx))
|
|
||||||
|
|
||||||
// update application config
|
|
||||||
adminSystemGroupRouter.PUT("/application_config", adminSystem.UpdateApplicationConfigHandler(serverCtx))
|
|
||||||
|
|
||||||
// get application config
|
|
||||||
adminSystemGroupRouter.GET("/application_config", adminSystem.GetApplicationConfigHandler(serverCtx))
|
|
||||||
|
|
||||||
// Update application version
|
|
||||||
adminSystemGroupRouter.PUT("/application_version", adminSystem.UpdateApplicationVersionHandler(serverCtx))
|
|
||||||
|
|
||||||
// Create application version
|
|
||||||
adminSystemGroupRouter.POST("/application_version", adminSystem.CreateApplicationVersionHandler(serverCtx))
|
|
||||||
|
|
||||||
// Delete application
|
|
||||||
adminSystemGroupRouter.DELETE("/application_version", adminSystem.DeleteApplicationVersionHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get Currency Config
|
// Get Currency Config
|
||||||
adminSystemGroupRouter.GET("/currency_config", adminSystem.GetCurrencyConfigHandler(serverCtx))
|
adminSystemGroupRouter.GET("/currency_config", adminSystem.GetCurrencyConfigHandler(serverCtx))
|
||||||
|
|
||||||
@ -565,153 +529,6 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
adminUserGroupRouter.GET("/subscribe/traffic_logs", adminUser.GetUserSubscribeTrafficLogsHandler(serverCtx))
|
adminUserGroupRouter.GET("/subscribe/traffic_logs", adminUser.GetUserSubscribeTrafficLogsHandler(serverCtx))
|
||||||
}
|
}
|
||||||
|
|
||||||
appAnnouncementGroupRouter := router.Group("/v1/app/announcement")
|
|
||||||
appAnnouncementGroupRouter.Use(middleware.AppMiddleware(serverCtx), middleware.AuthMiddleware(serverCtx))
|
|
||||||
|
|
||||||
{
|
|
||||||
// Query announcement
|
|
||||||
appAnnouncementGroupRouter.GET("/list", appAnnouncement.QueryAnnouncementHandler(serverCtx))
|
|
||||||
}
|
|
||||||
|
|
||||||
appAuthGroupRouter := router.Group("/v1/app/auth")
|
|
||||||
appAuthGroupRouter.Use(middleware.AppMiddleware(serverCtx))
|
|
||||||
|
|
||||||
{
|
|
||||||
// Check Account
|
|
||||||
appAuthGroupRouter.POST("/check", appAuth.CheckHandler(serverCtx))
|
|
||||||
|
|
||||||
// GetAppConfig
|
|
||||||
appAuthGroupRouter.POST("/config", appAuth.GetAppConfigHandler(serverCtx))
|
|
||||||
|
|
||||||
// Login
|
|
||||||
appAuthGroupRouter.POST("/login", appAuth.LoginHandler(serverCtx))
|
|
||||||
|
|
||||||
// Register
|
|
||||||
appAuthGroupRouter.POST("/register", appAuth.RegisterHandler(serverCtx))
|
|
||||||
|
|
||||||
// Reset Password
|
|
||||||
appAuthGroupRouter.POST("/reset_password", appAuth.ResetPasswordHandler(serverCtx))
|
|
||||||
}
|
|
||||||
|
|
||||||
appDocumentGroupRouter := router.Group("/v1/app/document")
|
|
||||||
appDocumentGroupRouter.Use(middleware.AppMiddleware(serverCtx), middleware.AuthMiddleware(serverCtx))
|
|
||||||
|
|
||||||
{
|
|
||||||
// Get document detail
|
|
||||||
appDocumentGroupRouter.GET("/detail", appDocument.QueryDocumentDetailHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get document list
|
|
||||||
appDocumentGroupRouter.GET("/list", appDocument.QueryDocumentListHandler(serverCtx))
|
|
||||||
}
|
|
||||||
|
|
||||||
appNodeGroupRouter := router.Group("/v1/app/node")
|
|
||||||
appNodeGroupRouter.Use(middleware.AppMiddleware(serverCtx), middleware.AuthMiddleware(serverCtx))
|
|
||||||
|
|
||||||
{
|
|
||||||
// Get Node list
|
|
||||||
appNodeGroupRouter.GET("/list", appNode.GetNodeListHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get rule group list
|
|
||||||
appNodeGroupRouter.GET("/rule_group_list", appNode.GetRuleGroupListHandler(serverCtx))
|
|
||||||
}
|
|
||||||
|
|
||||||
appOrderGroupRouter := router.Group("/v1/app/order")
|
|
||||||
appOrderGroupRouter.Use(middleware.AppMiddleware(serverCtx), middleware.AuthMiddleware(serverCtx))
|
|
||||||
|
|
||||||
{
|
|
||||||
// Checkout order
|
|
||||||
appOrderGroupRouter.POST("/checkout", appOrder.CheckoutOrderHandler(serverCtx))
|
|
||||||
|
|
||||||
// Close order
|
|
||||||
appOrderGroupRouter.POST("/close", appOrder.CloseOrderHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get order
|
|
||||||
appOrderGroupRouter.GET("/detail", appOrder.QueryOrderDetailHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get order list
|
|
||||||
appOrderGroupRouter.GET("/list", appOrder.QueryOrderListHandler(serverCtx))
|
|
||||||
|
|
||||||
// Pre create order
|
|
||||||
appOrderGroupRouter.POST("/pre", appOrder.PreCreateOrderHandler(serverCtx))
|
|
||||||
|
|
||||||
// purchase Subscription
|
|
||||||
appOrderGroupRouter.POST("/purchase", appOrder.PurchaseHandler(serverCtx))
|
|
||||||
|
|
||||||
// Recharge
|
|
||||||
appOrderGroupRouter.POST("/recharge", appOrder.RechargeHandler(serverCtx))
|
|
||||||
|
|
||||||
// Renewal Subscription
|
|
||||||
appOrderGroupRouter.POST("/renewal", appOrder.RenewalHandler(serverCtx))
|
|
||||||
|
|
||||||
// Reset traffic
|
|
||||||
appOrderGroupRouter.POST("/reset", appOrder.ResetTrafficHandler(serverCtx))
|
|
||||||
}
|
|
||||||
|
|
||||||
appPaymentGroupRouter := router.Group("/v1/app/payment")
|
|
||||||
appPaymentGroupRouter.Use(middleware.AppMiddleware(serverCtx), middleware.AuthMiddleware(serverCtx))
|
|
||||||
|
|
||||||
{
|
|
||||||
// Get available payment methods
|
|
||||||
appPaymentGroupRouter.GET("/methods", appPayment.GetAvailablePaymentMethodsHandler(serverCtx))
|
|
||||||
}
|
|
||||||
|
|
||||||
appSubscribeGroupRouter := router.Group("/v1/app/subscribe")
|
|
||||||
appSubscribeGroupRouter.Use(middleware.AppMiddleware(serverCtx), middleware.AuthMiddleware(serverCtx))
|
|
||||||
|
|
||||||
{
|
|
||||||
// Get application config
|
|
||||||
appSubscribeGroupRouter.GET("/application/config", appSubscribe.QueryApplicationConfigHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get subscribe group list
|
|
||||||
appSubscribeGroupRouter.GET("/group/list", appSubscribe.QuerySubscribeGroupListHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get subscribe list
|
|
||||||
appSubscribeGroupRouter.GET("/list", appSubscribe.QuerySubscribeListHandler(serverCtx))
|
|
||||||
|
|
||||||
// Reset user subscription period
|
|
||||||
appSubscribeGroupRouter.POST("/reset/period", appSubscribe.ResetUserSubscribePeriodHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get Already subscribed to package
|
|
||||||
appSubscribeGroupRouter.GET("/user/already_subscribe", appSubscribe.QueryUserAlreadySubscribeHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get Available subscriptions for users
|
|
||||||
appSubscribeGroupRouter.GET("/user/available_subscribe", appSubscribe.QueryUserAvailableUserSubscribeHandler(serverCtx))
|
|
||||||
}
|
|
||||||
|
|
||||||
appUserGroupRouter := router.Group("/v1/app/user")
|
|
||||||
appUserGroupRouter.Use(middleware.AppMiddleware(serverCtx), middleware.AuthMiddleware(serverCtx))
|
|
||||||
|
|
||||||
{
|
|
||||||
// Delete Account
|
|
||||||
appUserGroupRouter.DELETE("/account", appUser.DeleteAccountHandler(serverCtx))
|
|
||||||
|
|
||||||
// Query User Affiliate Count
|
|
||||||
appUserGroupRouter.GET("/affiliate/count", appUser.QueryUserAffiliateHandler(serverCtx))
|
|
||||||
|
|
||||||
// Query User Affiliate List
|
|
||||||
appUserGroupRouter.GET("/affiliate/list", appUser.QueryUserAffiliateListHandler(serverCtx))
|
|
||||||
|
|
||||||
// query user info
|
|
||||||
appUserGroupRouter.GET("/info", appUser.QueryUserInfoHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get user online time total
|
|
||||||
appUserGroupRouter.GET("/online_time/statistics", appUser.GetUserOnlineTimeStatisticsHandler(serverCtx))
|
|
||||||
|
|
||||||
// Update Password
|
|
||||||
appUserGroupRouter.PUT("/password", appUser.UpdatePasswordHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get user subcribe traffic logs
|
|
||||||
appUserGroupRouter.GET("/subscribe/traffic_logs", appUser.GetUserSubscribeTrafficLogsHandler(serverCtx))
|
|
||||||
}
|
|
||||||
|
|
||||||
appWsGroupRouter := router.Group("/v1/app/ws")
|
|
||||||
appWsGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
|
||||||
|
|
||||||
{
|
|
||||||
// App heartbeat
|
|
||||||
appWsGroupRouter.GET("/:userid/:identifier", appWs.AppWsHandler(serverCtx))
|
|
||||||
}
|
|
||||||
|
|
||||||
authGroupRouter := router.Group("/v1/auth")
|
authGroupRouter := router.Group("/v1/auth")
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -759,9 +576,6 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
// Get Ads
|
// Get Ads
|
||||||
commonGroupRouter.GET("/ads", common.GetAdsHandler(serverCtx))
|
commonGroupRouter.GET("/ads", common.GetAdsHandler(serverCtx))
|
||||||
|
|
||||||
// Get Tos Content
|
|
||||||
commonGroupRouter.GET("/application", common.GetApplicationHandler(serverCtx))
|
|
||||||
|
|
||||||
// Check verification code
|
// Check verification code
|
||||||
commonGroupRouter.POST("/check_verification_code", common.CheckVerificationCodeHandler(serverCtx))
|
commonGroupRouter.POST("/check_verification_code", common.CheckVerificationCodeHandler(serverCtx))
|
||||||
|
|
||||||
@ -869,9 +683,6 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
publicSubscribeGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
publicSubscribeGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Get application config
|
|
||||||
publicSubscribeGroupRouter.GET("/application/config", publicSubscribe.QueryApplicationConfigHandler(serverCtx))
|
|
||||||
|
|
||||||
// Get subscribe group list
|
// Get subscribe group list
|
||||||
publicSubscribeGroupRouter.GET("/group/list", publicSubscribe.QuerySubscribeGroupListHandler(serverCtx))
|
publicSubscribeGroupRouter.GET("/group/list", publicSubscribe.QuerySubscribeGroupListHandler(serverCtx))
|
||||||
|
|
||||||
|
|||||||
@ -1,125 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/application"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CreateApplicationLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCreateApplicationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateApplicationLogic {
|
|
||||||
return &CreateApplicationLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *CreateApplicationLogic) CreateApplication(req *types.CreateApplicationRequest) error {
|
|
||||||
var ios []application.ApplicationVersion
|
|
||||||
if len(req.Platform.IOS) > 0 {
|
|
||||||
for _, ios_ := range req.Platform.IOS {
|
|
||||||
ios = append(ios, application.ApplicationVersion{
|
|
||||||
Url: ios_.Url,
|
|
||||||
Version: ios_.Version,
|
|
||||||
Platform: "ios",
|
|
||||||
IsDefault: ios_.IsDefault,
|
|
||||||
Description: ios_.Description,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var mac []application.ApplicationVersion
|
|
||||||
if len(req.Platform.MacOS) > 0 {
|
|
||||||
for _, mac_ := range req.Platform.MacOS {
|
|
||||||
mac = append(mac, application.ApplicationVersion{
|
|
||||||
Url: mac_.Url,
|
|
||||||
Version: mac_.Version,
|
|
||||||
Platform: "macos",
|
|
||||||
IsDefault: mac_.IsDefault,
|
|
||||||
Description: mac_.Description,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var linux []application.ApplicationVersion
|
|
||||||
if len(req.Platform.Linux) > 0 {
|
|
||||||
for _, linux_ := range req.Platform.Linux {
|
|
||||||
linux = append(linux, application.ApplicationVersion{
|
|
||||||
Url: linux_.Url,
|
|
||||||
Version: linux_.Version,
|
|
||||||
Platform: "linux",
|
|
||||||
IsDefault: linux_.IsDefault,
|
|
||||||
Description: linux_.Description,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var android []application.ApplicationVersion
|
|
||||||
if len(req.Platform.Android) > 0 {
|
|
||||||
for _, android_ := range req.Platform.Android {
|
|
||||||
android = append(android, application.ApplicationVersion{
|
|
||||||
Url: android_.Url,
|
|
||||||
Version: android_.Version,
|
|
||||||
Platform: "android",
|
|
||||||
IsDefault: android_.IsDefault,
|
|
||||||
Description: android_.Description,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var windows []application.ApplicationVersion
|
|
||||||
if len(req.Platform.Windows) > 0 {
|
|
||||||
for _, windows_ := range req.Platform.Windows {
|
|
||||||
windows = append(windows, application.ApplicationVersion{
|
|
||||||
Url: windows_.Url,
|
|
||||||
Version: windows_.Version,
|
|
||||||
Platform: "windows",
|
|
||||||
IsDefault: windows_.IsDefault,
|
|
||||||
Description: windows_.Description,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var harmony []application.ApplicationVersion
|
|
||||||
if len(req.Platform.Harmony) > 0 {
|
|
||||||
for _, harmony_ := range req.Platform.Harmony {
|
|
||||||
harmony = append(harmony, application.ApplicationVersion{
|
|
||||||
Url: harmony_.Url,
|
|
||||||
Version: harmony_.Version,
|
|
||||||
Platform: "harmony",
|
|
||||||
IsDefault: harmony_.IsDefault,
|
|
||||||
Description: harmony_.Description,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var applicationVersions []application.ApplicationVersion
|
|
||||||
applicationVersions = append(applicationVersions, ios...)
|
|
||||||
applicationVersions = append(applicationVersions, mac...)
|
|
||||||
applicationVersions = append(applicationVersions, linux...)
|
|
||||||
applicationVersions = append(applicationVersions, android...)
|
|
||||||
applicationVersions = append(applicationVersions, windows...)
|
|
||||||
applicationVersions = append(applicationVersions, harmony...)
|
|
||||||
app := application.Application{
|
|
||||||
Name: req.Name,
|
|
||||||
Icon: req.Icon,
|
|
||||||
SubscribeType: req.SubscribeType,
|
|
||||||
ApplicationVersions: applicationVersions,
|
|
||||||
}
|
|
||||||
err := l.svcCtx.ApplicationModel.Insert(l.ctx, &app)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[CreateApplicationLogic] create application error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create application error: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/application"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CreateApplicationVersionLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create application version
|
|
||||||
func NewCreateApplicationVersionLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateApplicationVersionLogic {
|
|
||||||
return &CreateApplicationVersionLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *CreateApplicationVersionLogic) CreateApplicationVersion(req *types.CreateApplicationVersionRequest) error {
|
|
||||||
create := &application.ApplicationVersion{
|
|
||||||
Url: req.Url,
|
|
||||||
Platform: req.Platform,
|
|
||||||
Version: req.Version,
|
|
||||||
Description: req.Description,
|
|
||||||
IsDefault: req.IsDefault,
|
|
||||||
ApplicationId: req.ApplicationId,
|
|
||||||
}
|
|
||||||
err := l.svcCtx.ApplicationModel.InsertVersion(l.ctx, create)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[CreateApplicationVersion] create application version error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create application version error: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DeleteApplicationLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDeleteApplicationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteApplicationLogic {
|
|
||||||
return &DeleteApplicationLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *DeleteApplicationLogic) DeleteApplication(req *types.DeleteApplicationRequest) error {
|
|
||||||
// delete application
|
|
||||||
err := l.svcCtx.ApplicationModel.Delete(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[DeleteApplicationLogic] delete application error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete application error: %v", err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DeleteApplicationVersionLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete application
|
|
||||||
func NewDeleteApplicationVersionLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteApplicationVersionLogic {
|
|
||||||
return &DeleteApplicationVersionLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *DeleteApplicationVersionLogic) DeleteApplicationVersion(req *types.DeleteApplicationVersionRequest) error {
|
|
||||||
// delete application
|
|
||||||
err := l.svcCtx.ApplicationModel.DeleteVersion(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[DeleteApplicationVersion] delete application version error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete application version error: %v", err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetApplicationConfigLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// get application config
|
|
||||||
func NewGetApplicationConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetApplicationConfigLogic {
|
|
||||||
return &GetApplicationConfigLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetApplicationConfigLogic) GetApplicationConfig() (resp *types.ApplicationConfig, err error) {
|
|
||||||
resp = &types.ApplicationConfig{}
|
|
||||||
appConfig, err := l.svcCtx.ApplicationModel.FindOneConfig(l.ctx, 1)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
err = nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
l.Errorw("[GetApplicationConfig] Database Error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get app config error: %v", err.Error())
|
|
||||||
}
|
|
||||||
resp.AppId = appConfig.AppId
|
|
||||||
resp.EncryptionKey = appConfig.EncryptionKey
|
|
||||||
resp.EncryptionMethod = appConfig.EncryptionMethod
|
|
||||||
resp.Domains = strings.Split(appConfig.Domains, ";")
|
|
||||||
resp.StartupPicture = appConfig.StartupPicture
|
|
||||||
resp.StartupPictureSkipTime = appConfig.StartupPictureSkipTime
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/application"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetApplicationLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get application
|
|
||||||
func NewGetApplicationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetApplicationLogic {
|
|
||||||
return &GetApplicationLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetApplicationLogic) GetApplication() (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("[GetApplicationLogic] 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 {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/application"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateApplicationConfigLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// update application config
|
|
||||||
func NewUpdateApplicationConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateApplicationConfigLogic {
|
|
||||||
return &UpdateApplicationConfigLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UpdateApplicationConfigLogic) UpdateApplicationConfig(req *types.ApplicationConfig) error {
|
|
||||||
err := l.svcCtx.ApplicationModel.UpdateConfig(l.ctx, &application.ApplicationConfig{
|
|
||||||
Id: 1,
|
|
||||||
AppId: req.AppId,
|
|
||||||
EncryptionKey: req.EncryptionKey,
|
|
||||||
EncryptionMethod: req.EncryptionMethod,
|
|
||||||
Domains: strings.Join(req.Domains, ";"),
|
|
||||||
StartupPicture: req.StartupPicture,
|
|
||||||
StartupPictureSkipTime: req.StartupPictureSkipTime,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateApplicationConfig] Database Error", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update app config error: %v", err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,149 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/application"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateApplicationLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUpdateApplicationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateApplicationLogic {
|
|
||||||
return &UpdateApplicationLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UpdateApplicationLogic) UpdateApplication(req *types.UpdateApplicationRequest) error {
|
|
||||||
|
|
||||||
// find application
|
|
||||||
app, err := l.svcCtx.ApplicationModel.FindOne(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateApplication] find application error", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find application error: %v", err.Error())
|
|
||||||
}
|
|
||||||
app.Name = req.Name
|
|
||||||
app.Icon = req.Icon
|
|
||||||
app.SubscribeType = req.SubscribeType
|
|
||||||
app.Description = req.Description
|
|
||||||
|
|
||||||
var ios []application.ApplicationVersion
|
|
||||||
if len(req.Platform.IOS) > 0 {
|
|
||||||
for _, ios_ := range req.Platform.IOS {
|
|
||||||
ios = append(ios, application.ApplicationVersion{
|
|
||||||
Url: ios_.Url,
|
|
||||||
Version: ios_.Version,
|
|
||||||
Platform: "ios",
|
|
||||||
IsDefault: ios_.IsDefault,
|
|
||||||
Description: ios_.Description,
|
|
||||||
ApplicationId: app.Id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var mac []application.ApplicationVersion
|
|
||||||
if len(req.Platform.MacOS) > 0 {
|
|
||||||
for _, mac_ := range req.Platform.MacOS {
|
|
||||||
mac = append(mac, application.ApplicationVersion{
|
|
||||||
Url: mac_.Url,
|
|
||||||
Version: mac_.Version,
|
|
||||||
Platform: "macos",
|
|
||||||
IsDefault: mac_.IsDefault,
|
|
||||||
Description: mac_.Description,
|
|
||||||
ApplicationId: app.Id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var linux []application.ApplicationVersion
|
|
||||||
if len(req.Platform.Linux) > 0 {
|
|
||||||
for _, linux_ := range req.Platform.Linux {
|
|
||||||
linux = append(linux, application.ApplicationVersion{
|
|
||||||
Url: linux_.Url,
|
|
||||||
Version: linux_.Version,
|
|
||||||
Platform: "linux",
|
|
||||||
IsDefault: linux_.IsDefault,
|
|
||||||
Description: linux_.Description,
|
|
||||||
ApplicationId: app.Id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var android []application.ApplicationVersion
|
|
||||||
if len(req.Platform.Android) > 0 {
|
|
||||||
for _, android_ := range req.Platform.Android {
|
|
||||||
android = append(android, application.ApplicationVersion{
|
|
||||||
Url: android_.Url,
|
|
||||||
Version: android_.Version,
|
|
||||||
Platform: "android",
|
|
||||||
IsDefault: android_.IsDefault,
|
|
||||||
Description: android_.Description,
|
|
||||||
ApplicationId: app.Id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var windows []application.ApplicationVersion
|
|
||||||
if len(req.Platform.Windows) > 0 {
|
|
||||||
for _, windows_ := range req.Platform.Windows {
|
|
||||||
windows = append(windows, application.ApplicationVersion{
|
|
||||||
Url: windows_.Url,
|
|
||||||
Version: windows_.Version,
|
|
||||||
Platform: "windows",
|
|
||||||
IsDefault: windows_.IsDefault,
|
|
||||||
Description: windows_.Description,
|
|
||||||
ApplicationId: app.Id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var harmony []application.ApplicationVersion
|
|
||||||
if len(req.Platform.Harmony) > 0 {
|
|
||||||
for _, harmony_ := range req.Platform.Harmony {
|
|
||||||
harmony = append(harmony, application.ApplicationVersion{
|
|
||||||
Url: harmony_.Url,
|
|
||||||
Version: harmony_.Version,
|
|
||||||
Platform: "harmony",
|
|
||||||
IsDefault: harmony_.IsDefault,
|
|
||||||
Description: harmony_.Description,
|
|
||||||
ApplicationId: app.Id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var applicationVersions []application.ApplicationVersion
|
|
||||||
applicationVersions = append(applicationVersions, ios...)
|
|
||||||
applicationVersions = append(applicationVersions, mac...)
|
|
||||||
applicationVersions = append(applicationVersions, linux...)
|
|
||||||
applicationVersions = append(applicationVersions, android...)
|
|
||||||
applicationVersions = append(applicationVersions, windows...)
|
|
||||||
applicationVersions = append(applicationVersions, harmony...)
|
|
||||||
app.ApplicationVersions = applicationVersions
|
|
||||||
err = l.svcCtx.ApplicationModel.Transaction(l.ctx, func(db *gorm.DB) error {
|
|
||||||
|
|
||||||
if err = db.Where("application_id = ?", app.Id).Delete(&application.ApplicationVersion{}).Error; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = db.Create(&applicationVersions).Error; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return db.Save(app).Error
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateApplication] update application error", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update application error: %v", err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateApplicationVersionLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update application version
|
|
||||||
func NewUpdateApplicationVersionLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateApplicationVersionLogic {
|
|
||||||
return &UpdateApplicationVersionLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UpdateApplicationVersionLogic) UpdateApplicationVersion(req *types.UpdateApplicationVersionRequest) error {
|
|
||||||
// find application
|
|
||||||
app, err := l.svcCtx.ApplicationModel.FindOneVersion(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateApplicationVersion] find application version error", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find application error: %v", err.Error())
|
|
||||||
}
|
|
||||||
app.Url = req.Url
|
|
||||||
app.Version = req.Version
|
|
||||||
app.Description = req.Description
|
|
||||||
app.IsDefault = req.IsDefault
|
|
||||||
err = l.svcCtx.ApplicationModel.UpdateVersion(l.ctx, app)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateApplicationVersion] update application version error", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update application version error: %v", err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
package announcement
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/announcement"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type QueryAnnouncementLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewQueryAnnouncementLogic Query announcement
|
|
||||||
func NewQueryAnnouncementLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryAnnouncementLogic {
|
|
||||||
return &QueryAnnouncementLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *QueryAnnouncementLogic) QueryAnnouncement(req *types.QueryAnnouncementRequest) (resp *types.QueryAnnouncementResponse, err error) {
|
|
||||||
enable := true
|
|
||||||
total, list, err := l.svcCtx.AnnouncementModel.GetAnnouncementListByPage(l.ctx, req.Page, req.Size, announcement.Filter{
|
|
||||||
Show: &enable,
|
|
||||||
Pinned: req.Pinned,
|
|
||||||
Popup: req.Popup,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[QueryAnnouncementLogic] GetAnnouncementListByPage error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "GetAnnouncementListByPage error: %v", err.Error())
|
|
||||||
}
|
|
||||||
resp = &types.QueryAnnouncementResponse{}
|
|
||||||
resp.Total = total
|
|
||||||
resp.List = make([]types.Announcement, 0)
|
|
||||||
tool.DeepCopy(&resp.List, list)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CheckLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check Account
|
|
||||||
func NewCheckLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CheckLogic {
|
|
||||||
return &CheckLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *CheckLogic) Check(req *types.AppAuthCheckRequest) (resp *types.AppAuthCheckResponse, err error) {
|
|
||||||
resp = &types.AppAuthCheckResponse{}
|
|
||||||
_, err = findUserByMethod(l.ctx, l.svcCtx, req.Method, req.Identifier, req.Account, req.AreaCode)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
resp.Status = false
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
resp.Status = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/authmethod"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/phone"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func findUserByMethod(ctx context.Context, svcCtx *svc.ServiceContext, method, identifier, account, areaCode string) (userInfo *user.User, err error) {
|
|
||||||
var authMethods *user.AuthMethods
|
|
||||||
switch method {
|
|
||||||
case authmethod.Email:
|
|
||||||
authMethods, err = svcCtx.UserModel.FindUserAuthMethodByOpenID(ctx, authmethod.Email, account)
|
|
||||||
case authmethod.Mobile:
|
|
||||||
phoneNumber, err := phone.FormatToE164(areaCode, account)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.TelephoneError), "Invalid phone number")
|
|
||||||
}
|
|
||||||
authMethods, err = svcCtx.UserModel.FindUserAuthMethodByOpenID(ctx, authmethod.Mobile, phoneNumber)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
case authmethod.Device:
|
|
||||||
userDevice, err := svcCtx.UserModel.FindOneDeviceByIdentifier(ctx, identifier)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query user device imei error")
|
|
||||||
}
|
|
||||||
return svcCtx.UserModel.FindOne(ctx, userDevice.UserId)
|
|
||||||
default:
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserNotExist), "unknown method")
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return svcCtx.UserModel.FindOne(ctx, authMethods.UserId)
|
|
||||||
}
|
|
||||||
|
|
||||||
func existError(method string) error {
|
|
||||||
switch method {
|
|
||||||
case authmethod.Email:
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.EmailExist), "")
|
|
||||||
case authmethod.Mobile:
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.TelephoneExist), "")
|
|
||||||
case authmethod.Device:
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DeviceExist), "")
|
|
||||||
default:
|
|
||||||
return errors.New("unknown method")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/application"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetAppConfigLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAppConfig
|
|
||||||
func NewGetAppConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAppConfigLogic {
|
|
||||||
return &GetAppConfigLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetAppConfigLogic) GetAppConfig(req *types.AppConfigRequest) (resp *types.AppConfigResponse, err error) {
|
|
||||||
resp = &types.AppConfigResponse{}
|
|
||||||
systems, err := l.svcCtx.SystemModel.GetSiteConfig(l.ctx)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[QueryApplicationConfig] GetSiteConfig error: ", logger.Field("error", err.Error()))
|
|
||||||
}
|
|
||||||
for _, sysVal := range systems {
|
|
||||||
if sysVal.Key == "CustomData" {
|
|
||||||
jsonStr := strings.ReplaceAll(sysVal.Value, "\\", "")
|
|
||||||
customData := make(map[string]interface{})
|
|
||||||
if err = json.Unmarshal([]byte(jsonStr), &customData); err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
website := customData["website"]
|
|
||||||
if website != nil {
|
|
||||||
resp.OfficialWebsite = fmt.Sprintf("%v", website)
|
|
||||||
}
|
|
||||||
|
|
||||||
contacts := customData["contacts"]
|
|
||||||
if contacts != nil {
|
|
||||||
contactsJson, err := json.Marshal(contacts)
|
|
||||||
if err == nil {
|
|
||||||
contactsMap := make(map[string]string)
|
|
||||||
err = json.Unmarshal(contactsJson, &contactsMap)
|
|
||||||
if err == nil {
|
|
||||||
resp.OfficialEmail = fmt.Sprintf("%v", contactsMap["email"])
|
|
||||||
resp.OfficialTelegram = fmt.Sprintf("%v", contactsMap["telegram"])
|
|
||||||
resp.OfficialTelephone = fmt.Sprintf("%v", contactsMap["telephone"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
isOk := false
|
|
||||||
for _, app := range applications {
|
|
||||||
if isOk {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
resp.Application.Name = app.Name
|
|
||||||
resp.Application.Description = app.Description
|
|
||||||
applicationVersions := app.ApplicationVersions
|
|
||||||
if len(applicationVersions) != 0 {
|
|
||||||
for _, applicationVersion := range applicationVersions {
|
|
||||||
if applicationVersion.Platform == req.UserAgent {
|
|
||||||
resp.Application.Id = applicationVersion.ApplicationId
|
|
||||||
resp.Application.Url = applicationVersion.Url
|
|
||||||
resp.Application.Version = applicationVersion.Version
|
|
||||||
resp.Application.VersionDescription = applicationVersion.Description
|
|
||||||
resp.Application.IsDefault = applicationVersion.IsDefault
|
|
||||||
isOk = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
configs, err := l.svcCtx.ApplicationModel.FindOneConfig(l.ctx, 1)
|
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
l.Logger.Error("[GetAppInfo] FindOneAppConfig error: ", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "GetAppInfo FindOneAppConfig error: %v", err.Error())
|
|
||||||
}
|
|
||||||
resp.EncryptionKey = configs.EncryptionKey
|
|
||||||
resp.EncryptionMethod = configs.EncryptionMethod
|
|
||||||
resp.Domains = strings.Split(configs.Domains, ";")
|
|
||||||
resp.StartupPicture = configs.StartupPicture
|
|
||||||
resp.StartupPictureSkipTime = configs.StartupPictureSkipTime
|
|
||||||
resp.InvitationLink = configs.InvitationLink
|
|
||||||
resp.KrWebsiteId = configs.KrWebsiteId
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,194 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/authmethod"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
"github.com/perfect-panel/server/pkg/phone"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/config"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/common"
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/jwt"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/uuidx"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LoginLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx *gin.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Login
|
|
||||||
func NewLoginLogic(ctx *gin.Context, svcCtx *svc.ServiceContext) *LoginLogic {
|
|
||||||
return &LoginLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *LoginLogic) Login(req *types.AppAuthRequest) (resp *types.AppAuthRespone, err error) {
|
|
||||||
|
|
||||||
loginStatus := false
|
|
||||||
var userInfo *user.User
|
|
||||||
// Record login status
|
|
||||||
defer func(svcCtx *svc.ServiceContext) {
|
|
||||||
if userInfo != nil && userInfo.Id != 0 {
|
|
||||||
if err := svcCtx.UserModel.InsertLoginLog(l.ctx, &user.LoginLog{
|
|
||||||
UserId: userInfo.Id,
|
|
||||||
LoginIP: l.ctx.ClientIP(),
|
|
||||||
UserAgent: l.ctx.Request.UserAgent(),
|
|
||||||
Success: &loginStatus,
|
|
||||||
}); err != nil {
|
|
||||||
l.Errorw("InsertLoginLog Error", logger.Field("error", err.Error()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}(l.svcCtx)
|
|
||||||
|
|
||||||
resp = &types.AppAuthRespone{}
|
|
||||||
//query user
|
|
||||||
userInfo, err = findUserByMethod(l.ctx, l.svcCtx, req.Method, req.Identifier, req.Account, req.AreaCode)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserPasswordError), "user password")
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch req.Method {
|
|
||||||
case authmethod.Email:
|
|
||||||
|
|
||||||
if !l.svcCtx.Config.Email.Enable {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.EmailNotEnabled), "Email function is not enabled yet")
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Code != "" {
|
|
||||||
cacheKey := fmt.Sprintf("%s:%s:%s", config.AuthCodeCacheKey, constant.Security.String(), req.Account)
|
|
||||||
value, err := l.svcCtx.Redis.Get(l.ctx, cacheKey).Result()
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Redis Error", logger.Field("error", err.Error()), logger.Field("cacheKey", cacheKey))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload common.CacheKeyPayload
|
|
||||||
err = json.Unmarshal([]byte(value), &payload)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Unmarshal Error", logger.Field("error", err.Error()), logger.Field("value", value))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
if payload.Code != req.Code {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
l.svcCtx.Redis.Del(l.ctx, cacheKey)
|
|
||||||
} else {
|
|
||||||
// Verify password
|
|
||||||
if !tool.VerifyPassWord(req.Password, userInfo.Password) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserPasswordError), "user password")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case authmethod.Mobile:
|
|
||||||
if !l.svcCtx.Config.Mobile.Enable {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SmsNotEnabled), "sms login is not enabled")
|
|
||||||
}
|
|
||||||
phoneNumber, err := phone.FormatToE164(req.AreaCode, req.Account)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.TelephoneError), "Invalid phone number")
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Code != "" {
|
|
||||||
cacheKey := fmt.Sprintf("%s:%s:%s", config.AuthCodeTelephoneCacheKey, constant.Security, phoneNumber)
|
|
||||||
value, err := l.svcCtx.Redis.Get(l.ctx, cacheKey).Result()
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Redis Error", logger.Field("error", err.Error()), logger.Field("cacheKey", cacheKey))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
if value == "" {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload common.CacheKeyPayload
|
|
||||||
if err := json.Unmarshal([]byte(value), &payload); err != nil {
|
|
||||||
l.Errorw("[SendSmsCode]: Unmarshal Error", logger.Field("error", err.Error()), logger.Field("value", value))
|
|
||||||
}
|
|
||||||
if payload.Code != req.Code {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
l.svcCtx.Redis.Del(l.ctx, cacheKey)
|
|
||||||
} else {
|
|
||||||
// Verify password
|
|
||||||
if !tool.VerifyPassWord(req.Password, userInfo.Password) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserPasswordError), "user password")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case authmethod.Device:
|
|
||||||
default:
|
|
||||||
return nil, existError(req.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
device, err := l.svcCtx.UserModel.FindOneDeviceByIdentifier(l.ctx, req.Identifier)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
if req.Method == authmethod.Device {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserNotExist), "device not exist")
|
|
||||||
}
|
|
||||||
//Add User Device
|
|
||||||
userInfo.UserDevices = append(userInfo.UserDevices, user.Device{
|
|
||||||
UserAgent: req.UserAgent,
|
|
||||||
Identifier: req.Identifier,
|
|
||||||
Ip: l.ctx.ClientIP(),
|
|
||||||
})
|
|
||||||
err = l.svcCtx.UserModel.Update(l.ctx, userInfo)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateUserBindDevice] Fail", logger.Field("error", err.Error()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//Change the user who owns the device
|
|
||||||
if device.UserId != userInfo.Id {
|
|
||||||
device.UserId = userInfo.Id
|
|
||||||
}
|
|
||||||
device.Ip = l.ctx.ClientIP()
|
|
||||||
err = l.svcCtx.UserModel.UpdateDevice(l.ctx, device)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateUserBindDevice] Fail", logger.Field("error", err.Error()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate session id
|
|
||||||
sessionId := uuidx.NewUUID().String()
|
|
||||||
// Generate token
|
|
||||||
token, err := jwt.NewJwtToken(
|
|
||||||
l.svcCtx.Config.JwtAuth.AccessSecret,
|
|
||||||
time.Now().Unix(),
|
|
||||||
l.svcCtx.Config.JwtAuth.AccessExpire,
|
|
||||||
jwt.WithOption("UserId", userInfo.Id),
|
|
||||||
jwt.WithOption("SessionId", sessionId),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "token generate error: %v", err.Error())
|
|
||||||
}
|
|
||||||
sessionIdCacheKey := fmt.Sprintf("%v:%v", config.SessionIdKey, sessionId)
|
|
||||||
if err = l.svcCtx.Redis.Set(l.ctx, sessionIdCacheKey, userInfo.Id, time.Duration(l.svcCtx.Config.JwtAuth.AccessExpire)*time.Second).Err(); err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "set session id error: %v", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Token = token
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,249 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/authmethod"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/config"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/common"
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
"github.com/perfect-panel/server/pkg/jwt"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/phone"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/uuidx"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CacheKeyPayload struct {
|
|
||||||
Code string `json:"code"`
|
|
||||||
LastAt int64 `json:"lastAt"`
|
|
||||||
}
|
|
||||||
type RegisterLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx *gin.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register
|
|
||||||
func NewRegisterLogic(ctx *gin.Context, svcCtx *svc.ServiceContext) *RegisterLogic {
|
|
||||||
return &RegisterLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *RegisterLogic) Register(req *types.AppAuthRequest) (resp *types.AppAuthRespone, err error) {
|
|
||||||
resp = &types.AppAuthRespone{}
|
|
||||||
var referer *user.User
|
|
||||||
c := l.svcCtx.Config.Register
|
|
||||||
// Check if the registration is stopped
|
|
||||||
if c.StopRegister {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.StopRegister), "stop register")
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Invite == "" {
|
|
||||||
if l.svcCtx.Config.Invite.ForcedInvite {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InviteCodeError), "invite code is required")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Check if the invite code is valid
|
|
||||||
referer, err = l.svcCtx.UserModel.FindOneByReferCode(l.ctx, req.Invite)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("FindOneByReferCode Error", logger.Field("error", err))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InviteCodeError), "invite code is invalid")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Password == "" {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PasswordIsEmpty), "Password required")
|
|
||||||
}
|
|
||||||
|
|
||||||
userInfo, err := findUserByMethod(l.ctx, l.svcCtx, req.Method, req.Identifier, req.Account, req.AreaCode)
|
|
||||||
if err == nil && userInfo != nil {
|
|
||||||
return nil, existError(req.Method)
|
|
||||||
}
|
|
||||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Generate password
|
|
||||||
pwd := tool.EncodePassWord(req.Password)
|
|
||||||
userInfo = &user.User{
|
|
||||||
Password: pwd,
|
|
||||||
}
|
|
||||||
if referer != nil {
|
|
||||||
userInfo.RefererId = referer.Id
|
|
||||||
}
|
|
||||||
switch req.Method {
|
|
||||||
case authmethod.Email:
|
|
||||||
if !l.svcCtx.Config.Email.Enable {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.EmailNotEnabled), "Email function is not enabled yet")
|
|
||||||
}
|
|
||||||
if l.svcCtx.Config.Email.EnableVerify {
|
|
||||||
cacheKey := fmt.Sprintf("%s:%s:%s", config.AuthCodeCacheKey, constant.Register.String(), req.Account)
|
|
||||||
value, err := l.svcCtx.Redis.Get(l.ctx, cacheKey).Result()
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Redis Error", logger.Field("error", err.Error()), logger.Field("cacheKey", cacheKey))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload common.CacheKeyPayload
|
|
||||||
err = json.Unmarshal([]byte(value), &payload)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Unmarshal Error", logger.Field("error", err.Error()), logger.Field("value", value))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
if payload.Code != req.Code {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
userInfo.AuthMethods = []user.AuthMethods{{
|
|
||||||
AuthType: authmethod.Email,
|
|
||||||
AuthIdentifier: req.Account,
|
|
||||||
}}
|
|
||||||
|
|
||||||
case authmethod.Mobile:
|
|
||||||
if req.AreaCode == "" {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.TelephoneAreaCodeIsEmpty), "area code required")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !l.svcCtx.Config.Mobile.Enable {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SmsNotEnabled), "sms login is not enabled")
|
|
||||||
}
|
|
||||||
phoneNumber, err := phone.FormatToE164(req.AreaCode, req.Account)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.TelephoneError), "Invalid phone number")
|
|
||||||
}
|
|
||||||
cacheKey := fmt.Sprintf("%s:%s:%s", config.AuthCodeTelephoneCacheKey, constant.Register, phoneNumber)
|
|
||||||
value, err := l.svcCtx.Redis.Get(l.ctx, cacheKey).Result()
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Redis Error", logger.Field("error", err.Error()), logger.Field("cacheKey", cacheKey))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload CacheKeyPayload
|
|
||||||
_ = json.Unmarshal([]byte(value), &payload)
|
|
||||||
if payload.Code != req.Code {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
userInfo.AuthMethods = []user.AuthMethods{{
|
|
||||||
AuthType: authmethod.Mobile,
|
|
||||||
AuthIdentifier: phoneNumber,
|
|
||||||
Verified: true,
|
|
||||||
}}
|
|
||||||
case authmethod.Device:
|
|
||||||
oneDevice, err := l.svcCtx.UserModel.FindOneDeviceByIdentifier(l.ctx, req.Identifier)
|
|
||||||
if err == nil && oneDevice != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DeviceExist), "device exist")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, existError(req.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
device, err := l.svcCtx.UserModel.FindOneDeviceByIdentifier(l.ctx, req.Identifier)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
//Add User Device
|
|
||||||
userInfo.UserDevices = append(userInfo.UserDevices, user.Device{
|
|
||||||
Ip: l.ctx.ClientIP(),
|
|
||||||
Identifier: req.Identifier,
|
|
||||||
UserAgent: req.UserAgent,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query user info failed: %v", err.Error())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//Delete Other User Device
|
|
||||||
err = l.svcCtx.UserModel.DeleteDevice(l.ctx, device.Id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "delete old user device failed: %v", err.Error())
|
|
||||||
} else {
|
|
||||||
//User Add Device
|
|
||||||
userInfo.UserDevices = append(userInfo.UserDevices, user.Device{
|
|
||||||
Ip: l.ctx.ClientIP(),
|
|
||||||
Identifier: req.Identifier,
|
|
||||||
UserAgent: req.UserAgent,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error {
|
|
||||||
// Save user information
|
|
||||||
if err := db.Create(userInfo).Error; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Generate ReferCode
|
|
||||||
userInfo.ReferCode = uuidx.UserInviteCode(userInfo.Id)
|
|
||||||
// Update ReferCode
|
|
||||||
if err := db.Model(&user.User{}).Where("id = ?", userInfo.Id).Update("refer_code", userInfo.ReferCode).Error; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if l.svcCtx.Config.Register.EnableTrial {
|
|
||||||
// Active trial
|
|
||||||
if err = l.activeTrial(userInfo.Id); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "insert user info failed: %v", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate session id
|
|
||||||
sessionId := uuidx.NewUUID().String()
|
|
||||||
// Generate token
|
|
||||||
token, err := jwt.NewJwtToken(
|
|
||||||
l.svcCtx.Config.JwtAuth.AccessSecret,
|
|
||||||
time.Now().Unix(),
|
|
||||||
l.svcCtx.Config.JwtAuth.AccessExpire,
|
|
||||||
jwt.WithOption("UserId", userInfo.Id),
|
|
||||||
jwt.WithOption("SessionId", sessionId),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "token generate error: %v", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionIdCacheKey := fmt.Sprintf("%v:%v", config.SessionIdKey, sessionId)
|
|
||||||
if err := l.svcCtx.Redis.Set(l.ctx, sessionIdCacheKey, userInfo.Id, time.Duration(l.svcCtx.Config.JwtAuth.AccessExpire)*time.Second).Err(); err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "set session id error: %v", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Token = token
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *RegisterLogic) activeTrial(uid int64) error {
|
|
||||||
sub, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, l.svcCtx.Config.Register.TrialSubscribe)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
userSub := &user.Subscribe{
|
|
||||||
Id: 0,
|
|
||||||
UserId: uid,
|
|
||||||
OrderId: 0,
|
|
||||||
SubscribeId: sub.Id,
|
|
||||||
StartTime: time.Now(),
|
|
||||||
ExpireTime: tool.AddTime(l.svcCtx.Config.Register.TrialTimeUnit, l.svcCtx.Config.Register.TrialTime, time.Now()),
|
|
||||||
Traffic: sub.Traffic,
|
|
||||||
Download: 0,
|
|
||||||
Upload: 0,
|
|
||||||
Token: uuidx.SubscribeToken(fmt.Sprintf("Trial-%v", uid)),
|
|
||||||
UUID: uuidx.NewUUID().String(),
|
|
||||||
Status: 1,
|
|
||||||
}
|
|
||||||
return l.svcCtx.UserModel.InsertSubscribe(l.ctx, userSub)
|
|
||||||
}
|
|
||||||
@ -1,161 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/authmethod"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
"github.com/perfect-panel/server/pkg/phone"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/config"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/common"
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/jwt"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/uuidx"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ResetPasswordLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx *gin.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset Password
|
|
||||||
func NewResetPasswordLogic(ctx *gin.Context, svcCtx *svc.ServiceContext) *ResetPasswordLogic {
|
|
||||||
return &ResetPasswordLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *ResetPasswordLogic) ResetPassword(req *types.AppAuthRequest) (resp *types.AppAuthRespone, err error) {
|
|
||||||
resp = &types.AppAuthRespone{}
|
|
||||||
userInfo, err := findUserByMethod(l.ctx, l.svcCtx, req.Method, req.Identifier, req.Account, req.AreaCode)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserNotExist), "query user info failed")
|
|
||||||
}
|
|
||||||
l.Errorw("FindOneByEmail Error", logger.Field("error", err))
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch req.Method {
|
|
||||||
case authmethod.Mobile:
|
|
||||||
if !l.svcCtx.Config.Mobile.Enable {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SmsNotEnabled), "sms login is not enabled")
|
|
||||||
}
|
|
||||||
phoneNumber, err := phone.FormatToE164(req.AreaCode, req.Account)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.TelephoneError), "Invalid phone number")
|
|
||||||
}
|
|
||||||
cacheKey := fmt.Sprintf("%s:%s:%s", config.AuthCodeTelephoneCacheKey, constant.Security, phoneNumber)
|
|
||||||
value, err := l.svcCtx.Redis.Get(l.ctx, cacheKey).Result()
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Redis Error", logger.Field("error", err.Error()), logger.Field("cacheKey", cacheKey))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload common.CacheKeyPayload
|
|
||||||
err = json.Unmarshal([]byte(value), &payload)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Unmarshal Error", logger.Field("error", err.Error()), logger.Field("value", value))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
if payload.Code != req.Code {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
case authmethod.Email:
|
|
||||||
if !l.svcCtx.Config.Email.Enable {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.EmailNotEnabled), "Email function is not enabled yet")
|
|
||||||
}
|
|
||||||
|
|
||||||
cacheKey := fmt.Sprintf("%s:%s:%s", config.AuthCodeCacheKey, constant.Security.String(), req.Account)
|
|
||||||
value, err := l.svcCtx.Redis.Get(l.ctx, cacheKey).Result()
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Redis Error", logger.Field("error", err.Error()), logger.Field("cacheKey", cacheKey))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload CacheKeyPayload
|
|
||||||
err = json.Unmarshal([]byte(value), &payload)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("Unmarshal Error", logger.Field("error", err.Error()), logger.Field("value", value))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
|
|
||||||
if payload.Code != req.Code {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, errors.New("unknown method")
|
|
||||||
}
|
|
||||||
|
|
||||||
userInfo.Password = tool.EncodePassWord(req.Password)
|
|
||||||
err = l.svcCtx.UserModel.Update(l.ctx, userInfo)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("UpdateUser Error", logger.Field("error", err))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update user info failed: %v", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
device, err := l.svcCtx.UserModel.FindOneDeviceByIdentifier(l.ctx, req.Identifier)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
//Add User Device
|
|
||||||
userInfo.UserDevices = append(userInfo.UserDevices, user.Device{
|
|
||||||
Ip: l.ctx.ClientIP(),
|
|
||||||
Identifier: req.Identifier,
|
|
||||||
UserAgent: req.UserAgent,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query user info failed: %v", err.Error())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if device.UserId != userInfo.Id {
|
|
||||||
//Change the user who owns the device
|
|
||||||
if device.UserId != userInfo.Id {
|
|
||||||
device.UserId = userInfo.Id
|
|
||||||
}
|
|
||||||
device.Ip = l.ctx.ClientIP()
|
|
||||||
err = l.svcCtx.UserModel.UpdateDevice(l.ctx, device)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateUserBindDevice] Fail", logger.Field("error", err.Error()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate session id
|
|
||||||
sessionId := uuidx.NewUUID().String()
|
|
||||||
// Generate token
|
|
||||||
token, err := jwt.NewJwtToken(
|
|
||||||
l.svcCtx.Config.JwtAuth.AccessSecret,
|
|
||||||
time.Now().Unix(),
|
|
||||||
l.svcCtx.Config.JwtAuth.AccessExpire,
|
|
||||||
jwt.WithOption("UserId", userInfo.Id),
|
|
||||||
jwt.WithOption("SessionId", sessionId),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "token generate error: %v", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionIdCacheKey := fmt.Sprintf("%v:%v", config.SessionIdKey, sessionId)
|
|
||||||
if err := l.svcCtx.Redis.Set(l.ctx, sessionIdCacheKey, userInfo.Id, time.Duration(l.svcCtx.Config.JwtAuth.AccessExpire)*time.Second).Err(); err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "set session id error: %v", err.Error())
|
|
||||||
}
|
|
||||||
resp.Token = token
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
package document
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type QueryDocumentDetailLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewQueryDocumentDetailLogic Get document detail
|
|
||||||
func NewQueryDocumentDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryDocumentDetailLogic {
|
|
||||||
return &QueryDocumentDetailLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *QueryDocumentDetailLogic) QueryDocumentDetail(req *types.QueryDocumentDetailRequest) (resp *types.Document, err error) {
|
|
||||||
// find document
|
|
||||||
data, err := l.svcCtx.DocumentModel.FindOne(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[QueryDocumentDetailLogic] FindOne error", logger.Field("id", req.Id), logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "FindOne error: %s", err.Error())
|
|
||||||
}
|
|
||||||
resp = &types.Document{}
|
|
||||||
tool.DeepCopy(resp, data)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
package document
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type QueryDocumentListLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get document list
|
|
||||||
func NewQueryDocumentListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryDocumentListLogic {
|
|
||||||
return &QueryDocumentListLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *QueryDocumentListLogic) QueryDocumentList() (resp *types.QueryDocumentListResponse, err error) {
|
|
||||||
total, data, err := l.svcCtx.DocumentModel.GetDocumentListByAll(l.ctx)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[QueryDocumentList] error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "QueryDocumentList error: %v", err.Error())
|
|
||||||
}
|
|
||||||
resp = &types.QueryDocumentListResponse{
|
|
||||||
Total: total,
|
|
||||||
List: make([]types.Document, 0),
|
|
||||||
}
|
|
||||||
for _, item := range data {
|
|
||||||
resp.List = append(resp.List, types.Document{
|
|
||||||
Id: item.Id,
|
|
||||||
Title: item.Title,
|
|
||||||
Tags: tool.StringMergeAndRemoveDuplicates(item.Tags),
|
|
||||||
UpdatedAt: item.UpdatedAt.UnixMilli(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
package node
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetNodeListLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Node list
|
|
||||||
func NewGetNodeListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetNodeListLogic {
|
|
||||||
return &GetNodeListLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetNodeListLogic) GetNodeList(req *types.AppUserSubscbribeNodeRequest) (resp *types.AppUserSubscbribeNodeResponse, err error) {
|
|
||||||
resp = &types.AppUserSubscbribeNodeResponse{List: make([]types.AppUserSubscbribeNode, 0)}
|
|
||||||
userInfo := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
|
||||||
userSubscribe, err := l.svcCtx.UserModel.FindOneUserSubscribe(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find user subscribe: %v", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if userInfo.Id != userSubscribe.UserId {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "find user subscribe: %v", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
//拿到所有订阅下的服务组id
|
|
||||||
var ids []int64
|
|
||||||
for _, idStr := range strings.Split(userSubscribe.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 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, server := range servers {
|
|
||||||
resp.List = append(resp.List, types.AppUserSubscbribeNode{
|
|
||||||
Id: server.Id,
|
|
||||||
Uuid: userSubscribe.UUID,
|
|
||||||
Traffic: userSubscribe.Traffic,
|
|
||||||
Upload: userSubscribe.Upload,
|
|
||||||
Download: userSubscribe.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,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package node
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetRuleGroupListLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rule group list
|
|
||||||
func NewGetRuleGroupListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetRuleGroupListLogic {
|
|
||||||
return &GetRuleGroupListLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetRuleGroupListLogic) GetRuleGroupList() (resp *types.AppRuleGroupListResponse, err error) {
|
|
||||||
nodeRuleGroupList, err := l.svcCtx.ServerModel.QueryAllRuleGroup(l.ctx)
|
|
||||||
if err != nil {
|
|
||||||
l.Logger.Error("[GetRuleGroupList] get subscribe rule group list failed: ", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get subscribe rule group list failed: %v", err.Error())
|
|
||||||
}
|
|
||||||
nodeRuleGroups := make([]types.ServerRuleGroup, 0)
|
|
||||||
tool.DeepCopy(&nodeRuleGroups, nodeRuleGroupList)
|
|
||||||
return &types.AppRuleGroupListResponse{
|
|
||||||
Total: int64(len(nodeRuleGroups)),
|
|
||||||
List: nodeRuleGroups,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/perfect-panel/server/internal/model/coupon"
|
|
||||||
)
|
|
||||||
|
|
||||||
func calculateCoupon(amount int64, couponInfo *coupon.Coupon) int64 {
|
|
||||||
if couponInfo.Type == 1 {
|
|
||||||
return int64(float64(amount) * (float64(couponInfo.Discount) / float64(100)))
|
|
||||||
} else {
|
|
||||||
return min(couponInfo.Discount, amount)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import "github.com/perfect-panel/server/internal/model/payment"
|
|
||||||
|
|
||||||
func calculateFee(amount int64, config *payment.Payment) int64 {
|
|
||||||
var fee float64
|
|
||||||
switch config.FeeMode {
|
|
||||||
case 0:
|
|
||||||
return 0
|
|
||||||
case 1:
|
|
||||||
fee = float64(amount) * (float64(config.FeePercent) / float64(100))
|
|
||||||
case 2:
|
|
||||||
if amount > 0 {
|
|
||||||
fee = float64(config.FeeAmount)
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
fee = float64(amount)*(float64(config.FeePercent)/float64(100)) + float64(config.FeeAmount)
|
|
||||||
}
|
|
||||||
return int64(fee)
|
|
||||||
}
|
|
||||||
@ -1,325 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
paymentPlatform "github.com/perfect-panel/server/pkg/payment"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
|
|
||||||
"github.com/hibiken/asynq"
|
|
||||||
"github.com/perfect-panel/server/internal/model/order"
|
|
||||||
"github.com/perfect-panel/server/internal/model/payment"
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/exchangeRate"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/payment/alipay"
|
|
||||||
"github.com/perfect-panel/server/pkg/payment/epay"
|
|
||||||
"github.com/perfect-panel/server/pkg/payment/stripe"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
queueType "github.com/perfect-panel/server/queue/types"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CheckoutOrderLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
type CurrencyConfig struct {
|
|
||||||
CurrencyUnit string
|
|
||||||
CurrencySymbol string
|
|
||||||
AccessKey string
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
Stripe = "Stripe"
|
|
||||||
QR = "qr"
|
|
||||||
Link = "link"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewCheckoutOrderLogic Checkout order
|
|
||||||
func NewCheckoutOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CheckoutOrderLogic {
|
|
||||||
return &CheckoutOrderLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *CheckoutOrderLogic) CheckoutOrder(req *types.CheckoutOrderRequest, requestHost string) (resp *types.CheckoutOrderResponse, err error) {
|
|
||||||
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
|
||||||
if !ok {
|
|
||||||
l.Error("[CheckoutOrderLogic] Invalid access")
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid access")
|
|
||||||
}
|
|
||||||
// find order
|
|
||||||
orderInfo, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] FindOneByOrderNo error", logger.Field("orderNo", req.OrderNo), logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "FindOneByOrderNo error: %s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if orderInfo.Status != 1 {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "Order status error")
|
|
||||||
}
|
|
||||||
|
|
||||||
paymentConfig, err := l.svcCtx.PaymentModel.FindOne(l.ctx, orderInfo.PaymentId)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] FindOneByPaymentMark error", logger.Field("paymentMark", orderInfo.Method), logger.Field("PaymentID", orderInfo.PaymentId), logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "FindOneByPaymentMark error: %s", err.Error())
|
|
||||||
}
|
|
||||||
var stripePayment *types.StripePayment = nil
|
|
||||||
var url, t string
|
|
||||||
|
|
||||||
// switch payment method
|
|
||||||
switch paymentPlatform.ParsePlatform(paymentConfig.Platform) {
|
|
||||||
case paymentPlatform.Stripe:
|
|
||||||
result, err := l.stripePayment(paymentConfig.Config, orderInfo, u)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] stripePayment error", logger.Field("error", err.Error()))
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
stripePayment = result
|
|
||||||
t = Stripe
|
|
||||||
case paymentPlatform.EPay:
|
|
||||||
// epay
|
|
||||||
url, err = l.epayPayment(paymentConfig, orderInfo, req.ReturnUrl, requestHost)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] epayPayment error", logger.Field("error", err.Error()))
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
t = Link
|
|
||||||
case paymentPlatform.AlipayF2F:
|
|
||||||
// alipay f2f
|
|
||||||
url, err = l.alipayF2fPayment(paymentConfig, orderInfo, requestHost)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
t = QR
|
|
||||||
case paymentPlatform.Balance:
|
|
||||||
// balance
|
|
||||||
if err = l.balancePayment(u, orderInfo); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
t = paymentPlatform.Balance.String()
|
|
||||||
default:
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "Payment method not supported")
|
|
||||||
}
|
|
||||||
return &types.CheckoutOrderResponse{
|
|
||||||
Type: t,
|
|
||||||
CheckoutUrl: url,
|
|
||||||
Stripe: stripePayment,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query exchange rate
|
|
||||||
func (l *CheckoutOrderLogic) queryExchangeRate(to string, src int64) (amount float64, err error) {
|
|
||||||
amount = float64(src) / float64(100)
|
|
||||||
// query system currency
|
|
||||||
currency, err := l.svcCtx.SystemModel.GetCurrencyConfig(l.ctx)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] GetCurrencyConfig error", logger.Field("error", err.Error()))
|
|
||||||
return 0, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "GetCurrencyConfig error: %s", err.Error())
|
|
||||||
}
|
|
||||||
configs := &CurrencyConfig{}
|
|
||||||
tool.SystemConfigSliceReflectToStruct(currency, configs)
|
|
||||||
if configs.AccessKey == "" {
|
|
||||||
return amount, nil
|
|
||||||
}
|
|
||||||
if configs.CurrencyUnit != to {
|
|
||||||
// query exchange rate
|
|
||||||
result, err := exchangeRate.GetExchangeRete(configs.CurrencyUnit, to, configs.AccessKey, 1)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
amount = result * amount
|
|
||||||
}
|
|
||||||
return amount, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stripe Payment
|
|
||||||
func (l *CheckoutOrderLogic) stripePayment(config string, info *order.Order, u *user.User) (*types.StripePayment, error) {
|
|
||||||
// stripe WeChat pay or stripe alipay
|
|
||||||
stripeConfig := payment.StripeConfig{}
|
|
||||||
if err := json.Unmarshal([]byte(config), &stripeConfig); err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] Unmarshal error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "Unmarshal error: %s", err.Error())
|
|
||||||
}
|
|
||||||
client := stripe.NewClient(stripe.Config{
|
|
||||||
SecretKey: stripeConfig.SecretKey,
|
|
||||||
PublicKey: stripeConfig.PublicKey,
|
|
||||||
WebhookSecret: stripeConfig.WebhookSecret,
|
|
||||||
})
|
|
||||||
// Calculate the amount with exchange rate
|
|
||||||
amount, err := l.queryExchangeRate("CNY", info.Amount)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] queryExchangeRate error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "queryExchangeRate error: %s", err.Error())
|
|
||||||
}
|
|
||||||
convertAmount := int64(amount * 100)
|
|
||||||
// create payment
|
|
||||||
result, err := client.CreatePaymentSheet(&stripe.Order{
|
|
||||||
OrderNo: info.OrderNo,
|
|
||||||
Subscribe: strconv.FormatInt(info.SubscribeId, 10),
|
|
||||||
Amount: convertAmount,
|
|
||||||
Currency: "cny",
|
|
||||||
Payment: stripeConfig.Payment,
|
|
||||||
},
|
|
||||||
&stripe.User{
|
|
||||||
UserId: u.Id,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] CreatePaymentSheet error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "CreatePaymentSheet error: %s", err.Error())
|
|
||||||
}
|
|
||||||
tradeNo := result.TradeNo
|
|
||||||
stripePayment := &types.StripePayment{
|
|
||||||
PublishableKey: stripeConfig.PublicKey,
|
|
||||||
ClientSecret: result.ClientSecret,
|
|
||||||
Method: stripeConfig.Payment,
|
|
||||||
}
|
|
||||||
// save payment
|
|
||||||
info.TradeNo = tradeNo
|
|
||||||
err = l.svcCtx.OrderModel.Update(l.ctx, info)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] Update error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "Update error: %s", err.Error())
|
|
||||||
}
|
|
||||||
return stripePayment, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// epay payment
|
|
||||||
func (l *CheckoutOrderLogic) epayPayment(config *payment.Payment, info *order.Order, returnUrl, requestHost string) (string, error) {
|
|
||||||
epayConfig := payment.EPayConfig{}
|
|
||||||
if err := json.Unmarshal([]byte(config.Config), &epayConfig); err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] Unmarshal error", logger.Field("error", err.Error()))
|
|
||||||
return "", errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "Unmarshal error: %s", err.Error())
|
|
||||||
}
|
|
||||||
client := epay.NewClient(epayConfig.Pid, epayConfig.Url, epayConfig.Key)
|
|
||||||
// Calculate the amount with exchange rate
|
|
||||||
amount, err := l.queryExchangeRate("CNY", info.Amount)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
var domain string
|
|
||||||
if config.Domain != "" {
|
|
||||||
domain = config.Domain
|
|
||||||
} else {
|
|
||||||
domain = fmt.Sprintf("http://%s", requestHost)
|
|
||||||
}
|
|
||||||
// create payment
|
|
||||||
url := client.CreatePayUrl(epay.Order{
|
|
||||||
Name: l.svcCtx.Config.Site.SiteName,
|
|
||||||
Amount: amount,
|
|
||||||
OrderNo: info.OrderNo,
|
|
||||||
SignType: "MD5",
|
|
||||||
NotifyUrl: domain + "/v1/notify/epay",
|
|
||||||
ReturnUrl: returnUrl,
|
|
||||||
})
|
|
||||||
return url, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// alipay f2f payment
|
|
||||||
func (l *CheckoutOrderLogic) alipayF2fPayment(pay *payment.Payment, info *order.Order, requestHost string) (string, error) {
|
|
||||||
f2FConfig := payment.AlipayF2FConfig{}
|
|
||||||
if err := json.Unmarshal([]byte(pay.Config), &f2FConfig); err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] Unmarshal error", logger.Field("error", err.Error()))
|
|
||||||
return "", errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "Unmarshal error: %s", err.Error())
|
|
||||||
}
|
|
||||||
var domain string
|
|
||||||
if pay.Domain != "" {
|
|
||||||
domain = pay.Domain
|
|
||||||
} else {
|
|
||||||
domain = fmt.Sprintf("http://%s", requestHost)
|
|
||||||
}
|
|
||||||
client := alipay.NewClient(alipay.Config{
|
|
||||||
AppId: f2FConfig.AppId,
|
|
||||||
PrivateKey: f2FConfig.PrivateKey,
|
|
||||||
PublicKey: f2FConfig.PublicKey,
|
|
||||||
InvoiceName: f2FConfig.InvoiceName,
|
|
||||||
NotifyURL: domain + "/notify/alipay",
|
|
||||||
})
|
|
||||||
// Calculate the amount with exchange rate
|
|
||||||
amount, err := l.queryExchangeRate("CNY", info.Amount)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] queryExchangeRate error", logger.Field("error", err.Error()))
|
|
||||||
return "", errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "queryExchangeRate error: %s", err.Error())
|
|
||||||
}
|
|
||||||
convertAmount := int64(amount * 100)
|
|
||||||
// create payment
|
|
||||||
QRCode, err := client.PreCreateTrade(l.ctx, alipay.Order{
|
|
||||||
OrderNo: info.OrderNo,
|
|
||||||
Amount: convertAmount,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] PreCreateTrade error", logger.Field("error", err.Error()))
|
|
||||||
return "", errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "PreCreateTrade error: %s", err.Error())
|
|
||||||
}
|
|
||||||
return QRCode, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Balance payment
|
|
||||||
func (l *CheckoutOrderLogic) balancePayment(u *user.User, o *order.Order) error {
|
|
||||||
var userInfo user.User
|
|
||||||
err := l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error {
|
|
||||||
err := db.Model(&user.User{}).Where("id = ?", u.Id).First(&userInfo).Error
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if userInfo.Balance < o.Amount {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.InsufficientBalance), "Insufficient balance")
|
|
||||||
}
|
|
||||||
// deduct balance
|
|
||||||
userInfo.Balance -= o.Amount
|
|
||||||
err = l.svcCtx.UserModel.Update(l.ctx, &userInfo)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// create balance log
|
|
||||||
balanceLog := &user.BalanceLog{
|
|
||||||
Id: 0,
|
|
||||||
UserId: u.Id,
|
|
||||||
Amount: o.Amount,
|
|
||||||
Type: 3,
|
|
||||||
OrderId: o.Id,
|
|
||||||
Balance: userInfo.Balance,
|
|
||||||
}
|
|
||||||
err = db.Create(balanceLog).Error
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return l.svcCtx.OrderModel.UpdateOrderStatus(l.ctx, o.OrderNo, 2)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] Transaction error", logger.Field("error", err.Error()), logger.Field("orderNo", o.OrderNo))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// create activity order task
|
|
||||||
payload := queueType.ForthwithActivateOrderPayload{
|
|
||||||
OrderNo: o.OrderNo,
|
|
||||||
}
|
|
||||||
bytes, err := json.Marshal(payload)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] Marshal error", logger.Field("error", err.Error()))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
task := asynq.NewTask(queueType.ForthwithActivateOrder, bytes)
|
|
||||||
_, err = l.svcCtx.Queue.EnqueueContext(l.ctx, task)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CheckoutOrderLogic] Enqueue error", logger.Field("error", err.Error()))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
l.Logger.Info("[CheckoutOrderLogic] Enqueue success", logger.Field("orderNo", o.OrderNo))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,186 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
paymentPlatform "github.com/perfect-panel/server/pkg/payment"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/pkg/payment/stripe"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/order"
|
|
||||||
"github.com/perfect-panel/server/internal/model/payment"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/payment/alipay"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CloseOrderLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCloseOrderLogic Close order
|
|
||||||
func NewCloseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CloseOrderLogic {
|
|
||||||
return &CloseOrderLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *CloseOrderLogic) CloseOrder(req *types.CloseOrderRequest) error {
|
|
||||||
// Find order information by order number
|
|
||||||
orderInfo, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CloseOrder] Find order info failed",
|
|
||||||
logger.Field("error", err.Error()),
|
|
||||||
logger.Field("orderNo", req.OrderNo),
|
|
||||||
)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// If the order status is not 1, it means that the order has been closed or paid
|
|
||||||
if orderInfo.Status != 1 {
|
|
||||||
l.Info("[CloseOrder] Order status is not 1",
|
|
||||||
logger.Field("orderNo", req.OrderNo),
|
|
||||||
logger.Field("status", orderInfo.Status),
|
|
||||||
)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if l.confirmationPayment(orderInfo) {
|
|
||||||
l.Info("[CloseOrder] Order has been paid",
|
|
||||||
logger.Field("orderNo", req.OrderNo),
|
|
||||||
logger.Field("status", orderInfo.Status),
|
|
||||||
)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err = l.svcCtx.DB.Transaction(func(tx *gorm.DB) error {
|
|
||||||
// update order status
|
|
||||||
err := tx.Model(&order.Order{}).Where("order_no = ?", req.OrderNo).Update("status", 3).Error
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CloseOrder] Update order status failed",
|
|
||||||
logger.Field("error", err.Error()),
|
|
||||||
logger.Field("orderNo", req.OrderNo),
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// refund deduction amount to user deduction balance
|
|
||||||
if orderInfo.GiftAmount > 0 {
|
|
||||||
userInfo, err := l.svcCtx.UserModel.FindOne(l.ctx, orderInfo.UserId)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CloseOrder] Find user info failed",
|
|
||||||
logger.Field("error", err.Error()),
|
|
||||||
logger.Field("user_id", orderInfo.UserId),
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
deduction := userInfo.GiftAmount + orderInfo.GiftAmount
|
|
||||||
err = tx.Model(&user.User{}).Where("id = ?", orderInfo.UserId).Update("deduction", deduction).Error
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CloseOrder] Refund deduction amount failed",
|
|
||||||
logger.Field("error", err.Error()),
|
|
||||||
logger.Field("uid", orderInfo.UserId),
|
|
||||||
logger.Field("deduction", orderInfo.GiftAmount),
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Record the deduction refund log
|
|
||||||
giftAmountLog := &user.GiftAmountLog{
|
|
||||||
UserId: orderInfo.UserId,
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
Amount: orderInfo.GiftAmount,
|
|
||||||
Type: 1,
|
|
||||||
Balance: deduction,
|
|
||||||
Remark: "Order cancellation refund",
|
|
||||||
}
|
|
||||||
err = tx.Model(&user.GiftAmountLog{}).Create(giftAmountLog).Error
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CloseOrder] Record cancellation refund log failed",
|
|
||||||
logger.Field("error", err.Error()),
|
|
||||||
logger.Field("uid", orderInfo.UserId),
|
|
||||||
logger.Field("deduction", orderInfo.GiftAmount),
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// update user cache
|
|
||||||
return l.svcCtx.UserModel.UpdateUserCache(l.ctx, userInfo)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// confirmationPayment Determine whether the payment is successful
|
|
||||||
//
|
|
||||||
//nolint:unused
|
|
||||||
func (l *CloseOrderLogic) confirmationPayment(order *order.Order) bool {
|
|
||||||
paymentConfig, err := l.svcCtx.PaymentModel.FindOne(l.ctx, order.PaymentId)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CloseOrder] Find payment config failed", logger.Field("error", err.Error()), logger.Field("paymentMark", order.Method))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
switch paymentPlatform.ParsePlatform(order.Method) {
|
|
||||||
case paymentPlatform.AlipayF2F:
|
|
||||||
if l.queryAlipay(paymentConfig, order.TradeNo) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case paymentPlatform.Stripe:
|
|
||||||
if l.queryStripe(paymentConfig, order.TradeNo) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
l.Info("[CloseOrder] Unsupported payment method", logger.Field("paymentMethod", order.Method))
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// queryAlipay Query Alipay payment status
|
|
||||||
func (l *CloseOrderLogic) queryAlipay(paymentConfig *payment.Payment, TradeNo string) bool {
|
|
||||||
config := payment.AlipayF2FConfig{}
|
|
||||||
if err := json.Unmarshal([]byte(paymentConfig.Config), &config); err != nil {
|
|
||||||
l.Error("[CloseOrder] Unmarshal payment config failed", logger.Field("error", err.Error()), logger.Field("config", paymentConfig.Config))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
client := alipay.NewClient(alipay.Config{
|
|
||||||
AppId: config.AppId,
|
|
||||||
PrivateKey: config.PrivateKey,
|
|
||||||
PublicKey: config.PublicKey,
|
|
||||||
InvoiceName: config.InvoiceName,
|
|
||||||
})
|
|
||||||
status, err := client.QueryTrade(l.ctx, TradeNo)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CloseOrder] Query trade failed", logger.Field("error", err.Error()), logger.Field("TradeNo", TradeNo))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if status == alipay.Success || status == alipay.Finished {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// queryStripe Query Stripe payment status
|
|
||||||
func (l *CloseOrderLogic) queryStripe(paymentConfig *payment.Payment, TradeNo string) bool {
|
|
||||||
config := payment.StripeConfig{}
|
|
||||||
if err := json.Unmarshal([]byte(paymentConfig.Config), &config); err != nil {
|
|
||||||
l.Error("[CloseOrder] Unmarshal payment config failed", logger.Field("error", err.Error()), logger.Field("config", paymentConfig.Config))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
client := stripe.NewClient(stripe.Config{
|
|
||||||
PublicKey: config.PublicKey,
|
|
||||||
SecretKey: config.SecretKey,
|
|
||||||
WebhookSecret: config.WebhookSecret,
|
|
||||||
})
|
|
||||||
status, err := client.QueryOrderStatus(TradeNo)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CloseOrder] Query order status failed", logger.Field("error", err.Error()), logger.Field("TradeNo", TradeNo))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return status
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import "github.com/perfect-panel/server/internal/types"
|
|
||||||
|
|
||||||
func getDiscount(discounts []types.SubscribeDiscount, inputMonths int64) float64 {
|
|
||||||
var finalDiscount int64 = 100
|
|
||||||
|
|
||||||
for _, discount := range discounts {
|
|
||||||
if inputMonths >= discount.Quantity && discount.Discount < finalDiscount {
|
|
||||||
finalDiscount = discount.Discount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return float64(finalDiscount) / float64(100)
|
|
||||||
}
|
|
||||||
@ -1,123 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/order"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PreCreateOrderLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pre create order
|
|
||||||
func NewPreCreateOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PreCreateOrderLogic {
|
|
||||||
return &PreCreateOrderLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PurchaseOrderRequest) (resp *types.PreOrderResponse, err error) {
|
|
||||||
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
|
||||||
if !ok {
|
|
||||||
logger.Error("current user is not found in context")
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
|
|
||||||
}
|
|
||||||
// find subscribe plan
|
|
||||||
sub, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, req.SubscribeId)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[PreCreateOrder] Database query error", logger.Field("error", err.Error()), logger.Field("subscribe_id", req.SubscribeId))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find subscribe error: %v", err.Error())
|
|
||||||
}
|
|
||||||
var discount float64 = 1
|
|
||||||
if sub.Discount != "" {
|
|
||||||
var dis []types.SubscribeDiscount
|
|
||||||
_ = json.Unmarshal([]byte(sub.Discount), &dis)
|
|
||||||
discount = getDiscount(dis, req.Quantity)
|
|
||||||
}
|
|
||||||
price := sub.UnitPrice * req.Quantity
|
|
||||||
amount := int64(float64(price) * discount)
|
|
||||||
discountAmount := price - amount
|
|
||||||
var coupon int64
|
|
||||||
if req.Coupon != "" {
|
|
||||||
couponInfo, err := l.svcCtx.CouponModel.FindOneByCode(l.ctx, req.Coupon)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.CouponNotExist), "coupon not found")
|
|
||||||
}
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find coupon error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if couponInfo.Count > 0 && couponInfo.Count <= couponInfo.UsedCount {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.CouponInsufficientUsage), "coupon used")
|
|
||||||
}
|
|
||||||
couponSub := tool.StringToInt64Slice(couponInfo.Subscribe)
|
|
||||||
if len(couponSub) > 0 && !tool.Contains(couponSub, req.SubscribeId) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.CouponNotApplicable), "coupon not match")
|
|
||||||
}
|
|
||||||
var count int64
|
|
||||||
err = l.svcCtx.DB.Transaction(func(tx *gorm.DB) error {
|
|
||||||
return tx.Model(&order.Order{}).Where("user_id = ? and coupon = ?", u.Id, req.Coupon).Count(&count).Error
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[Purchase] Database query error", logger.Field("error", err.Error()), logger.Field("user_id", u.Id), logger.Field("coupon", req.Coupon))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find coupon error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if couponInfo.UserLimit > 0 && count >= couponInfo.UserLimit {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.CouponInsufficientUsage), "coupon limit exceeded")
|
|
||||||
}
|
|
||||||
coupon = calculateCoupon(amount, couponInfo)
|
|
||||||
}
|
|
||||||
amount -= coupon
|
|
||||||
|
|
||||||
var deductionAmount int64
|
|
||||||
// Check user deduction amount
|
|
||||||
if u.GiftAmount > 0 {
|
|
||||||
if u.GiftAmount >= amount {
|
|
||||||
deductionAmount = amount
|
|
||||||
amount = 0
|
|
||||||
} else {
|
|
||||||
deductionAmount = u.GiftAmount
|
|
||||||
amount -= u.GiftAmount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
payment, err := l.svcCtx.PaymentModel.FindOne(l.ctx, req.Payment)
|
|
||||||
if err != nil {
|
|
||||||
l.Logger.Error("[PreCreateOrder] Database query error", logger.Field("error", err.Error()), logger.Field("payment", req.Payment))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find payment method error: %v", err.Error())
|
|
||||||
}
|
|
||||||
var feeAmount int64
|
|
||||||
// Calculate the handling fee
|
|
||||||
if amount > 0 {
|
|
||||||
feeAmount = calculateFee(amount, payment)
|
|
||||||
}
|
|
||||||
amount += feeAmount
|
|
||||||
|
|
||||||
resp = &types.PreOrderResponse{
|
|
||||||
Price: price,
|
|
||||||
Amount: amount,
|
|
||||||
Discount: discountAmount,
|
|
||||||
GiftAmount: deductionAmount,
|
|
||||||
Coupon: req.Coupon,
|
|
||||||
CouponDiscount: coupon,
|
|
||||||
FeeAmount: feeAmount,
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,214 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
|
|
||||||
"github.com/hibiken/asynq"
|
|
||||||
"github.com/perfect-panel/server/internal/model/order"
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
queue "github.com/perfect-panel/server/queue/types"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PurchaseLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
const CloseOrderTimeMinutes = 15
|
|
||||||
|
|
||||||
// purchase Subscription
|
|
||||||
func NewPurchaseLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PurchaseLogic {
|
|
||||||
return &PurchaseLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *PurchaseLogic) Purchase(req *types.PurchaseOrderRequest) (resp *types.PurchaseOrderResponse, err error) {
|
|
||||||
|
|
||||||
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
|
||||||
if !ok {
|
|
||||||
logger.Error("current user is not found in context")
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
|
|
||||||
}
|
|
||||||
// find user subscription
|
|
||||||
|
|
||||||
if l.svcCtx.Config.Subscribe.SingleModel {
|
|
||||||
userSub, err := l.svcCtx.UserModel.QueryUserSubscribe(l.ctx, u.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Purchase] Database query error", logger.Field("error", err.Error()), logger.Field("user_id", u.Id))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find user subscription error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if len(userSub) > 0 {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserSubscribeExist), "user has subscription")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find subscribe plan
|
|
||||||
sub, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, req.SubscribeId)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Purchase] Database query error", logger.Field("error", err.Error()), logger.Field("subscribe_id", req.SubscribeId))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find subscribe error: %v", err.Error())
|
|
||||||
}
|
|
||||||
// check subscribe plan status
|
|
||||||
if !*sub.Sell {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "subscribe not sell")
|
|
||||||
}
|
|
||||||
var discount float64 = 1
|
|
||||||
if sub.Discount != "" {
|
|
||||||
var dis []types.SubscribeDiscount
|
|
||||||
_ = json.Unmarshal([]byte(sub.Discount), &dis)
|
|
||||||
discount = getDiscount(dis, req.Quantity)
|
|
||||||
}
|
|
||||||
price := sub.UnitPrice * req.Quantity
|
|
||||||
// discount amount
|
|
||||||
amount := int64(float64(price) * discount)
|
|
||||||
discountAmount := price - amount
|
|
||||||
var coupon int64 = 0
|
|
||||||
// Calculate the coupon deduction
|
|
||||||
if req.Coupon != "" {
|
|
||||||
couponInfo, err := l.svcCtx.CouponModel.FindOneByCode(l.ctx, req.Coupon)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.CouponNotExist), "coupon not found")
|
|
||||||
}
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find coupon error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if couponInfo.Count <= couponInfo.UsedCount {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.CouponInsufficientUsage), "coupon used")
|
|
||||||
}
|
|
||||||
couponSub := tool.StringToInt64Slice(couponInfo.Subscribe)
|
|
||||||
if len(couponSub) > 0 && !tool.Contains(couponSub, req.SubscribeId) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.CouponNotApplicable), "coupon not match")
|
|
||||||
}
|
|
||||||
var count int64
|
|
||||||
err = l.svcCtx.DB.Transaction(func(tx *gorm.DB) error {
|
|
||||||
return tx.Model(&order.Order{}).Where("user_id = ? and coupon = ?", u.Id, req.Coupon).Count(&count).Error
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[Purchase] Database query error", logger.Field("error", err.Error()), logger.Field("user_id", u.Id), logger.Field("coupon", req.Coupon))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find coupon error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if count >= couponInfo.UserLimit {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.CouponInsufficientUsage), "coupon limit exceeded")
|
|
||||||
}
|
|
||||||
coupon = calculateCoupon(amount, couponInfo)
|
|
||||||
}
|
|
||||||
// Calculate the handling fee
|
|
||||||
amount -= coupon
|
|
||||||
var deductionAmount int64
|
|
||||||
// Check user deduction amount
|
|
||||||
if u.GiftAmount > 0 {
|
|
||||||
if u.GiftAmount >= amount {
|
|
||||||
deductionAmount = amount
|
|
||||||
amount = 0
|
|
||||||
u.GiftAmount -= amount
|
|
||||||
} else {
|
|
||||||
deductionAmount = u.GiftAmount
|
|
||||||
amount -= u.GiftAmount
|
|
||||||
u.GiftAmount = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// find payment method
|
|
||||||
payment, err := l.svcCtx.PaymentModel.FindOne(l.ctx, req.Payment)
|
|
||||||
if err != nil {
|
|
||||||
l.Logger.Error("[Purchase] Database query error", logger.Field("error", err.Error()), logger.Field("payment", req.Payment))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find payment method error: %v", err.Error())
|
|
||||||
}
|
|
||||||
var feeAmount int64
|
|
||||||
// Calculate the handling fee
|
|
||||||
if amount > 0 {
|
|
||||||
feeAmount = calculateFee(amount, payment)
|
|
||||||
}
|
|
||||||
// query user is new purchase or renewal
|
|
||||||
isNew, err := l.svcCtx.OrderModel.IsUserEligibleForNewOrder(l.ctx, u.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Purchase] Database query error", logger.Field("error", err.Error()), logger.Field("user_id", u.Id))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find user order error: %v", err.Error())
|
|
||||||
}
|
|
||||||
// create order
|
|
||||||
orderInfo := &order.Order{
|
|
||||||
UserId: u.Id,
|
|
||||||
OrderNo: tool.GenerateTradeNo(),
|
|
||||||
Type: 1,
|
|
||||||
Quantity: req.Quantity,
|
|
||||||
Price: price,
|
|
||||||
Amount: amount,
|
|
||||||
Discount: discountAmount,
|
|
||||||
GiftAmount: deductionAmount,
|
|
||||||
Coupon: req.Coupon,
|
|
||||||
CouponDiscount: coupon,
|
|
||||||
PaymentId: req.Payment,
|
|
||||||
Method: payment.Platform,
|
|
||||||
FeeAmount: feeAmount,
|
|
||||||
Status: 1,
|
|
||||||
IsNew: isNew,
|
|
||||||
SubscribeId: req.SubscribeId,
|
|
||||||
}
|
|
||||||
// Database transaction
|
|
||||||
err = l.svcCtx.DB.Transaction(func(db *gorm.DB) error {
|
|
||||||
// update user deduction && Pre deduction ,Return after canceling the order
|
|
||||||
if orderInfo.GiftAmount > 0 {
|
|
||||||
// update user deduction && Pre deduction ,Return after canceling the order
|
|
||||||
if e := l.svcCtx.UserModel.Update(l.ctx, u, db); err != nil {
|
|
||||||
l.Error("[Purchase] Database update error", logger.Field("error", err.Error()), logger.Field("user", u))
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
// create deduction record
|
|
||||||
giftAmountLog := user.GiftAmountLog{
|
|
||||||
UserId: orderInfo.UserId,
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
Amount: orderInfo.GiftAmount,
|
|
||||||
Type: 2,
|
|
||||||
Balance: u.GiftAmount,
|
|
||||||
Remark: "Purchase order deduction",
|
|
||||||
}
|
|
||||||
if e := db.Model(&user.GiftAmountLog{}).Create(&giftAmountLog).Error; e != nil {
|
|
||||||
l.Error("[Purchase] Database insert error",
|
|
||||||
logger.Field("error", err.Error()),
|
|
||||||
logger.Field("deductionLog", giftAmountLog),
|
|
||||||
)
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// insert order
|
|
||||||
return db.Model(&order.Order{}).Create(&orderInfo).Error
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "insert order error: %v", err.Error())
|
|
||||||
}
|
|
||||||
// Deferred task
|
|
||||||
payload := queue.DeferCloseOrderPayload{
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
}
|
|
||||||
val, err := json.Marshal(payload)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CreateOrder] Marshal payload error", logger.Field("error", err.Error()), logger.Field("payload", payload))
|
|
||||||
}
|
|
||||||
task := asynq.NewTask(queue.DeferCloseOrder, val, asynq.MaxRetry(3))
|
|
||||||
taskInfo, err := l.svcCtx.Queue.Enqueue(task, asynq.ProcessIn(CloseOrderTimeMinutes*time.Minute))
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[CreateOrder] Enqueue task error", logger.Field("error", err.Error()), logger.Field("task", task))
|
|
||||||
} else {
|
|
||||||
l.Info("[CreateOrder] Enqueue task success", logger.Field("TaskID", taskInfo.ID))
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.PurchaseOrderResponse{
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type QueryOrderDetailLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get order
|
|
||||||
func NewQueryOrderDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryOrderDetailLogic {
|
|
||||||
return &QueryOrderDetailLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *QueryOrderDetailLogic) QueryOrderDetail(req *types.QueryOrderDetailRequest) (resp *types.OrderDetail, err error) {
|
|
||||||
orderInfo, err := l.svcCtx.OrderModel.FindOneDetailsByOrderNo(l.ctx, req.OrderNo)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[QueryOrderDetail] Database query error", logger.Field("error", err.Error()), logger.Field("order_no", req.OrderNo))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find order error: %v", err.Error())
|
|
||||||
}
|
|
||||||
resp = &types.OrderDetail{}
|
|
||||||
tool.DeepCopy(resp, orderInfo)
|
|
||||||
// Prevent commission amount leakage
|
|
||||||
resp.Commission = 0
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type QueryOrderListLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get order list
|
|
||||||
func NewQueryOrderListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryOrderListLogic {
|
|
||||||
return &QueryOrderListLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *QueryOrderListLogic) QueryOrderList(req *types.QueryOrderListRequest) (resp *types.QueryOrderListResponse, err error) {
|
|
||||||
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
|
||||||
if !ok {
|
|
||||||
logger.Error("current user is not found in context")
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
|
|
||||||
}
|
|
||||||
total, data, err := l.svcCtx.OrderModel.QueryOrderListByPage(l.ctx, req.Page, req.Size, 0, u.Id, 0, "")
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[QueryOrderListLogic] Query order list failed", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "Query order list failed")
|
|
||||||
}
|
|
||||||
resp = &types.QueryOrderListResponse{
|
|
||||||
Total: total,
|
|
||||||
List: make([]types.OrderDetail, 0),
|
|
||||||
}
|
|
||||||
for _, item := range data {
|
|
||||||
var orderInfo types.OrderDetail
|
|
||||||
tool.DeepCopy(&orderInfo, item)
|
|
||||||
// Prevent commission amount leakage
|
|
||||||
orderInfo.Commission = 0
|
|
||||||
resp.List = append(resp.List, orderInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
|
|
||||||
"github.com/hibiken/asynq"
|
|
||||||
"github.com/perfect-panel/server/internal/model/order"
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
queue "github.com/perfect-panel/server/queue/types"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RechargeLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRechargeLogic Recharge
|
|
||||||
func NewRechargeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RechargeLogic {
|
|
||||||
return &RechargeLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *RechargeLogic) Recharge(req *types.RechargeOrderRequest) (resp *types.RechargeOrderResponse, err error) {
|
|
||||||
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
|
||||||
if !ok {
|
|
||||||
logger.Error("current user is not found in context")
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
|
|
||||||
}
|
|
||||||
// find payment method
|
|
||||||
payment, err := l.svcCtx.PaymentModel.FindOne(l.ctx, req.Payment)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Recharge] Database query error", logger.Field("error", err.Error()), logger.Field("payment", req.Payment))
|
|
||||||
return nil, errors.Wrapf(err, "find payment error: %v", err.Error())
|
|
||||||
}
|
|
||||||
// Calculate the handling fee
|
|
||||||
feeAmount := calculateFee(req.Amount, payment)
|
|
||||||
// query user is new purchase or renewal
|
|
||||||
isNew, err := l.svcCtx.OrderModel.IsUserEligibleForNewOrder(l.ctx, u.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Recharge] Database query error", logger.Field("error", err.Error()), logger.Field("user_id", u.Id))
|
|
||||||
return nil, errors.Wrapf(err, "query user error: %v", err.Error())
|
|
||||||
}
|
|
||||||
orderInfo := order.Order{
|
|
||||||
UserId: u.Id,
|
|
||||||
OrderNo: tool.GenerateTradeNo(),
|
|
||||||
Type: 4,
|
|
||||||
Price: req.Amount,
|
|
||||||
Amount: req.Amount + feeAmount,
|
|
||||||
FeeAmount: feeAmount,
|
|
||||||
PaymentId: req.Payment,
|
|
||||||
Method: payment.Platform,
|
|
||||||
Status: 1,
|
|
||||||
IsNew: isNew,
|
|
||||||
}
|
|
||||||
err = l.svcCtx.OrderModel.Insert(l.ctx, &orderInfo)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Recharge] Database insert error", logger.Field("error", err.Error()), logger.Field("order", orderInfo))
|
|
||||||
return nil, errors.Wrapf(err, "insert order error: %v", err.Error())
|
|
||||||
}
|
|
||||||
// Deferred task
|
|
||||||
payload := queue.DeferCloseOrderPayload{
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
}
|
|
||||||
val, err := json.Marshal(payload)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Recharge] Marshal payload error", logger.Field("error", err.Error()), logger.Field("payload", payload))
|
|
||||||
}
|
|
||||||
task := asynq.NewTask(queue.DeferCloseOrder, val, asynq.MaxRetry(3))
|
|
||||||
taskInfo, err := l.svcCtx.Queue.Enqueue(task, asynq.ProcessIn(CloseOrderTimeMinutes*time.Minute))
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Recharge] Enqueue task error", logger.Field("error", err.Error()), logger.Field("task", task))
|
|
||||||
} else {
|
|
||||||
l.Info("[Recharge] Enqueue task success", logger.Field("TaskID", taskInfo.ID))
|
|
||||||
}
|
|
||||||
return &types.RechargeOrderResponse{
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,178 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
|
|
||||||
"github.com/hibiken/asynq"
|
|
||||||
"github.com/perfect-panel/server/internal/model/order"
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
queue "github.com/perfect-panel/server/queue/types"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RenewalLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Renewal Subscription
|
|
||||||
func NewRenewalLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RenewalLogic {
|
|
||||||
return &RenewalLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *RenewalLogic) Renewal(req *types.RenewalOrderRequest) (resp *types.RenewalOrderResponse, err error) {
|
|
||||||
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
|
||||||
if !ok {
|
|
||||||
logger.Error("current user is not found in context")
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
|
|
||||||
}
|
|
||||||
orderNo := tool.GenerateTradeNo()
|
|
||||||
// find user subscribe
|
|
||||||
userSubscribe, err := l.svcCtx.UserModel.FindOneUserSubscribe(l.ctx, req.UserSubscribeID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find user subscribe error: %v", err.Error())
|
|
||||||
}
|
|
||||||
// find subscription
|
|
||||||
sub, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, userSubscribe.SubscribeId)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Renewal] Database query error", logger.Field("error", err.Error()), logger.Field("subscribe_id", userSubscribe.SubscribeId))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find subscribe error: %v", err.Error())
|
|
||||||
}
|
|
||||||
// check subscribe plan status
|
|
||||||
if !*sub.Sell {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "subscribe not sell")
|
|
||||||
}
|
|
||||||
var discount float64 = 1
|
|
||||||
if sub.Discount != "" {
|
|
||||||
var dis []types.SubscribeDiscount
|
|
||||||
_ = json.Unmarshal([]byte(sub.Discount), &dis)
|
|
||||||
discount = getDiscount(dis, req.Quantity)
|
|
||||||
}
|
|
||||||
price := sub.UnitPrice * req.Quantity
|
|
||||||
amount := int64(float64(price) * discount)
|
|
||||||
discountAmount := price - amount
|
|
||||||
var coupon int64 = 0
|
|
||||||
if req.Coupon != "" {
|
|
||||||
couponInfo, err := l.svcCtx.CouponModel.FindOneByCode(l.ctx, req.Coupon)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Renewal] Database query error", logger.Field("error", err.Error()), logger.Field("coupon", req.Coupon))
|
|
||||||
return nil, errors.Wrapf(err, "find coupon error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if couponInfo.Count <= couponInfo.UsedCount {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.CouponInsufficientUsage), "coupon used")
|
|
||||||
}
|
|
||||||
coupon = calculateCoupon(amount, couponInfo)
|
|
||||||
}
|
|
||||||
payment, err := l.svcCtx.PaymentModel.FindOne(l.ctx, req.Payment)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Renewal] Database query error", logger.Field("error", err.Error()), logger.Field("payment", req.Payment))
|
|
||||||
return nil, errors.Wrapf(err, "find payment error: %v", err.Error())
|
|
||||||
}
|
|
||||||
amount -= coupon
|
|
||||||
|
|
||||||
var deductionAmount int64
|
|
||||||
// Check user deduction amount
|
|
||||||
if u.GiftAmount > 0 {
|
|
||||||
if u.GiftAmount >= amount {
|
|
||||||
deductionAmount = amount
|
|
||||||
amount = 0
|
|
||||||
u.GiftAmount -= amount
|
|
||||||
} else {
|
|
||||||
deductionAmount = u.GiftAmount
|
|
||||||
amount -= u.GiftAmount
|
|
||||||
u.GiftAmount = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var feeAmount int64
|
|
||||||
// Calculate the handling fee
|
|
||||||
if amount > 0 {
|
|
||||||
feeAmount = calculateFee(amount, payment)
|
|
||||||
}
|
|
||||||
|
|
||||||
amount += feeAmount
|
|
||||||
|
|
||||||
// create order
|
|
||||||
orderInfo := order.Order{
|
|
||||||
UserId: u.Id,
|
|
||||||
ParentId: userSubscribe.OrderId,
|
|
||||||
OrderNo: orderNo,
|
|
||||||
Type: 2,
|
|
||||||
Quantity: req.Quantity,
|
|
||||||
Price: price,
|
|
||||||
Amount: amount,
|
|
||||||
GiftAmount: deductionAmount,
|
|
||||||
Discount: discountAmount,
|
|
||||||
Coupon: req.Coupon,
|
|
||||||
CouponDiscount: coupon,
|
|
||||||
PaymentId: payment.Id,
|
|
||||||
Method: payment.Platform,
|
|
||||||
FeeAmount: feeAmount,
|
|
||||||
Status: 1,
|
|
||||||
SubscribeId: userSubscribe.SubscribeId,
|
|
||||||
SubscribeToken: userSubscribe.Token,
|
|
||||||
}
|
|
||||||
// Database transaction
|
|
||||||
err = l.svcCtx.DB.Transaction(func(db *gorm.DB) error {
|
|
||||||
// update user deduction && Pre deduction ,Return after canceling the order
|
|
||||||
if orderInfo.GiftAmount > 0 {
|
|
||||||
// update user deduction && Pre deduction ,Return after canceling the order
|
|
||||||
if err := l.svcCtx.UserModel.Update(l.ctx, u, db); err != nil {
|
|
||||||
l.Error("[Purchase] Database update error", logger.Field("error", err.Error()), logger.Field("user", u))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// create deduction record
|
|
||||||
deductionLog := user.GiftAmountLog{
|
|
||||||
UserId: orderInfo.UserId,
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
Amount: orderInfo.GiftAmount,
|
|
||||||
Type: 2,
|
|
||||||
Balance: u.GiftAmount,
|
|
||||||
Remark: "Renewal order deduction",
|
|
||||||
}
|
|
||||||
if err := db.Model(&user.GiftAmountLog{}).Create(&deductionLog).Error; err != nil {
|
|
||||||
l.Error("[Renewal] Database insert error", logger.Field("error", err.Error()), logger.Field("deductionLog", deductionLog))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// insert order
|
|
||||||
return db.Model(&order.Order{}).Create(&orderInfo).Error
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Renewal] Database insert error", logger.Field("error", err.Error()), logger.Field("order", orderInfo))
|
|
||||||
return nil, errors.Wrapf(err, "insert order error: %v", err.Error())
|
|
||||||
}
|
|
||||||
// Deferred task
|
|
||||||
payload := queue.DeferCloseOrderPayload{
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
}
|
|
||||||
val, err := json.Marshal(payload)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Renewal] Marshal payload error", logger.Field("error", err.Error()), logger.Field("payload", payload))
|
|
||||||
}
|
|
||||||
task := asynq.NewTask(queue.DeferCloseOrder, val, asynq.MaxRetry(3))
|
|
||||||
taskInfo, err := l.svcCtx.Queue.Enqueue(task, asynq.ProcessIn(CloseOrderTimeMinutes*time.Minute))
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[Renewal] Enqueue task error", logger.Field("error", err.Error()), logger.Field("task", task))
|
|
||||||
} else {
|
|
||||||
l.Info("[Renewal] Enqueue task success", logger.Field("TaskID", taskInfo.ID))
|
|
||||||
}
|
|
||||||
return &types.RenewalOrderResponse{
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
package order
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"github.com/hibiken/asynq"
|
|
||||||
"github.com/perfect-panel/server/internal/model/order"
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
queue "github.com/perfect-panel/server/queue/types"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ResetTrafficLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset traffic
|
|
||||||
func NewResetTrafficLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ResetTrafficLogic {
|
|
||||||
return &ResetTrafficLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *ResetTrafficLogic) ResetTraffic(req *types.ResetTrafficOrderRequest) (resp *types.ResetTrafficOrderResponse, err error) {
|
|
||||||
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
|
||||||
if !ok {
|
|
||||||
logger.Error("current user is not found in context")
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
|
|
||||||
}
|
|
||||||
// find user subscription
|
|
||||||
userSubscribe, err := l.svcCtx.UserModel.FindOneUserSubscribe(l.ctx, req.UserSubscribeID)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[ResetTraffic] Database query error", logger.Field("error", err.Error()), logger.Field("UserSubscribeID", req.UserSubscribeID))
|
|
||||||
return nil, errors.Wrapf(err, "find user subscribe error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if userSubscribe.Subscribe == nil {
|
|
||||||
l.Error("[ResetTraffic] subscribe not found", logger.Field("UserSubscribeID", req.UserSubscribeID))
|
|
||||||
return nil, errors.New("subscribe not found")
|
|
||||||
}
|
|
||||||
amount := userSubscribe.Subscribe.Replacement
|
|
||||||
var deductionAmount int64
|
|
||||||
// Check user deduction amount
|
|
||||||
if u.GiftAmount > 0 {
|
|
||||||
if u.GiftAmount >= amount {
|
|
||||||
deductionAmount = amount
|
|
||||||
amount = 0
|
|
||||||
u.GiftAmount -= amount
|
|
||||||
} else {
|
|
||||||
deductionAmount = u.GiftAmount
|
|
||||||
amount -= u.GiftAmount
|
|
||||||
u.GiftAmount = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// find payment method
|
|
||||||
payment, err := l.svcCtx.PaymentModel.FindOne(l.ctx, req.Payment)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[ResetTraffic] Database query error", logger.Field("error", err.Error()), logger.Field("payment", req.Payment))
|
|
||||||
return nil, errors.Wrapf(err, "find payment error: %v", err.Error())
|
|
||||||
}
|
|
||||||
var feeAmount int64
|
|
||||||
// Calculate the handling fee
|
|
||||||
if amount > 0 {
|
|
||||||
feeAmount = calculateFee(amount, payment)
|
|
||||||
}
|
|
||||||
// create order
|
|
||||||
orderInfo := order.Order{
|
|
||||||
Id: 0,
|
|
||||||
ParentId: userSubscribe.OrderId,
|
|
||||||
UserId: u.Id,
|
|
||||||
OrderNo: tool.GenerateTradeNo(),
|
|
||||||
Type: 3,
|
|
||||||
Price: userSubscribe.Subscribe.Replacement,
|
|
||||||
Amount: amount + feeAmount,
|
|
||||||
GiftAmount: deductionAmount,
|
|
||||||
FeeAmount: feeAmount,
|
|
||||||
PaymentId: req.Payment,
|
|
||||||
Method: payment.Platform,
|
|
||||||
Status: 1,
|
|
||||||
SubscribeId: userSubscribe.SubscribeId,
|
|
||||||
SubscribeToken: userSubscribe.Token,
|
|
||||||
}
|
|
||||||
// Database transaction
|
|
||||||
err = l.svcCtx.DB.Transaction(func(db *gorm.DB) error {
|
|
||||||
// update user deduction && Pre deduction ,Return after canceling the order
|
|
||||||
if orderInfo.GiftAmount > 0 {
|
|
||||||
// update user deduction && Pre deduction ,Return after canceling the order
|
|
||||||
if err := l.svcCtx.UserModel.Update(l.ctx, u, db); err != nil {
|
|
||||||
l.Error("[ResetTraffic] Database update error", logger.Field("error", err.Error()), logger.Field("user", u))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// create deduction record
|
|
||||||
deductionLog := user.GiftAmountLog{
|
|
||||||
UserId: orderInfo.UserId,
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
Amount: orderInfo.GiftAmount,
|
|
||||||
Type: 2,
|
|
||||||
Balance: u.GiftAmount,
|
|
||||||
Remark: "ResetTraffic order deduction",
|
|
||||||
}
|
|
||||||
if err := db.Model(&user.GiftAmountLog{}).Create(&deductionLog).Error; err != nil {
|
|
||||||
l.Error("[ResetTraffic] Database insert error", logger.Field("error", err.Error()), logger.Field("deductionLog", deductionLog))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// insert order
|
|
||||||
return db.Model(&order.Order{}).Create(&orderInfo).Error
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[ResetTraffic] Database insert error", logger.Field("error", err.Error()), logger.Field("order", orderInfo))
|
|
||||||
return nil, errors.Wrapf(err, "insert order error: %v", err.Error())
|
|
||||||
}
|
|
||||||
// Deferred task
|
|
||||||
payload := queue.DeferCloseOrderPayload{
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
}
|
|
||||||
val, err := json.Marshal(payload)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[ResetTraffic] Marshal payload error", logger.Field("error", err.Error()), logger.Field("payload", payload))
|
|
||||||
}
|
|
||||||
task := asynq.NewTask(queue.DeferCloseOrder, val, asynq.MaxRetry(3))
|
|
||||||
taskInfo, err := l.svcCtx.Queue.Enqueue(task, asynq.ProcessIn(CloseOrderTimeMinutes*time.Minute))
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[ResetTraffic] Enqueue task error", logger.Field("error", err.Error()), logger.Field("task", task))
|
|
||||||
} else {
|
|
||||||
l.Info("[ResetTraffic] Enqueue task success", logger.Field("TaskID", taskInfo.ID))
|
|
||||||
}
|
|
||||||
return &types.ResetTrafficOrderResponse{
|
|
||||||
OrderNo: orderInfo.OrderNo,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package payment
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetAvailablePaymentMethodsLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewGetAvailablePaymentMethodsLogic Get available payment methods
|
|
||||||
func NewGetAvailablePaymentMethodsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAvailablePaymentMethodsLogic {
|
|
||||||
return &GetAvailablePaymentMethodsLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetAvailablePaymentMethodsLogic) GetAvailablePaymentMethods() (resp *types.GetAvailablePaymentMethodsResponse, err error) {
|
|
||||||
data, err := l.svcCtx.PaymentModel.FindAvailableMethods(l.ctx)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("[GetAvailablePaymentMethods] database error", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "GetAvailablePaymentMethods: %v", err.Error())
|
|
||||||
}
|
|
||||||
resp = &types.GetAvailablePaymentMethodsResponse{
|
|
||||||
List: make([]types.PaymentMethod, 0),
|
|
||||||
}
|
|
||||||
tool.DeepCopy(&resp.List, data)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,115 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/application"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/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
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/subscribe"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/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
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
"github.com/perfect-panel/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
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/order"
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/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
|
|
||||||
}
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
package subscribe
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/user"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/constant"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/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
|
|
||||||
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user