feat(migration): replace sqlx::migrate with standalone Go migrate tool

Schema is now managed by a separate Go CLI at tools/migrate/, which embeds
the SQL files copied from server/initialize/migrate/database/ and tracks
state in the shared schema_migrations table. Rust no longer owns migrations
at startup.

Rust startup:
  1. Connect to DB
  2. Probe for the `user` table (schema marker)
  3. If missing, fork-exec `ppanel-migrate up` to bring schema to v2131
  4. Create admin if not present
  5. Continue with redis/queue/scheduler

Verified:
  - Empty DB → ppanel-migrate applies all 39 migrations in ~0.4s, admin created
  - Go server's ppanel_go DB → schema detected, migrate skipped, clean start

Changes:
  - Add tools/migrate/ — Go module wrapping golang-migrate
    * migrate/migrate.go: Migrate() + RunUp() (RunUp bypasses the iofs vs
      os.ErrNotExist sentinel mismatch that breaks Up() on already-migrated DBs)
    * migrate/sql/{postgres,mysql}/: SQL files copied from server
    * cmd/migrate/main.go: CLI (up/down/version/force/drop)
  - Widen password column from varchar(100) → varchar(255) in
    00001_init_schema.up.sql to fit Rust's 112-char PBKDF2 hash
    (Rust uses 16-byte salt; Go's 8-byte salt fits in 100 but Rust's doesn't)
  - Rewrite src/migration.rs:
    * Remove sqlx::migrate!, run_migrations()
    * Add ensure_schema(db, cfg): probe + invoke ppanel-migrate subprocess
  - Fix src/db.rs::build_dsn: previously used cfg.config verbatim even when
    the default config string was for the wrong dialect (PG got MySQL's
    charset=utf8mb4 string and crashed on connect)
  - Delete old migrations/{postgres,mysql}/ (no longer used)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ember Moth
2026-07-06 02:11:10 +08:00
parent 0305d058c4
commit e4996ade03
166 changed files with 556 additions and 123 deletions
+129
View File
@@ -0,0 +1,129 @@
// ppanel-migrate is a standalone CLI for managing PPanel database schema.
//
// It uses the migrate package (copied from server/initialize/migrate) which embeds
// the SQL migration files and applies them via golang-migrate. Tracks state in the
// schema_migrations table — the same table the Go server uses — so the Rust
// ppanel-backend can attach to a database that was already initialised by either tool.
//
// Usage:
//
// ppanel-migrate -driver=postgres -dsn="postgres://..." up
// ppanel-migrate -driver=postgres -dsn="postgres://..." version
// ppanel-migrate -driver=postgres -dsn="postgres://..." force 2131
package main
import (
"errors"
"flag"
"fmt"
"log"
"os"
"strconv"
gomigrate "github.com/golang-migrate/migrate/v4"
ppmigrate "github.com/perfect-panel/ppanel-backend/tools/migrate/migrate"
)
func main() {
var (
driver = flag.String("driver", "postgres", "Database driver: postgres | mysql")
dsn = flag.String("dsn", "", "Database DSN. URL scheme (postgres:// | mysql://) is auto-prepended if absent.")
verbose = flag.Bool("v", false, "Verbose logging")
)
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "ppanel-migrate: standalone PPanel schema migration tool\n\n")
fmt.Fprintf(os.Stderr, "Usage: ppanel-migrate -driver=<postgres|mysql> -dsn=<dsn> <command> [args]\n\n")
fmt.Fprintf(os.Stderr, "Commands:\n")
fmt.Fprintf(os.Stderr, " up [N] Apply all (or N) pending migrations\n")
fmt.Fprintf(os.Stderr, " down [N] Roll back one (or N) migration\n")
fmt.Fprintf(os.Stderr, " version Print current schema version\n")
fmt.Fprintf(os.Stderr, " force <version> Mark database at <version> without running migrations\n")
fmt.Fprintf(os.Stderr, " drop Drop every object in the database (dangerous)\n\n")
flag.PrintDefaults()
}
flag.Parse()
if *dsn == "" {
flag.Usage()
os.Exit(2)
}
if *verbose {
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
}
cmd := flag.Arg(0)
sess := ppmigrate.Migrate(*driver, *dsn)
m := sess.Migrate
switch cmd {
case "", "up":
if err := ppmigrate.RunUp(sess); err != nil && !errors.Is(err, gomigrate.ErrNoChange) {
log.Fatalf("up: %v", err)
}
reportVersion(m)
case "down":
n := -parseStep(flag.Arg(1))
if err := m.Steps(n); err != nil && !errors.Is(err, gomigrate.ErrNoChange) {
log.Fatalf("down: %v", err)
}
reportVersion(m)
case "version":
v, dirty, err := m.Version()
if errors.Is(err, gomigrate.ErrNilVersion) {
fmt.Println("no schema_migrations row (database is empty / not yet migrated)")
os.Exit(0)
}
if err != nil {
log.Fatalf("version: %v", err)
}
fmt.Printf("version=%d dirty=%v\n", v, dirty)
case "force":
v, err := strconv.Atoi(flag.Arg(1))
if err != nil {
log.Fatalf("force: bad version %q: %v", flag.Arg(1), err)
}
if err := m.Force(v); err != nil {
log.Fatalf("force %d: %v", v, err)
}
fmt.Printf("forced to version %d\n", v)
case "drop":
log.Println("WARNING: dropping all database objects")
if err := m.Drop(); err != nil {
log.Fatalf("drop: %v", err)
}
fmt.Println("dropped")
default:
fmt.Fprintf(os.Stderr, "unknown command %q\n\n", cmd)
flag.Usage()
os.Exit(2)
}
}
func parseStep(s string) int {
if s == "" {
return 1
}
n, err := strconv.Atoi(s)
if err != nil || n <= 0 {
log.Fatalf("step must be a positive integer, got %q", s)
}
return n
}
func reportVersion(m *gomigrate.Migrate) {
v, dirty, err := m.Version()
if errors.Is(err, gomigrate.ErrNilVersion) {
fmt.Println("no schema_migrations row (empty database)")
return
}
if err != nil {
log.Fatalf("version: %v", err)
}
fmt.Printf("schema_migrations: version=%d dirty=%v\n", v, dirty)
}
+11
View File
@@ -0,0 +1,11 @@
module github.com/perfect-panel/ppanel-backend/tools/migrate
go 1.25.0
require github.com/golang-migrate/migrate/v4 v4.19.1
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/lib/pq v1.10.9 // indirect
)
+66
View File
@@ -0,0 +1,66 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dhui/dktest v0.4.6 h1:+DPKyScKSEp3VLtbMDHcUq6V5Lm5zfZZVb0Sk7Ahom4=
github.com/dhui/dktest v0.4.6/go.mod h1:JHTSYDtKkvFNFHJKqCzVzqXecyv+tKt8EzceOmQOgbU=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+133
View File
@@ -0,0 +1,133 @@
package migrate
import (
"embed"
"errors"
"fmt"
"io/fs"
"os"
"regexp"
"sort"
"strconv"
"strings"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/mysql"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
"github.com/golang-migrate/migrate/v4/source/iofs"
)
//go:embed sql/postgres/*.sql sql/mysql/*.sql
var sqlFiles embed.FS
// NoChange is re-exported so callers don't have to import golang-migrate directly.
var NoChange = migrate.ErrNoChange
// Session bundles a configured golang-migrate instance alongside the parsed
// source-version list so callers can introspect what migrations exist.
type Session struct {
Migrate *migrate.Migrate
Versions []uint // sorted ascending; all .up.sql versions found in source
}
// Migrate returns a configured golang-migrate instance that reads SQL files from
// the embedded sql/{postgres,mysql}/ directories, based on the requested driver.
//
// driver: "postgres" or "mysql"
// dsn: golang-migrate URL (e.g. postgres://user:pass@host:port/db?sslmode=disable).
//
// If dsn does not include a URL scheme, the driver is prepended automatically.
func Migrate(driver, dsn string) *Session {
sourcePath := "sql/postgres"
databaseURL := dsn
switch driver {
case "mysql":
sourcePath = "sql/mysql"
databaseURL = ensureScheme("mysql://", dsn)
case "postgres":
databaseURL = ensureScheme("postgres://", dsn)
default:
panic(fmt.Errorf("[Migrate] unsupported database driver: %s", driver))
}
d, err := iofs.New(sqlFiles, sourcePath)
if err != nil {
panic(fmt.Errorf("[Migrate] iofs.New error: %v", err))
}
client, err := migrate.NewWithSourceInstance("iofs", d, databaseURL)
if err != nil {
panic(fmt.Errorf("[Migrate] NewWithSourceInstance error: %v", err))
}
return &Session{
Migrate: client,
Versions: scanVersions(sourcePath),
}
}
// sourceVersionRe matches migration filenames like "02131_xxx.up.sql" / ".down.sql".
var sourceVersionRe = regexp.MustCompile(`^([0-9]+)_[^.]+\.(up|down)\.sql$`)
// scanVersions lists all up-version numbers present in the embedded source dir.
func scanVersions(sourcePath string) []uint {
entries, err := sqlFiles.ReadDir(sourcePath)
if err != nil {
panic(fmt.Errorf("[scanVersions] read %s: %w", sourcePath, err))
}
seen := map[uint]struct{}{}
for _, e := range entries {
m := sourceVersionRe.FindStringSubmatch(e.Name())
if m == nil || m[2] != "up" {
continue
}
v, err := strconv.ParseUint(m[1], 10, 64)
if err != nil {
continue
}
seen[uint(v)] = struct{}{}
}
out := make([]uint, 0, len(seen))
for v := range seen {
out = append(out, v)
}
sort.Slice(out, func(i, j int) bool { return out[i] < out[j] })
return out
}
// RunUp applies all pending migrations. Unlike m.Up(), it correctly handles the
// "database is already at the latest version" case under the iofs source driver —
// whose Next() / ReadUp() methods return fs.ErrNotExist rather than the
// os.ErrNotExist sentinel that golang-migrate's internal logic checks for.
//
// Returns migrate.ErrNoChange if there is nothing to apply.
func RunUp(s *Session) error {
if len(s.Versions) == 0 {
return fmt.Errorf("no migration files embedded")
}
srcLast := s.Versions[len(s.Versions)-1]
dbVer, _, err := s.Migrate.Version()
if errors.Is(err, migrate.ErrNilVersion) {
// Empty DB — apply everything from the top.
return s.Migrate.Up()
}
if err != nil {
return err
}
if uint(dbVer) >= srcLast {
// DB already at or beyond the latest source version. Nothing to do.
return migrate.ErrNoChange
}
steps := int(srcLast - uint(dbVer))
return s.Migrate.Steps(steps)
}
func ensureScheme(scheme, dsn string) string {
if strings.Contains(dsn, "://") {
return dsn
}
return scheme + dsn
}
// keep imports referenced (io/fs and os are used elsewhere via errors.Is)
var _ = fs.ErrNotExist
var _ = os.ErrNotExist
@@ -0,0 +1,36 @@
-- 000001_init_schema.down.sql
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `user_subscribe_log`;
DROP TABLE IF EXISTS `user_subscribe`;
DROP TABLE IF EXISTS `user_login_log`;
DROP TABLE IF EXISTS `user_gift_amount_log`;
DROP TABLE IF EXISTS `user_device`;
DROP TABLE IF EXISTS `user_commission_log`;
DROP TABLE IF EXISTS `user_balance_log`;
DROP TABLE IF EXISTS `user_auth_methods`;
DROP TABLE IF EXISTS `user`;
DROP TABLE IF EXISTS `traffic_log`;
DROP TABLE IF EXISTS `ticket_follow`;
DROP TABLE IF EXISTS `ticket`;
DROP TABLE IF EXISTS `system`;
DROP TABLE IF EXISTS `subscribe_type`;
DROP TABLE IF EXISTS `subscribe_group`;
DROP TABLE IF EXISTS `subscribe`;
DROP TABLE IF EXISTS `sms`;
DROP TABLE IF EXISTS `server_rule_group`;
DROP TABLE IF EXISTS `server_group`;
DROP TABLE IF EXISTS `server`;
DROP TABLE IF EXISTS `payment`;
DROP TABLE IF EXISTS `order`;
DROP TABLE IF EXISTS `message_log`;
DROP TABLE IF EXISTS `document`;
DROP TABLE IF EXISTS `coupon`;
DROP TABLE IF EXISTS `auth_method`;
DROP TABLE IF EXISTS `application_version`;
DROP TABLE IF EXISTS `application_config`;
DROP TABLE IF EXISTS `application`;
DROP TABLE IF EXISTS `announcement`;
DROP TABLE IF EXISTS `ads`;
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,555 @@
-- 000001_init_schema.up.sql
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE IF NOT EXISTS `ads`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Ads title',
`type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Ads type',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Ads content',
`target_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Ads target url',
`start_time` datetime DEFAULT NULL COMMENT 'Ads start time',
`end_time` datetime DEFAULT NULL COMMENT 'Ads end time',
`status` tinyint(1) DEFAULT '0' COMMENT 'Ads status,0 disable,1 enable',
`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;
CREATE TABLE IF NOT EXISTS `announcement`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Title',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Content',
`show` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Show',
`pinned` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Pinned',
`popup` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Popup',
`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;
CREATE TABLE IF NOT EXISTS `application`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '应用名称',
`icon` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '应用图标',
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '更新描述',
`subscribe_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '订阅类型',
`created_at` datetime(3) DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime(3) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `application_config`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`app_id` bigint NOT NULL DEFAULT '0' COMMENT 'App id',
`encryption_key` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Encryption Key',
`encryption_method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Encryption Method',
`domains` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`startup_picture` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`startup_picture_skip_time` bigint NOT NULL DEFAULT '0' COMMENT 'Startup Picture Skip Time',
`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;
CREATE TABLE IF NOT EXISTS `application_version`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '应用地址',
`version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '应用版本',
`platform` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '应用平台',
`is_default` tinyint(1) NOT NULL DEFAULT '0' COMMENT '默认版本',
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '更新描述',
`application_id` bigint DEFAULT NULL COMMENT '所属应用',
`created_at` datetime(3) DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime(3) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `fk_application_application_versions` (`application_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `auth_method`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'method',
`config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'OAuth Configuration',
`enabled` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Is Enabled',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Create Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_auth_method` (`method`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `coupon`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Coupon Name',
`code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Coupon Code',
`count` bigint NOT NULL DEFAULT '0' COMMENT 'Count Limit',
`type` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Coupon Type: 1: Percentage 2: Fixed Amount',
`discount` bigint NOT NULL DEFAULT '0' COMMENT 'Coupon Discount',
`start_time` bigint NOT NULL DEFAULT '0' COMMENT 'Start Time',
`expire_time` bigint NOT NULL DEFAULT '0' COMMENT 'Expire Time',
`user_limit` bigint NOT NULL DEFAULT '0' COMMENT 'User Limit',
`subscribe` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Subscribe Limit',
`used_count` bigint NOT NULL DEFAULT '0' COMMENT 'Used Count',
`enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Enable',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Create Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_coupon_code` (`code`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `document`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Document Title',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Document Content',
`tags` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Document Tags',
`show` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Show',
`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;
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;
CREATE TABLE IF NOT EXISTS `order`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`parent_id` bigint DEFAULT NULL COMMENT 'Parent Order Id',
`user_id` bigint NOT NULL DEFAULT '0' COMMENT 'User Id',
`order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Order No',
`type` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Order Type: 1: Subscribe, 2: Renewal, 3: ResetTraffic, 4: Recharge',
`quantity` bigint NOT NULL DEFAULT '1' COMMENT 'Quantity',
`price` bigint NOT NULL DEFAULT '0' COMMENT 'Original price',
`amount` bigint NOT NULL DEFAULT '0' COMMENT 'Order Amount',
`gift_amount` bigint NOT NULL DEFAULT '0' COMMENT 'User Gift Amount',
`discount` bigint NOT NULL DEFAULT '0' COMMENT 'Discount Amount',
`coupon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Coupon',
`coupon_discount` bigint NOT NULL DEFAULT '0' COMMENT 'Coupon Discount Amount',
`commission` bigint NOT NULL DEFAULT '0' COMMENT 'Order Commission',
`payment_id` bigint NOT NULL DEFAULT '-1' COMMENT 'Payment Id',
`method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Payment Method',
`fee_amount` bigint NOT NULL DEFAULT '0' COMMENT 'Fee Amount',
`trade_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Trade No',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Order Status: 1: Pending, 2: Paid, 3:Close, 4: Failed, 5:Finished',
`subscribe_id` bigint NOT NULL DEFAULT '0' COMMENT 'Subscribe Id',
`subscribe_token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Renewal Subscribe Token',
`is_new` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Is New Order',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Create Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_order_order_no` (`order_no`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `payment`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Payment Name',
`platform` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Payment Platform',
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Payment Description',
`icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Payment Icon',
`domain` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Notification Domain',
`config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Payment Configuration',
`fee_mode` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Fee Mode: 0: No Fee 1: Percentage 2: Fixed Amount 3: Percentage + Fixed Amount',
`fee_percent` bigint DEFAULT '0' COMMENT 'Fee Percentage',
`fee_amount` bigint DEFAULT '0' COMMENT 'Fixed Fee Amount',
`enable` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Is Enabled',
`token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Payment Token',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_payment_token` (`token`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `server`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Node Name',
`tags` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Tags',
`country` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Country',
`city` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'City',
`latitude` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'latitude',
`longitude` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'longitude',
`server_addr` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Server Address',
`relay_mode` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none' COMMENT 'Relay Mode',
`relay_node` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Relay Node',
`speed_limit` bigint NOT NULL DEFAULT '0' COMMENT 'Speed Limit',
`traffic_ratio` decimal(4, 2) NOT NULL DEFAULT '0.00' COMMENT 'Traffic Ratio',
`group_id` bigint DEFAULT NULL COMMENT 'Group ID',
`protocol` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Protocol',
`config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Config',
`enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Enabled',
`sort` bigint NOT NULL DEFAULT '0' COMMENT 'Sort',
`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`),
KEY `idx_group_id` (`group_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `server_group`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Group Name',
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Group Description',
`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;
-- if `sms` not exist, create it
CREATE TABLE IF NOT EXISTS `sms`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`platform` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`area_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`telephone` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`status` tinyint(1) DEFAULT '1',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `subscribe`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Subscribe Name',
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Subscribe Description',
`unit_price` bigint NOT NULL DEFAULT '0' COMMENT 'Unit Price',
`unit_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Unit Time',
`discount` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Discount',
`replacement` bigint NOT NULL DEFAULT '0' COMMENT 'Replacement',
`inventory` bigint NOT NULL DEFAULT '0' COMMENT 'Inventory',
`traffic` bigint NOT NULL DEFAULT '0' COMMENT 'Traffic',
`speed_limit` bigint NOT NULL DEFAULT '0' COMMENT 'Speed Limit',
`device_limit` bigint NOT NULL DEFAULT '0' COMMENT 'Device Limit',
`quota` bigint NOT NULL DEFAULT '0' COMMENT 'Quota',
`group_id` bigint DEFAULT NULL COMMENT 'Group Id',
`server_group` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Server Group',
`server` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Server',
`show` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Show portal page',
`sell` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Sell',
`sort` bigint NOT NULL DEFAULT '0' COMMENT 'Sort',
`deduction_ratio` bigint DEFAULT '0' COMMENT 'Deduction Ratio',
`allow_deduction` tinyint(1) DEFAULT '1' COMMENT 'Allow deduction',
`reset_cycle` bigint DEFAULT '0' COMMENT 'Reset Cycle: 0: No Reset, 1: 1st, 2: Monthly, 3: Yearly',
`renewal_reset` tinyint(1) DEFAULT '0' COMMENT 'Renew Reset',
`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;
CREATE TABLE IF NOT EXISTS `subscribe_group`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Group Name',
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Group Description',
`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;
CREATE TABLE IF NOT EXISTS `subscribe_type`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '订阅类型',
`mark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '订阅标识',
`created_at` datetime(3) DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime(3) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `system`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`category` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Category',
`key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Key Name',
`value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Key Value',
`type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Type',
`desc` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Description',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_system_key` (`key`),
KEY `index_key` (`key`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `ticket`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Title',
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Description',
`user_id` bigint NOT NULL DEFAULT '0' COMMENT 'UserId',
`status` tinyint(1) NOT NULL DEFAULT '1' 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;
CREATE TABLE IF NOT EXISTS `ticket_follow`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`ticket_id` bigint NOT NULL DEFAULT '0' COMMENT 'TicketId',
`from` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'From',
`type` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Type: 1 text, 2 image',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Content',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Create Time',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `traffic_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`server_id` bigint NOT NULL COMMENT 'Server ID',
`user_id` bigint NOT NULL COMMENT 'User ID',
`subscribe_id` bigint NOT NULL COMMENT 'Subscription ID',
`download` bigint DEFAULT '0' COMMENT 'Download Traffic',
`upload` bigint DEFAULT '0' COMMENT 'Upload Traffic',
`timestamp` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Traffic Log Time',
PRIMARY KEY (`id`),
KEY `idx_subscribe_id` (`subscribe_id`),
KEY `idx_server_id` (`server_id`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'User Password',
`avatar` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'User Avatar',
`balance` bigint DEFAULT '0' COMMENT 'User Balance',
`telegram` bigint DEFAULT NULL COMMENT 'Telegram Account',
`refer_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Referral Code',
`referer_id` bigint DEFAULT NULL COMMENT 'Referrer ID',
`commission` bigint DEFAULT '0' COMMENT 'Commission',
`gift_amount` bigint DEFAULT '0' COMMENT 'User Gift Amount',
`enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Is Account Enabled',
`is_admin` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Is Admin',
`valid_email` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Is Email Verified',
`enable_email_notify` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Enable Email Notifications',
`enable_telegram_notify` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Enable Telegram Notifications',
`enable_balance_notify` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Enable Balance Change Notifications',
`enable_login_notify` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Enable Login Notifications',
`enable_subscribe_notify` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Enable Subscription Notifications',
`enable_trade_notify` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Enable Trade Notifications',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
`deleted_at` datetime(3) DEFAULT NULL COMMENT 'Deletion Time',
`is_del` bigint unsigned DEFAULT NULL COMMENT '1: Normal 0: Deleted',
PRIMARY KEY (`id`),
KEY `idx_referer` (`referer_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_auth_methods`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`auth_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Auth Type 1: apple 2: google 3: github 4: facebook 5: telegram 6: email 7: phone',
`auth_identifier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Auth Identifier',
`verified` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Is Verified',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_auth_identifier` (`auth_identifier`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
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_device`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`subscribe_id` bigint DEFAULT NULL COMMENT 'Subscribe ID',
`ip` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Device Ip.',
`Identifier` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Device Identifier.',
`user_agent` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Device User Agent.',
`online` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Online',
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'EnableDeviceNumber',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update 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_subscribe`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`order_id` bigint NOT NULL COMMENT 'Order ID',
`subscribe_id` bigint NOT NULL COMMENT 'Subscription ID',
`start_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Subscription Start Time',
`expire_time` datetime(3) DEFAULT NULL COMMENT 'Subscription Expire Time',
`traffic` bigint DEFAULT '0' COMMENT 'Traffic',
`download` bigint DEFAULT '0' COMMENT 'Download Traffic',
`upload` bigint DEFAULT '0' COMMENT 'Upload Traffic',
`token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Token',
`uuid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'UUID',
`status` tinyint(1) DEFAULT '0' COMMENT 'Subscription Status: 0: Pending 1: Active 2: Finished 3: Expired 4: Deducted',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_user_subscribe_token` (`token`),
UNIQUE KEY `uni_user_subscribe_uuid` (`uuid`),
KEY `idx_user_id` (`user_id`),
KEY `idx_order_id` (`order_id`),
KEY `idx_subscribe_id` (`subscribe_id`),
KEY `idx_token` (`token`),
KEY `idx_uuid` (`uuid`)
) 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 `server_rule_group`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Rule Group Name',
`icon` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Rule Group Icon',
`tags` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Selected Node Tags',
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Rule Group Description',
`enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Rule Group Enable',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`),
UNIQUE KEY `unique_name` (`name`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,21 @@
-- 000002_init_data.down.sql
SET
FOREIGN_KEY_CHECKS = 0;
DELETE
FROM `auth_method`
WHERE `id` IN (1, 2, 3, 4, 5, 6, 7, 8);
DELETE
FROM `payment`
WHERE `id` = -1;
DELETE
FROM `subscribe_type`
WHERE `id` IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
DELETE
FROM `system`
WHERE `id` IN
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41);
SET
FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,127 @@
-- 000002_init_data.up.sql
SET FOREIGN_KEY_CHECKS = 0;
-- auth_method
INSERT IGNORE INTO `auth_method` (`id`, `method`, `config`, `enabled`, `created_at`, `updated_at`)
VALUES (1, 'email',
'{"platform":"smtp","platform_config":{"host":"","port":0,"user":"","pass":"","from":"","ssl":false},"enable_verify":false,"enable_notify":false,"enable_domain_suffix":false,"domain_suffix_list":"","verify_email_template":"","expiration_email_template":"","maintenance_email_template":"","traffic_exceed_email_template":""}',
1, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(2, 'mobile',
'{"platform":"AlibabaCloud","platform_config":{"access":"","secret":"","sign_name":"","endpoint":"","template_code":""},"enable_whitelist":false,"whitelist":[]}',
0, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(3, 'apple', '{"team_id":"","key_id":"","client_id":"","client_secret":"","redirect_url":""}', 0,
'2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(4, 'google', '{"client_id":"","client_secret":"","redirect_url":""}', 0, '2025-04-22 14:25:16.642',
'2025-04-22 14:25:16.642'),
(5, 'github', '{"client_id":"","client_secret":"","redirect_url":""}', 0, '2025-04-22 14:25:16.642',
'2025-04-22 14:25:16.642'),
(6, 'facebook', '{"client_id":"","client_secret":"","redirect_url":""}', 0, '2025-04-22 14:25:16.642',
'2025-04-22 14:25:16.642'),
(7, 'telegram', '{"bot_token":"","enable_notify":false,"webhook_domain":""}', 0, '2025-04-22 14:25:16.642',
'2025-04-22 14:25:16.642'),
(8, 'device', '{"show_ads":false,"only_real_device":false,"enable_security":false,"security_secret":""}', 0,
'2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642');
-- payment
INSERT IGNORE INTO `payment` (`id`, `name`, `platform`, `description`, `icon`, `domain`, `config`, `fee_mode`,
`fee_percent`, `fee_amount`, `enable`, `token`)
VALUES (-1, 'Balance', 'balance', '', '', '', '', 0, 0, 0, 1, '');
-- subscribe_type
INSERT IGNORE INTO `subscribe_type` (`id`, `name`, `mark`, `created_at`, `updated_at`)
VALUES (1, 'Clash', 'Clash', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(2, 'Hiddify', 'Hiddify', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(3, 'Loon', 'Loon', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(4, 'NekoBox', 'NekoBox', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(5, 'NekoRay', 'NekoRay', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(6, 'Netch', 'Netch', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(7, 'Quantumult', 'Quantumult', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(8, 'Shadowrocket', 'Shadowrocket', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(9, 'SingBox', ' SingBox', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(10, 'Surfboard', 'Surfboard', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(11, 'Surge', 'Surge', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(12, 'V2box', 'V2box', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(13, 'V2rayN', 'V2rayN', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(14, 'V2rayNg', 'V2rayNg', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648');
-- system
INSERT IGNORE INTO `system` (`id`, `category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
VALUES (1, 'site', 'SiteLogo', '/favicon.svg', 'string', 'Site Logo', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(2, 'site', 'SiteName', 'Perfect Panel', 'string', 'Site Name', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(3, 'site', 'SiteDesc',
'PPanel is a pure, professional, and perfect open-source proxy panel tool, designed to be your ideal choice for learning and practical use.',
'string', 'Site Description', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(4, 'site', 'Host', '', 'string', 'Site Host', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(5, 'site', 'Keywords', 'Perfect Panel,PPanel', 'string', 'Site Keywords', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(6, 'site', 'CustomHTML', '', 'string', 'Custom HTML', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(7, 'tos', 'TosContent', 'Welcome to use Perfect Panel', 'string', 'Terms of Service', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(8, 'tos', 'PrivacyPolicy', '', 'string', 'PrivacyPolicy', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(9, 'ad', 'WebAD', 'false', 'bool', 'Display ad on the web', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(10, 'subscribe', 'SingleModel', 'false', 'bool', '是否单订阅模式', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(11, 'subscribe', 'SubscribePath', '/api/subscribe', 'string', '订阅路径', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(12, 'subscribe', 'SubscribeDomain', '', 'string', '订阅域名', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(13, 'subscribe', 'PanDomain', 'false', 'bool', '是否使用泛域名', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(14, 'verify', 'TurnstileSiteKey', '', 'string', 'TurnstileSiteKey', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(15, 'verify', 'TurnstileSecret', '', 'string', 'TurnstileSecret', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(16, 'verify', 'EnableLoginVerify', 'false', 'bool', 'is enable login verify', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(17, 'verify', 'EnableRegisterVerify', 'false', 'bool', 'is enable register verify', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(18, 'verify', 'EnableResetPasswordVerify', 'false', 'bool', 'is enable reset password verify',
'2025-04-22 14:25:16.639', '2025-04-22 14:25:16.639'),
(19, 'server', 'NodeSecret', '12345678', 'string', 'node secret', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(20, 'server', 'NodePullInterval', '10', 'int', 'node pull interval', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(21, 'server', 'NodePushInterval', '60', 'int', 'node push interval', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(22, 'server', 'NodeMultiplierConfig', '[]', 'string', 'node multiplier config', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(23, 'invite', 'ForcedInvite', 'false', 'bool', 'Forced invite', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(24, 'invite', 'ReferralPercentage', '20', 'int', 'Referral percentage', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(25, 'invite', 'OnlyFirstPurchase', 'false', 'bool', 'Only first purchase', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(26, 'register', 'StopRegister', 'false', 'bool', 'is stop register', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(27, 'register', 'EnableTrial', 'false', 'bool', 'is enable trial', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(28, 'register', 'TrialSubscribe', '', 'int', 'Trial subscription', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(29, 'register', 'TrialTime', '24', 'int', 'Trial time', '2025-04-22 14:25:16.640', '2025-04-22 14:25:16.640'),
(30, 'register', 'TrialTimeUnit', 'Hour', 'string', 'Trial time unit', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(31, 'register', 'EnableIpRegisterLimit', 'false', 'bool', 'is enable IP register limit',
'2025-04-22 14:25:16.640', '2025-04-22 14:25:16.640'),
(32, 'register', 'IpRegisterLimit', '3', 'int', 'IP Register Limit', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(33, 'register', 'IpRegisterLimitDuration', '64', 'int', 'IP Register Limit Duration (minutes)',
'2025-04-22 14:25:16.640', '2025-04-22 14:25:16.640'),
(34, 'currency', 'Currency', 'USD', 'string', 'Currency', '2025-04-22 14:25:16.641', '2025-04-22 14:25:16.641'),
(35, 'currency', 'CurrencySymbol', '$', 'string', 'Currency Symbol', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(36, 'currency', 'CurrencyUnit', 'USD', 'string', 'Currency Unit', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(37, 'currency', 'AccessKey', '', 'string', 'Exchangerate Access Key', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(38, 'verify_code', 'VerifyCodeExpireTime', '300', 'int', 'Verify code expire time', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(39, 'verify_code', 'VerifyCodeLimit', '15', 'int', 'limits of verify code', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(40, 'verify_code', 'VerifyCodeInterval', '60', 'int', 'Interval of verify code', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(41, 'system', 'Version', '0.2.0(02002)', 'string', 'System Version', '2025-04-22 14:25:16.642',
'2025-04-22 14:25:16.642');
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,72 @@
-- migrations/02003_update_payment.down.sql
-- Purpose: Revert updates to payment and order tables
-- Author: PPanel Team, 2025-04-21
SET FOREIGN_KEY_CHECKS = 0;
-- Drop payment_id column from order table (if exists)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order'
AND COLUMN_NAME = 'payment_id');
SET @sql = IF(@column_exists > 0,
'ALTER TABLE `order` DROP COLUMN `payment_id`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Drop platform column from payment table (if exists)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'platform');
SET @sql = IF(@column_exists > 0,
'ALTER TABLE `payment` DROP COLUMN `platform`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Drop description column from payment table (if exists)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'description');
SET @sql = IF(@column_exists > 0,
'ALTER TABLE `payment` DROP COLUMN `description`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Drop token column from payment table (if exists)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'token');
SET @sql = IF(@column_exists > 0,
'ALTER TABLE `payment` DROP COLUMN `token`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Optionally restore mark column (if needed, adjust definition as per original schema)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'mark');
SET @sql = IF(@column_exists = 0,
'ALTER TABLE `payment` ADD COLUMN `mark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT \'Payment Mark\' AFTER `name`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,72 @@
-- 2025-04-22 16:16:00
-- Purpose: Update payment table
-- Author: PPanel Team, 2025-04-21
SET FOREIGN_KEY_CHECKS = 0;
-- Alter the order table to add a payment_id column (if not exists)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order'
AND COLUMN_NAME = 'payment_id');
SET @sql = IF(@column_exists = 0,
'ALTER TABLE `order` ADD COLUMN `payment_id` bigint NOT NULL DEFAULT \'-1\' COMMENT \'Payment Id\' AFTER `commission`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Alter the payment table to add a platform column (if not exists)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'platform');
SET @sql = IF(@column_exists = 0,
'ALTER TABLE `payment` ADD COLUMN `platform` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT \'Payment Platform\' AFTER `name`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Drop the mark column from the payment table (only if exists)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'mark');
SET @sql = IF(@column_exists > 0,
'ALTER TABLE `payment` DROP COLUMN `mark`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Alter the payment table to add a description column (if not exists)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'description');
SET @sql = IF(@column_exists = 0,
'ALTER TABLE `payment` ADD COLUMN `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT \'Payment Description\' AFTER `platform`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Alter the payment table to add a token column (if not exists)
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'token');
SET @sql = IF(@column_exists = 0,
'ALTER TABLE `payment` ADD COLUMN `token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT \'Payment Token\' AFTER `description`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,4 @@
-- migrations/02003_rebuild_rule.up.sql
-- Purpose: Back rebuilding server rule table
-- Author: PPanel Team, 2025-04-21
DROP TABLE IF EXISTS server_rule_group;
@@ -0,0 +1,22 @@
-- migrations/02003_rebuild_rule.up.sql
-- Purpose: rebuilding server rule table
-- Author: PPanel Team, 2025-04-21
DROP TABLE IF EXISTS `server_rule_group`;
CREATE TABLE `server_rule_group`
(
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Rule Group Name',
`icon` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Rule Group Icon',
`tags` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Selected Node Tags',
`rules` MEDIUMTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Rules',
`enable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'Rule Group Enable',
`created_at` DATETIME(3) COMMENT 'Creation Time',
`updated_at` DATETIME(3) COMMENT 'Update Time',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_server_rule_group_name` (`name`),
INDEX `idx_enable` (`enable`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
@@ -0,0 +1,52 @@
-- migrations/02004_create_user_device_online_record.down.sql
-- Purpose: Drop user device online record table
-- Author: PPanel Team, 2025-04-22
DROP TABLE IF EXISTS `user_device_online_record`;
-- User subscribe table migration for removing finished_at column
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'user_subscribe'
AND COLUMN_NAME = 'finished_at');
SET @sql = IF(@column_exists > 0,
'ALTER TABLE `user_subscribe` DROP COLUMN `finished_at`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Application config table migration for removing invitation_link column
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'application_config'
AND COLUMN_NAME = 'invitation_link');
SET @sql = IF(@column_exists > 0,
'ALTER TABLE `application_config` DROP COLUMN `invitation_link`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Application config table migration for removing kr_website_id column
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'application_config'
AND COLUMN_NAME = 'kr_website_id');
SET @sql = IF(@column_exists > 0,
'ALTER TABLE `application_config` DROP COLUMN `kr_website_id`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -0,0 +1,69 @@
-- migrations/02005_create_user_device_online_record.up.sql
-- Purpose: Create table for tracking user device online records
-- Author: PPanel Team, 2025-04-22
CREATE TABLE IF NOT EXISTS `user_device_online_record`
(
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` BIGINT NOT NULL COMMENT 'User ID',
`identifier` VARCHAR(255) NOT NULL COMMENT 'Device Identifier',
`online_time` DATETIME COMMENT 'Online Time',
`offline_time` DATETIME COMMENT 'Offline Time',
`online_seconds` BIGINT COMMENT 'Offline Seconds',
`duration_days` BIGINT COMMENT 'Duration Days',
`created_at` DATETIME COMMENT 'Creation Time'
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- User subscribe table migration for adding finished_at column
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'user_subscribe'
AND COLUMN_NAME = 'finished_at');
SET @sql = IF(@column_exists = 0,
'ALTER TABLE `user_subscribe` ADD COLUMN `finished_at` DATETIME NULL COMMENT ''Subscribe Finished Time'' AFTER `expire_time`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Application config table migration for adding Link column
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'application_config'
AND COLUMN_NAME = 'invitation_link');
SET @sql = IF(@column_exists = 0,
'ALTER TABLE `application_config` ADD COLUMN `invitation_link` TEXT NULL DEFAULT NULL COMMENT ''Invitation Link'' AFTER `startup_picture_skip_time`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Application config table migration for adding kr_website_id column
SET @column_exists = (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'application_config'
AND COLUMN_NAME = 'kr_website_id');
SET @sql = IF(@column_exists = 0,
'ALTER TABLE `application_config` ADD COLUMN `kr_website_id` VARCHAR(255) NULL DEFAULT NULL COMMENT ''KR Website ID'' AFTER `invitation_link`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -0,0 +1,5 @@
-- migrations/02008_create_user_reset_subscribe_log.down.sql
-- Purpose: Drop user_reset_subscribe_log table
-- Author: PPanel Team, 2025-04-22
DROP TABLE IF EXISTS `user_reset_subscribe_log`;
@@ -0,0 +1,17 @@
-- migrations/02008_create_user_reset_subscribe_log.up.sql
-- Purpose: Create user_reset_subscribe_log table
-- Author: PPanel Team, 2025-04-22
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;
@@ -0,0 +1,3 @@
ALTER TABLE `server_rule_group`
DROP COLUMN `default`,
DROP COLUMN `type`;
@@ -0,0 +1,3 @@
ALTER TABLE `server_rule_group`
ADD COLUMN `default` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Is Default Group',
ADD COLUMN `type` VARCHAR(100) NOT NULL DEFAULT '' COMMENT 'Rule Group Type';
@@ -0,0 +1 @@
DROP TABLE IF EXISTS `email_task`;
@@ -0,0 +1,23 @@
DROP TABLE IF EXISTS `email_task`;
CREATE TABLE `email_task` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`subject` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Email Subject',
`content` text COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Email Content',
`recipient` text COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Email Recipient',
`scope` varchar(50) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Email Scope',
`register_start_time` datetime(3) DEFAULT NULL COMMENT 'Register Start Time',
`register_end_time` datetime(3) DEFAULT NULL COMMENT 'Register End Time',
`additional` text COLLATE utf8mb4_general_ci COMMENT 'Additional Information',
`scheduled` datetime(3) NOT NULL COMMENT 'Scheduled Time',
`interval` tinyint unsigned NOT NULL COMMENT 'Interval in Seconds',
`limit` bigint unsigned NOT NULL COMMENT 'Daily send limit',
`status` tinyint unsigned NOT NULL COMMENT 'Daily Status',
`errors` text COLLATE utf8mb4_general_ci NOT NULL COMMENT '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;
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS `subscribe_application`;
File diff suppressed because one or more lines are too long
@@ -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');
@@ -0,0 +1,3 @@
DROP TABLE IF EXISTS `application`;
DROP TABLE IF EXISTS `application_version`;
DROP TABLE IF EXISTS `application_config`;
@@ -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`;
@@ -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;
@@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `nodes`;
DROP TABLE IF EXISTS `servers`;
@@ -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;
@@ -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';
@@ -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`;
@@ -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');
@@ -0,0 +1,3 @@
ALTER TABLE `user`
DROP COLUMN `referral_percentage`,
DROP COLUMN `only_first_purchase`;
@@ -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`;
@@ -0,0 +1,2 @@
ALTER TABLE `nodes`
DROP COLUMN `sort`;
@@ -0,0 +1,3 @@
ALTER TABLE `nodes`
ADD COLUMN `sort` INT UNSIGNED NOT NULL DEFAULT 0
COMMENT 'Sort' AFTER `enabled`;
@@ -0,0 +1 @@
DROP INDEX idx_traffic_log_time_user_sub ON traffic_log;
@@ -0,0 +1 @@
CREATE INDEX idx_traffic_log_time_user_sub ON traffic_log (timestamp, user_id, subscribe_id);
@@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `subscribe_type`;
DROP TABLE IF EXISTS `sms`;
@@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `subscribe_type`;
DROP TABLE IF EXISTS `sms`;
@@ -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`;
@@ -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;
@@ -0,0 +1,8 @@
INSERT
IGNORE INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
VALUE
('server', 'TrafficReportThreshold', '0', 'int', 'Traffic report threshold', '2025-04-22 14:25:16.637','2025-04-22 14:25:16.637'),
('server', 'IPStrategy', '', 'string', 'IP Strategy', '2025-04-22 14:25:16.637','2025-04-22 14:25:16.637'),
('server', 'DNS', '', 'string', 'DNS', '2025-04-22 14:25:16.637','2025-04-22 14:25:16.637'),
('server', 'Block', '', 'string', 'Block', '2025-04-22 14:25:16.637','2025-04-22 14:25:16.637'),
('server', 'Outbound', '', 'string', 'Proxy Outbound', '2025-04-22 14:25:16.637','2025-04-22 14:25:16.637');
@@ -0,0 +1,20 @@
-- 只有当 ads 表中不存在 description 字段时才添加
SET
@col_exists := (
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'ads'
AND COLUMN_NAME = 'description'
);
SET
@query := IF(
@col_exists = 0,
'ALTER TABLE `ads` ADD COLUMN `description` VARCHAR(255) DEFAULT '''' COMMENT ''Description'';',
'SELECT "Column `description` already exists"'
);
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -0,0 +1,3 @@
ALTER TABLE `user`
DROP COLUMN `algo`,
DROP COLUMN `salt`;
@@ -0,0 +1,35 @@
-- 添加 algo 列(如果不存在)
SET @dbname = DATABASE();
SET @tablename = 'user';
SET @colname = 'algo';
SET @sql = (
SELECT IF(
COUNT(*) = 0,
'ALTER TABLE `user` ADD COLUMN `algo` VARCHAR(20) NOT NULL DEFAULT ''default'' COMMENT ''Encryption Algorithm'' AFTER `password`;',
'SELECT "Column `algo` already exists";'
)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @dbname
AND TABLE_NAME = @tablename
AND COLUMN_NAME = @colname
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 添加 salt 列(如果不存在)
SET @colname = 'salt';
SET @sql = (
SELECT IF(
COUNT(*) = 0,
'ALTER TABLE `user` ADD COLUMN `salt` VARCHAR(20) NOT NULL DEFAULT ''default'' COMMENT ''Password Salt'' AFTER `algo`;',
'SELECT "Column `salt` already exists";'
)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @dbname
AND TABLE_NAME = @tablename
AND COLUMN_NAME = @colname
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -0,0 +1,7 @@
INSERT INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
SELECT 'site', 'CustomData', '{
"kr_website_id": ""
}', 'string', 'Custom Data', '2025-04-22 14:25:16.637', '2025-10-14 15:47:19.187'
WHERE NOT EXISTS (
SELECT 1 FROM `system` WHERE `category` = 'site' AND `key` = 'CustomData'
);
@@ -0,0 +1,7 @@
INSERT INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
SELECT 'site', 'CustomData', '{
"kr_website_id": ""
}', 'string', 'Custom Data', '2025-04-22 14:25:16.637', '2025-10-14 15:47:19.187'
WHERE NOT EXISTS (
SELECT 1 FROM `system` WHERE `category` = 'site' AND `key` = 'CustomData'
);
@@ -0,0 +1 @@
ALTER TABLE traffic_log DROP INDEX idx_timestamp;
@@ -0,0 +1 @@
ALTER TABLE traffic_log ADD INDEX idx_timestamp (timestamp);
@@ -0,0 +1,2 @@
ALTER TABLE `user_subscribe`
DROP COLUMN `note`;
@@ -0,0 +1,4 @@
ALTER TABLE `user_subscribe`
ADD COLUMN `note` VARCHAR(500) NOT NULL DEFAULT ''
COMMENT 'User note for subscription'
AFTER `status`;
@@ -0,0 +1,2 @@
ALTER TABLE `user`
DROP COLUMN IF EXISTS `rules`;
@@ -0,0 +1,4 @@
ALTER TABLE `user`
ADD COLUMN `rules` TEXT NULL
COMMENT 'User rules for subscription'
AFTER `created_at`;
@@ -0,0 +1,5 @@
DROP TABLE IF EXISTS `withdrawals`;
DELETE FROM `system`
WHERE `category` = 'invite'
AND `key` = 'WithdrawalMethod';
@@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS `withdrawals` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`user_id` BIGINT NOT NULL COMMENT 'User ID',
`amount` BIGINT NOT NULL COMMENT 'Withdrawal Amount',
`content` TEXT COMMENT 'Withdrawal Content',
`status` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Withdrawal Status',
`reason` VARCHAR(500) NOT NULL DEFAULT '' COMMENT 'Rejection Reason',
`created_at` DATETIME NOT NULL COMMENT 'Creation Time',
`updated_at` DATETIME NOT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT IGNORE INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
VALUES
('invite', 'WithdrawalMethod', '', 'string', 'withdrawal method', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637');
@@ -0,0 +1,27 @@
CREATE TABLE IF NOT EXISTS `server`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Node Name',
`tags` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Tags',
`country` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Country',
`city` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'City',
`latitude` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'latitude',
`longitude` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'longitude',
`server_addr` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Server Address',
`relay_mode` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none' COMMENT 'Relay Mode',
`relay_node` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Relay Node',
`speed_limit` bigint NOT NULL DEFAULT '0' COMMENT 'Speed Limit',
`traffic_ratio` decimal(4, 2) NOT NULL DEFAULT '0.00' COMMENT 'Traffic Ratio',
`group_id` bigint DEFAULT NULL COMMENT 'Group ID',
`protocol` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Protocol',
`config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Config',
`enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Enabled',
`sort` bigint NOT NULL DEFAULT '0' COMMENT 'Sort',
`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`),
KEY `idx_group_id` (`group_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS `server`;
@@ -0,0 +1,2 @@
ALTER TABLE `subscribe`
DROP COLUMN `show_original_price`;
@@ -0,0 +1,2 @@
ALTER TABLE `subscribe`
ADD COLUMN `show_original_price` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'display the original price: 0 not display, 1 display' AFTER `created_at`;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS `server_group`;
@@ -0,0 +1,5 @@
-- This migration script reverts the inventory values in the 'subscribe' table
UPDATE `subscribe`
SET `inventory` = 0
WHERE `inventory` = -1;
@@ -0,0 +1,4 @@
-- Update the `subscribe` table to set `inventory` to -1 where it is currently 0
UPDATE `subscribe`
SET `inventory` = -1
WHERE `inventory` = 0;
@@ -0,0 +1 @@
DROP INDEX idx_type_date ON system_logs;
@@ -0,0 +1 @@
CREATE INDEX idx_type_date ON system_logs (type, date);
@@ -0,0 +1,131 @@
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'nodes'
AND INDEX_NAME = 'idx_nodes_port');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `nodes` DROP INDEX `idx_nodes_port`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'nodes'
AND INDEX_NAME = 'idx_nodes_tags');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `nodes` DROP INDEX `idx_nodes_tags`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'nodes'
AND INDEX_NAME = 'idx_nodes_address');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `nodes` DROP INDEX `idx_nodes_address`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'nodes'
AND INDEX_NAME = 'idx_nodes_name');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `nodes` DROP INDEX `idx_nodes_name`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'servers'
AND INDEX_NAME = 'idx_servers_address');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `servers` DROP INDEX `idx_servers_address`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'servers'
AND INDEX_NAME = 'idx_servers_name');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `servers` DROP INDEX `idx_servers_name`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND INDEX_NAME = 'idx_payment_name');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `payment` DROP INDEX `idx_payment_name`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'coupon'
AND INDEX_NAME = 'idx_coupon_name');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `coupon` DROP INDEX `idx_coupon_name`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'user'
AND INDEX_NAME = 'idx_user_refer_code');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `user` DROP INDEX `idx_user_refer_code`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order'
AND INDEX_NAME = 'idx_order_coupon');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `order` DROP INDEX `idx_order_coupon`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order'
AND INDEX_NAME = 'idx_order_trade_no');
SET @sql = IF(@index_exists > 0,
'ALTER TABLE `order` DROP INDEX `idx_order_trade_no`',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -0,0 +1,131 @@
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order'
AND INDEX_NAME = 'idx_order_trade_no');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `order` ADD INDEX `idx_order_trade_no` (`trade_no`(191))',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order'
AND INDEX_NAME = 'idx_order_coupon');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `order` ADD INDEX `idx_order_coupon` (`coupon`(191))',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'user'
AND INDEX_NAME = 'idx_user_refer_code');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `user` ADD INDEX `idx_user_refer_code` (`refer_code`)',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'coupon'
AND INDEX_NAME = 'idx_coupon_name');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `coupon` ADD INDEX `idx_coupon_name` (`name`(191))',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND INDEX_NAME = 'idx_payment_name');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `payment` ADD INDEX `idx_payment_name` (`name`)',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'servers'
AND INDEX_NAME = 'idx_servers_name');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `servers` ADD INDEX `idx_servers_name` (`name`)',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'servers'
AND INDEX_NAME = 'idx_servers_address');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `servers` ADD INDEX `idx_servers_address` (`address`)',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'nodes'
AND INDEX_NAME = 'idx_nodes_name');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `nodes` ADD INDEX `idx_nodes_name` (`name`)',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'nodes'
AND INDEX_NAME = 'idx_nodes_address');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `nodes` ADD INDEX `idx_nodes_address` (`address`(191))',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'nodes'
AND INDEX_NAME = 'idx_nodes_tags');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `nodes` ADD INDEX `idx_nodes_tags` (`tags`(191))',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'nodes'
AND INDEX_NAME = 'idx_nodes_port');
SET @sql = IF(@index_exists = 0,
'ALTER TABLE `nodes` ADD INDEX `idx_nodes_port` (`port`)',
'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS `server_config_overrides`;
@@ -0,0 +1,15 @@
CREATE TABLE IF NOT EXISTS `server_config_overrides`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`server_id` bigint NOT NULL COMMENT 'Server ID',
`ip_strategy` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'IP strategy override, NULL means inherit',
`dns` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'DNS override, NULL means inherit',
`block` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Block override, NULL means inherit',
`outbound` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Outbound override, NULL means inherit',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_server_config_overrides_server_id` (`server_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
@@ -0,0 +1,17 @@
SET @column_exists = (
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'sort'
);
SET @sql = IF(
@column_exists > 0,
'ALTER TABLE `payment` DROP COLUMN `sort`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -0,0 +1,21 @@
SET @column_exists = (
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'payment'
AND COLUMN_NAME = 'sort'
);
SET @sql = IF(
@column_exists = 0,
'ALTER TABLE `payment` ADD COLUMN `sort` bigint NOT NULL DEFAULT 0 COMMENT ''Sort'' AFTER `fee_amount`',
'SELECT 1'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
UPDATE `payment`
SET `sort` = `id`
WHERE `sort` = 0;
@@ -0,0 +1 @@
DELETE FROM `system` WHERE `category` = 'subscribe' AND `key` = 'ShowTutorial';
@@ -0,0 +1,5 @@
INSERT INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
SELECT 'subscribe', 'ShowTutorial', 'true', 'bool', 'Show tutorial section on the user document page', '2025-04-22 14:25:16.639', '2025-04-22 14:25:16.639'
WHERE NOT EXISTS (
SELECT 1 FROM `system` WHERE `category` = 'subscribe' AND `key` = 'ShowTutorial'
);
@@ -0,0 +1 @@
SELECT 1;
@@ -0,0 +1,4 @@
-- MySQL datetime type does not have timezone support.
-- The Go code fix (serverPushStatusLogic.go, serverPushUserTrafficLogic.go)
-- removing .UTC() is sufficient for MySQL environments.
SELECT 1;
@@ -0,0 +1,32 @@
-- 000001_init_schema.down.sql
DROP TABLE IF EXISTS "user_subscribe_log";
DROP TABLE IF EXISTS "user_subscribe";
DROP TABLE IF EXISTS "user_login_log";
DROP TABLE IF EXISTS "user_gift_amount_log";
DROP TABLE IF EXISTS "user_device";
DROP TABLE IF EXISTS "user_commission_log";
DROP TABLE IF EXISTS "user_balance_log";
DROP TABLE IF EXISTS "user_auth_methods";
DROP TABLE IF EXISTS "user";
DROP TABLE IF EXISTS "traffic_log";
DROP TABLE IF EXISTS "ticket_follow";
DROP TABLE IF EXISTS "ticket";
DROP TABLE IF EXISTS "system";
DROP TABLE IF EXISTS "subscribe_type";
DROP TABLE IF EXISTS "subscribe_group";
DROP TABLE IF EXISTS "subscribe";
DROP TABLE IF EXISTS "sms";
DROP TABLE IF EXISTS "server_rule_group";
DROP TABLE IF EXISTS "server_group";
DROP TABLE IF EXISTS "server";
DROP TABLE IF EXISTS "payment";
DROP TABLE IF EXISTS "order";
DROP TABLE IF EXISTS "message_log";
DROP TABLE IF EXISTS "document";
DROP TABLE IF EXISTS "coupon";
DROP TABLE IF EXISTS "auth_method";
DROP TABLE IF EXISTS "application_version";
DROP TABLE IF EXISTS "application_config";
DROP TABLE IF EXISTS "application";
DROP TABLE IF EXISTS "announcement";
DROP TABLE IF EXISTS "ads";
@@ -0,0 +1,458 @@
-- 000001_init_schema.up.sql
CREATE TABLE IF NOT EXISTS "ads"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"title" varchar(255) NOT NULL DEFAULT '',
"type" varchar(255) NOT NULL DEFAULT '',
"content" text,
"target_url" varchar(512) DEFAULT '',
"start_time" TIMESTAMP DEFAULT NULL,
"end_time" TIMESTAMP DEFAULT NULL,
"status" SMALLINT DEFAULT '0',
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "announcement"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"title" varchar(255) NOT NULL DEFAULT '',
"content" text,
"show" BOOLEAN NOT NULL DEFAULT false,
"pinned" BOOLEAN NOT NULL DEFAULT false,
"popup" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "application"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" varchar(255) NOT NULL DEFAULT '',
"icon" text NOT NULL,
"description" text,
"subscribe_type" varchar(50) NOT NULL DEFAULT '',
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "application_config"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"app_id" bigint NOT NULL DEFAULT '0',
"encryption_key" text,
"encryption_method" varchar(255) DEFAULT NULL,
"domains" text,
"startup_picture" text,
"startup_picture_skip_time" bigint NOT NULL DEFAULT '0',
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "application_version"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"url" varchar(255) NOT NULL DEFAULT '',
"version" varchar(255) NOT NULL DEFAULT '',
"platform" varchar(50) NOT NULL DEFAULT '',
"is_default" BOOLEAN NOT NULL DEFAULT false,
"description" text,
"application_id" bigint DEFAULT NULL,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "application_version_fk_application_application_versions" ON "application_version" ("application_id");
CREATE TABLE IF NOT EXISTS "auth_method"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"method" varchar(255) NOT NULL DEFAULT '',
"config" text NOT NULL,
"enabled" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "uni_auth_method" UNIQUE ("method")
);
CREATE TABLE IF NOT EXISTS "coupon"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" varchar(255) NOT NULL DEFAULT '',
"code" varchar(255) NOT NULL DEFAULT '',
"count" bigint NOT NULL DEFAULT '0',
"type" SMALLINT NOT NULL DEFAULT '1',
"discount" bigint NOT NULL DEFAULT '0',
"start_time" bigint NOT NULL DEFAULT '0',
"expire_time" bigint NOT NULL DEFAULT '0',
"user_limit" bigint NOT NULL DEFAULT '0',
"subscribe" varchar(255) NOT NULL DEFAULT '',
"used_count" bigint NOT NULL DEFAULT '0',
"enable" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "uni_coupon_code" UNIQUE ("code")
);
CREATE TABLE IF NOT EXISTS "document"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"title" varchar(255) NOT NULL DEFAULT '',
"content" text,
"tags" varchar(255) NOT NULL DEFAULT '',
"show" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "message_log"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"type" varchar(50) NOT NULL DEFAULT 'email',
"platform" varchar(50) NOT NULL DEFAULT 'smtp',
"to" text NOT NULL,
"subject" varchar(255) NOT NULL DEFAULT '',
"content" text,
"status" SMALLINT NOT NULL DEFAULT '0',
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "order"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"parent_id" bigint DEFAULT NULL,
"user_id" bigint NOT NULL DEFAULT '0',
"order_no" varchar(255) NOT NULL DEFAULT '',
"type" SMALLINT NOT NULL DEFAULT '1',
"quantity" bigint NOT NULL DEFAULT '1',
"price" bigint NOT NULL DEFAULT '0',
"amount" bigint NOT NULL DEFAULT '0',
"gift_amount" bigint NOT NULL DEFAULT '0',
"discount" bigint NOT NULL DEFAULT '0',
"coupon" varchar(255) DEFAULT NULL,
"coupon_discount" bigint NOT NULL DEFAULT '0',
"commission" bigint NOT NULL DEFAULT '0',
"payment_id" bigint NOT NULL DEFAULT '-1',
"method" varchar(255) NOT NULL DEFAULT '',
"fee_amount" bigint NOT NULL DEFAULT '0',
"trade_no" varchar(255) DEFAULT NULL,
"status" SMALLINT NOT NULL DEFAULT '1',
"subscribe_id" bigint NOT NULL DEFAULT '0',
"subscribe_token" varchar(255) DEFAULT NULL,
"is_new" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "uni_order_order_no" UNIQUE ("order_no")
);
CREATE TABLE IF NOT EXISTS "payment"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" varchar(100) NOT NULL DEFAULT '',
"platform" varchar(100) NOT NULL,
"description" text,
"icon" varchar(255) DEFAULT '',
"domain" varchar(255) DEFAULT '',
"config" text NOT NULL,
"fee_mode" SMALLINT NOT NULL DEFAULT '0',
"fee_percent" bigint DEFAULT '0',
"fee_amount" bigint DEFAULT '0',
"enable" BOOLEAN NOT NULL DEFAULT false,
"token" varchar(255) DEFAULT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "uni_payment_token" UNIQUE ("token")
);
CREATE TABLE IF NOT EXISTS "server"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" varchar(100) NOT NULL DEFAULT '',
"tags" varchar(128) NOT NULL DEFAULT '',
"country" varchar(128) NOT NULL DEFAULT '',
"city" varchar(128) NOT NULL DEFAULT '',
"latitude" varchar(128) NOT NULL DEFAULT '',
"longitude" varchar(128) NOT NULL DEFAULT '',
"server_addr" varchar(100) NOT NULL DEFAULT '',
"relay_mode" varchar(20) NOT NULL DEFAULT 'none',
"relay_node" text,
"speed_limit" bigint NOT NULL DEFAULT '0',
"traffic_ratio" decimal(4, 2) NOT NULL DEFAULT '0.00',
"group_id" bigint DEFAULT NULL,
"protocol" varchar(20) NOT NULL DEFAULT '',
"config" text,
"enable" SMALLINT NOT NULL DEFAULT '1',
"sort" bigint NOT NULL DEFAULT '0',
"last_reported_at" TIMESTAMP(3) DEFAULT NULL,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "server_idx_group_id" ON "server" ("group_id");
CREATE TABLE IF NOT EXISTS "server_group"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" varchar(100) NOT NULL DEFAULT '',
"description" varchar(255) DEFAULT '',
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
-- if "sms" not exist, create it
CREATE TABLE IF NOT EXISTS "sms"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"content" text,
"platform" varchar(64) DEFAULT NULL,
"area_code" varchar(64) DEFAULT NULL,
"telephone" varchar(64) DEFAULT NULL,
"status" SMALLINT DEFAULT '1',
"created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "subscribe"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" varchar(255) NOT NULL DEFAULT '',
"description" text,
"unit_price" bigint NOT NULL DEFAULT '0',
"unit_time" varchar(255) NOT NULL DEFAULT '',
"discount" text,
"replacement" bigint NOT NULL DEFAULT '0',
"inventory" bigint NOT NULL DEFAULT '0',
"traffic" bigint NOT NULL DEFAULT '0',
"speed_limit" bigint NOT NULL DEFAULT '0',
"device_limit" bigint NOT NULL DEFAULT '0',
"quota" bigint NOT NULL DEFAULT '0',
"group_id" bigint DEFAULT NULL,
"server_group" varchar(255) DEFAULT NULL,
"server" varchar(255) DEFAULT NULL,
"show" BOOLEAN NOT NULL DEFAULT false,
"sell" BOOLEAN NOT NULL DEFAULT false,
"sort" bigint NOT NULL DEFAULT '0',
"deduction_ratio" bigint DEFAULT '0',
"allow_deduction" BOOLEAN DEFAULT true,
"reset_cycle" bigint DEFAULT '0',
"renewal_reset" BOOLEAN DEFAULT false,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "subscribe_group"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" varchar(255) NOT NULL DEFAULT '',
"description" text,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "subscribe_type"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" varchar(50) NOT NULL DEFAULT '',
"mark" varchar(255) NOT NULL DEFAULT '',
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "system"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"category" varchar(100) NOT NULL DEFAULT '',
"key" varchar(100) NOT NULL DEFAULT '',
"value" text NOT NULL,
"type" varchar(50) NOT NULL DEFAULT '',
"desc" text NOT NULL,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "uni_system_key" UNIQUE ("key")
);
CREATE INDEX IF NOT EXISTS "system_index_key" ON "system" ("key");
CREATE TABLE IF NOT EXISTS "ticket"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"title" varchar(255) NOT NULL DEFAULT '',
"description" text,
"user_id" bigint NOT NULL DEFAULT '0',
"status" SMALLINT NOT NULL DEFAULT '1',
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "ticket_follow"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"ticket_id" bigint NOT NULL DEFAULT '0',
"from" varchar(255) NOT NULL DEFAULT '',
"type" SMALLINT NOT NULL DEFAULT '1',
"content" text,
"created_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "traffic_log"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"server_id" bigint NOT NULL,
"user_id" bigint NOT NULL,
"subscribe_id" bigint NOT NULL,
"download" bigint DEFAULT '0',
"upload" bigint DEFAULT '0',
"timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "traffic_log_idx_subscribe_id" ON "traffic_log" ("subscribe_id");
CREATE INDEX IF NOT EXISTS "traffic_log_idx_server_id" ON "traffic_log" ("server_id");
CREATE INDEX IF NOT EXISTS "traffic_log_idx_user_id" ON "traffic_log" ("user_id");
CREATE TABLE IF NOT EXISTS "user"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"password" varchar(255) NOT NULL,
"avatar" text,
"balance" bigint DEFAULT '0',
"telegram" bigint DEFAULT NULL,
"refer_code" varchar(20) DEFAULT '',
"referer_id" bigint DEFAULT NULL,
"commission" bigint DEFAULT '0',
"gift_amount" bigint DEFAULT '0',
"enable" BOOLEAN NOT NULL DEFAULT true,
"is_admin" BOOLEAN NOT NULL DEFAULT false,
"valid_email" SMALLINT NOT NULL DEFAULT '0',
"enable_email_notify" SMALLINT NOT NULL DEFAULT '0',
"enable_telegram_notify" SMALLINT NOT NULL DEFAULT '0',
"enable_balance_notify" BOOLEAN NOT NULL DEFAULT false,
"enable_login_notify" BOOLEAN NOT NULL DEFAULT false,
"enable_subscribe_notify" BOOLEAN NOT NULL DEFAULT false,
"enable_trade_notify" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
"deleted_at" TIMESTAMP(3) DEFAULT NULL,
"is_del" BIGINT DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "user_idx_referer" ON "user" ("referer_id");
CREATE TABLE IF NOT EXISTS "user_auth_methods"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"user_id" bigint NOT NULL,
"auth_type" varchar(255) NOT NULL,
"auth_identifier" varchar(255) NOT NULL,
"verified" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "idx_auth_identifier" UNIQUE ("auth_identifier")
);
CREATE INDEX IF NOT EXISTS "user_auth_methods_idx_user_id" ON "user_auth_methods" ("user_id");
CREATE TABLE IF NOT EXISTS "user_balance_log"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"user_id" bigint NOT NULL,
"amount" bigint NOT NULL,
"type" SMALLINT NOT NULL,
"order_id" bigint DEFAULT NULL,
"balance" bigint NOT NULL,
"created_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "user_balance_log_idx_user_id" ON "user_balance_log" ("user_id");
CREATE TABLE IF NOT EXISTS "user_commission_log"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"user_id" bigint NOT NULL,
"order_no" varchar(191) DEFAULT NULL,
"amount" bigint NOT NULL,
"created_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "user_commission_log_idx_user_id" ON "user_commission_log" ("user_id");
CREATE TABLE IF NOT EXISTS "user_device"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"user_id" bigint NOT NULL,
"subscribe_id" bigint DEFAULT NULL,
"ip" varchar(191) DEFAULT NULL,
"identifier" varchar(191) DEFAULT NULL,
"user_agent" varchar(64) DEFAULT NULL,
"online" BOOLEAN NOT NULL DEFAULT false,
"enabled" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "user_device_idx_user_id" ON "user_device" ("user_id");
CREATE TABLE IF NOT EXISTS "user_gift_amount_log"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"user_id" bigint NOT NULL,
"user_subscribe_id" bigint DEFAULT NULL,
"order_no" varchar(191) DEFAULT NULL,
"type" SMALLINT NOT NULL,
"amount" bigint NOT NULL,
"balance" bigint NOT NULL,
"remark" varchar(255) DEFAULT '',
"created_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "user_gift_amount_log_idx_user_id" ON "user_gift_amount_log" ("user_id");
CREATE TABLE IF NOT EXISTS "user_login_log"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"user_id" bigint NOT NULL,
"login_ip" varchar(255) NOT NULL,
"user_agent" text NOT NULL,
"success" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "user_login_log_idx_user_id" ON "user_login_log" ("user_id");
CREATE TABLE IF NOT EXISTS "user_subscribe"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"user_id" bigint NOT NULL,
"order_id" bigint NOT NULL,
"subscribe_id" bigint NOT NULL,
"start_time" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
"expire_time" TIMESTAMP(3) DEFAULT NULL,
"traffic" bigint DEFAULT '0',
"download" bigint DEFAULT '0',
"upload" bigint DEFAULT '0',
"token" varchar(255) DEFAULT '',
"uuid" varchar(255) DEFAULT '',
"status" SMALLINT DEFAULT '0',
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "uni_user_subscribe_token" UNIQUE ("token"),
CONSTRAINT "uni_user_subscribe_uuid" UNIQUE ("uuid")
);
CREATE INDEX IF NOT EXISTS "user_subscribe_idx_user_id" ON "user_subscribe" ("user_id");
CREATE INDEX IF NOT EXISTS "user_subscribe_idx_order_id" ON "user_subscribe" ("order_id");
CREATE INDEX IF NOT EXISTS "user_subscribe_idx_subscribe_id" ON "user_subscribe" ("subscribe_id");
CREATE INDEX IF NOT EXISTS "user_subscribe_idx_token" ON "user_subscribe" ("token");
CREATE INDEX IF NOT EXISTS "user_subscribe_idx_uuid" ON "user_subscribe" ("uuid");
CREATE TABLE IF NOT EXISTS "user_subscribe_log"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"user_id" bigint NOT NULL,
"user_subscribe_id" bigint NOT NULL,
"token" varchar(255) NOT NULL,
"ip" varchar(255) NOT NULL,
"user_agent" text NOT NULL,
"created_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "user_subscribe_log_idx_user_id" ON "user_subscribe_log" ("user_id");
CREATE INDEX IF NOT EXISTS "user_subscribe_log_idx_user_subscribe_id" ON "user_subscribe_log" ("user_subscribe_id");
CREATE TABLE IF NOT EXISTS "server_rule_group"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" varchar(100) NOT NULL DEFAULT '',
"icon" text,
"tags" text,
"description" varchar(255) DEFAULT '',
"enable" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "unique_name" UNIQUE ("name")
);
@@ -0,0 +1,15 @@
-- 000002_init_data.down.sql
DELETE
FROM "auth_method"
WHERE "id" IN (1, 2, 3, 4, 5, 6, 7, 8);
DELETE
FROM "payment"
WHERE "id" = -1;
DELETE
FROM "subscribe_type"
WHERE "id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
DELETE
FROM "system"
WHERE "id" IN
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41);
@@ -0,0 +1,116 @@
-- 000002_init_data.up.sql
-- auth_method
INSERT INTO "auth_method" ("id", "method", "config", "enabled", "created_at", "updated_at")
VALUES
(1, 'email', '{"platform":"smtp","platform_config":{"host":"","port":0,"user":"","pass":"","from":"","ssl":false},"enable_verify":false,"enable_notify":false,"enable_domain_suffix":false,"domain_suffix_list":"","verify_email_template":"","expiration_email_template":"","maintenance_email_template":"","traffic_exceed_email_template":""}', true, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(2, 'mobile', '{"platform":"AlibabaCloud","platform_config":{"access":"","secret":"","sign_name":"","endpoint":"","template_code":""},"enable_whitelist":false,"whitelist":[]}', false, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(3, 'apple', '{"team_id":"","key_id":"","client_id":"","client_secret":"","redirect_url":""}', false, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(4, 'google', '{"client_id":"","client_secret":"","redirect_url":""}', false, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(5, 'github', '{"client_id":"","client_secret":"","redirect_url":""}', false, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(6, 'facebook', '{"client_id":"","client_secret":"","redirect_url":""}', false, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(7, 'telegram', '{"bot_token":"","enable_notify":false,"webhook_domain":""}', false, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642'),
(8, 'device', '{"show_ads":false,"only_real_device":false,"enable_security":false,"security_secret":""}', false, '2025-04-22 14:25:16.642', '2025-04-22 14:25:16.642');
-- payment
INSERT INTO "payment" ("id", "name", "platform", "description", "icon", "domain", "config", "fee_mode",
"fee_percent", "fee_amount", "enable", "token")
VALUES
(-1, 'Balance', 'balance', '', '', '', '', 0, 0, 0, true, '');
-- subscribe_type
INSERT INTO "subscribe_type" ("id", "name", "mark", "created_at", "updated_at")
VALUES (1, 'Clash', 'Clash', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(2, 'Hiddify', 'Hiddify', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(3, 'Loon', 'Loon', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(4, 'NekoBox', 'NekoBox', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(5, 'NekoRay', 'NekoRay', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(6, 'Netch', 'Netch', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(7, 'Quantumult', 'Quantumult', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(8, 'Shadowrocket', 'Shadowrocket', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(9, 'SingBox', ' SingBox', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(10, 'Surfboard', 'Surfboard', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(11, 'Surge', 'Surge', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(12, 'V2box', 'V2box', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(13, 'V2rayN', 'V2rayN', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648'),
(14, 'V2rayNg', 'V2rayNg', '2025-04-22 14:25:16.648', '2025-04-22 14:25:16.648');
-- system
INSERT INTO "system" ("id", "category", "key", "value", "type", "desc", "created_at", "updated_at")
VALUES (1, 'site', 'SiteLogo', '/favicon.svg', 'string', 'Site Logo', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(2, 'site', 'SiteName', 'Perfect Panel', 'string', 'Site Name', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(3, 'site', 'SiteDesc',
'PPanel is a pure, professional, and perfect open-source proxy panel tool, designed to be your ideal choice for learning and practical use.',
'string', 'Site Description', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(4, 'site', 'Host', '', 'string', 'Site Host', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(5, 'site', 'Keywords', 'Perfect Panel,PPanel', 'string', 'Site Keywords', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(6, 'site', 'CustomHTML', '', 'string', 'Custom HTML', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(7, 'tos', 'TosContent', 'Welcome to use Perfect Panel', 'string', 'Terms of Service', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(8, 'tos', 'PrivacyPolicy', '', 'string', 'PrivacyPolicy', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(9, 'ad', 'WebAD', 'false', 'bool', 'Display ad on the web', '2025-04-22 14:25:16.637',
'2025-04-22 14:25:16.637'),
(10, 'subscribe', 'SingleModel', 'false', 'bool', '是否单订阅模式', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(11, 'subscribe', 'SubscribePath', '/api/subscribe', 'string', '订阅路径', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(12, 'subscribe', 'SubscribeDomain', '', 'string', '订阅域名', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(13, 'subscribe', 'PanDomain', 'false', 'bool', '是否使用泛域名', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(14, 'verify', 'TurnstileSiteKey', '', 'string', 'TurnstileSiteKey', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(15, 'verify', 'TurnstileSecret', '', 'string', 'TurnstileSecret', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(16, 'verify', 'EnableLoginVerify', 'false', 'bool', 'is enable login verify', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(17, 'verify', 'EnableRegisterVerify', 'false', 'bool', 'is enable register verify', '2025-04-22 14:25:16.639',
'2025-04-22 14:25:16.639'),
(18, 'verify', 'EnableResetPasswordVerify', 'false', 'bool', 'is enable reset password verify',
'2025-04-22 14:25:16.639', '2025-04-22 14:25:16.639'),
(19, 'server', 'NodeSecret', '12345678', 'string', 'node secret', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(20, 'server', 'NodePullInterval', '10', 'int', 'node pull interval', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(21, 'server', 'NodePushInterval', '60', 'int', 'node push interval', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(22, 'server', 'NodeMultiplierConfig', '[]', 'string', 'node multiplier config', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(23, 'invite', 'ForcedInvite', 'false', 'bool', 'Forced invite', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(24, 'invite', 'ReferralPercentage', '20', 'int', 'Referral percentage', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(25, 'invite', 'OnlyFirstPurchase', 'false', 'bool', 'Only first purchase', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(26, 'register', 'StopRegister', 'false', 'bool', 'is stop register', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(27, 'register', 'EnableTrial', 'false', 'bool', 'is enable trial', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(28, 'register', 'TrialSubscribe', '', 'int', 'Trial subscription', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(29, 'register', 'TrialTime', '24', 'int', 'Trial time', '2025-04-22 14:25:16.640', '2025-04-22 14:25:16.640'),
(30, 'register', 'TrialTimeUnit', 'Hour', 'string', 'Trial time unit', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(31, 'register', 'EnableIpRegisterLimit', 'false', 'bool', 'is enable IP register limit',
'2025-04-22 14:25:16.640', '2025-04-22 14:25:16.640'),
(32, 'register', 'IpRegisterLimit', '3', 'int', 'IP Register Limit', '2025-04-22 14:25:16.640',
'2025-04-22 14:25:16.640'),
(33, 'register', 'IpRegisterLimitDuration', '64', 'int', 'IP Register Limit Duration (minutes)',
'2025-04-22 14:25:16.640', '2025-04-22 14:25:16.640'),
(34, 'currency', 'Currency', 'USD', 'string', 'Currency', '2025-04-22 14:25:16.641', '2025-04-22 14:25:16.641'),
(35, 'currency', 'CurrencySymbol', '$', 'string', 'Currency Symbol', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(36, 'currency', 'CurrencyUnit', 'USD', 'string', 'Currency Unit', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(37, 'currency', 'AccessKey', '', 'string', 'Exchangerate Access Key', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(38, 'verify_code', 'VerifyCodeExpireTime', '300', 'int', 'Verify code expire time', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(39, 'verify_code', 'VerifyCodeLimit', '15', 'int', 'limits of verify code', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(40, 'verify_code', 'VerifyCodeInterval', '60', 'int', 'Interval of verify code', '2025-04-22 14:25:16.641',
'2025-04-22 14:25:16.641'),
(41, 'system', 'Version', '0.2.0(02002)', 'string', 'System Version', '2025-04-22 14:25:16.642',
'2025-04-22 14:25:16.642');
SELECT setval(pg_get_serial_sequence('"auth_method"', 'id'), COALESCE((SELECT MAX("id") FROM "auth_method"), 1), true);
SELECT setval(pg_get_serial_sequence('"subscribe_type"', 'id'), COALESCE((SELECT MAX("id") FROM "subscribe_type"), 1), true);
SELECT setval(pg_get_serial_sequence('"system"', 'id'), COALESCE((SELECT MAX("id") FROM "system"), 1), true);
@@ -0,0 +1,5 @@
ALTER TABLE "order" DROP COLUMN IF EXISTS "payment_id";
ALTER TABLE "payment" DROP COLUMN IF EXISTS "platform";
ALTER TABLE "payment" DROP COLUMN IF EXISTS "description";
ALTER TABLE "payment" DROP COLUMN IF EXISTS "token";
ALTER TABLE "payment" ADD COLUMN IF NOT EXISTS "mark" VARCHAR(255) DEFAULT NULL;
@@ -0,0 +1,6 @@
-- PostgreSQL version of payment/order compatibility migration.
ALTER TABLE "order" ADD COLUMN IF NOT EXISTS "payment_id" BIGINT NOT NULL DEFAULT -1;
ALTER TABLE "payment" ADD COLUMN IF NOT EXISTS "platform" VARCHAR(100) NOT NULL DEFAULT '';
ALTER TABLE "payment" DROP COLUMN IF EXISTS "mark";
ALTER TABLE "payment" ADD COLUMN IF NOT EXISTS "description" TEXT;
ALTER TABLE "payment" ADD COLUMN IF NOT EXISTS "token" VARCHAR(255) DEFAULT NULL;
@@ -0,0 +1,4 @@
-- migrations/02003_rebuild_rule.up.sql
-- Purpose: Back rebuilding server rule table
-- Author: PPanel Team, 2025-04-21
DROP TABLE IF EXISTS server_rule_group;
@@ -0,0 +1,19 @@
-- migrations/02003_rebuild_rule.up.sql
-- Purpose: rebuilding server rule table
-- Author: PPanel Team, 2025-04-21
DROP TABLE IF EXISTS "server_rule_group";
CREATE TABLE "server_rule_group"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"name" VARCHAR(64) NOT NULL DEFAULT '',
"icon" VARCHAR(255),
"tags" TEXT,
"rules" TEXT,
"enable" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3),
"updated_at" TIMESTAMP(3),
PRIMARY KEY ("id"),
CONSTRAINT "uni_server_rule_group_name" UNIQUE ("name")
);
CREATE INDEX IF NOT EXISTS "server_rule_group_idx_enable" ON "server_rule_group" ("enable");
@@ -0,0 +1,4 @@
DROP TABLE IF EXISTS "user_device_online_record";
ALTER TABLE "user_subscribe" DROP COLUMN IF EXISTS "finished_at";
ALTER TABLE "application_config" DROP COLUMN IF EXISTS "invitation_link";
ALTER TABLE "application_config" DROP COLUMN IF EXISTS "kr_website_id";
@@ -0,0 +1,15 @@
CREATE TABLE IF NOT EXISTS "user_device_online_record"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
"user_id" BIGINT NOT NULL,
"identifier" VARCHAR(255) NOT NULL,
"online_time" TIMESTAMP,
"offline_time" TIMESTAMP,
"online_seconds" BIGINT,
"duration_days" BIGINT,
"created_at" TIMESTAMP
);
ALTER TABLE "user_subscribe" ADD COLUMN IF NOT EXISTS "finished_at" TIMESTAMP NULL;
ALTER TABLE "application_config" ADD COLUMN IF NOT EXISTS "invitation_link" TEXT NULL DEFAULT NULL;
ALTER TABLE "application_config" ADD COLUMN IF NOT EXISTS "kr_website_id" VARCHAR(255) NULL DEFAULT NULL;
@@ -0,0 +1,5 @@
-- migrations/02008_create_user_reset_subscribe_log.down.sql
-- Purpose: Drop user_reset_subscribe_log table
-- Author: PPanel Team, 2025-04-22
DROP TABLE IF EXISTS "user_reset_subscribe_log";
@@ -0,0 +1,15 @@
-- migrations/02008_create_user_reset_subscribe_log.up.sql
-- Purpose: Create user_reset_subscribe_log table
-- Author: PPanel Team, 2025-04-22
CREATE TABLE IF NOT EXISTS "user_reset_subscribe_log"
(
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY,
"user_id" BIGINT NOT NULL,
"type" SMALLINT NOT NULL,
"order_no" VARCHAR(255) DEFAULT NULL,
"user_subscribe_id" BIGINT NOT NULL,
"created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS "user_reset_subscribe_log_idx_user_id" ON "user_reset_subscribe_log" ("user_id");
CREATE INDEX IF NOT EXISTS "user_reset_subscribe_log_idx_user_subscribe_id" ON "user_reset_subscribe_log" ("user_subscribe_id");
@@ -0,0 +1,3 @@
ALTER TABLE "server_rule_group"
DROP COLUMN "default",
DROP COLUMN "type";
@@ -0,0 +1,3 @@
ALTER TABLE "server_rule_group"
ADD COLUMN "default" BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN "type" VARCHAR(100) NOT NULL DEFAULT '';
@@ -0,0 +1 @@
DROP TABLE IF EXISTS "email_task";
@@ -0,0 +1,21 @@
DROP TABLE IF EXISTS "email_task";
CREATE TABLE "email_task" (
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"subject" varchar(255) NOT NULL,
"content" text NOT NULL,
"recipient" text NOT NULL,
"scope" varchar(50) NOT NULL,
"register_start_time" TIMESTAMP(3) DEFAULT NULL,
"register_end_time" TIMESTAMP(3) DEFAULT NULL,
"additional" text,
"scheduled" TIMESTAMP(3) NOT NULL,
"interval" SMALLINT NOT NULL,
"limit" BIGINT NOT NULL,
"status" SMALLINT NOT NULL,
"errors" text NOT NULL,
"total" BIGINT NOT NULL DEFAULT '0',
"current" BIGINT NOT NULL DEFAULT '0',
"created_at" TIMESTAMP(3) DEFAULT NULL,
"updated_at" TIMESTAMP(3) DEFAULT NULL,
PRIMARY KEY ("id")
);
@@ -0,0 +1 @@
DROP TABLE IF EXISTS "subscribe_application";
File diff suppressed because one or more lines are too long

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