Files
backend_v2/scripts/seed_users/main.go
toom1996 1fd9c48f58 update
2026-09-02 21:51:35 +08:00

108 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Command seed_users 预置内部账号(运营/编辑用,不开放公开注册)。
//
// 项目已移除 AutoMigrate,表结构由 scripts/sql/005_create_users.sql 托管;
// 本脚本用 CREATE TABLE IF NOT EXISTS 兜底建表,再 upsert 一个内部账号。
//
// 用法:
// go run ./scripts/seed_users
// SEED_ADMIN_PASSWORD='你的强密码' go run ./scripts/seed_users
//
// 默认账号 admin / admin@studio.local,密码取环境变量 SEED_ADMIN_PASSWORD,
// 缺省回落强密码常量。生产部署请务必通过环境变量指定并尽快修改。
package main
import (
"errors"
"flag"
"log"
"os"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
"fashionapi/internal/config"
"fashionapi/internal/database"
"fashionapi/internal/model"
)
func main() {
configPath := flag.String("config", "", "配置文件路径,默认查找 configs/config.yml")
flag.Parse()
cfg, err := config.Load(*configPath)
if err != nil {
log.Fatalf("✗ 加载配置失败: %v", err)
}
db, err := database.New(cfg.Database)
if err != nil {
log.Fatalf("✗ 连接数据库失败: %v", err)
}
defer func() {
if e := database.Close(db); e != nil {
log.Printf("! 关闭数据库连接失败: %v", e)
}
}()
// 1. 兜底建表(与 scripts/sql/005_create_users.sql 完全一致)
createSQL := `CREATE TABLE IF NOT EXISTS users (
id int unsigned NOT NULL AUTO_INCREMENT,
created_at int unsigned NOT NULL DEFAULT 0,
updated_at int unsigned NOT NULL DEFAULT 0,
username varchar(64) NOT NULL,
email varchar(191) NOT NULL,
password_hash varchar(255) NOT NULL DEFAULT '',
is_deleted tinyint unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (id),
UNIQUE KEY uk_username (username),
UNIQUE KEY uk_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`
if e := db.Exec(createSQL).Error; e != nil {
log.Fatalf("✗ 建表失败: %v", e)
}
log.Println("✓ users 表就绪")
// 2. 预置内部账号
// admin: 正式内部账号,密码取环境变量 SEED_ADMIN_PASSWORD(缺省回落强密码常量)。
// root: 测试账号,固定弱密码 root,仅供本地联调使用,勿用于生产。
adminPassword := os.Getenv("SEED_ADMIN_PASSWORD")
if adminPassword == "" {
adminPassword = "Studio#2026!Admin"
}
accounts := []struct {
username string
email string
password string
}{
{username: "admin", email: "admin@studio.local", password: adminPassword},
{username: "root", email: "root@studio.local", password: "root"},
}
for _, acc := range accounts {
hash, e := bcrypt.GenerateFromPassword([]byte(acc.password), bcrypt.DefaultCost)
if e != nil {
log.Fatalf("✗ 生成密码哈希失败(%s): %v", acc.username, e)
}
var existing model.User
qerr := db.Where("username = ?", acc.username).First(&existing).Error
switch {
case errors.Is(qerr, gorm.ErrRecordNotFound):
user := model.User{Username: acc.username, Email: acc.email, PasswordHash: string(hash)}
if cerr := db.Create(&user).Error; cerr != nil {
log.Fatalf("✗ 创建内部账号失败(%s): %v", acc.username, cerr)
}
log.Printf("✓ 已创建内部账号: %s / %s", acc.username, acc.email)
case qerr != nil:
log.Fatalf("✗ 查询账号失败(%s): %v", acc.username, qerr)
default:
existing.PasswordHash = string(hash)
if uerr := db.Save(&existing).Error; uerr != nil {
log.Fatalf("✗ 更新账号密码失败(%s): %v", acc.username, uerr)
}
log.Printf("✓ 内部账号已存在,已刷新密码哈希: %s", acc.username)
}
log.Printf("ℹ 账号 %s 登录方式: %s / 密码: %s", acc.username, acc.username, acc.password)
}
log.Println("⚠ admin 为强密码账号请尽快改默认密码;root 为弱密码测试账号,仅本地使用")
}