Compare commits

...

122 Commits

Author SHA1 Message Date
Chang lue Tsen
4ad18a8b70 fix(model): update save method to use specific ID for record updates 2025-09-16 11:20:48 -04:00
Chang lue Tsen
596434454c feat(client): add additional options for Shadowsocks and Vless protocols 2025-09-16 11:20:39 -04:00
Chang lue Tsen
b5c756af35 feat(subscribe): update subscribe path 2025-09-16 10:39:19 -04:00
Chang lue Tsen
621eda41c2 fix(client): Shadowrocket template 2025-09-16 10:26:39 -04:00
Chang lue Tsen
900096ed12 fix(coupon): add check for zero count in coupon usage validation 2025-09-16 10:17:18 -04:00
Chang lue Tsen
26fe430d7c fix(subscribe): update status filter in subscription count query 2025-09-16 10:16:56 -04:00
Chang lue Tsen
0c55d173cb fix(model): add sorting to server and node queries 2025-09-16 10:10:11 -04:00
Chang lue Tsen
537dab1c3b fix(quota): simplify gift amount calculation 2025-09-16 09:53:03 -04:00
Leif Draven
4b2976a670
fix(schema): remove unnecessary AUTO_INCREMENT values from initial schema (#79)
Co-authored-by: Chang lue Tsen <tension@ppanel.dev>
2025-09-16 09:33:28 -04:00
Chang lue Tsen
38491ddc0d Merge branch 'master' into develop 2025-09-14 11:34:07 -04:00
Leif Draven
e895180388
Develop (#76)
* refactor: rename queryannouncementhandler.go to queryAnnouncementLogic.go for clarity

* feat(panDomain): update subscription logic to use V2 handler for improved functionality

* refactor(subscribe): replace V2 handler with a unified Handler method for subscription logic

* feat(subscribe): implement user agent limit feature with configurable list

* fix(subscribe): improve error handling and logging for subscription requests

* feat(subscribe): add user agent limit configuration to system settings

* refactor(api): remove deprecated application-related endpoints and types

* refactor(swagger): remove deprecated app.json generation from swagger configuration

* refactor(swagger): remove deprecated app.json check from swagger configuration

* fix(subscribe): update delete method to use Where clause for improved query accuracy

* fix(subscribe): update Id field tag to use primaryKey and improve save method query

* fix(subscribe): update Id field tag to use primaryKey and improve model queries

* fix(subscribe): rename variable for clarity and add special handling for Stash user agent

* fix(email): convert RegisterStartTime and RegisterEndTime to time.Time for accurate query filtering

* refactor(log): consolidate logging models and update related logic for improved clarity and functionality

* fix(types): change Content field type in MessageLog to interface{} for improved flexibility

* fix(log): change MessageLog list to use value type for improved performance and memory efficiency

* fix(email): set EmailTypeVerify in task payload and update content type conversion for verification email

* fix(log): remove unused Id field from SystemLog during login log insertion

* fix(login): remove debug logs and error logging during user login process

* fix(log): add traffic reset logging for subscription resets

* fix(log): insert reset traffic log during subscription activation

* feat(log): add endpoints for retrieving and resetting subscribe traffic logs

* refactor(log): remove Reset Subscribe Traffic Log endpoint and related types

* feat(traffic): add traffic statistics logging and scheduling

* fix(subscribe): ensure active status and reset timestamps during traffic resets

* feat(api): enhance server and node management with new request/response structures

* refactor(api): rename OnlineUser to ServerOnlineUser for clarity

* feat(api): define OnlineUser type with SID and IP fields

* feat(server): implement server management handlers and database schema

* feat(api): add traffic log details filtering and enhance traffic log structures

* feat(api): migrate server and node data handling, update related structures and logic

* feat(server): implement server deletion logic with error handling

* feat(api): update log filtering to use ResetSubscribe type for subscription logs

* feat(api): standardize timestamp field across log structures

* feat(api): refactor cache key handling for server and user lists

* feat(api): enhance server status handling with protocol support and refactor related logic

* fix(traffic): adjust start date for traffic statistics and improve log deletion comment

* feat(api): implement daily traffic ranking for users and servers with error handling

* feat(api): update server total data response to use 'OnlineUsers' and implement daily traffic statistics logging

* feat(api): add log settings management with auto-clear and clear days configuration

* fix(log): correct category in log settings update query

* feat(routes): add handler for scheduled traffic statistics

* feat(model): add user counts struct and update queries for new and renewal users

* feat(api): add referral percentage and only first purchase fields to user model and requests

* feat(database): update user table to add referral percentage and only first purchase fields

* feat(api): add reset sort endpoints for server and node

* feat(api): add sort field to server model

* feat(api): implement sorting functionality for nodes and servers

* fix(database): add sort column to nodes table

* fix(model): enhance user statistics queries with new order and renewal order counts

* fix(log): update timestamp handling in login and registration logs

* fix(log): update sorting logic for server and user subscribe traffic logs

* fix(server): add server status handling based on last reported time

* fix(model): correct filter condition to use 'date' instead of 'data'

* fix(migration): add index for traffic log on timestamp, user_id, and subscribe_id

* fix(log): optimize user traffic rank data handling by using append instead of index assignment

* fix(filter): refactor node list creation to use append and remove duplicates from tags

* fix(node): add ServerId and Enabled fields to node update logic

* feat(tags): add endpoint to query all node tags

* fix(preview): add Preload parameter to FilterNodeList for improved data retrieval

* fix(log): date is empty

* feat(subscribe): add Language field to subscription models and update query logic

* feat(subscription): add Language parameter to GetSubscription request and update query logic

* fix(server): encode ServerKey in base64 and update last reported time for nodes

* feat: delete common GetSubscription

* feat(subscription): implement FilterList method for subscription queries and update related logic

* fix(subscribe): remove duplicate user agents in SubscribeHandler

* fix(push): initialize onlineUsers as a map in pushOnlineUsersLogic

* fix(reset): initialize subs as a map in clearCache method

* refactor(query): simplify node and tag filtering using InSet function

* feat(userlist): enhance GetServerUserListLogic with improved node and tag handling

* fix(userlist): correct node ID assignment and update query logic for tag filtering

* fix(userlist): correct node ID assignment in getServerUserListLogic

* refactor(query): streamline query construction for tag filtering

* fix(statistics): optimize server ranking data handling in QueryServerTotalDataLogic

* refactor(statistics): simplify server ranking data construction in QueryServerTotalDataLogic

* fix(statistics): correct server traffic data assignment in QueryServerTotalDataLogic

* fix(statistics): optimize yesterday's top 10 server traffic data assignment in QueryServerTotalDataLogic

* fix(middleware): remove duplicate elements from user agent list in PanDomainMiddleware

* feat(middleware): enhance user agent handling by querying client list in PanDomainMiddleware

* feat(client): subscribe_template

* feat(oauth): add user agent and IP logging to registration and login processes

* fix(balance): add timestamp to balance logs for payment, refund, and recharge transactions

* fix(log): correct comment for CommissionTypeRefund to improve clarity

* fix(log): replace magic number with constant for gift type in purchase checkout logic

* fix(log): rename OrderId to OrderNo for consistency in balance logging

* feat(log): add logging for balance, gift amount, and commission adjustments

* fix(user): correct placement of DeepCopy for user info update logic

* feat(log): add UserSubscribeId to FilterSubscribeLogRequest for enhanced filtering

* fix(purchase): streamline error handling and improve JSON marshaling for temporary orders

* fix(order): simplify commission handling and improve payload parsing logic

* fix(order): update commission calculation to actual payment amount minus gateway handling fee

* feat(payment): add support for CryptoSaaS payment platform and enhance configuration handling

* fix(balance): update QueryUserBalanceLog response structure to include balance log list

* fix(email): update task progress handling to use specific task ID for updates

* feat(quota): add quota task creation and querying endpoints with updated data structures

* fix(email): update task handling to use generic task model and improve error logging

* fix(order): improve error logging for database transaction and user cache updates

* feat(quota): enhance quota task management with new request structures and processing logic

* fix(quota): remove redundant quota task status endpoint from admin marketing routes

* fix(worker): update task completion status handling in worker logic

* fix(quota): update taskInfo to include current subscription count in quota logic

* doc(log): rename function for clarity and add cache cleanup comment

* fix(quota): update time handling in quota logic and correct subscriber ID query

* fix(quota): update time handling to use UnixMilli for start time in quota logic

* feat(protocol): add server protocol configuration query and enhance protocol options

* fix(quota): correct time range queries for start and expire times in quota logic

* fix(types): update plugin options to include 'none' in the plugin field

---------

Co-authored-by: Chang lue Tsen <tension@ppanel.dev>
2025-09-14 09:50:22 -04:00
Chang lue Tsen
435283f962 fix(types): update plugin options to include 'none' in the plugin field 2025-09-14 09:46:14 -04:00
Chang lue Tsen
b0ffb15825 fix(quota): correct time range queries for start and expire times in quota logic 2025-09-14 09:43:21 -04:00
Chang lue Tsen
2c5efa2026 feat(protocol): add server protocol configuration query and enhance protocol options 2025-09-13 14:20:04 -04:00
Chang lue Tsen
c1c913cb00 fix(quota): update time handling to use UnixMilli for start time in quota logic 2025-09-13 14:12:33 -04:00
Chang lue Tsen
cf4792cdc8 fix(quota): update time handling in quota logic and correct subscriber ID query 2025-09-13 14:02:49 -04:00
Chang lue Tsen
9b0e1b1e0f doc(log): rename function for clarity and add cache cleanup comment 2025-09-11 11:42:20 -04:00
Chang lue Tsen
6bc0fb4d90 fix(quota): update taskInfo to include current subscription count in quota logic 2025-09-11 06:29:12 -04:00
Chang lue Tsen
32633920b5 fix(worker): update task completion status handling in worker logic 2025-09-11 06:24:52 -04:00
Chang lue Tsen
d55bad712c fix(quota): remove redundant quota task status endpoint from admin marketing routes 2025-09-10 14:54:31 -04:00
Chang lue Tsen
3f5aac239b feat(quota): enhance quota task management with new request structures and processing logic 2025-09-10 14:53:48 -04:00
Chang lue Tsen
83c1c14b01 fix(order): improve error logging for database transaction and user cache updates 2025-09-10 10:41:29 -04:00
Chang lue Tsen
1c1365d862 fix(email): update task handling to use generic task model and improve error logging 2025-09-10 09:02:54 -04:00
Chang lue Tsen
d1be5febc3 feat(quota): add quota task creation and querying endpoints with updated data structures 2025-09-09 13:39:05 -04:00
Chang lue Tsen
f4c6bd919b fix(email): update task progress handling to use specific task ID for updates 2025-09-08 12:53:28 -04:00
Chang lue Tsen
31cdcd2cb9 fix(balance): update QueryUserBalanceLog response structure to include balance log list 2025-09-07 11:59:34 -04:00
Chang lue Tsen
4d95834c22 feat(payment): add support for CryptoSaaS payment platform and enhance configuration handling 2025-09-06 12:22:39 -04:00
Chang lue Tsen
47446ef410 fix(order): update commission calculation to actual payment amount minus gateway handling fee 2025-09-06 11:41:17 -04:00
Chang lue Tsen
0872099e98 fix(order): simplify commission handling and improve payload parsing logic 2025-09-06 11:28:32 -04:00
Chang lue Tsen
d5ed82955e fix(purchase): streamline error handling and improve JSON marshaling for temporary orders 2025-09-06 11:03:14 -04:00
Chang lue Tsen
d477ba4772 feat(log): add UserSubscribeId to FilterSubscribeLogRequest for enhanced filtering 2025-09-05 13:35:55 -04:00
Chang lue Tsen
6460f2f2e1 fix(user): correct placement of DeepCopy for user info update logic 2025-09-05 11:14:38 -04:00
Chang lue Tsen
0199dc7fa2 feat(log): add logging for balance, gift amount, and commission adjustments 2025-09-05 11:00:19 -04:00
Chang lue Tsen
1d878592ed fix(log): rename OrderId to OrderNo for consistency in balance logging 2025-09-05 10:25:19 -04:00
Chang lue Tsen
d0d03e724e fix(log): replace magic number with constant for gift type in purchase checkout logic 2025-09-05 09:52:45 -04:00
Chang lue Tsen
2f4cc46a38 fix(log): correct comment for CommissionTypeRefund to improve clarity 2025-09-05 09:51:28 -04:00
Chang lue Tsen
3199dc5141 fix(balance): add timestamp to balance logs for payment, refund, and recharge transactions 2025-09-05 09:29:19 -04:00
Chang lue Tsen
71d32d73bb feat(oauth): add user agent and IP logging to registration and login processes 2025-09-05 09:26:10 -04:00
Chang lue Tsen
584067375b feat(client): subscribe_template 2025-09-05 05:13:30 -04:00
Chang lue Tsen
b9ef8f4572 feat(middleware): enhance user agent handling by querying client list in PanDomainMiddleware 2025-09-05 04:28:05 -04:00
Chang lue Tsen
f3c73a5224 fix(middleware): remove duplicate elements from user agent list in PanDomainMiddleware 2025-09-05 04:16:33 -04:00
Chang lue Tsen
51335f4c19 fix(statistics): optimize yesterday's top 10 server traffic data assignment in QueryServerTotalDataLogic 2025-09-04 15:31:19 -04:00
Chang lue Tsen
7912d2908f fix(statistics): correct server traffic data assignment in QueryServerTotalDataLogic 2025-09-04 15:26:52 -04:00
Chang lue Tsen
e913f974bb refactor(statistics): simplify server ranking data construction in QueryServerTotalDataLogic 2025-09-04 15:21:07 -04:00
Chang lue Tsen
e8d3ebba68 fix(statistics): optimize server ranking data handling in QueryServerTotalDataLogic 2025-09-04 15:11:12 -04:00
Chang lue Tsen
b4a05166a4 refactor(query): streamline query construction for tag filtering 2025-09-04 14:17:26 -04:00
Chang lue Tsen
712e31cc60 fix(userlist): correct node ID assignment in getServerUserListLogic 2025-09-04 14:09:17 -04:00
Chang lue Tsen
60988bc2ba fix(userlist): correct node ID assignment and update query logic for tag filtering 2025-09-04 14:05:04 -04:00
Chang lue Tsen
61ac829c37 feat(userlist): enhance GetServerUserListLogic with improved node and tag handling 2025-09-04 13:46:24 -04:00
Chang lue Tsen
805fca90e0 refactor(query): simplify node and tag filtering using InSet function 2025-09-04 13:08:57 -04:00
Chang lue Tsen
ef7491d025 fix(reset): initialize subs as a map in clearCache method 2025-09-04 12:32:28 -04:00
Chang lue Tsen
a2d8d7d0bd fix(push): initialize onlineUsers as a map in pushOnlineUsersLogic 2025-09-04 12:13:55 -04:00
Chang lue Tsen
e798f8de1b fix(subscribe): remove duplicate user agents in SubscribeHandler 2025-09-04 11:38:46 -04:00
Chang lue Tsen
0636a4bddf feat(subscription): implement FilterList method for subscription queries and update related logic 2025-09-04 10:20:35 -04:00
Chang lue Tsen
8f11380e7a feat: delete common GetSubscription 2025-09-04 09:32:39 -04:00
Chang lue Tsen
7ecf955eb7 fix(server): encode ServerKey in base64 and update last reported time for nodes 2025-09-04 09:26:50 -04:00
Chang lue Tsen
10757612f5 feat(subscription): add Language parameter to GetSubscription request and update query logic 2025-09-04 03:14:31 -04:00
Chang lue Tsen
f632ea2c89 feat(subscribe): add Language field to subscription models and update query logic 2025-09-03 15:44:04 -04:00
Chang lue Tsen
f8e6cf515e fix(log): date is empty 2025-09-03 12:35:32 -04:00
Chang lue Tsen
73ffd0d1c7 fix(preview): add Preload parameter to FilterNodeList for improved data retrieval 2025-09-03 12:09:14 -04:00
Chang lue Tsen
1f824fd5a9 feat(tags): add endpoint to query all node tags 2025-09-03 11:57:12 -04:00
Chang lue Tsen
42df466104 fix(node): add ServerId and Enabled fields to node update logic 2025-09-03 09:49:57 -04:00
Chang lue Tsen
68000574b2 fix(filter): refactor node list creation to use append and remove duplicates from tags 2025-09-03 09:42:42 -04:00
Chang lue Tsen
64366d0dec fix(log): optimize user traffic rank data handling by using append instead of index assignment 2025-09-03 09:20:26 -04:00
Chang lue Tsen
949efdad34 fix(migration): add index for traffic log on timestamp, user_id, and subscribe_id 2025-09-03 07:03:37 -04:00
Chang lue Tsen
107fe82f10 fix(model): correct filter condition to use 'date' instead of 'data' 2025-09-03 06:49:55 -04:00
Chang lue Tsen
ca344a1ce9 fix(server): add server status handling based on last reported time 2025-09-02 14:38:53 -04:00
Chang lue Tsen
3e5284c4ec fix(log): update sorting logic for server and user subscribe traffic logs 2025-09-02 14:29:50 -04:00
Chang lue Tsen
fe629e59dd fix(log): update timestamp handling in login and registration logs 2025-09-02 14:12:06 -04:00
Chang lue Tsen
d578dca17e fix(model): enhance user statistics queries with new order and renewal order counts 2025-09-02 14:06:26 -04:00
Chang lue Tsen
ff574b3955 fix(database): add sort column to nodes table 2025-09-02 11:51:07 -04:00
Chang lue Tsen
26b2afe06d feat(api): implement sorting functionality for nodes and servers 2025-09-01 13:13:07 -04:00
Chang lue Tsen
d4850a73f3 feat(api): add sort field to server model 2025-09-01 12:24:15 -04:00
Chang lue Tsen
367ef9d2e7 feat(api): add reset sort endpoints for server and node 2025-09-01 11:41:34 -04:00
Chang lue Tsen
e910d0e345 feat(database): update user table to add referral percentage and only first purchase fields 2025-09-01 09:40:33 -04:00
Chang lue Tsen
aea20ffd5e feat(api): add referral percentage and only first purchase fields to user model and requests 2025-09-01 09:03:39 -04:00
Chang lue Tsen
4438b05272 feat(model): add user counts struct and update queries for new and renewal users 2025-09-01 08:25:53 -04:00
Chang lue Tsen
1745c7194b feat(routes): add handler for scheduled traffic statistics 2025-09-01 08:14:57 -04:00
Chang lue Tsen
4432115844 fix(log): correct category in log settings update query 2025-09-01 06:31:41 -04:00
Chang lue Tsen
b6cae7bbb5 feat(api): add log settings management with auto-clear and clear days configuration 2025-09-01 06:11:35 -04:00
Chang lue Tsen
4184a32c0f feat(api): update server total data response to use 'OnlineUsers' and implement daily traffic statistics logging 2025-09-01 05:30:05 -04:00
Chang lue Tsen
9ff965bbea feat(api): implement daily traffic ranking for users and servers with error handling 2025-09-01 05:03:02 -04:00
Chang lue Tsen
8a37472e61 fix(traffic): adjust start date for traffic statistics and improve log deletion comment 2025-09-01 05:02:53 -04:00
Chang lue Tsen
3012a68339 feat(api): enhance server status handling with protocol support and refactor related logic 2025-09-01 04:17:33 -04:00
Chang lue Tsen
6dc1bee14c feat(api): refactor cache key handling for server and user lists 2025-08-31 11:29:55 -04:00
Chang lue Tsen
82fd674ae4 feat(api): standardize timestamp field across log structures 2025-08-26 14:39:54 -04:00
Chang lue Tsen
88cbfbb7d6 feat(api): update log filtering to use ResetSubscribe type for subscription logs 2025-08-26 14:26:55 -04:00
Chang lue Tsen
92466d62a4 feat(server): implement server deletion logic with error handling 2025-08-26 10:49:03 -04:00
Chang lue Tsen
c7884d94aa feat(api): migrate server and node data handling, update related structures and logic 2025-08-26 07:05:59 -04:00
Chang lue Tsen
9b3cdbbb4f feat(api): add traffic log details filtering and enhance traffic log structures 2025-08-26 02:29:25 -04:00
Chang lue Tsen
ad4f3df74e feat(server): implement server management handlers and database schema 2025-08-25 14:06:37 -04:00
lyndon986
b5e244d83d
renew readme_zh.md 2025-08-26 01:57:50 +10:00
lyndon986
2acbdbc9e0
renew README.md 2025-08-26 01:56:34 +10:00
Chang lue Tsen
1ccbdc18b1 feat(api): define OnlineUser type with SID and IP fields 2025-08-25 11:16:39 -04:00
Chang lue Tsen
630098bfbb refactor(api): rename OnlineUser to ServerOnlineUser for clarity 2025-08-25 11:16:25 -04:00
Chang lue Tsen
7bd026a600 feat(api): enhance server and node management with new request/response structures 2025-08-25 10:10:13 -04:00
Chang lue Tsen
d5460d0cd1 fix(subscribe): ensure active status and reset timestamps during traffic resets 2025-08-23 09:07:56 -04:00
Chang lue Tsen
d33f4cd1ce feat(traffic): add traffic statistics logging and scheduling 2025-08-21 14:11:03 -04:00
Chang lue Tsen
6b1b365734 refactor(log): remove Reset Subscribe Traffic Log endpoint and related types 2025-08-21 11:19:45 -04:00
Chang lue Tsen
062533412a feat(log): add endpoints for retrieving and resetting subscribe traffic logs 2025-08-21 11:02:11 -04:00
Chang lue Tsen
ec4e95451b fix(log): insert reset traffic log during subscription activation 2025-08-21 10:53:12 -04:00
Chang lue Tsen
fcdb9f72ef fix(log): add traffic reset logging for subscription resets 2025-08-21 10:35:40 -04:00
Chang lue Tsen
7c707f2ecf fix(login): remove debug logs and error logging during user login process 2025-08-21 09:18:14 -04:00
Chang lue Tsen
70815c0d50 fix(log): remove unused Id field from SystemLog during login log insertion 2025-08-21 09:15:37 -04:00
Chang lue Tsen
38706c0b29 fix(email): set EmailTypeVerify in task payload and update content type conversion for verification email 2025-08-21 09:07:48 -04:00
Chang lue Tsen
5e903868c4 fix(log): change MessageLog list to use value type for improved performance and memory efficiency 2025-08-21 08:49:13 -04:00
Chang lue Tsen
c04923015e fix(types): change Content field type in MessageLog to interface{} for improved flexibility 2025-08-21 08:24:30 -04:00
Chang lue Tsen
87c771bbd4 refactor(log): consolidate logging models and update related logic for improved clarity and functionality 2025-08-20 13:36:06 -04:00
Chang lue Tsen
4f32d67113 fix(email): convert RegisterStartTime and RegisterEndTime to time.Time for accurate query filtering 2025-08-20 08:22:48 -04:00
Chang lue Tsen
bc1e6315a8 fix(subscribe): rename variable for clarity and add special handling for Stash user agent 2025-08-18 02:54:00 -04:00
Chang lue Tsen
3a98616093 fix(subscribe): update Id field tag to use primaryKey and improve model queries 2025-08-18 02:33:17 -04:00
Chang lue Tsen
41c51fbbff fix(subscribe): update Id field tag to use primaryKey and improve save method query 2025-08-18 02:30:35 -04:00
Chang lue Tsen
3bb83edf05 fix(subscribe): update delete method to use Where clause for improved query accuracy 2025-08-18 02:09:15 -04:00
Chang lue Tsen
245f347d22 refactor(swagger): remove deprecated app.json check from swagger configuration 2025-08-17 12:39:17 -04:00
Chang lue Tsen
70a0fd96ab refactor(swagger): remove deprecated app.json generation from swagger configuration 2025-08-17 12:37:27 -04:00
Chang lue Tsen
8996a62b54 refactor(api): remove deprecated application-related endpoints and types 2025-08-17 12:14:55 -04:00
Chang lue Tsen
14a86c50b2 feat(subscribe): add user agent limit configuration to system settings 2025-08-17 11:52:14 -04:00
Chang lue Tsen
5d80d95568 fix(subscribe): improve error handling and logging for subscription requests 2025-08-17 10:01:12 -04:00
Chang lue Tsen
6580cc9d44 feat(subscribe): implement user agent limit feature with configurable list 2025-08-16 13:37:09 -04:00
Chang lue Tsen
4f2aafd8b2 refactor(subscribe): replace V2 handler with a unified Handler method for subscription logic 2025-08-16 12:59:28 -04:00
Chang lue Tsen
81a46d1f13 feat(panDomain): update subscription logic to use V2 handler for improved functionality 2025-08-16 06:18:44 -04:00
Chang lue Tsen
2dfb1030e1 refactor: rename queryannouncementhandler.go to queryAnnouncementLogic.go for clarity 2025-08-15 14:58:01 -04:00
363 changed files with 9254 additions and 12135 deletions

View File

@ -35,7 +35,6 @@ jobs:
mkdir -p swagger mkdir -p swagger
goctl api plugin -plugin goctl-swagger='swagger -filename common.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_common.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename common.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_common.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename user.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_user.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename user.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_user.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename app.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_app.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename admin.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_admin.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename admin.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_admin.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename ppanel.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ppanel.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename ppanel.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ppanel.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename node.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_node.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename node.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_node.api -dir ./swagger
@ -45,7 +44,6 @@ jobs:
run: | run: |
test -f ./swagger/common.json test -f ./swagger/common.json
test -f ./swagger/user.json test -f ./swagger/user.json
test -f ./swagger/app.json
test -f ./swagger/admin.json test -f ./swagger/admin.json
- name: Checkout target repository - name: Checkout target repository

View File

@ -3,9 +3,6 @@
<module name="server" /> <module name="server" />
<working_directory value="$PROJECT_DIR$" /> <working_directory value="$PROJECT_DIR$" />
<parameters value="run --config etc/ppanel-dev.yaml" /> <parameters value="run --config etc/ppanel-dev.yaml" />
<envs>
<env name="PPANEL_MODE" value="demo" />
</envs>
<kind value="PACKAGE" /> <kind value="PACKAGE" />
<package value="github.com/perfect-panel/server" /> <package value="github.com/perfect-panel/server" />
<directory value="$PROJECT_DIR$" /> <directory value="$PROJECT_DIR$" />

View File

@ -14,6 +14,19 @@
</div> </div>
> **Article 1.**
> All human beings are born free and equal in dignity and rights.
> They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood.
>
> **Article 12.**
> No one shall be subjected to arbitrary interference with his privacy, family, home or correspondence, nor to attacks upon his honour and reputation.
> Everyone has the right to the protection of the law against such interference or attacks.
>
> **Article 19.**
> Everyone has the right to freedom of opinion and expression; this right includes freedom to hold opinions without interference and to seek, receive and impart information and ideas through any media and regardless of frontiers.
>
> *Source: [United Nations Universal Declaration of Human Rights (UN.org)](https://www.un.org/sites/un2.un.org/files/2021/03/udhr.pdf)*
## 📋 Overview ## 📋 Overview
PPanel Server is the backend component of the PPanel project, providing robust APIs and core functionality for managing PPanel Server is the backend component of the PPanel project, providing robust APIs and core functionality for managing

View File

@ -1,26 +1,25 @@
package adapter package adapter
import ( import (
"encoding/json" "strings"
"github.com/perfect-panel/server/internal/model/server" "github.com/perfect-panel/server/internal/model/node"
"github.com/perfect-panel/server/pkg/logger" "github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/random"
) )
type Adapter struct { type Adapter struct {
SiteName string // 站点名称 SiteName string // 站点名称
Servers []*server.Server // 服务器列表 Servers []*node.Node // 服务器列表
UserInfo User // 用户信息 UserInfo User // 用户信息
ClientTemplate string // 客户端配置模板 ClientTemplate string // 客户端配置模板
OutputFormat string // 输出格式,默认是 base64 OutputFormat string // 输出格式,默认是 base64
SubscribeName string // 订阅名称 SubscribeName string // 订阅名称
} }
type Option func(*Adapter) type Option func(*Adapter)
// WithServers 设置服务器列表 // WithServers 设置服务器列表
func WithServers(servers []*server.Server) Option { func WithServers(servers []*node.Node) Option {
return func(opts *Adapter) { return func(opts *Adapter) {
opts.Servers = servers opts.Servers = servers
} }
@ -56,7 +55,7 @@ func WithSubscribeName(name string) Option {
func NewAdapter(tpl string, opts ...Option) *Adapter { func NewAdapter(tpl string, opts ...Option) *Adapter {
adapter := &Adapter{ adapter := &Adapter{
Servers: []*server.Server{}, Servers: []*node.Node{},
UserInfo: User{}, UserInfo: User{},
ClientTemplate: tpl, ClientTemplate: tpl,
OutputFormat: "base64", // 默认输出格式 OutputFormat: "base64", // 默认输出格式
@ -87,51 +86,55 @@ func (adapter *Adapter) Client() (*Client, error) {
return client, nil return client, nil
} }
func (adapter *Adapter) Proxies(servers []*server.Server) ([]Proxy, error) { func (adapter *Adapter) Proxies(servers []*node.Node) ([]Proxy, error) {
var proxies []Proxy var proxies []Proxy
for _, srv := range servers {
switch srv.RelayMode {
case server.RelayModeAll:
var relays []server.NodeRelay
if err := json.Unmarshal([]byte(srv.RelayNode), &relays); err != nil {
logger.Errorw("Unmarshal RelayNode", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("relayNode", srv.RelayNode))
continue
}
for _, relay := range relays {
proxy, err := adapterProxy(*srv, relay.Host, uint64(relay.Port))
if err != nil {
logger.Errorw("Adapter Proxy", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("relayNode", relay))
continue
}
proxies = append(proxies, proxy)
}
case server.RelayModeRandom: for _, item := range servers {
var relays []server.NodeRelay if item.Server == nil {
if err := json.Unmarshal([]byte(srv.RelayNode), &relays); err != nil { logger.Errorf("[Adapter] Server is nil for node ID: %d", item.Id)
logger.Errorw("Unmarshal RelayNode", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("relayNode", srv.RelayNode)) continue
continue }
} protocols, err := item.Server.UnmarshalProtocols()
randNum := random.RandomInRange(0, len(relays)-1) if err != nil {
relay := relays[randNum] logger.Errorf("[Adapter] Unmarshal Protocols error: %s; server id : %d", err.Error(), item.ServerId)
proxy, err := adapterProxy(*srv, relay.Host, uint64(relay.Port)) continue
if err != nil { }
logger.Errorw("Adapter Proxy", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("relayNode", relay)) for _, protocol := range protocols {
continue if protocol.Type == item.Protocol {
} proxies = append(proxies, Proxy{
proxies = append(proxies, proxy) Sort: item.Sort,
Name: item.Name,
case server.RelayModeNone: Server: item.Address,
proxy, err := adapterProxy(*srv, srv.ServerAddr, 0) Port: item.Port,
if err != nil { Type: item.Protocol,
logger.Errorw("Adapter Proxy", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("serverAddr", srv.ServerAddr)) Tags: strings.Split(item.Tags, ","),
continue Security: protocol.Security,
} SNI: protocol.SNI,
proxies = append(proxies, proxy) AllowInsecure: protocol.AllowInsecure,
default: Fingerprint: protocol.Fingerprint,
logger.Errorw("Unknown RelayMode", logger.Field("node", srv.Name), logger.Field("relayMode", srv.RelayMode)) RealityServerAddr: protocol.RealityServerAddr,
RealityServerPort: protocol.RealityServerPort,
RealityPrivateKey: protocol.RealityPrivateKey,
RealityPublicKey: protocol.RealityPublicKey,
RealityShortId: protocol.RealityShortId,
Transport: protocol.Transport,
Host: protocol.Host,
Path: protocol.Path,
ServiceName: protocol.ServiceName,
Method: protocol.Cipher,
ServerKey: protocol.ServerKey,
Flow: protocol.Flow,
HopPorts: protocol.HopPorts,
HopInterval: protocol.HopInterval,
ObfsPassword: protocol.ObfsPassword,
DisableSNI: protocol.DisableSNI,
ReduceRtt: protocol.ReduceRtt,
UDPRelayMode: protocol.UDPRelayMode,
CongestionController: protocol.CongestionController,
})
}
} }
} }
return proxies, nil return proxies, nil
} }

View File

@ -11,9 +11,10 @@ import (
) )
type Proxy struct { type Proxy struct {
Sort int
Name string Name string
Server string Server string
Port uint64 Port uint16
Type string Type string
Tags []string Tags []string
@ -35,18 +36,46 @@ type Proxy struct {
// Shadowsocks Options // Shadowsocks Options
Method string Method string
ServerKey string // For Shadowsocks 2022 ServerKey string // For Shadowsocks 2022
// Vmess/Vless/Trojan Options // Vmess/Vless/Trojan Options
Flow string // Flow for Vmess/Vless/Trojan Flow string // Flow for Vmess/Vless/Trojan
// Hysteria2 Options // Hysteria2 Options
HopPorts string // Comma-separated list of hop ports HopPorts string // Comma-separated list of hop ports
HopInterval int // Interval for hop ports in seconds HopInterval int // Interval for hop ports in seconds
ObfsPassword string // Obfuscation password for Hysteria2 ObfsPassword string // Obfuscation password for Hysteria2
UpMbps int // Upload speed in Mbps
DownMbps int // Download speed in Mbps
// Tuic Options // Tuic Options
DisableSNI bool // Disable SNI DisableSNI bool // Disable SNI
ReduceRtt bool // Reduce RTT ReduceRtt bool // Reduce RTT
UDPRelayMode string // UDP relay mode (e.g., "full", "partial") UDPRelayMode string // UDP relay mode (e.g., "full", "partial")
CongestionController string // Congestion controller (e.g., "cubic", "bbr") CongestionController string // Congestion controller (e.g., "cubic", "bbr")
// AnyTLS
PaddingScheme string
// Mieru
Multiplex string
// Obfs
Obfs string // obfs, 'none', 'http', 'tls'
ObfsHost string // obfs host
ObfsPath string // obfs path
// Vless
XhttpMode string // xhttp mode
XhttpExtra string // xhttp path
// encryption
Encryption string // encryption'none', 'mlkem768x25519plus'
EncryptionMode string // encryption mode'native', 'xorpub', 'random'
EncryptionRtt string // encryption rtt'0rtt', '1rtt'
EncryptionTicket string // encryption ticket
EncryptionServerPadding string // encryption server padding
EncryptionPrivateKey string // encryption private key
EncryptionClientPadding string // encryption client padding
EncryptionPassword string // encryption password
} }
type User struct { type User struct {

View File

@ -1,113 +1 @@
package adapter package adapter
import (
"encoding/json"
"fmt"
"strings"
"github.com/perfect-panel/server/internal/model/server"
"github.com/perfect-panel/server/pkg/tool"
)
func adapterProxy(svr server.Server, host string, port uint64) (Proxy, error) {
tags := strings.Split(svr.Tags, ",")
if len(tags) > 0 {
tags = tool.RemoveDuplicateElements(tags...)
}
node := Proxy{
Name: svr.Name,
Host: host,
Port: port,
Type: svr.Protocol,
Tags: tags,
}
switch svr.Protocol {
case "shadowsocks":
var ss server.Shadowsocks
if err := json.Unmarshal([]byte(svr.Config), &ss); err != nil {
return node, fmt.Errorf("unmarshal shadowsocks config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(ss.Port)
}
node.Method = ss.Method
node.ServerKey = ss.ServerKey
case "vless":
var vless server.Vless
if err := json.Unmarshal([]byte(svr.Config), &vless); err != nil {
return node, fmt.Errorf("unmarshal vless config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(vless.Port)
}
node.Flow = vless.Flow
node.Transport = vless.Transport
tool.DeepCopy(&node, vless.TransportConfig)
node.Security = vless.Security
tool.DeepCopy(&node, vless.SecurityConfig)
case "vmess":
var vmess server.Vmess
if err := json.Unmarshal([]byte(svr.Config), &vmess); err != nil {
return node, fmt.Errorf("unmarshal vmess config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(vmess.Port)
}
node.Flow = vmess.Flow
node.Transport = vmess.Transport
tool.DeepCopy(&node, vmess.TransportConfig)
node.Security = vmess.Security
tool.DeepCopy(&node, vmess.SecurityConfig)
case "trojan":
var trojan server.Trojan
if err := json.Unmarshal([]byte(svr.Config), &trojan); err != nil {
return node, fmt.Errorf("unmarshal trojan config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(trojan.Port)
}
node.Flow = trojan.Flow
node.Transport = trojan.Transport
tool.DeepCopy(&node, trojan.TransportConfig)
node.Security = trojan.Security
tool.DeepCopy(&node, trojan.SecurityConfig)
case "hysteria2":
var hysteria2 server.Hysteria2
if err := json.Unmarshal([]byte(svr.Config), &hysteria2); err != nil {
return node, fmt.Errorf("unmarshal hysteria2 config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(hysteria2.Port)
}
node.HopPorts = hysteria2.HopPorts
node.HopInterval = hysteria2.HopInterval
node.ObfsPassword = hysteria2.ObfsPassword
tool.DeepCopy(&node, hysteria2.SecurityConfig)
case "tuic":
var tuic server.Tuic
if err := json.Unmarshal([]byte(svr.Config), &tuic); err != nil {
return node, fmt.Errorf("unmarshal tuic config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(tuic.Port)
}
node.DisableSNI = tuic.DisableSNI
node.ReduceRtt = tuic.ReduceRtt
node.UDPRelayMode = tuic.UDPRelayMode
node.CongestionController = tuic.CongestionController
case "anytls":
var anytls server.AnyTLS
if err := json.Unmarshal([]byte(svr.Config), &anytls); err != nil {
return node, fmt.Errorf("unmarshal anytls config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(anytls.Port)
}
tool.DeepCopy(&node, anytls.SecurityConfig)
default:
return node, fmt.Errorf("unsupported protocol: %s", svr.Protocol)
}
return node, nil
}

View File

@ -21,7 +21,7 @@ type (
Download int64 `json:"download"` Download int64 `json:"download"`
} }
ServerTotalDataResponse { ServerTotalDataResponse {
OnlineUserIPs int64 `json:"online_user_ips"` OnlineUsers int64 `json:"online_users"`
OnlineServers int64 `json:"online_servers"` OnlineServers int64 `json:"online_servers"`
OfflineServers int64 `json:"offline_servers"` OfflineServers int64 `json:"offline_servers"`
TodayUpload int64 `json:"today_upload"` TodayUpload int64 `json:"today_upload"`

View File

@ -12,19 +12,184 @@ import "../types.api"
type ( type (
GetMessageLogListRequest { GetMessageLogListRequest {
Page int `form:"page"` Page int `form:"page"`
Size int `form:"size"` Size int `form:"size"`
Type string `form:"type"` Type uint8 `form:"type"`
Platform string `form:"platform,omitempty"` Search string `form:"search,optional"`
To string `form:"to,omitempty"`
Subject string `form:"subject,omitempty"`
Content string `form:"content,omitempty"`
Status int `form:"status,omitempty"`
} }
GetMessageLogListResponse { GetMessageLogListResponse {
Total int64 `json:"total"` Total int64 `json:"total"`
List []MessageLog `json:"list"` List []MessageLog `json:"list"`
} }
FilterLogParams {
Page int `form:"page"`
Size int `form:"size"`
Date string `form:"date,optional"`
Search string `form:"search,optional"`
}
FilterEmailLogResponse {
Total int64 `json:"total"`
List []MessageLog `json:"list"`
}
FilterMobileLogResponse {
Total int64 `json:"total"`
List []MessageLog `json:"list"`
}
SubscribeLog {
UserId int64 `json:"user_id"`
Token string `json:"token"`
UserAgent string `json:"user_agent"`
ClientIP string `json:"client_ip"`
UserSubscribeId int64 `json:"user_subscribe_id"`
Timestamp int64 `json:"timestamp"`
}
FilterSubscribeLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
UserSubscribeId int64 `form:"user_subscribe_id,optional"`
}
FilterSubscribeLogResponse {
Total int64 `json:"total"`
List []SubscribeLog `json:"list"`
}
LoginLog {
UserId int64 `json:"user_id"`
Method string `json:"method"`
LoginIP string `json:"login_ip"`
UserAgent string `json:"user_agent"`
Success bool `json:"success"`
Timestamp int64 `json:"timestamp"`
}
FilterLoginLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterLoginLogResponse {
Total int64 `json:"total"`
List []LoginLog `json:"list"`
}
RegisterLog {
UserId int64 `json:"user_id"`
AuthMethod string `json:"auth_method"`
Identifier string `json:"identifier"`
RegisterIP string `json:"register_ip"`
UserAgent string `json:"user_agent"`
Timestamp int64 `json:"timestamp"`
}
FilterRegisterLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterRegisterLogResponse {
Total int64 `json:"total"`
List []RegisterLog `json:"list"`
}
ResetSubscribeLog {
Type uint16 `json:"type"`
UserId int64 `json:"user_id"`
UserSubscribeId int64 `json:"user_subscribe_id"`
OrderNo string `json:"order_no,omitempty"`
Timestamp int64 `json:"timestamp"`
}
FilterResetSubscribeLogRequest {
FilterLogParams
UserSubscribeId int64 `form:"user_subscribe_id,optional"`
}
FilterResetSubscribeLogResponse {
Total int64 `json:"total"`
List []ResetSubscribeLog `json:"list"`
}
UserSubscribeTrafficLog {
SubscribeId int64 `json:"subscribe_id"` // Subscribe ID
UserId int64 `json:"user_id"` // User ID
Upload int64 `json:"upload"` // Upload traffic in bytes
Download int64 `json:"download"` // Download traffic in bytes
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
Date string `json:"date"` // Date in YYYY-MM-DD format
Details bool `json:"details"` // Whether to show detailed traffic
}
FilterSubscribeTrafficRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
UserSubscribeId int64 `form:"user_subscribe_id,optional"`
}
FilterSubscribeTrafficResponse {
Total int64 `json:"total"`
List []UserSubscribeTrafficLog `json:"list"`
}
ServerTrafficLog {
ServerId int64 `json:"server_id"` // Server ID
Upload int64 `json:"upload"` // Upload traffic in bytes
Download int64 `json:"download"` // Download traffic in bytes
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
Date string `json:"date"` // Date in YYYY-MM-DD format
Details bool `json:"details"` // Whether to show detailed traffic
}
FilterServerTrafficLogRequest {
FilterLogParams
ServerId int64 `form:"server_id,optional"`
}
FilterServerTrafficLogResponse {
Total int64 `json:"total"`
List []ServerTrafficLog `json:"list"`
}
FilterBalanceLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterBalanceLogResponse {
Total int64 `json:"total"`
List []BalanceLog `json:"list"`
}
FilterCommissionLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterCommissionLogResponse {
Total int64 `json:"total"`
List []CommissionLog `json:"list"`
}
GiftLog {
Type uint16 `json:"type"`
userId int64 `json:"user_id"`
OrderNo string `json:"order_no"`
SubscribeId int64 `json:"subscribe_id"`
Amount int64 `json:"amount"`
Balance int64 `json:"balance"`
Remark string `json:"remark,omitempty"`
Timestamp int64 `json:"timestamp"`
}
FilterGiftLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterGiftLogResponse {
Total int64 `json:"total"`
List []GiftLog `json:"list"`
}
TrafficLogDetails {
Id int64 `json:"id"`
ServerId int64 `json:"server_id"`
UserId int64 `json:"user_id"`
SubscribeId int64 `json:"subscribe_id"`
Download int64 `json:"download"`
Upload int64 `json:"upload"`
Timestamp int64 `json:"timestamp"`
}
FilterTrafficLogDetailsRequest {
FilterLogParams
ServerId int64 `form:"server_id,optional"`
SubscribeId int64 `form:"subscribe_id,optional"`
UserId int64 `form:"user_id,optional"`
}
FilterTrafficLogDetailsResponse {
Total int64 `json:"total"`
List []TrafficLogDetails `json:"list"`
}
LogSetting {
AutoClear *bool `json:"auto_clear"`
ClearDays int64 `json:"clear_days"`
}
) )
@server ( @server (
@ -36,5 +201,61 @@ service ppanel {
@doc "Get message log list" @doc "Get message log list"
@handler GetMessageLogList @handler GetMessageLogList
get /message/list (GetMessageLogListRequest) returns (GetMessageLogListResponse) get /message/list (GetMessageLogListRequest) returns (GetMessageLogListResponse)
@doc "Filter email log"
@handler FilterEmailLog
get /email/list (FilterLogParams) returns (FilterEmailLogResponse)
@doc "Filter mobile log"
@handler FilterMobileLog
get /mobile/list (FilterLogParams) returns (FilterMobileLogResponse)
@doc "Filter subscribe log"
@handler FilterSubscribeLog
get /subscribe/list (FilterSubscribeLogRequest) returns (FilterSubscribeLogResponse)
@doc "Filter login log"
@handler FilterLoginLog
get /login/list (FilterLoginLogRequest) returns (FilterLoginLogResponse)
@doc "Filter register log"
@handler FilterRegisterLog
get /register/list (FilterRegisterLogRequest) returns (FilterRegisterLogResponse)
@doc "Filter reset subscribe log"
@handler FilterResetSubscribeLog
get /subscribe/reset/list (FilterResetSubscribeLogRequest) returns (FilterResetSubscribeLogResponse)
@doc "Filter user subscribe traffic log"
@handler FilterUserSubscribeTrafficLog
get /subscribe/traffic/list (FilterSubscribeTrafficRequest) returns (FilterSubscribeTrafficResponse)
@doc "Filter server traffic log"
@handler FilterServerTrafficLog
get /server/traffic/list (FilterServerTrafficLogRequest) returns (FilterServerTrafficLogResponse)
@doc "Filter balance log"
@handler FilterBalanceLog
get /balance/list (FilterBalanceLogRequest) returns (FilterBalanceLogResponse)
@doc "Filter commission log"
@handler FilterCommissionLog
get /commission/list (FilterCommissionLogRequest) returns (FilterCommissionLogResponse)
@doc "Filter gift log"
@handler FilterGiftLog
get /gift/list (FilterGiftLogRequest) returns (FilterGiftLogResponse)
@doc "Filter traffic log details"
@handler FilterTrafficLogDetails
get /traffic/details (FilterTrafficLogDetailsRequest) returns (FilterTrafficLogDetailsResponse)
@doc "Get log setting"
@handler GetLogSetting
get /setting returns (LogSetting)
@doc "Update log setting"
@handler UpdateLogSetting
post /setting (LogSetting)
} }

View File

@ -12,7 +12,7 @@ type (
CreateBatchSendEmailTaskRequest { CreateBatchSendEmailTaskRequest {
Subject string `json:"subject"` Subject string `json:"subject"`
Content string `json:"content"` Content string `json:"content"`
Scope string `json:"scope"` Scope int8 `json:"scope"`
RegisterStartTime int64 `json:"register_start_time,omitempty"` RegisterStartTime int64 `json:"register_start_time,omitempty"`
RegisterEndTime int64 `json:"register_end_time,omitempty"` RegisterEndTime int64 `json:"register_end_time,omitempty"`
Additional string `json:"additional,omitempty"` Additional string `json:"additional,omitempty"`
@ -25,7 +25,7 @@ type (
Subject string `json:"subject"` Subject string `json:"subject"`
Content string `json:"content"` Content string `json:"content"`
Recipients string `json:"recipients"` Recipients string `json:"recipients"`
Scope string `json:"scope"` Scope int8 `json:"scope"`
RegisterStartTime int64 `json:"register_start_time"` RegisterStartTime int64 `json:"register_start_time"`
RegisterEndTime int64 `json:"register_end_time"` RegisterEndTime int64 `json:"register_end_time"`
Additional string `json:"additional"` Additional string `json:"additional"`
@ -42,7 +42,7 @@ type (
GetBatchSendEmailTaskListRequest { GetBatchSendEmailTaskListRequest {
Page int `form:"page"` Page int `form:"page"`
Size int `form:"size"` Size int `form:"size"`
Scope string `form:"scope,omitempty"` Scope *int8 `form:"scope,omitempty"`
Status *uint8 `form:"status,omitempty"` Status *uint8 `form:"status,omitempty"`
} }
GetBatchSendEmailTaskListResponse { GetBatchSendEmailTaskListResponse {
@ -53,9 +53,9 @@ type (
Id int64 `json:"id"` Id int64 `json:"id"`
} }
GetPreSendEmailCountRequest { GetPreSendEmailCountRequest {
Scope string `json:"scope"` Scope int8 `json:"scope"`
RegisterStartTime int64 `json:"register_start_time,omitempty"` RegisterStartTime int64 `json:"register_start_time,omitempty"`
RegisterEndTime int64 `json:"register_end_time,omitempty"` RegisterEndTime int64 `json:"register_end_time,omitempty"`
} }
GetPreSendEmailCountResponse { GetPreSendEmailCountResponse {
Count int64 `json:"count"` Count int64 `json:"count"`
@ -69,6 +69,61 @@ type (
Total int64 `json:"total"` Total int64 `json:"total"`
Errors string `json:"errors"` Errors string `json:"errors"`
} }
CreateQuotaTaskRequest {
Subscribers []int64 `json:"subscribers"`
IsActive *bool `json:"is_active"`
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
ResetTraffic bool `json:"reset_traffic"`
Days uint64 `json:"days"`
GiftType uint8 `json:"gift_type"`
GiftValue uint64 `json:"gift_value"`
}
QuotaTask {
Id int64 `json:"id"`
Subscribers []int64 `json:"subscribers"`
IsActive *bool `json:"is_active"`
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
ResetTraffic bool `json:"reset_traffic"`
Days uint64 `json:"days"`
GiftType uint8 `json:"gift_type"`
GiftValue uint64 `json:"gift_value"`
Objects []int64 `json:"objects"` // UserSubscribe IDs
Status uint8 `json:"status"`
Total int64 `json:"total"`
Current int64 `json:"current"`
Errors string `json:"errors"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
QueryQuotaTaskPreCountRequest {
Subscribers []int64 `json:"subscribers"`
IsActive *bool `json:"is_active"`
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
}
QueryQuotaTaskPreCountResponse {
Count int64 `json:"count"`
}
QueryQuotaTaskListRequest {
Page int `form:"page"`
Size int `form:"size"`
Status *uint8 `form:"status,omitempty"`
}
QueryQuotaTaskListResponse {
Total int64 `json:"total"`
List []QuotaTask `json:"list"`
}
QueryQuotaTaskStatusRequest {
Id int64 `json:"id"`
}
QueryQuotaTaskStatusResponse {
Status uint8 `json:"status"`
Current int64 `json:"current"`
Total int64 `json:"total"`
Errors string `json:"errors"`
}
) )
@server ( @server (
@ -96,5 +151,17 @@ service ppanel {
@doc "Get batch send email task status" @doc "Get batch send email task status"
@handler GetBatchSendEmailTaskStatus @handler GetBatchSendEmailTaskStatus
post /email/batch/status (GetBatchSendEmailTaskStatusRequest) returns (GetBatchSendEmailTaskStatusResponse) post /email/batch/status (GetBatchSendEmailTaskStatusRequest) returns (GetBatchSendEmailTaskStatusResponse)
@doc "Create a quota task"
@handler CreateQuotaTask
post /quota/create (CreateQuotaTaskRequest)
@doc "Query quota task pre-count"
@handler QueryQuotaTaskPreCount
post /quota/pre-count (QueryQuotaTaskPreCountRequest) returns (QueryQuotaTaskPreCountResponse)
@doc "Query quota task list"
@handler QueryQuotaTaskList
get /quota/list (QueryQuotaTaskListRequest) returns (QueryQuotaTaskListResponse)
} }

View File

@ -11,108 +11,137 @@ info (
import "../types.api" import "../types.api"
type ( type (
GetNodeServerListRequest { ServerOnlineIP {
Page int `form:"page" validate:"required"` IP string `json:"ip"`
Size int `form:"size" validate:"required"` Protocol string `json:"protocol"`
Tags string `form:"tags,omitempty"`
GroupId int64 `form:"group_id,omitempty"`
Search string `form:"search,omitempty"`
} }
GetNodeServerListResponse { ServerOnlineUser {
IP []ServerOnlineIP `json:"ip"`
UserId int64 `json:"user_id"`
Subscribe string `json:"subscribe"`
SubscribeId int64 `json:"subscribe_id"`
Traffic int64 `json:"traffic"`
ExpiredAt int64 `json:"expired_at"`
}
ServerStatus {
Cpu float64 `json:"cpu"`
Mem float64 `json:"mem"`
Disk float64 `json:"disk"`
Protocol string `json:"protocol"`
Online []ServerOnlineUser `json:"online"`
Status string `json:"status"`
}
Server {
Id int64 `json:"id"`
Name string `json:"name"`
Country string `json:"country"`
City string `json:"city"`
Ratio float32 `json:"ratio"`
Address string `json:"address"`
Sort int `json:"sort"`
Protocols []Protocol `json:"protocols"`
LastReportedAt int64 `json:"last_reported_at"`
Status ServerStatus `json:"status"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
CreateServerRequest {
Name string `json:"name"`
Country string `json:"country,omitempty"`
City string `json:"city,omitempty"`
Ratio float32 `json:"ratio"`
Address string `json:"address"`
Sort int `json:"sort,omitempty"`
Protocols []Protocol `json:"protocols"`
}
UpdateServerRequest {
Id int64 `json:"id"`
Name string `json:"name"`
Country string `json:"country,omitempty"`
City string `json:"city,omitempty"`
Ratio float32 `json:"ratio"`
Address string `json:"address"`
Sort int `json:"sort,omitempty"`
Protocols []Protocol `json:"protocols"`
}
DeleteServerRequest {
Id int64 `json:"id"`
}
FilterServerListRequest {
Page int `form:"page"`
Size int `form:"size"`
Search string `form:"search,omitempty"`
}
FilterServerListResponse {
Total int64 `json:"total"` Total int64 `json:"total"`
List []Server `json:"list"` List []Server `json:"list"`
} }
UpdateNodeRequest { GetServerProtocolsRequest {
Id int64 `json:"id" validate:"required"` Id int64 `form:"id"`
Tags []string `json:"tags"` }
Country string `json:"country"` GetServerProtocolsResponse {
City string `json:"city"` Protocols []Protocol `json:"protocols"`
Name string `json:"name" validate:"required"` }
ServerAddr string `json:"server_addr" validate:"required"` Node {
RelayMode string `json:"relay_mode"` Id int64 `json:"id"`
RelayNode []NodeRelay `json:"relay_node"` Name string `json:"name"`
SpeedLimit int `json:"speed_limit"` Tags []string `json:"tags"`
TrafficRatio float32 `json:"traffic_ratio"` Port uint16 `json:"port"`
GroupId int64 `json:"group_id"` Address string `json:"address"`
Protocol string `json:"protocol" validate:"required"` ServerId int64 `json:"server_id"`
Config interface{} `json:"config" validate:"required"` Protocol string `json:"protocol"`
Enable *bool `json:"enable"` Enabled *bool `json:"enabled"`
Sort int64 `json:"sort"` Sort int `json:"sort,omitempty"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
} }
CreateNodeRequest { CreateNodeRequest {
Name string `json:"name" validate:"required"` Name string `json:"name"`
Tags []string `json:"tags"` Tags []string `json:"tags,omitempty"`
Country string `json:"country"` Port uint16 `json:"port"`
City string `json:"city"` Address string `json:"address"`
ServerAddr string `json:"server_addr" validate:"required"` ServerId int64 `json:"server_id"`
RelayMode string `json:"relay_mode"` Protocol string `json:"protocol"`
RelayNode []NodeRelay `json:"relay_node"` Enabled *bool `json:"enabled"`
SpeedLimit int `json:"speed_limit"` }
TrafficRatio float32 `json:"traffic_ratio"` UpdateNodeRequest {
GroupId int64 `json:"group_id"` Id int64 `json:"id"`
Protocol string `json:"protocol" validate:"required"` Name string `json:"name"`
Config interface{} `json:"config" validate:"required"` Tags []string `json:"tags,omitempty"`
Enable *bool `json:"enable"` Port uint16 `json:"port"`
Sort int64 `json:"sort"` Address string `json:"address"`
ServerId int64 `json:"server_id"`
Protocol string `json:"protocol"`
Enabled *bool `json:"enabled"`
}
ToggleNodeStatusRequest {
Id int64 `json:"id"`
Enable *bool `json:"enable"`
} }
DeleteNodeRequest { DeleteNodeRequest {
Id int64 `json:"id" validate:"required"` Id int64 `json:"id"`
} }
GetNodeGroupListResponse { FilterNodeListRequest {
Total int64 `json:"total"` Page int `form:"page"`
List []ServerGroup `json:"list"` Size int `form:"size"`
Search string `form:"search,omitempty"`
} }
CreateNodeGroupRequest { FilterNodeListResponse {
Name string `json:"name" validate:"required"` Total int64 `json:"total"`
Description string `json:"description"` List []Node `json:"list"`
} }
UpdateNodeGroupRequest { HasMigrateSeverNodeResponse {
Id int64 `json:"id" validate:"required"` HasMigrate bool `json:"has_migrate"`
Name string `json:"name" validate:"required"`
Description string `json:"description"`
} }
DeleteNodeGroupRequest { MigrateServerNodeResponse {
Id int64 `json:"id" validate:"required"` Succee uint64 `json:"succee"`
Fail uint64 `json:"fail"`
Message string `json:"message,omitempty"`
} }
BatchDeleteNodeRequest { ResetSortRequest {
Ids []int64 `json:"ids" validate:"required"`
}
BatchDeleteNodeGroupRequest {
Ids []int64 `json:"ids" validate:"required"`
}
GetNodeDetailRequest {
Id int64 `form:"id" validate:"required"`
}
NodeSortRequest {
Sort []SortItem `json:"sort"` Sort []SortItem `json:"sort"`
} }
CreateRuleGroupRequest { QueryNodeTagResponse {
Name string `json:"name" validate:"required"`
Icon string `json:"icon"`
Type string `json:"type"`
Tags []string `json:"tags"`
Rules string `json:"rules"`
Default bool `json:"default"`
Enable bool `json:"enable"`
}
UpdateRuleGroupRequest {
Id int64 `json:"id" validate:"required"`
Icon string `json:"icon"`
Type string `json:"type"`
Name string `json:"name" validate:"required"`
Tags []string `json:"tags"`
Rules string `json:"rules"`
Default bool `json:"default"`
Enable bool `json:"enable"`
}
DeleteRuleGroupRequest {
Id int64 `json:"id" validate:"required"`
}
GetRuleGroupResponse {
Total int64 `json:"total"`
List []ServerRuleGroup `json:"list"`
}
GetNodeTagListResponse {
Tags []string `json:"tags"` Tags []string `json:"tags"`
} }
) )
@ -123,72 +152,64 @@ type (
middleware: AuthMiddleware middleware: AuthMiddleware
) )
service ppanel { service ppanel {
@doc "Get node tag list" @doc "Create Server"
@handler GetNodeTagList @handler CreateServer
get /tag/list returns (GetNodeTagListResponse) post /create (CreateServerRequest)
@doc "Get node list" @doc "Update Server"
@handler GetNodeList @handler UpdateServer
get /list (GetNodeServerListRequest) returns (GetNodeServerListResponse) post /update (UpdateServerRequest)
@doc "Get node detail" @doc "Delete Server"
@handler GetNodeDetail @handler DeleteServer
get /detail (GetNodeDetailRequest) returns (Server) post /delete (DeleteServerRequest)
@doc "Update node" @doc "Filter Server List"
@handler UpdateNode @handler FilterServerList
put / (UpdateNodeRequest) get /list (FilterServerListRequest) returns (FilterServerListResponse)
@doc "Create node" @doc "Get Server Protocols"
@handler GetServerProtocols
get /protocols (GetServerProtocolsRequest) returns (GetServerProtocolsResponse)
@doc "Create Node"
@handler CreateNode @handler CreateNode
post / (CreateNodeRequest) post /node/create (CreateNodeRequest)
@doc "Delete node" @doc "Update Node"
@handler UpdateNode
post /node/update (UpdateNodeRequest)
@doc "Delete Node"
@handler DeleteNode @handler DeleteNode
delete / (DeleteNodeRequest) post /node/delete (DeleteNodeRequest)
@doc "Batch delete node" @doc "Filter Node List"
@handler BatchDeleteNode @handler FilterNodeList
delete /batch (BatchDeleteNodeRequest) get /node/list (FilterNodeListRequest) returns (FilterNodeListResponse)
@doc "Get node group list" @doc "Toggle Node Status"
@handler GetNodeGroupList @handler ToggleNodeStatus
get /group/list returns (GetNodeGroupListResponse) post /node/status/toggle (ToggleNodeStatusRequest)
@doc "Create node group" @doc "Check if there is any server or node to migrate"
@handler CreateNodeGroup @handler HasMigrateSeverNode
post /group (CreateNodeGroupRequest) get /migrate/has returns (HasMigrateSeverNodeResponse)
@doc "Update node group" @doc "Migrate server and node data to new database"
@handler UpdateNodeGroup @handler MigrateServerNode
put /group (UpdateNodeGroupRequest) post /migrate/run returns (MigrateServerNodeResponse)
@doc "Delete node group" @doc "Reset server sort"
@handler DeleteNodeGroup @handler ResetSortWithServer
delete /group (DeleteNodeGroupRequest) post /server/sort (ResetSortRequest)
@doc "Batch delete node group" @doc "Reset node sort"
@handler BatchDeleteNodeGroup @handler ResetSortWithNode
delete /group/batch (BatchDeleteNodeGroupRequest) post /node/sort (ResetSortRequest)
@doc "Node sort " @doc "Query all node tags"
@handler NodeSort @handler QueryNodeTag
post /sort (NodeSortRequest) get /node/tags returns (QueryNodeTagResponse)
@doc "Create rule group"
@handler CreateRuleGroup
post /rule_group (CreateRuleGroupRequest)
@doc "Update rule group"
@handler UpdateRuleGroup
put /rule_group (UpdateRuleGroupRequest)
@doc "Delete rule group"
@handler DeleteRuleGroup
delete /rule_group (DeleteRuleGroupRequest)
@doc "Get rule group list"
@handler GetRuleGroupList
get /rule_group_list returns (GetRuleGroupResponse)
} }

View File

@ -35,6 +35,7 @@ type (
} }
CreateSubscribeRequest { CreateSubscribeRequest {
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Language string `json:"language"`
Description string `json:"description"` Description string `json:"description"`
UnitPrice int64 `json:"unit_price"` UnitPrice int64 `json:"unit_price"`
UnitTime string `json:"unit_time"` UnitTime string `json:"unit_time"`
@ -45,9 +46,8 @@ type (
SpeedLimit int64 `json:"speed_limit"` SpeedLimit int64 `json:"speed_limit"`
DeviceLimit int64 `json:"device_limit"` DeviceLimit int64 `json:"device_limit"`
Quota int64 `json:"quota"` Quota int64 `json:"quota"`
GroupId int64 `json:"group_id"` Nodes []int64 `json:"nodes"`
ServerGroup []int64 `json:"server_group"` NodeTags []string `json:"node_tags"`
Server []int64 `json:"server"`
Show *bool `json:"show"` Show *bool `json:"show"`
Sell *bool `json:"sell"` Sell *bool `json:"sell"`
DeductionRatio int64 `json:"deduction_ratio"` DeductionRatio int64 `json:"deduction_ratio"`
@ -58,6 +58,7 @@ type (
UpdateSubscribeRequest { UpdateSubscribeRequest {
Id int64 `json:"id" validate:"required"` Id int64 `json:"id" validate:"required"`
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Language string `json:"language"`
Description string `json:"description"` Description string `json:"description"`
UnitPrice int64 `json:"unit_price"` UnitPrice int64 `json:"unit_price"`
UnitTime string `json:"unit_time"` UnitTime string `json:"unit_time"`
@ -68,9 +69,8 @@ type (
SpeedLimit int64 `json:"speed_limit"` SpeedLimit int64 `json:"speed_limit"`
DeviceLimit int64 `json:"device_limit"` DeviceLimit int64 `json:"device_limit"`
Quota int64 `json:"quota"` Quota int64 `json:"quota"`
GroupId int64 `json:"group_id"` Nodes []int64 `json:"nodes"`
ServerGroup []int64 `json:"server_group"` NodeTags []string `json:"node_tags"`
Server []int64 `json:"server"`
Show *bool `json:"show"` Show *bool `json:"show"`
Sell *bool `json:"sell"` Sell *bool `json:"sell"`
Sort int64 `json:"sort"` Sort int64 `json:"sort"`
@ -83,10 +83,10 @@ type (
Sort []SortItem `json:"sort"` Sort []SortItem `json:"sort"`
} }
GetSubscribeListRequest { GetSubscribeListRequest {
Page int64 `form:"page" validate:"required"` Page int64 `form:"page" validate:"required"`
Size int64 `form:"size" validate:"required"` Size int64 `form:"size" validate:"required"`
GroupId int64 `form:"group_id,omitempty"` Language string `form:"language,omitempty"`
Search string `form:"search,omitempty"` Search string `form:"search,omitempty"`
} }
SubscribeItem { SubscribeItem {
Subscribe Subscribe

View File

@ -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"`
} }
@ -86,46 +42,6 @@ service ppanel {
@handler UpdateSubscribeConfig @handler UpdateSubscribeConfig
put /subscribe_config (SubscribeConfig) put /subscribe_config (SubscribeConfig)
@doc "Get subscribe type"
@handler GetSubscribeType
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)

View File

@ -32,17 +32,19 @@ type (
Id int64 `form:"id" validate:"required"` Id int64 `form:"id" validate:"required"`
} }
UpdateUserBasiceInfoRequest { UpdateUserBasiceInfoRequest {
UserId int64 `json:"user_id" validate:"required"` UserId int64 `json:"user_id" validate:"required"`
Password string `json:"password"` Password string `json:"password"`
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
Balance int64 `json:"balance"` Balance int64 `json:"balance"`
Commission int64 `json:"commission"` Commission int64 `json:"commission"`
GiftAmount int64 `json:"gift_amount"` ReferralPercentage uint8 `json:"referral_percentage"`
Telegram int64 `json:"telegram"` OnlyFirstPurchase bool `json:"only_first_purchase"`
ReferCode string `json:"refer_code"` GiftAmount int64 `json:"gift_amount"`
RefererId int64 `json:"referer_id"` Telegram int64 `json:"telegram"`
Enable bool `json:"enable"` ReferCode string `json:"refer_code"`
IsAdmin bool `json:"is_admin"` RefererId int64 `json:"referer_id"`
Enable bool `json:"enable"`
IsAdmin bool `json:"is_admin"`
} }
UpdateUserNotifySettingRequest { UpdateUserNotifySettingRequest {
UserId int64 `json:"user_id" validate:"required"` UserId int64 `json:"user_id" validate:"required"`
@ -52,18 +54,20 @@ type (
EnableTradeNotify bool `json:"enable_trade_notify"` EnableTradeNotify bool `json:"enable_trade_notify"`
} }
CreateUserRequest { CreateUserRequest {
Email string `json:"email"` Email string `json:"email"`
Telephone string `json:"telephone"` Telephone string `json:"telephone"`
TelephoneAreaCode string `json:"telephone_area_code"` TelephoneAreaCode string `json:"telephone_area_code"`
Password string `json:"password"` Password string `json:"password"`
ProductId int64 `json:"product_id"` ProductId int64 `json:"product_id"`
Duration int64 `json:"duration"` Duration int64 `json:"duration"`
RefererUser string `json:"referer_user"` ReferralPercentage uint8 `json:"referral_percentage"`
ReferCode string `json:"refer_code"` OnlyFirstPurchase bool `json:"only_first_purchase"`
Balance int64 `json:"balance"` RefererUser string `json:"referer_user"`
Commission int64 `json:"commission"` ReferCode string `json:"refer_code"`
GiftAmount int64 `json:"gift_amount"` Balance int64 `json:"balance"`
IsAdmin bool `json:"is_admin"` Commission int64 `json:"commission"`
GiftAmount int64 `json:"gift_amount"`
IsAdmin bool `json:"is_admin"`
} }
UserSubscribeDetail { UserSubscribeDetail {
Id int64 `json:"id"` Id int64 `json:"id"`
@ -164,6 +168,15 @@ type (
List []UserLoginLog `json:"list"` List []UserLoginLog `json:"list"`
Total int64 `json:"total"` Total int64 `json:"total"`
} }
GetUserSubscribeResetTrafficLogsRequest {
Page int `form:"page"`
Size int `form:"size"`
UserSubscribeId int64 `form:"user_subscribe_id"`
}
GetUserSubscribeResetTrafficLogsResponse {
List []ResetSubscribeTrafficLog `json:"list"`
Total int64 `json:"total"`
}
DeleteUserSubscribeRequest { DeleteUserSubscribeRequest {
UserSubscribeId int64 `json:"user_subscribe_id"` UserSubscribeId int64 `json:"user_subscribe_id"`
} }
@ -251,6 +264,10 @@ service ppanel {
@handler GetUserSubscribeLogs @handler GetUserSubscribeLogs
get /subscribe/logs (GetUserSubscribeLogsRequest) returns (GetUserSubscribeLogsResponse) get /subscribe/logs (GetUserSubscribeLogsRequest) returns (GetUserSubscribeLogsResponse)
@doc "Get user subcribe reset traffic logs"
@handler GetUserSubscribeResetTrafficLogs
get /subscribe/reset/logs (GetUserSubscribeResetTrafficLogsRequest) returns (GetUserSubscribeResetTrafficLogsResponse)
@doc "Get user subcribe traffic logs" @doc "Get user subcribe traffic logs"
@handler GetUserSubscribeTrafficLogs @handler GetUserSubscribeTrafficLogs
get /subscribe/traffic_logs (GetUserSubscribeTrafficLogsRequest) returns (GetUserSubscribeTrafficLogsResponse) get /subscribe/traffic_logs (GetUserSubscribeTrafficLogsRequest) returns (GetUserSubscribeTrafficLogsResponse)

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -65,6 +65,7 @@ type (
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"` TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
Password string `json:"password"` Password string `json:"password"`
IP string `header:"X-Original-Forwarded-For"` IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
CfToken string `json:"cf_token,optional"` CfToken string `json:"cf_token,optional"`
} }
// Check user is exist request // Check user is exist request
@ -84,6 +85,7 @@ type (
Invite string `json:"invite,optional"` Invite string `json:"invite,optional"`
Code string `json:"code,optional"` Code string `json:"code,optional"`
IP string `header:"X-Original-Forwarded-For"` IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
CfToken string `json:"cf_token,optional"` CfToken string `json:"cf_token,optional"`
} }
// User login response // User login response
@ -93,6 +95,7 @@ type (
Password string `json:"password" validate:"required"` Password string `json:"password" validate:"required"`
Code string `json:"code,optional"` Code string `json:"code,optional"`
IP string `header:"X-Original-Forwarded-For"` IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
CfToken string `json:"cf_token,optional"` CfToken string `json:"cf_token,optional"`
} }
AppleLoginCallbackRequest { AppleLoginCallbackRequest {

View File

@ -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)

View File

@ -11,6 +11,10 @@ info (
import "../types.api" import "../types.api"
type ( type (
OnlineUser {
SID int64 `json:"uid"`
IP string `json:"ip"`
}
ShadowsocksProtocol { ShadowsocksProtocol {
Port int `json:"port"` Port int `json:"port"`
Method string `json:"method"` Method string `json:"method"`
@ -89,6 +93,13 @@ type (
ServerCommon ServerCommon
Users []OnlineUser `json:"users"` Users []OnlineUser `json:"users"`
} }
QueryServerConfigRequest {
ServerID int64 `path:"server_id"`
SecretKey string `header:"secret_key"`
}
QueryServerConfigResponse {
Protocols []Protocol `json:"protocols"`
}
) )
@server ( @server (
@ -118,3 +129,13 @@ service ppanel {
post /online (OnlineUsersRequest) post /online (OnlineUsersRequest)
} }
@server (
prefix: v2/server
group: server
)
service ppanel {
@doc "Get Server Protocol Config"
@handler QueryServerProtocolConfig
get /:server_id (QueryServerConfigRequest) returns (QueryServerConfigResponse)
}

View File

@ -25,6 +25,9 @@ type (
PortalPurchaseResponse { PortalPurchaseResponse {
OrderNo string `json:"order_no"` OrderNo string `json:"order_no"`
} }
GetSubscriptionRequest {
Language string `form:"language"`
}
GetSubscriptionResponse { GetSubscriptionResponse {
List []Subscribe `json:"list"` List []Subscribe `json:"list"`
} }
@ -75,7 +78,7 @@ service ppanel {
@doc "Get Subscription" @doc "Get Subscription"
@handler GetSubscription @handler GetSubscription
get /subscribe returns (GetSubscriptionResponse) get /subscribe (GetSubscriptionRequest) returns (GetSubscriptionResponse)
@doc "Pre Purchase Order" @doc "Pre Purchase Order"
@handler PrePurchaseOrder @handler PrePurchaseOrder

View File

@ -10,6 +10,12 @@ info (
import "../types.api" import "../types.api"
type (
QuerySubscribeListRequest {
Language string `form:"language"`
}
)
@server ( @server (
prefix: v1/public/subscribe prefix: v1/public/subscribe
group: public/subscribe group: public/subscribe
@ -18,14 +24,6 @@ import "../types.api"
service ppanel { service ppanel {
@doc "Get subscribe list" @doc "Get subscribe list"
@handler QuerySubscribeList @handler QuerySubscribeList
get /list returns (QuerySubscribeListResponse) get /list (QuerySubscribeListRequest) 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)
} }

View File

@ -25,15 +25,8 @@ type (
Total int64 `json:"total"` Total int64 `json:"total"`
} }
QueryUserBalanceLogListResponse { QueryUserBalanceLogListResponse {
List []UserBalanceLog `json:"list"` List []BalanceLog `json:"list"`
Total int64 `json:"total"` Total int64 `json:"total"`
}
CommissionLog {
Id int64 `json:"id"`
UserId int64 `json:"user_id"`
OrderNo string `json:"order_no"`
Amount int64 `json:"amount"`
CreatedAt int64 `json:"created_at"`
} }
QueryUserCommissionLogListRequest { QueryUserCommissionLogListRequest {
Page int `form:"page"` Page int `form:"page"`

View File

@ -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"
)

View File

@ -14,6 +14,8 @@ type (
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
Balance int64 `json:"balance"` Balance int64 `json:"balance"`
Commission int64 `json:"commission"` Commission int64 `json:"commission"`
ReferralPercentage uint8 `json:"referral_percentage"`
OnlyFirstPurchase bool `json:"only_first_purchase"`
GiftAmount int64 `json:"gift_amount"` GiftAmount int64 `json:"gift_amount"`
Telegram int64 `json:"telegram"` Telegram int64 `json:"telegram"`
ReferCode string `json:"refer_code"` ReferCode string `json:"refer_code"`
@ -183,6 +185,7 @@ type (
Subscribe { Subscribe {
Id int64 `json:"id"` Id int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Language string `json:"language"`
Description string `json:"description"` Description string `json:"description"`
UnitPrice int64 `json:"unit_price"` UnitPrice int64 `json:"unit_price"`
UnitTime string `json:"unit_time"` UnitTime string `json:"unit_time"`
@ -193,9 +196,8 @@ type (
SpeedLimit int64 `json:"speed_limit"` SpeedLimit int64 `json:"speed_limit"`
DeviceLimit int64 `json:"device_limit"` DeviceLimit int64 `json:"device_limit"`
Quota int64 `json:"quota"` Quota int64 `json:"quota"`
GroupId int64 `json:"group_id"` Nodes []int64 `json:"nodes"`
ServerGroup []int64 `json:"server_group"` NodeTags []string `json:"node_tags"`
Server []int64 `json:"server"`
Show bool `json:"show"` Show bool `json:"show"`
Sell bool `json:"sell"` Sell bool `json:"sell"`
Sort int64 `json:"sort"` Sort int64 `json:"sort"`
@ -274,37 +276,37 @@ type (
Host string `json:"host"` Host string `json:"host"`
ServiceName string `json:"service_name"` ServiceName string `json:"service_name"`
} }
Server { // Server {
Id int64 `json:"id"` // Id int64 `json:"id"`
Tags []string `json:"tags"` // Tags []string `json:"tags"`
Country string `json:"country"` // Country string `json:"country"`
City string `json:"city"` // City string `json:"city"`
Name string `json:"name"` // Name string `json:"name"`
ServerAddr string `json:"server_addr"` // ServerAddr string `json:"server_addr"`
RelayMode string `json:"relay_mode"` // RelayMode string `json:"relay_mode"`
RelayNode []NodeRelay `json:"relay_node"` // RelayNode []NodeRelay `json:"relay_node"`
SpeedLimit int `json:"speed_limit"` // SpeedLimit int `json:"speed_limit"`
TrafficRatio float32 `json:"traffic_ratio"` // TrafficRatio float32 `json:"traffic_ratio"`
GroupId int64 `json:"group_id"` // GroupId int64 `json:"group_id"`
Protocol string `json:"protocol"` // Protocol string `json:"protocol"`
Config interface{} `json:"config"` // Config interface{} `json:"config"`
Enable *bool `json:"enable"` // Enable *bool `json:"enable"`
CreatedAt int64 `json:"created_at"` // CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"` // UpdatedAt int64 `json:"updated_at"`
Status *NodeStatus `json:"status"` // Status *NodeStatus `json:"status"`
Sort int64 `json:"sort"` // Sort int64 `json:"sort"`
} // }
OnlineUser { // OnlineUser {
SID int64 `json:"uid"` // SID int64 `json:"uid"`
IP string `json:"ip"` // IP string `json:"ip"`
} // }
NodeStatus { // NodeStatus {
Online interface{} `json:"online"` // Online interface{} `json:"online"`
Cpu float64 `json:"cpu"` // Cpu float64 `json:"cpu"`
Mem float64 `json:"mem"` // Mem float64 `json:"mem"`
Disk float64 `json:"disk"` // Disk float64 `json:"disk"`
UpdatedAt int64 `json:"updated_at"` // UpdatedAt int64 `json:"updated_at"`
} // }
ServerGroup { ServerGroup {
Id int64 `json:"id"` Id int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
@ -446,15 +448,6 @@ type (
CreatedAt int64 `json:"created_at"` CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"` UpdatedAt int64 `json:"updated_at"`
} }
UserBalanceLog {
Id int64 `json:"id"`
UserId int64 `json:"user_id"`
Amount int64 `json:"amount"`
Type uint8 `json:"type"`
OrderId int64 `json:"order_id"`
Balance int64 `json:"balance"`
CreatedAt int64 `json:"created_at"`
}
UserAffiliate { UserAffiliate {
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
Identifier string `json:"identifier"` Identifier string `json:"identifier"`
@ -475,14 +468,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"`
@ -532,7 +517,7 @@ type (
Token string `json:"token"` Token string `json:"token"`
IP string `json:"ip"` IP string `json:"ip"`
UserAgent string `json:"user_agent"` UserAgent string `json:"user_agent"`
CreatedAt int64 `json:"created_at"` Timestamp int64 `json:"timestamp"`
} }
UserLoginLog { UserLoginLog {
Id int64 `json:"id"` Id int64 `json:"id"`
@ -540,18 +525,17 @@ type (
LoginIP string `json:"login_ip"` LoginIP string `json:"login_ip"`
UserAgent string `json:"user_agent"` UserAgent string `json:"user_agent"`
Success bool `json:"success"` Success bool `json:"success"`
CreatedAt int64 `json:"created_at"` Timestamp int64 `json:"timestamp"`
} }
MessageLog { MessageLog {
Id int64 `json:"id"` Id int64 `json:"id"`
Type string `json:"type"` Type uint8 `json:"type"`
Platform string `json:"platform"` Platform string `json:"platform"`
To string `json:"to"` To string `json:"to"`
Subject string `json:"subject"` Subject string `json:"subject"`
Content string `json:"content"` Content interface{} `json:"content"`
Status int `json:"status"` Status uint8 `json:"status"`
CreatedAt int64 `json:"created_at"` CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
} }
Ads { Ads {
Id int `json:"id"` Id int `json:"id"`
@ -763,5 +747,72 @@ type (
Linux string `json:"linux,omitempty"` Linux string `json:"linux,omitempty"`
Harmony string `json:"harmony,omitempty"` Harmony string `json:"harmony,omitempty"`
} }
ResetSubscribeTrafficLog {
Id int64 `json:"id"`
Type uint16 `json:"type"`
UserSubscribeId int64 `json:"user_subscribe_id"`
OrderNo string `json:"order_no,omitempty"`
Timestamp int64 `json:"timestamp"`
}
BalanceLog {
Type uint16 `json:"type"`
UserId int64 `json:"user_id"`
Amount int64 `json:"amount"`
OrderNo string `json:"order_no,omitempty"`
Balance int64 `json:"balance"`
Timestamp int64 `json:"timestamp"`
}
CommissionLog {
Type uint16 `json:"type"`
UserId int64 `json:"user_id"`
Amount int64 `json:"amount"`
OrderNo string `json:"order_no"`
Timestamp int64 `json:"timestamp"`
}
Protocol {
Type string `json:"type"`
Port uint16 `json:"port"`
Enable bool `json:"enable"`
Security string `json:"security,omitempty"`
SNI string `json:"sni,omitempty"`
AllowInsecure bool `json:"allow_insecure,omitempty"`
Fingerprint string `json:"fingerprint,omitempty"`
RealityServerAddr string `json:"reality_server_addr,omitempty"`
RealityServerPort int `json:"reality_server_port,omitempty"`
RealityPrivateKey string `json:"reality_private_key,omitempty"`
RealityPublicKey string `json:"reality_public_key,omitempty"`
RealityShortId string `json:"reality_short_id,omitempty"`
Transport string `json:"transport,omitempty"`
Host string `json:"host,omitempty"`
Path string `json:"path,omitempty"`
ServiceName string `json:"service_name,omitempty"`
Cipher string `json:"cipher,omitempty"`
ServerKey string `json:"server_key,omitempty"`
Flow string `json:"flow,omitempty"`
HopPorts string `json:"hop_ports,omitempty"`
HopInterval int `json:"hop_interval,omitempty"`
ObfsPassword string `json:"obfs_password,omitempty"`
DisableSNI bool `json:"disable_sni,omitempty"`
ReduceRtt bool `json:"reduce_rtt,omitempty"`
UDPRelayMode string `json:"udp_relay_mode,omitempty"`
CongestionController string `json:"congestion_controller,omitempty"`
Multiplex string `json:"multiplex,omitempty"` // mux, eg: off/low/medium/high
PaddingScheme string `json:"padding_scheme,omitempty"` // padding scheme
UpMbps int `json:"up_mbps,omitempty"` // upload speed limit
DownMbps int `json:"down_mbps,omitempty"` // download speed limit
Obfs string `json:"obfs,omitempty"` // obfs, 'none', 'http', 'tls'
ObfsHost string `json:"obfs_host,omitempty"` // obfs host
ObfsPath string `json:"obfs_path,omitempty"` // obfs path
XhttpMode string `json:"xhttp_mode,omitempty"` // xhttp mode
XhttpExtra string `json:"xhttp_extra,omitempty"` // xhttp extra path
Encryption string `json:"encryption,omitempty"` // encryption'none', 'mlkem768x25519plus'
EncryptionMode string `json:"encryption_mode,omitempty"` // encryption mode'native', 'xorpub', 'random'
EncryptionRtt string `json:"encryption_rtt,omitempty"` // encryption rtt'0rtt', '1rtt'
EncryptionTicket string `json:"encryption_ticket,omitempty"` // encryption ticket
EncryptionServerPadding string `json:"encryption_server_padding,omitempty"` // encryption server padding
EncryptionPrivateKey string `json:"encryption_private_key,omitempty"` // encryption private key
EncryptionClientPadding string `json:"encryption_client_padding,omitempty"` // encryption client padding
EncryptionPassword string `json:"encryption_password,omitempty"` // encryption password
}
) )

4
go.mod
View File

@ -20,7 +20,7 @@ require (
github.com/go-sql-driver/mysql v1.8.1 github.com/go-sql-driver/mysql v1.8.1
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
github.com/gofrs/uuid/v5 v5.3.0 github.com/gofrs/uuid/v5 v5.3.0
github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang-jwt/jwt/v5 v5.2.2
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3 github.com/gorilla/websocket v1.5.3
github.com/hibiken/asynq v0.24.1 github.com/hibiken/asynq v0.24.1
@ -28,7 +28,7 @@ require (
github.com/klauspost/compress v1.17.7 github.com/klauspost/compress v1.17.7
github.com/nyaruka/phonenumbers v1.5.0 github.com/nyaruka/phonenumbers v1.5.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/redis/go-redis/v9 v9.6.1 github.com/redis/go-redis/v9 v9.7.2
github.com/smartwalle/alipay/v3 v3.2.23 github.com/smartwalle/alipay/v3 v3.2.23
github.com/spf13/cast v1.7.0 // indirect github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.1

8
go.sum
View File

@ -155,8 +155,8 @@ github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-migrate/migrate/v4 v4.18.2 h1:2VSCMz7x7mjyTXx3m2zPokOY82LTRgxK1yQYKo6wWQ8= github.com/golang-migrate/migrate/v4 v4.18.2 h1:2VSCMz7x7mjyTXx3m2zPokOY82LTRgxK1yQYKo6wWQ8=
github.com/golang-migrate/migrate/v4 v4.18.2/go.mod h1:2CM6tJvn2kqPXwnXO/d3rAQYiyoIm180VsO8PRX6Rpk= github.com/golang-migrate/migrate/v4 v4.18.2/go.mod h1:2CM6tJvn2kqPXwnXO/d3rAQYiyoIm180VsO8PRX6Rpk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -294,8 +294,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= github.com/redis/go-redis/v9 v9.7.2 h1:PSGhv13dJyrTCw1+55H0pIKM3WFov7HuUrKUmInGL0o=
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/redis/go-redis/v9 v9.7.2/go.mod h1:yp5+a5FnEEP0/zTYuw6u6/2nn3zivwhv274qYgWQhDM=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=

View File

@ -14,7 +14,6 @@ func StartInitSystemConfig(svc *svc.ServiceContext) {
Subscribe(svc) Subscribe(svc)
Register(svc) Register(svc)
Mobile(svc) Mobile(svc)
TrafficDataToRedis(svc)
if !svc.Config.Debug { if !svc.Config.Debug {
Telegram(svc) Telegram(svc)
} }

View File

@ -91,7 +91,6 @@ CREATE TABLE IF NOT EXISTS `auth_method`
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `uni_auth_method` (`method`) UNIQUE KEY `uni_auth_method` (`method`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 9
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;
@ -305,7 +304,6 @@ CREATE TABLE IF NOT EXISTS `subscribe_type`
`updated_at` datetime(3) DEFAULT NULL COMMENT '更新时间', `updated_at` datetime(3) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 15
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;
@ -323,7 +321,6 @@ CREATE TABLE IF NOT EXISTS `system`
UNIQUE KEY `uni_system_key` (`key`), UNIQUE KEY `uni_system_key` (`key`),
KEY `index_key` (`key`) KEY `index_key` (`key`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 42
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;
@ -398,7 +395,6 @@ CREATE TABLE IF NOT EXISTS `user`
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `idx_referer` (`referer_id`) KEY `idx_referer` (`referer_id`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 2
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;
@ -415,7 +411,6 @@ CREATE TABLE IF NOT EXISTS `user_auth_methods`
UNIQUE KEY `idx_auth_identifier` (`auth_identifier`), UNIQUE KEY `idx_auth_identifier` (`auth_identifier`),
KEY `idx_user_id` (`user_id`) KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 2
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,4 @@
INSERT IGNORE INTO `system` (`id`, `category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
VALUES
(42, 'subscribe', 'UserAgentLimit', 'false', 'bool', 'User Agent Limit', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(43, 'subscribe', 'UserAgentList', '', 'string', 'User Agent List', '2025-04-22 14:25:16.637','2025-04-22 14:25:16.637');

View File

@ -0,0 +1,3 @@
DROP TABLE IF EXISTS `application`;
DROP TABLE IF EXISTS `application_version`;
DROP TABLE IF EXISTS `application_config`;

View File

@ -0,0 +1,106 @@
CREATE TABLE IF NOT EXISTS `user_balance_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`amount` bigint NOT NULL COMMENT 'Amount',
`type` tinyint(1) NOT NULL COMMENT 'Type: 1: Recharge 2: Withdraw 3: Payment 4: Refund 5: Reward',
`order_id` bigint DEFAULT NULL COMMENT 'Order ID',
`balance` bigint NOT NULL COMMENT 'Balance',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_commission_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`order_no` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Order No.',
`amount` bigint NOT NULL COMMENT 'Amount',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_gift_amount_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`user_subscribe_id` bigint DEFAULT NULL COMMENT 'Deduction User Subscribe ID',
`order_no` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Order No.',
`type` tinyint(1) NOT NULL COMMENT 'Type: 1: Increase 2: Reduce',
`amount` bigint NOT NULL COMMENT 'Amount',
`balance` bigint NOT NULL COMMENT 'Balance',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Remark',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_login_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`login_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Login IP',
`user_agent` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'UserAgent',
`success` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Login Success',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_reset_subscribe_log`
(
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` BIGINT NOT NULL COMMENT 'User ID',
`type` TINYINT(1) NOT NULL COMMENT 'Type: 1: Auto 2: Advance 3: Paid',
`order_no` VARCHAR(255) DEFAULT NULL COMMENT 'Order No.',
`user_subscribe_id` BIGINT NOT NULL COMMENT 'User Subscribe ID',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation Time',
INDEX `idx_user_id` (`user_id`),
INDEX `idx_user_subscribe_id` (`user_subscribe_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_subscribe_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`user_subscribe_id` bigint NOT NULL COMMENT 'User Subscribe ID',
`token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Token',
`ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'IP',
`user_agent` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'UserAgent',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_user_subscribe_id` (`user_subscribe_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `message_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'email' COMMENT 'Message Type',
`platform` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'smtp' COMMENT 'Platform',
`to` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'To',
`subject` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Subject',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Content',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Status',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Create Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
DROP TABLE IF EXISTS `system_logs`;

View File

@ -0,0 +1,19 @@
DROP TABLE IF EXISTS `user_balance_log`;
DROP TABLE IF EXISTS `user_commission_log`;
DROP TABLE IF EXISTS `user_gift_amount_log`;
DROP TABLE IF EXISTS `user_login_log`;
DROP TABLE IF EXISTS `user_reset_subscribe_log`;
DROP TABLE IF EXISTS `user_subscribe_log`;
DROP TABLE IF EXISTS `message_log`;
DROP TABLE IF EXISTS `system_logs`;
CREATE TABLE `system_logs` (
`id` bigint NOT NULL AUTO_INCREMENT,
`type` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Log Type: 1: Email Message 2: Mobile Message 3: Subscribe 4: Subscribe Traffic 5: Server Traffic 6: Login 7: Register 8: Balance 9: Commission 10: Reset Subscribe 11: Gift',
`date` varchar(20) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Log Date',
`object_id` bigint NOT NULL DEFAULT '0' COMMENT 'Object ID',
`content` text COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Log Content',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Create Time',
PRIMARY KEY (`id`),
KEY `idx_type` (`type`),
KEY `idx_object_id` (`object_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `nodes`;
DROP TABLE IF EXISTS `servers`;

View File

@ -0,0 +1,28 @@
CREATE TABLE IF NOT EXISTS `servers` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Server Name',
`country` varchar(128) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Country',
`city` varchar(128) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'City',
`ratio` decimal(4,2) NOT NULL DEFAULT '0.00' COMMENT 'Traffic Ratio',
`address` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Server Address',
`sort` bigint NOT NULL DEFAULT '0' COMMENT 'Sort',
`protocols` text COLLATE utf8mb4_general_ci COMMENT 'Protocol',
`last_reported_at` datetime(3) DEFAULT NULL COMMENT 'Last Reported Time',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `nodes` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Node Name',
`tags` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Tags',
`port` smallint unsigned NOT NULL DEFAULT '0' COMMENT 'Connect Port',
`address` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Connect Address',
`server_id` bigint NOT NULL DEFAULT '0' COMMENT 'Server ID',
`protocol` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Protocol',
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Enabled',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

View File

@ -0,0 +1,5 @@
ALTER TABLE `subscribe`
DROP COLUMN `nodes`,
DROP COLUMN `node_tags`,
ADD COLUMN `server` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Server',
ADD COLUMN `server_group` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Server Group';

View File

@ -0,0 +1,7 @@
ALTER TABLE `subscribe`
ADD COLUMN `nodes` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Node IDs',
ADD COLUMN `node_tags` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Node Tags',
DROP COLUMN `server`,
DROP COLUMN `server_group`;
DROP TABLE IF EXISTS `server_rule_group`;

View File

@ -0,0 +1,4 @@
INSERT IGNORE INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
VALUES
('log', 'AutoClear', 'true', 'bool', 'Auto Clear Log', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
('log', 'ClearDays', '7', 'int', 'Clear Days', '2025-04-22 14:25:16.637','2025-04-22 14:25:16.637');

View File

@ -0,0 +1,3 @@
ALTER TABLE `user`
DROP COLUMN `referral_percentage`,
DROP COLUMN `only_first_purchase`;

View File

@ -0,0 +1,7 @@
ALTER TABLE `user`
ADD COLUMN `referral_percentage` TINYINT UNSIGNED NOT NULL DEFAULT 0
COMMENT 'Referral Percentage'
AFTER `commission`,
ADD COLUMN `only_first_purchase` TINYINT(1) NOT NULL DEFAULT 1
COMMENT 'Only First Purchase'
AFTER `referral_percentage`;

View File

@ -0,0 +1,2 @@
ALTER TABLE `nodes`
DROP COLUMN `sort`;

View File

@ -0,0 +1,3 @@
ALTER TABLE `nodes`
ADD COLUMN `sort` INT UNSIGNED NOT NULL DEFAULT 0
COMMENT 'Sort' AFTER `enabled`;

View File

@ -0,0 +1 @@
DROP INDEX idx_traffic_log_time_user_sub ON traffic_log;

View File

@ -0,0 +1 @@
CREATE INDEX idx_traffic_log_time_user_sub ON traffic_log (timestamp, user_id, subscribe_id);

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `subscribe_type`;
DROP TABLE IF EXISTS `sms`;

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `subscribe_type`;
DROP TABLE IF EXISTS `sms`;

View File

@ -0,0 +1,7 @@
ALTER TABLE `subscribe`
DROP COLUMN `group_id`,
ADD COLUMN `language` VARCHAR(255) NOT NULL DEFAULT ''
COMMENT 'Language'
AFTER `name`;
DROP TABLE IF EXISTS `subscribe_group`;

View File

@ -0,0 +1,14 @@
DROP TABLE IF EXISTS `email_task`;
CREATE TABLE `task` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`type` tinyint NOT NULL COMMENT 'Task Type',
`scope` text COLLATE utf8mb4_general_ci COMMENT 'Task Scope',
`content` text COLLATE utf8mb4_general_ci COMMENT 'Task Content',
`status` tinyint NOT NULL DEFAULT '0' COMMENT 'Task Status: 0: Pending, 1: In Progress, 2: Completed, 3: Failed',
`errors` text COLLATE utf8mb4_general_ci COMMENT 'Task Errors',
`total` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'Total Number',
`current` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'Current Number',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

View File

@ -3,7 +3,10 @@ package migrate
import ( import (
"testing" "testing"
"github.com/perfect-panel/server/internal/model/node"
"github.com/perfect-panel/server/pkg/orm" "github.com/perfect-panel/server/pkg/orm"
"gorm.io/driver/mysql"
"gorm.io/gorm"
) )
func getDSN() string { func getDSN() string {
@ -30,3 +33,17 @@ func TestMigrate(t *testing.T) {
t.Log("migrate success") t.Log("migrate success")
} }
} }
func TestMysql(t *testing.T) {
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: "root:mylove520@tcp(localhost:3306)/vpnboard",
}))
if err != nil {
t.Fatalf("Failed to connect to MySQL: %v", err)
}
err = db.Migrator().AutoMigrate(&node.Node{})
if err != nil {
t.Fatalf("Failed to auto migrate: %v", err)
return
}
t.Log("MySQL connection and migration successful")
}

View File

@ -1,57 +0,0 @@
package initialize
import (
"context"
"time"
"github.com/perfect-panel/server/internal/model/cache"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/logger"
)
func TrafficDataToRedis(svcCtx *svc.ServiceContext) {
ctx := context.Background()
// 统计昨天的节点流量数据排行榜前10
nodeData, err := svcCtx.TrafficLogModel.TopServersTrafficByDay(ctx, time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day()-1, 0, 0, 0, 0, time.Local), 10)
if err != nil {
logger.Errorw("统计昨天的流量数据失败", logger.Field("error", err.Error()))
}
var nodeCacheData []cache.NodeTodayTrafficRank
for _, node := range nodeData {
serverInfo, err := svcCtx.ServerModel.FindOne(ctx, node.ServerId)
if err != nil {
logger.Errorw("查询节点信息失败", logger.Field("error", err.Error()))
continue
}
nodeCacheData = append(nodeCacheData, cache.NodeTodayTrafficRank{
ID: node.ServerId,
Name: serverInfo.Name,
Upload: node.Upload,
Download: node.Download,
Total: node.Upload + node.Download,
})
}
// 写入缓存
if err = svcCtx.NodeCache.UpdateYesterdayNodeTotalTrafficRank(ctx, nodeCacheData); err != nil {
logger.Errorw("写入昨天的流量数据到缓存失败", logger.Field("error", err.Error()))
}
// 统计昨天的用户流量数据排行榜前10
userData, err := svcCtx.TrafficLogModel.TopUsersTrafficByDay(ctx, time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day()-1, 0, 0, 0, 0, time.Local), 10)
if err != nil {
logger.Errorw("统计昨天的流量数据失败", logger.Field("error", err.Error()))
}
var userCacheData []cache.UserTodayTrafficRank
for _, user := range userData {
userCacheData = append(userCacheData, cache.UserTodayTrafficRank{
SID: user.SubscribeId,
Upload: user.Upload,
Download: user.Download,
Total: user.Upload + user.Download,
})
}
// 写入缓存
if err = svcCtx.NodeCache.UpdateYesterdayUserTotalTrafficRank(ctx, userCacheData); err != nil {
logger.Errorw("写入昨天的流量数据到缓存失败", logger.Field("error", err.Error()))
}
logger.Infow("初始化昨天的流量数据到缓存成功")
}

View File

@ -12,9 +12,6 @@ const SiteConfigKey = "system:site_config"
// SubscribeConfigKey Subscribe Config Key // SubscribeConfigKey Subscribe Config Key
const SubscribeConfigKey = "system:subscribe_config" const SubscribeConfigKey = "system:subscribe_config"
// ApplicationKey Application Key
const ApplicationKey = "system:application"
// RegisterConfigKey Register Config Key // RegisterConfigKey Register Config Key
const RegisterConfigKey = "system:register_config" const RegisterConfigKey = "system:register_config"
@ -51,26 +48,12 @@ const AuthCodeCacheKey = "auth:verify:email"
// AuthCodeTelephoneCacheKey Register Code Cache Key // AuthCodeTelephoneCacheKey Register Code Cache Key
const AuthCodeTelephoneCacheKey = "auth:verify:telephone" const AuthCodeTelephoneCacheKey = "auth:verify:telephone"
// ServerUserListCacheKey Server User List Cache Key // CommonStatCacheKey CommonStat Cache Key
const ServerUserListCacheKey = "server:user_list:id:"
// ServerConfigCacheKey Server Config Cache Key
const ServerConfigCacheKey = "server:config:id:"
// CommonStat Cache Key
const CommonStatCacheKey = "common:stat" const CommonStatCacheKey = "common:stat"
// ServerStatusCacheKey Server Status Cache Key
const ServerStatusCacheKey = "server:status:id:"
// ServerCountCacheKey Server Count Cache Key // ServerCountCacheKey Server Count Cache Key
const ServerCountCacheKey = "server:count" const ServerCountCacheKey = "server:count"
// UserBindTelegramCacheKey User Bind Telegram Cache Key
const UserBindTelegramCacheKey = "user:bind:telegram:code:"
const CacheSmsCount = "cache:sms:count"
// SendIntervalKeyPrefix Auth Code Send Interval Key Prefix // SendIntervalKeyPrefix Auth Code Send Interval Key Prefix
const SendIntervalKeyPrefix = "send:interval:" const SendIntervalKeyPrefix = "send:interval:"

View File

@ -25,6 +25,7 @@ type Config struct {
Subscribe SubscribeConfig `yaml:"Subscribe"` Subscribe SubscribeConfig `yaml:"Subscribe"`
Invite InviteConfig `yaml:"Invite"` Invite InviteConfig `yaml:"Invite"`
Telegram Telegram `yaml:"Telegram"` Telegram Telegram `yaml:"Telegram"`
Log Log `yaml:"Log"`
Administrator struct { Administrator struct {
Email string `yaml:"Email" default:"admin@ppanel.dev"` Email string `yaml:"Email" default:"admin@ppanel.dev"`
Password string `yaml:"Password" default:"password"` Password string `yaml:"Password" default:"password"`
@ -52,9 +53,11 @@ type Verify struct {
type SubscribeConfig struct { type SubscribeConfig struct {
SingleModel bool `yaml:"SingleModel" default:"false"` SingleModel bool `yaml:"SingleModel" default:"false"`
SubscribePath string `yaml:"SubscribePath" default:"/api/subscribe"` SubscribePath string `yaml:"SubscribePath" default:"/v1/subscribe/config"`
SubscribeDomain string `yaml:"SubscribeDomain" default:""` SubscribeDomain string `yaml:"SubscribeDomain" default:""`
PanDomain bool `yaml:"PanDomain" default:"false"` PanDomain bool `yaml:"PanDomain" default:"false"`
UserAgentLimit bool `yaml:"UserAgentLimit" default:"false"`
UserAgentList string `yaml:"UserAgentList" default:""`
} }
type RegisterConfig struct { type RegisterConfig struct {
@ -144,3 +147,8 @@ type VerifyCode struct {
Limit int64 `yaml:"Limit" default:"15"` Limit int64 `yaml:"Limit" default:"15"`
Interval int64 `yaml:"Interval" default:"60"` Interval int64 `yaml:"Interval" default:"60"`
} }
type Log struct {
AutoClear bool `yaml:"AutoClear" default:"true"`
ClearDays int64 `yaml:"ClearDays" default:"7"`
}

View File

@ -1,17 +1,17 @@
package order package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/order" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get order // Filter balance log
func QueryOrderDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterBalanceLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.QueryOrderDetailRequest var req types.FilterBalanceLogRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func QueryOrderDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := order.NewQueryOrderDetailLogic(c.Request.Context(), svcCtx) l := log.NewFilterBalanceLogLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryOrderDetail(&req) resp, err := l.FilterBalanceLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -1,17 +1,17 @@
package document package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/document" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get document detail // Filter commission log
func QueryDocumentDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterCommissionLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.QueryDocumentDetailRequest var req types.FilterCommissionLogRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func QueryDocumentDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context)
return return
} }
l := document.NewQueryDocumentDetailLogic(c.Request.Context(), svcCtx) l := log.NewFilterCommissionLogLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryDocumentDetail(&req) resp, err := l.FilterCommissionLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -1,17 +1,17 @@
package order package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/order" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get order list // Filter email log
func QueryOrderListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterEmailLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.QueryOrderListRequest var req types.FilterLogParams
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func QueryOrderListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := order.NewQueryOrderListLogic(c.Request.Context(), svcCtx) l := log.NewFilterEmailLogLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryOrderList(&req) resp, err := l.FilterEmailLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -1,17 +1,17 @@
package order package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/order" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Checkout order // Filter gift log
func CheckoutOrderHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterGiftLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.CheckoutOrderRequest var req types.FilterGiftLogRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func CheckoutOrderHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := order.NewCheckoutOrderLogic(c.Request.Context(), svcCtx) l := log.NewFilterGiftLogLogic(c.Request.Context(), svcCtx)
resp, err := l.CheckoutOrder(&req, c.Request.Host) resp, err := l.FilterGiftLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -1,17 +1,17 @@
package order package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/order" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Pre create order // Filter login log
func PreCreateOrderHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterLoginLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.PurchaseOrderRequest var req types.FilterLoginLogRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func PreCreateOrderHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := order.NewPreCreateOrderLogic(c.Request.Context(), svcCtx) l := log.NewFilterLoginLogLogic(c.Request.Context(), svcCtx)
resp, err := l.PreCreateOrder(&req) resp, err := l.FilterLoginLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -1,17 +1,17 @@
package node package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/node" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get Node list // Filter mobile log
func GetNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterMobileLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.AppUserSubscbribeNodeRequest var req types.FilterLogParams
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func GetNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := node.NewGetNodeListLogic(c.Request.Context(), svcCtx) l := log.NewFilterMobileLogLogic(c.Request.Context(), svcCtx)
resp, err := l.GetNodeList(&req) resp, err := l.FilterMobileLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -1,17 +1,17 @@
package announcement package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/announcement" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Query announcement // Filter register log
func QueryAnnouncementHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterRegisterLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.QueryAnnouncementRequest var req types.FilterRegisterLogRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func QueryAnnouncementHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := announcement.NewQueryAnnouncementLogic(c.Request.Context(), svcCtx) l := log.NewFilterRegisterLogLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryAnnouncement(&req) resp, err := l.FilterRegisterLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -0,0 +1,26 @@
package log
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Filter reset subscribe log
func FilterResetSubscribeLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.FilterResetSubscribeLogRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := log.NewFilterResetSubscribeLogLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterResetSubscribeLog(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -1,17 +1,17 @@
package user package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/user" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Query User Affiliate List // Filter server traffic log
func QueryUserAffiliateListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterServerTrafficLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.QueryUserAffiliateListRequest var req types.FilterServerTrafficLogRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func QueryUserAffiliateListHandler(svcCtx *svc.ServiceContext) func(c *gin.Conte
return return
} }
l := user.NewQueryUserAffiliateListLogic(c.Request.Context(), svcCtx) l := log.NewFilterServerTrafficLogLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryUserAffiliateList(&req) resp, err := l.FilterServerTrafficLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -1,17 +1,17 @@
package auth package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/auth" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// GetAppConfig // Filter subscribe log
func GetAppConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterSubscribeLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.AppConfigRequest var req types.FilterSubscribeLogRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func GetAppConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := auth.NewGetAppConfigLogic(c, svcCtx) l := log.NewFilterSubscribeLogLogic(c.Request.Context(), svcCtx)
resp, err := l.GetAppConfig(&req) resp, err := l.FilterSubscribeLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -0,0 +1,26 @@
package log
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Filter traffic log details
func FilterTrafficLogDetailsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.FilterTrafficLogDetailsRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := log.NewFilterTrafficLogDetailsLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterTrafficLogDetails(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -0,0 +1,26 @@
package log
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Filter user subscribe traffic log
func FilterUserSubscribeTrafficLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.FilterSubscribeTrafficRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := log.NewFilterUserSubscribeTrafficLogLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterUserSubscribeTrafficLog(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -0,0 +1,18 @@
package log
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/result"
)
// Get log setting
func GetLogSettingHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
l := log.NewGetLogSettingLogic(c.Request.Context(), svcCtx)
resp, err := l.GetLogSetting()
result.HttpResult(c, resp, err)
}
}

View File

@ -1,17 +1,17 @@
package order package log
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/order" "github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Close order // Update log setting
func CloseOrderHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func UpdateLogSettingHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.CloseOrderRequest var req types.LogSetting
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func CloseOrderHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := order.NewCloseOrderLogic(c.Request.Context(), svcCtx) l := log.NewUpdateLogSettingLogic(c.Request.Context(), svcCtx)
err := l.CloseOrder(&req) err := l.UpdateLogSetting(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -0,0 +1,26 @@
package marketing
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/marketing"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Create a quota task
func CreateQuotaTaskHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.CreateQuotaTaskRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := marketing.NewCreateQuotaTaskLogic(c.Request.Context(), svcCtx)
err := l.CreateQuotaTask(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -1,17 +1,17 @@
package auth package marketing
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/app/auth" "github.com/perfect-panel/server/internal/logic/admin/marketing"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Check Account // Query quota task list
func CheckHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func QueryQuotaTaskListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.AppAuthCheckRequest var req types.QueryQuotaTaskListRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func CheckHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := auth.NewCheckLogic(c, svcCtx) l := marketing.NewQueryQuotaTaskListLogic(c.Request.Context(), svcCtx)
resp, err := l.Check(&req) resp, err := l.QueryQuotaTaskList(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -0,0 +1,26 @@
package marketing
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/marketing"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Query quota task pre-count
func QueryQuotaTaskPreCountHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.QueryQuotaTaskPreCountRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := marketing.NewQueryQuotaTaskPreCountLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryQuotaTaskPreCount(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -0,0 +1,26 @@
package marketing
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/marketing"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Query quota task status
func QueryQuotaTaskStatusHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.QueryQuotaTaskStatusRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := marketing.NewQueryQuotaTaskStatusLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryQuotaTaskStatus(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -1,26 +0,0 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Batch delete node group
func BatchDeleteNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.BatchDeleteNodeGroupRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewBatchDeleteNodeGroupLogic(c.Request.Context(), svcCtx)
err := l.BatchDeleteNodeGroup(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -8,7 +8,7 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Create node // Create Node
func CreateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func CreateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.CreateNodeRequest var req types.CreateNodeRequest

View File

@ -1,26 +0,0 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// CreateRuleGroupHandler Create rule group
func CreateRuleGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.CreateRuleGroupRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewCreateRuleGroupLogic(c.Request.Context(), svcCtx)
err := l.CreateRuleGroup(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Delete node group // CreateServerHandler Create Server
func DeleteNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func CreateServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.DeleteNodeGroupRequest var req types.CreateServerRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func DeleteNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewDeleteNodeGroupLogic(c.Request.Context(), svcCtx) l := server.NewCreateServerLogic(c.Request.Context(), svcCtx)
err := l.DeleteNodeGroup(&req) err := l.CreateServer(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -8,7 +8,7 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Delete node // Delete Node
func DeleteNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func DeleteNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.DeleteNodeRequest var req types.DeleteNodeRequest

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Node sort // Delete Server
func NodeSortHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func DeleteServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.NodeSortRequest var req types.DeleteServerRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func NodeSortHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewNodeSortLogic(c.Request.Context(), svcCtx) l := server.NewDeleteServerLogic(c.Request.Context(), svcCtx)
err := l.NodeSort(&req) err := l.DeleteServer(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get node detail // Filter Node List
func GetNodeDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func FilterNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.GetDetailRequest var req types.FilterNodeListRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func GetNodeDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewGetNodeDetailLogic(c.Request.Context(), svcCtx) l := server.NewFilterNodeListLogic(c.Request.Context(), svcCtx)
resp, err := l.GetNodeDetail(&req) resp, err := l.FilterNodeList(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -0,0 +1,26 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// FilterServerListHandler Filter Server List
func FilterServerListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.FilterServerListRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewFilterServerListLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterServerList(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get node list // Get Server Protocols
func GetNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func GetServerProtocolsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.GetNodeServerListRequest var req types.GetServerProtocolsRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func GetNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewGetNodeListLogic(c.Request.Context(), svcCtx) l := server.NewGetServerProtocolsLogic(c.Request.Context(), svcCtx)
resp, err := l.GetNodeList(&req) resp, err := l.GetServerProtocols(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -7,12 +7,12 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get node group list // Check if there is any server or node to migrate
func GetNodeGroupListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func HasMigrateSeverNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
l := server.NewGetNodeGroupListLogic(c.Request.Context(), svcCtx) l := server.NewHasMigrateSeverNodeLogic(c.Request.Context(), svcCtx)
resp, err := l.GetNodeGroupList() resp, err := l.HasMigrateSeverNode()
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -7,12 +7,12 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get rule group list // Migrate server and node data to new database
func GetRuleGroupListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func MigrateServerNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
l := server.NewGetRuleGroupListLogic(c.Request.Context(), svcCtx) l := server.NewMigrateServerNodeLogic(c.Request.Context(), svcCtx)
resp, err := l.GetRuleGroupList() resp, err := l.MigrateServerNode()
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -7,12 +7,12 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get node tag list // Query all node tags
func GetNodeTagListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func QueryNodeTagHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
l := server.NewGetNodeTagListLogic(c.Request.Context(), svcCtx) l := server.NewQueryNodeTagLogic(c.Request.Context(), svcCtx)
resp, err := l.GetNodeTagList() resp, err := l.QueryNodeTag()
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Delete rule group // Reset node sort
func DeleteRuleGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func ResetSortWithNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.DeleteRuleGroupRequest var req types.ResetSortRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func DeleteRuleGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewDeleteRuleGroupLogic(c.Request.Context(), svcCtx) l := server.NewResetSortWithNodeLogic(c.Request.Context(), svcCtx)
err := l.DeleteRuleGroup(&req) err := l.ResetSortWithNode(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -0,0 +1,26 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Reset server sort
func ResetSortWithServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.ResetSortRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewResetSortWithServerLogic(c.Request.Context(), svcCtx)
err := l.ResetSortWithServer(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Create node group // Toggle Node Status
func CreateNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func ToggleNodeStatusHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.CreateNodeGroupRequest var req types.ToggleNodeStatusRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func CreateNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewCreateNodeGroupLogic(c.Request.Context(), svcCtx) l := server.NewToggleNodeStatusLogic(c.Request.Context(), svcCtx)
err := l.CreateNodeGroup(&req) err := l.ToggleNodeStatus(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -1,26 +0,0 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Update node group
func UpdateNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.UpdateNodeGroupRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewUpdateNodeGroupLogic(c.Request.Context(), svcCtx)
err := l.UpdateNodeGroup(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -8,7 +8,7 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Update node // Update Node
func UpdateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func UpdateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.UpdateNodeRequest var req types.UpdateNodeRequest

View File

@ -1,26 +0,0 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Update rule group
func UpdateRuleGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.UpdateRuleGroupRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewUpdateRuleGroupLogic(c.Request.Context(), svcCtx)
err := l.UpdateRuleGroup(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Batch delete node // Update Server
func BatchDeleteNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func UpdateServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.BatchDeleteNodeRequest var req types.UpdateServerRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func BatchDeleteNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewBatchDeleteNodeLogic(c.Request.Context(), svcCtx) l := server.NewUpdateServerLogic(c.Request.Context(), svcCtx)
err := l.BatchDeleteNode(&req) err := l.UpdateServer(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

Some files were not shown because too many files have changed in this diff Show More