feat: 迁移订阅表字段,为用户认证方法添加软删除功能及索引,并调整 Docker Compose 中 MySQL 端口映射。
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m34s
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m34s
This commit is contained in:
parent
ad578883e4
commit
3db14ae472
@ -57,7 +57,7 @@ services:
|
|||||||
container_name: ppanel-mysql
|
container_name: ppanel-mysql
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:3306:3306" # 仅宿主机可访问,ppanel-server(host网络)通过127.0.0.1连接
|
- "3306:3306" # 仅宿主机可访问,ppanel-server(host网络)通过127.0.0.1连接
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:?请在 .env 文件中设置 MYSQL_ROOT_PASSWORD}"
|
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:?请在 .env 文件中设置 MYSQL_ROOT_PASSWORD}"
|
||||||
MYSQL_DATABASE: "ppanel"
|
MYSQL_DATABASE: "ppanel"
|
||||||
|
|||||||
@ -61,6 +61,10 @@ Trace: # 链路追踪配置 (OpenTelemetry)
|
|||||||
Batcher: otlpgrpc # 本地开发留空""; 生产填 otlpgrpc
|
Batcher: otlpgrpc # 本地开发留空""; 生产填 otlpgrpc
|
||||||
Endpoint: "127.0.0.1:4317" # host 网络模式; bridge 模式改为 tempo:4317
|
Endpoint: "127.0.0.1:4317" # host 网络模式; bridge 模式改为 tempo:4317
|
||||||
|
|
||||||
|
device:
|
||||||
|
enable: true # 开启设备加密通信
|
||||||
|
security_secret: "" # AES加密密钥,需要和App端一致,key=SHA256(security_secret)[:32]
|
||||||
|
|
||||||
Administrator:
|
Administrator:
|
||||||
Email: admin@ppanel.dev # 后台登录邮箱,请修改
|
Email: admin@ppanel.dev # 后台登录邮箱,请修改
|
||||||
Password: CHANGE_ME_TO_STRONG_PASSWORD # 后台登录密码,请修改为强密码
|
Password: CHANGE_ME_TO_STRONG_PASSWORD # 后台登录密码,请修改为强密码
|
||||||
|
|||||||
@ -1,7 +1,53 @@
|
|||||||
ALTER TABLE `subscribe`
|
-- Add nodes column if not exists
|
||||||
ADD COLUMN `nodes` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Node IDs',
|
SET @col_exists = (SELECT COUNT(*)
|
||||||
ADD COLUMN `node_tags` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Node Tags',
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
DROP COLUMN `server`,
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
DROP COLUMN `server_group`;
|
AND TABLE_NAME = 'subscribe'
|
||||||
|
AND COLUMN_NAME = 'nodes');
|
||||||
|
SET @sql = IF(@col_exists = 0,
|
||||||
|
'ALTER TABLE `subscribe` ADD COLUMN `nodes` VARCHAR(255) NOT NULL DEFAULT '''' COMMENT ''Node IDs''',
|
||||||
|
'SELECT 1');
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- Add node_tags column if not exists
|
||||||
|
SET @col_exists = (SELECT COUNT(*)
|
||||||
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'subscribe'
|
||||||
|
AND COLUMN_NAME = 'node_tags');
|
||||||
|
SET @sql = IF(@col_exists = 0,
|
||||||
|
'ALTER TABLE `subscribe` ADD COLUMN `node_tags` VARCHAR(255) NOT NULL DEFAULT '''' COMMENT ''Node Tags''',
|
||||||
|
'SELECT 1');
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- Drop server column if exists
|
||||||
|
SET @col_exists = (SELECT COUNT(*)
|
||||||
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'subscribe'
|
||||||
|
AND COLUMN_NAME = 'server');
|
||||||
|
SET @sql = IF(@col_exists > 0,
|
||||||
|
'ALTER TABLE `subscribe` DROP COLUMN `server`',
|
||||||
|
'SELECT 1');
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- Drop server_group column if exists
|
||||||
|
SET @col_exists = (SELECT COUNT(*)
|
||||||
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'subscribe'
|
||||||
|
AND COLUMN_NAME = 'server_group');
|
||||||
|
SET @sql = IF(@col_exists > 0,
|
||||||
|
'ALTER TABLE `subscribe` DROP COLUMN `server_group`',
|
||||||
|
'SELECT 1');
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `server_rule_group`;
|
DROP TABLE IF EXISTS `server_rule_group`;
|
||||||
|
|||||||
@ -121,6 +121,25 @@ func EnsureSchemaCompatibility(ctx *svc.ServiceContext) error {
|
|||||||
column: "status",
|
column: "status",
|
||||||
ddl: "ALTER TABLE `redemption_code` ADD COLUMN `status` TINYINT NOT NULL DEFAULT 1 COMMENT 'Status: 1=enabled, 0=disabled';",
|
ddl: "ALTER TABLE `redemption_code` ADD COLUMN `status` TINYINT NOT NULL DEFAULT 1 COMMENT 'Status: 1=enabled, 0=disabled';",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
table: "user_auth_methods",
|
||||||
|
column: "deleted_at",
|
||||||
|
ddl: "ALTER TABLE `user_auth_methods` ADD COLUMN `deleted_at` DATETIME(3) DEFAULT NULL COMMENT 'Deletion Time';",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index patches: ensure critical indexes exist
|
||||||
|
type schemaIndexPatch struct {
|
||||||
|
table string
|
||||||
|
index string
|
||||||
|
ddl string
|
||||||
|
}
|
||||||
|
indexPatches := []schemaIndexPatch{
|
||||||
|
{
|
||||||
|
table: "user_auth_methods",
|
||||||
|
index: "idx_user_deleted_at",
|
||||||
|
ddl: "CREATE INDEX `idx_user_deleted_at` ON `user_auth_methods` (`user_id`, `deleted_at`);",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, patch := range tablePatches {
|
for _, patch := range tablePatches {
|
||||||
@ -159,6 +178,27 @@ func EnsureSchemaCompatibility(ctx *svc.ServiceContext) error {
|
|||||||
logger.Infof("[SchemaCompat] added missing column: %s.%s", patch.table, patch.column)
|
logger.Infof("[SchemaCompat] added missing column: %s.%s", patch.table, patch.column)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, patch := range indexPatches {
|
||||||
|
tblExists, err := tableExists(ctx.DB, patch.table)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "check table %s failed", patch.table)
|
||||||
|
}
|
||||||
|
if !tblExists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
exists, err := indexExists(ctx.DB, patch.table, patch.index)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "check index %s.%s failed", patch.table, patch.index)
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err = ctx.DB.Exec(patch.ddl).Error; err != nil {
|
||||||
|
return errors.Wrapf(err, "create index %s.%s failed", patch.table, patch.index)
|
||||||
|
}
|
||||||
|
logger.Infof("[SchemaCompat] created missing index: %s.%s", patch.table, patch.index)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,6 +224,19 @@ func columnExists(db *gorm.DB, table, column string) (bool, error) {
|
|||||||
return count > 0, nil
|
return count > 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func indexExists(db *gorm.DB, table, index string) (bool, error) {
|
||||||
|
var count int64
|
||||||
|
err := db.Raw(
|
||||||
|
"SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND INDEX_NAME = ?",
|
||||||
|
table,
|
||||||
|
index,
|
||||||
|
).Scan(&count).Error
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return count > 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
func _schemaCompatDebug(table, column string) string {
|
func _schemaCompatDebug(table, column string) string {
|
||||||
if column == "" {
|
if column == "" {
|
||||||
return table
|
return table
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user