This commit is contained in:
+8
-13
@@ -1,33 +1,28 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/model"
|
||||
)
|
||||
|
||||
// LoadAccountConfig 读取账号并把 Config 字段反序列化到 out。
|
||||
// GetAccount 读取一个账号,返回数据库里的原始记录。
|
||||
//
|
||||
// 各个 driver 之前都各自实现了一遍这段逻辑,其中 github driver 甚至
|
||||
// 直接把驱动内的结构体当成 gorm model 查询,这里统一收敛。
|
||||
func LoadAccountConfig(accountID uint, out any) error {
|
||||
// 规则执行需要的账号凭据由上层(handler/runner)在这里取好再传给 driver,
|
||||
// driver 自己不碰数据库。accountID 为 0 表示该规则不需要账号,返回 (nil, nil)。
|
||||
func GetAccount(accountID uint) (*model.Account, error) {
|
||||
if accountID == 0 {
|
||||
return fmt.Errorf("该规则没有关联账号")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
gormDB, err := GetGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var account model.Account
|
||||
if err := gormDB.First(&account, accountID).Error; err != nil {
|
||||
return fmt.Errorf("获取账号(ID: %d)失败: %w", accountID, err)
|
||||
return nil, fmt.Errorf("获取账号(ID: %d)失败: %w", accountID, err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(account.Config), out); err != nil {
|
||||
return fmt.Errorf("解析账号(ID: %d)配置失败: %w", accountID, err)
|
||||
}
|
||||
return nil
|
||||
return &account, nil
|
||||
}
|
||||
|
||||
@@ -43,6 +43,9 @@ func MustInit() *gorm.DB {
|
||||
if err := ensureAdmin(gormDB); err != nil {
|
||||
log.Fatalf("初始化管理员失败: %v", err)
|
||||
}
|
||||
if err := migrateGatewayRules(gormDB); err != nil {
|
||||
log.Fatalf("迁移消息网关规则失败: %v", err)
|
||||
}
|
||||
return gormDB
|
||||
}
|
||||
|
||||
@@ -136,6 +139,7 @@ func AutoMigrate(gormDB *gorm.DB) error {
|
||||
&model.User{},
|
||||
&model.Timer{},
|
||||
&model.Rule{},
|
||||
&model.GatewayRule{},
|
||||
&model.Account{},
|
||||
&model.ExecutionLog{},
|
||||
&model.MessageGateway{},
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// legacyRule 是迁移前的 rules 表结构,只用来读出已经废弃的 gateway_id
|
||||
type legacyRule struct {
|
||||
ID uint
|
||||
UID uint
|
||||
GatewayID uint
|
||||
Name string
|
||||
AccountID uint
|
||||
Type string
|
||||
ConfigJson string
|
||||
Enabled bool
|
||||
CreateAt int64
|
||||
}
|
||||
|
||||
// migrateGatewayRules 把历史数据里混在 rules 表中的消息网关规则搬到 gateway_rules 表。
|
||||
//
|
||||
// v2.1 之前消息网关规则和定时器规则共用 rules 表,靠 gateway_id 区分;
|
||||
// 现在两者分表存储,这里做一次性搬迁,避免老用户升级后规则凭空消失。
|
||||
func migrateGatewayRules(gormDB *gorm.DB) error {
|
||||
if !gormDB.Migrator().HasColumn("rules", "gateway_id") {
|
||||
return nil
|
||||
}
|
||||
|
||||
var legacy []legacyRule
|
||||
if err := gormDB.Table("rules").Where("gateway_id <> 0").Find(&legacy).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if len(legacy) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gormDB.Transaction(func(tx *gorm.DB) error {
|
||||
for _, rule := range legacy {
|
||||
moved := model.GatewayRule{
|
||||
UID: rule.UID,
|
||||
GatewayID: rule.GatewayID,
|
||||
Name: rule.Name,
|
||||
AccountID: rule.AccountID,
|
||||
Type: rule.Type,
|
||||
ConfigJson: rule.ConfigJson,
|
||||
Enabled: rule.Enabled,
|
||||
CreateAt: rule.CreateAt,
|
||||
}
|
||||
if err := tx.Create(&moved).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Exec("DELETE FROM rules WHERE id = ?", rule.ID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
log.Printf("已迁移 %d 条消息网关规则到 gateway_rules 表", len(legacy))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user