108 lines
3.7 KiB
Go
108 lines
3.7 KiB
Go
// 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 为弱密码测试账号,仅本地使用")
|
||
}
|