✅ 已完成功能: - 后端 Go 服务 (认证/授权/检测) - JWT 认证 + RBAC 权限控制 - 登录速率限制 (5 次失败锁定 15 分钟) - 密码强度校验 - 敏感数据脱敏 - Vue3 管理后台 - 路由守卫 - 删除二次确认 📦 部署配置: - Docker Compose 生产环境配置 - MySQL/Redis/MongoDB 数据库 - Nginx 前端服务 - 强密码安全配置 ⚠️ P2 待办 (下次迭代): - 学生/检测/预警等业务模块实现 - 错误处理统一化 - 缓存策略优化 - 日志分级 📍 生产环境: - 服务器:192.168.15.222 - 管理后台:http://192.168.15.222:8081 - API 服务:http://192.168.15.222:8080 2026-03-29 上线部署完成
248 lines
7.2 KiB
Go
248 lines
7.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"time"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
"gorm.io/driver/mysql"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// UserAccount 用户账号模型
|
|
type UserAccount struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
Username string `gorm:"type:varchar(64);uniqueIndex" json:"username"`
|
|
PasswordHash string `gorm:"type:varchar(255)" json:"-"` // 不在JSON中暴露
|
|
Name string `gorm:"type:varchar(64)" json:"name"`
|
|
Phone string `gorm:"type:varchar(20);uniqueIndex" json:"phone"`
|
|
UserType string `gorm:"type:varchar(16)" json:"user_type"` // student, parent, teacher, admin
|
|
Status int `gorm:"default:1" json:"status"` // 1:正常, 0:禁用
|
|
LastLoginAt *time.Time `json:"last_login_at"`
|
|
LastLoginIP string `json:"last_login_ip"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func main() {
|
|
fmt.Println("AI近视防控系统 - 测试账号创建工具")
|
|
|
|
// 从环境变量获取数据库连接信息,如果不存在则使用默认值
|
|
dbHost := os.Getenv("DB_HOST")
|
|
if dbHost == "" {
|
|
dbHost = "localhost"
|
|
}
|
|
dbUser := os.Getenv("DB_USER")
|
|
if dbUser == "" {
|
|
dbUser = "root"
|
|
}
|
|
dbPassword := os.Getenv("DB_PASSWORD")
|
|
if dbPassword == "" {
|
|
dbPassword = "MyopiaTest2026!"
|
|
}
|
|
dbName := os.Getenv("DB_NAME")
|
|
if dbName == "" {
|
|
dbName = "ai_myopia_db"
|
|
}
|
|
|
|
// 数据库连接字符串
|
|
dsn := fmt.Sprintf("%s:%s@tcp(%s:3306)/%s?charset=utf8mb4&parseTime=True&loc=Local",
|
|
dbUser, dbPassword, dbHost, dbName)
|
|
|
|
// 连接数据库
|
|
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
|
if err != nil {
|
|
log.Fatal("连接数据库失败: ", err)
|
|
}
|
|
|
|
// 加密密码
|
|
adminPassword := "Admin123!@#"
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(adminPassword), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
log.Fatal("密码加密失败: ", err)
|
|
}
|
|
|
|
// 创建管理员账号
|
|
adminAccount := UserAccount{
|
|
Username: "admin",
|
|
PasswordHash: string(hashedPassword),
|
|
Name: "系统管理员",
|
|
Phone: "13800138000",
|
|
UserType: "admin",
|
|
Status: 1,
|
|
}
|
|
|
|
// 检查管理员账号是否存在
|
|
var existingAdmin UserAccount
|
|
result := db.Where("username = ?", "admin").First(&existingAdmin)
|
|
if result.Error != nil {
|
|
// 管理员账号不存在,创建新账号
|
|
if err := db.Create(&adminAccount).Error; err != nil {
|
|
log.Fatal("创建管理员账号失败: ", err)
|
|
}
|
|
fmt.Println("✅ 管理员账号创建成功")
|
|
} else {
|
|
// 管理员账号已存在,更新密码
|
|
if err := db.Model(&existingAdmin).Updates(UserAccount{
|
|
PasswordHash: string(hashedPassword),
|
|
Name: "系统管理员",
|
|
Phone: "13800138000",
|
|
UserType: "admin",
|
|
Status: 1,
|
|
}).Error; err != nil {
|
|
log.Fatal("更新管理员账号失败: ", err)
|
|
}
|
|
fmt.Println("✅ 管理员账号更新成功")
|
|
}
|
|
|
|
// 创建测试老师账号
|
|
teacherPassword := "Teacher123!@#"
|
|
teacherHashed, err := bcrypt.GenerateFromPassword([]byte(teacherPassword), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
log.Fatal("老师密码加密失败: ", err)
|
|
}
|
|
|
|
teacherAccount := UserAccount{
|
|
Username: "teacher",
|
|
PasswordHash: string(teacherHashed),
|
|
Name: "测试老师",
|
|
Phone: "13800138001",
|
|
UserType: "teacher",
|
|
Status: 1,
|
|
}
|
|
|
|
var existingTeacher UserAccount
|
|
result = db.Where("username = ?", "teacher").First(&existingTeacher)
|
|
if result.Error != nil {
|
|
// 老师账号不存在,创建新账号
|
|
if err := db.Create(&teacherAccount).Error; err != nil {
|
|
log.Println("创建老师账号失败: ", err)
|
|
} else {
|
|
fmt.Println("✅ 老师账号创建成功")
|
|
}
|
|
} else {
|
|
// 老师账号已存在,更新密码
|
|
if err := db.Model(&existingTeacher).Updates(UserAccount{
|
|
PasswordHash: string(teacherHashed),
|
|
Name: "测试老师",
|
|
Phone: "13800138001",
|
|
UserType: "teacher",
|
|
Status: 1,
|
|
}).Error; err != nil {
|
|
log.Println("更新老师账号失败: ", err)
|
|
} else {
|
|
fmt.Println("✅ 老师账号更新成功")
|
|
}
|
|
}
|
|
|
|
// 创建测试学生账号
|
|
studentPassword := "Student123!@#"
|
|
studentHashed, err := bcrypt.GenerateFromPassword([]byte(studentPassword), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
log.Fatal("学生密码加密失败: ", err)
|
|
}
|
|
|
|
studentAccount := UserAccount{
|
|
Username: "student",
|
|
PasswordHash: string(studentHashed),
|
|
Name: "测试学生",
|
|
Phone: "13800138002",
|
|
UserType: "student",
|
|
Status: 1,
|
|
}
|
|
|
|
var existingStudent UserAccount
|
|
result = db.Where("username = ?", "student").First(&existingStudent)
|
|
if result.Error != nil {
|
|
// 学生账号不存在,创建新账号
|
|
if err := db.Create(&studentAccount).Error; err != nil {
|
|
log.Println("创建学生账号失败: ", err)
|
|
} else {
|
|
fmt.Println("✅ 学生账号创建成功")
|
|
}
|
|
} else {
|
|
// 学生账号已存在,更新密码
|
|
if err := db.Model(&existingStudent).Updates(UserAccount{
|
|
PasswordHash: string(studentHashed),
|
|
Name: "测试学生",
|
|
Phone: "13800138002",
|
|
UserType: "student",
|
|
Status: 1,
|
|
}).Error; err != nil {
|
|
log.Println("更新学生账号失败: ", err)
|
|
} else {
|
|
fmt.Println("✅ 学生账号更新成功")
|
|
}
|
|
}
|
|
|
|
// 创建测试家长账号
|
|
parentPassword := "Parent123!@#"
|
|
parentHashed, err := bcrypt.GenerateFromPassword([]byte(parentPassword), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
log.Fatal("家长密码加密失败: ", err)
|
|
}
|
|
|
|
parentAccount := UserAccount{
|
|
Username: "parent",
|
|
PasswordHash: string(parentHashed),
|
|
Name: "测试家长",
|
|
Phone: "13800138003",
|
|
UserType: "parent",
|
|
Status: 1,
|
|
}
|
|
|
|
var existingParent UserAccount
|
|
result = db.Where("username = ?", "parent").First(&existingParent)
|
|
if result.Error != nil {
|
|
// 家长账号不存在,创建新账号
|
|
if err := db.Create(&parentAccount).Error; err != nil {
|
|
log.Println("创建家长账号失败: ", err)
|
|
} else {
|
|
fmt.Println("✅ 家长账号创建成功")
|
|
}
|
|
} else {
|
|
// 家长账号已存在,更新密码
|
|
if err := db.Model(&existingParent).Updates(UserAccount{
|
|
PasswordHash: string(parentHashed),
|
|
Name: "测试家长",
|
|
Phone: "13800138003",
|
|
UserType: "parent",
|
|
Status: 1,
|
|
}).Error; err != nil {
|
|
log.Println("更新家长账号失败: ", err)
|
|
} else {
|
|
fmt.Println("✅ 家长账号更新成功")
|
|
}
|
|
}
|
|
|
|
fmt.Println("\n📋 测试账号信息:")
|
|
fmt.Println("==================")
|
|
fmt.Println("管理员账号:")
|
|
fmt.Println(" 用户名: admin")
|
|
fmt.Println(" 密码: Admin123!@#")
|
|
fmt.Println(" 角色: admin")
|
|
fmt.Println(" 手机: 13800138000")
|
|
|
|
fmt.Println("\n老师账号:")
|
|
fmt.Println(" 用户名: teacher")
|
|
fmt.Println(" 密码: Teacher123!@#")
|
|
fmt.Println(" 角色: teacher")
|
|
fmt.Println(" 手机: 13800138001")
|
|
|
|
fmt.Println("\n学生账号:")
|
|
fmt.Println(" 用户名: student")
|
|
fmt.Println(" 密码: Student123!@#")
|
|
fmt.Println(" 角色: student")
|
|
fmt.Println(" 手机: 13800138002")
|
|
|
|
fmt.Println("\n家长账号:")
|
|
fmt.Println(" 用户名: parent")
|
|
fmt.Println(" 密码: Parent123!@#")
|
|
fmt.Println(" 角色: parent")
|
|
fmt.Println(" 手机: 13800138003")
|
|
|
|
fmt.Println("\n✅ 测试账号创建/更新完成!")
|
|
fmt.Println("💡 提示: 可使用这些账号登录系统进行功能测试")
|
|
} |