admin_backend/model/admin.go
hahwu 9468ec5873 用户权限管理
Co-authored-by: Copilot <copilot@github.com>
2026-04-29 10:35:36 +08:00

289 lines
11 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.

package model
import (
"backend/store"
"backend/util"
"fmt"
"github.com/gin-gonic/gin"
)
type Admin struct {
ID int `json:"id" db:"id"`
Username string `json:"username" db:"username"`
Password string `json:"password" db:"password"`
RealName string `json:"real_name" db:"real_name"`
Nickname string `json:"nickname" db:"nickname"`
Phone string `json:"phone" db:"phone"`
Email string `json:"email" db:"email"`
Token string `json:"token" db:"token"`
Group string `json:"group" db:"group"`
Status int `json:"status" db:"status"`
Expires int `json:"expires" db:"expires"`
Role int `json:"role" db:"role"`
LastLoginTime int `json:"lastLoginTime" db:"lastLoginTime"`
LastLoginIP string `json:"lastLoginIp" db:"lastLoginIp"`
CreateTime int `json:"createTime" db:"createTime"`
UpdateTime int `json:"updateTime" db:"updateTime"`
Remark string `json:"remark" db:"remark"`
}
type AdminLog struct {
ID int `json:"id" db:"id"`
Admin string `json:"admin" db:"admin"`
Action string `json:"action" db:"action"`
Params string `json:"params" db:"params"`
IP string `json:"ip" db:"ip"`
CreateTime int `json:"createTime" db:"createTime"`
}
func (a *Admin) List() (*Result, error) {
// 这里可以添加数据库查询逻辑来获取管理员列表
// 假设我们从数据库中查询到数据并返回
var admins []Admin
db := util.MPool.GetGameDB() // 假设使用默认的AppConfig和ServerId为0
defer db.Close()
if db == nil {
return nil, fmt.Errorf("failed to get database connection")
}
err := db.Select(&admins, "SELECT * FROM admin")
if err != nil {
return nil, fmt.Errorf("failed to scan rows: %v", err)
}
var total int
db.Get(&total, "SELECT COUNT(*) FROM admin")
return &Result{
Data: admins,
Total: total,
}, nil
}
func (a *Admin) Add() (*Result, error) {
// 这里可以添加逻辑来保存管理员信息到数据库
// 假设我们将管理员信息插入到数据库中
db := util.MPool.GetGameDB() // 假设使用默认的AppConfig和ServerId为0
defer db.Close()
if db == nil {
return nil, fmt.Errorf("failed to get database connection")
}
defer db.Close()
a.CreateTime = int(util.Now())
a.UpdateTime = a.CreateTime
a.Password, _ = util.Encrypt(a.Password) // 假设有一个加密函数
_, err := db.NamedExec("INSERT INTO admin (`username`, `password`, `phone`, `email`, `token`, `group`, `status`, `role`, `createTime`, `updateTime`, `expires`, `remark`) VALUES (:username, :password, :phone, :email, :token, :group, :status, :role, :createTime, :updateTime, :expires, :remark)", a)
if err != nil {
return nil, fmt.Errorf("failed to add admin: %v", err)
}
var total int
db.Get(&total, "SELECT COUNT(*) FROM admin")
return &Result{
Data: a,
Total: total,
}, nil
}
func (a *Admin) Login() (*Admin, error) {
// 这里可以添加逻辑来验证用户名和密码
// 假设我们从数据库中查询到管理员信息并返回
db := util.MPool.GetGameDB() // 假设使用默认的AppConfig和ServerId为0
defer db.Close()
if db == nil {
return nil, fmt.Errorf("failed to get database connection")
}
var admin Admin
err := db.Get(&admin, "SELECT * FROM admin WHERE username = ?", a.Username)
admin.Password, _ = util.Decrypt(admin.Password) // 假设有一个解密函数Login
if err != nil {
return nil, fmt.Errorf("账号不存在")
}
if admin.Password != a.Password {
return nil, fmt.Errorf("密码错误")
}
if (admin.Expires > 0 && admin.Expires < int(util.Now())) || admin.Token == "" || admin.Expires == 0 {
admin.CreateToken() // 如果令牌过期,重新生成令牌
}
return &Admin{
ID: admin.ID,
Username: admin.Username,
Token: admin.Token,
}, nil
}
func (a *Admin) LoginByCode(phone, code string) (*Admin, error) {
db := util.MPool.GetGameDB() // 假设使用默认的AppConfig和ServerId为0
defer db.Close()
if db == nil {
return nil, fmt.Errorf("failed to get database connection")
}
var admin Admin
err := db.Get(&admin, "SELECT * FROM admin WHERE phone = ?", phone)
if (admin.Expires > 0 && admin.Expires < int(util.Now())) || admin.Token == "" || admin.Expires == 0 {
admin.CreateToken() // 如果令牌过期,重新生成令牌
}
if err != nil {
return nil, fmt.Errorf("账号不存在")
}
if code == "" {
return nil, fmt.Errorf("验证码不能为空")
}
storedCode, exists := store.GetCode(phone)
if !exists || storedCode != code {
return nil, fmt.Errorf("验证码错误")
}
return &Admin{
ID: admin.ID,
Username: admin.Username,
Token: admin.Token,
}, nil
}
func (a *Admin) CreateToken() error {
// 这里可以添加逻辑来生成令牌
// 假设我们生成一个新的令牌并更新到数据库中
a.Token = util.GenerateToken() // 假设有一个生成令牌的函数
db := util.MPool.GetGameDB() // 假设使用默认的AppConfig和ServerId为0
defer db.Close()
if db == nil {
return fmt.Errorf("failed to get database connection")
}
a.Expires = int(util.Now()) + 604800
store.AddToken(a.Token, int64(a.Expires), a.Username, util.GetRole(a.Role)) // 添加到TokenList
_, err := db.NamedExec("UPDATE admin SET token = :token, expires = :expires WHERE id = :id", a)
if err != nil {
return fmt.Errorf("failed to update token: %v", err)
}
return nil
}
func (a *Admin) GetAdmin(username string) error {
db := util.MPool.GetGameDB() // 假设使用默认的AppConfig和ServerId为0
defer db.Close()
if db == nil {
return fmt.Errorf("failed to get database connection")
}
return db.Get(a, "SELECT `username`, `role`, `password`, `token`, `group`, `remark` FROM admin WHERE username = ?", username)
}
func InitToken() {
// 初始化TokenList可以从数据库中加载现有的令牌
db := util.MPool.GetGameDB() // 假设使用默认的AppConfig和ServerId为0
defer db.Close()
if db == nil {
return
}
var tokens []struct {
Token string `db:"token"`
Expires int64 `db:"expires"`
UserName string `db:"username"`
Role int `db:"role"` // 假设有一个角色字段
}
err := db.Select(&tokens, "SELECT username, token, expires, role FROM admin WHERE token IS NOT NULL")
if err != nil {
return // 处理错误
}
for _, t := range tokens {
store.AddToken(t.Token, t.Expires, t.UserName, util.GetRole(t.Role))
}
}
func SendPhoneCode(phone string) error {
// 这里可以添加逻辑来发送验证码到手机
// 假设我们使用一个外部服务发送验证码
Code, err := util.GeneratedCode(phone) // 假设有一个发送短信的函数
store.AddCode(phone, Code) // 将验证码存储到CodeList
if err != nil {
return fmt.Errorf("failed to send code: %v", err)
}
return nil
}
var PermissionList = map[string][]string{
"/api/admin/list": {"super", "admin"},
"/api/admin/add": {"super"},
"/api/admin/log/list": {"super", "admin"},
"/api/admin/usergroup/list": {"super", "admin"},
"/api/admin/usergroup/add": {"super", "admin"},
"/api/admin/usergroup/edit": {"super", "admin"},
"/api/admin/usergroup/delete": {"super", "admin"},
"/api/admin/usergroup/role/set": {"super", "admin"},
"/api/admin/usergroup/role/list": {"super", "admin"},
"/api/admin/role/list": {"super", "admin"},
"/api/admin/role/add": {"super", "admin"},
"/api/admin/role/edit": {"super", "admin"},
"/api/admin/role/delete": {"super", "admin"},
"/api/admin/role/permission/set": {"super", "admin"},
"/api/admin/role/permission/list": {"super", "admin"},
"/api/admin/permission/list": {"super", "admin"},
"/api/admin/permission/add": {"super", "admin"},
"/api/admin/permission/edit": {"super", "admin"},
"/api/admin/permission/delete": {"super", "admin"},
"/api/admin/user/group/list": {"super", "admin"},
"/api/admin/user/group/set": {"super", "admin"},
"/api/log/user": {"super", "admin", "user"},
"/api/log/asset": {"super", "admin", "user"},
"/api/log/event": {"super", "admin", "user"},
"/api/log/order": {"super", "admin", "user"},
"/api/user/list": {"super", "admin", "user"},
"/api/user/gm": {"super", "admin"},
"/api/user/ban": {"super", "admin"},
"/api/server/list": {"super", "admin"},
"/api/server/serverList": {"super", "admin"},
"/api/server/addServer": {"super"},
"/api/server/nodeList": {"super"},
"/api/server/addNode": {"super"},
"/api/server/updateApp": {"super", "admin"},
"/api/server/restart": {"super", "admin"},
"/api/server/reload": {"super", "admin"},
"/api/statistics/level": {"super", "admin"},
"/api/statistics/order": {"super", "admin"},
"/api/statistics/info": {"super", "admin"},
"/api/statistics/heat": {"super", "admin"},
"/api/mail/send": {"super", "admin"},
"/api/mail/list": {"super", "admin"},
"/api/mail/delete": {"super", "admin"},
"/api/language/list": {"super", "admin", "wb_transfer"},
"/api/language/export": {"super", "admin", "wb_transfer"},
"/api/language/save": {"super", "admin", "wb_transfer"},
"/api/language/add": {"super", "admin", "wb_transfer"},
"/api/language/delete": {"super", "admin"},
"/api/client/notification": {"super", "admin"},
"/api/v1/experiments": {"super", "admin"},
"/api/v1/experiments/:id": {"super", "admin"},
"/api/v1/experiments/:id/variants": {"super", "admin"},
"/api/v1/experiments/:id/variants/:variantId": {"super", "admin"},
"/api/v1/experiments/:id/whitelist": {"super", "admin"},
"/api/v1/experiments/:id/whitelist/batch": {"super", "admin"},
"/api/v1/experiments/:id/whitelist/:userId": {"super", "admin"},
"/api/v1/experiments/:id/results": {"super", "admin"},
"/api/v1/users/:userId/groups": {"super", "admin"},
}
func CheckUserPermission(username, path string) bool {
Admin := &Admin{}
err := Admin.GetAdmin(username)
if err != nil {
return false
}
PermissionRoles, exists := PermissionList[path]
if !exists {
// 如果路径不存在于权限列表中,默认允许访问
return true
}
for _, role := range PermissionRoles {
if util.GetRole(Admin.Role) == role {
return true
}
}
return false
}
func GetAdminRole(c *gin.Context) (string, error) {
username := c.GetString("admin")
Admin := &Admin{}
err := Admin.GetAdmin(username)
if err != nil {
return "", err
}
return util.GetRole(Admin.Role), nil
}