package database import ( "database/sql" "fmt" "time" _ "github.com/mattn/go-sqlite3" ) // TeamOwner 账号结构 type TeamOwner struct { ID int64 `json:"id"` Email string `json:"email"` Password string `json:"password,omitempty"` Token string `json:"token,omitempty"` AccountID string `json:"account_id"` Status string `json:"status"` CreatedAt time.Time `json:"created_at"` } // DB 数据库管理器 type DB struct { db *sql.DB } // 全局数据库实例 var Instance *DB // Init 初始化数据库 func Init(dbPath string) error { db, err := sql.Open("sqlite3", dbPath) if err != nil { return fmt.Errorf("打开数据库失败: %w", err) } Instance = &DB{db: db} if err := Instance.createTables(); err != nil { return fmt.Errorf("创建表失败: %w", err) } fmt.Printf("[数据库] SQLite 已连接: %s\n", dbPath) return nil } // createTables 创建表 func (d *DB) createTables() error { _, err := d.db.Exec(` CREATE TABLE IF NOT EXISTS team_owners ( id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL UNIQUE, password TEXT, token TEXT, account_id TEXT NOT NULL, status TEXT DEFAULT 'valid', created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX IF NOT EXISTS idx_team_owners_email ON team_owners(email); CREATE INDEX IF NOT EXISTS idx_team_owners_status ON team_owners(status); CREATE INDEX IF NOT EXISTS idx_team_owners_account_id ON team_owners(account_id); -- 配置表 (key-value 形式) CREATE TABLE IF NOT EXISTS app_config ( key TEXT PRIMARY KEY, value TEXT NOT NULL, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); `) return err } // GetConfig 获取配置值 func (d *DB) GetConfig(key string) (string, error) { var value string err := d.db.QueryRow("SELECT value FROM app_config WHERE key = ?", key).Scan(&value) if err == sql.ErrNoRows { return "", nil } return value, err } // SetConfig 设置配置值 func (d *DB) SetConfig(key, value string) error { _, err := d.db.Exec(` INSERT INTO app_config (key, value, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP) ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP `, key, value, value) return err } // GetAllConfig 获取所有配置 func (d *DB) GetAllConfig() (map[string]string, error) { rows, err := d.db.Query("SELECT key, value FROM app_config") if err != nil { return nil, err } defer rows.Close() result := make(map[string]string) for rows.Next() { var key, value string if err := rows.Scan(&key, &value); err != nil { continue } result[key] = value } return result, nil } // AddTeamOwner 添加 Team Owner func (d *DB) AddTeamOwner(owner TeamOwner) (int64, error) { result, err := d.db.Exec(` INSERT OR REPLACE INTO team_owners (email, password, token, account_id, status, created_at) VALUES (?, ?, ?, ?, 'valid', CURRENT_TIMESTAMP) `, owner.Email, owner.Password, owner.Token, owner.AccountID) if err != nil { return 0, err } return result.LastInsertId() } // AddTeamOwners 批量添加 func (d *DB) AddTeamOwners(owners []TeamOwner) (int, error) { tx, err := d.db.Begin() if err != nil { return 0, err } defer tx.Rollback() stmt, err := tx.Prepare(` INSERT OR REPLACE INTO team_owners (email, password, token, account_id, status, created_at) VALUES (?, ?, ?, ?, 'valid', CURRENT_TIMESTAMP) `) if err != nil { return 0, err } defer stmt.Close() count := 0 for _, owner := range owners { _, err := stmt.Exec(owner.Email, owner.Password, owner.Token, owner.AccountID) if err != nil { fmt.Printf("[数据库] 插入失败 %s: %v\n", owner.Email, err) continue } count++ } if err := tx.Commit(); err != nil { return 0, err } return count, nil } // GetTeamOwners 获取列表 func (d *DB) GetTeamOwners(status string, limit, offset int) ([]TeamOwner, int, error) { query := "SELECT id, email, password, token, account_id, status, created_at FROM team_owners WHERE 1=1" countQuery := "SELECT COUNT(*) FROM team_owners WHERE 1=1" args := []interface{}{} if status != "" { query += " AND status = ?" countQuery += " AND status = ?" args = append(args, status) } var total int err := d.db.QueryRow(countQuery, args...).Scan(&total) if err != nil { return nil, 0, err } query += " ORDER BY created_at DESC LIMIT ? OFFSET ?" args = append(args, limit, offset) rows, err := d.db.Query(query, args...) if err != nil { return nil, 0, err } defer rows.Close() var owners []TeamOwner for rows.Next() { var owner TeamOwner err := rows.Scan(&owner.ID, &owner.Email, &owner.Password, &owner.Token, &owner.AccountID, &owner.Status, &owner.CreatedAt) if err != nil { continue } owners = append(owners, owner) } return owners, total, nil } // GetPendingOwners 获取待处理 func (d *DB) GetPendingOwners() ([]TeamOwner, error) { rows, err := d.db.Query(` SELECT id, email, password, token, account_id, status, created_at FROM team_owners WHERE status = 'valid' ORDER BY created_at ASC `) if err != nil { return nil, err } defer rows.Close() var owners []TeamOwner for rows.Next() { var owner TeamOwner err := rows.Scan(&owner.ID, &owner.Email, &owner.Password, &owner.Token, &owner.AccountID, &owner.Status, &owner.CreatedAt) if err != nil { continue } owners = append(owners, owner) } return owners, nil } // UpdateOwnerStatus 更新状态 func (d *DB) UpdateOwnerStatus(id int64, status string) error { _, err := d.db.Exec("UPDATE team_owners SET status = ? WHERE id = ?", status, id) return err } // DeleteTeamOwner 删除 func (d *DB) DeleteTeamOwner(id int64) error { _, err := d.db.Exec("DELETE FROM team_owners WHERE id = ?", id) return err } // ClearTeamOwners 清空 func (d *DB) ClearTeamOwners() error { _, err := d.db.Exec("DELETE FROM team_owners") return err } // GetOwnerStats 获取统计 func (d *DB) GetOwnerStats() map[string]int { stats := map[string]int{ "total": 0, "valid": 0, "registered": 0, "pooled": 0, } var count int if err := d.db.QueryRow("SELECT COUNT(*) FROM team_owners").Scan(&count); err == nil { stats["total"] = count } if err := d.db.QueryRow("SELECT COUNT(*) FROM team_owners WHERE status = 'valid'").Scan(&count); err == nil { stats["valid"] = count } if err := d.db.QueryRow("SELECT COUNT(*) FROM team_owners WHERE status = 'registered'").Scan(&count); err == nil { stats["registered"] = count } if err := d.db.QueryRow("SELECT COUNT(*) FROM team_owners WHERE status = 'pooled'").Scan(&count); err == nil { stats["pooled"] = count } return stats } // Close 关闭数据库 func (d *DB) Close() error { if d.db != nil { return d.db.Close() } return nil }