This commit is contained in:
loveuer
2025-07-14 10:48:21 +08:00
parent b48fa05d9f
commit 13ca43ee28
25 changed files with 830 additions and 125 deletions

View File

@ -0,0 +1,11 @@
package enum
type Privilege string
const (
PrivilegeAll Privilege = "*"
PrivilegeUserCreate Privilege = "user:create"
PrivilegeUserRead Privilege = "user:read"
PrivilegeUserUpdate Privilege = "user:update"
PrivilegeUserDelete Privilege = "user:delete"
)

View File

@ -0,0 +1,8 @@
package enum
type UserRole string
const (
UserRoleAdmin UserRole = "admin"
UserRoleUser UserRole = "user"
)

View File

@ -0,0 +1,9 @@
package enum
type TwoFactor string
const (
TwoFactorEmail TwoFactor = "email"
TwoFactorSMS TwoFactor = "sms"
TwoFactorGoogle TwoFactor = "google" // 2fa with google authenticator
)

View File

@ -2,14 +2,60 @@ package model
import (
"context"
"loveuer/utodo/internal/model/enum"
"loveuer/utodo/pkg/logger"
"loveuer/utodo/pkg/sqlType"
"loveuer/utodo/pkg/tool"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
func Init(ctx context.Context, tx *gorm.DB) error {
return tx.AutoMigrate(
func Init(ctx context.Context, tx *gorm.DB) (err error) {
if err = tx.AutoMigrate(
&Todo{},
&User{},
&Object{},
)
&Privilege{},
); err != nil {
return err
}
if err = tx.Model(&Privilege{}).
Clauses(clause.OnConflict{
DoNothing: true,
}).
Create(&Privilege{
Role: enum.UserRoleAdmin,
Privileges: sqlType.SliceStr[enum.Privilege]{enum.PrivilegeAll},
}).Error; err != nil {
return err
}
var uc int64
if err = tx.Model(&User{}).
Select("COUNT(id)").
Where("deleted_at", 0).
Find(&uc).
Error; err != nil {
return err
}
if uc == 0 {
password := tool.RandomString(16)
if err = tx.Model(&User{}).
Create(&User{
Username: "admin",
Nickname: "admin",
Password: tool.NewPassword(password),
Roles: sqlType.SliceStr[enum.UserRole]{enum.UserRoleAdmin},
ResetPassword: 1,
}).Error; err != nil {
return err
}
logger.InfoCtx(ctx, "inited admin password: %s", password)
}
return nil
}

View File

@ -0,0 +1,15 @@
package model
import (
"loveuer/utodo/internal/model/enum"
"loveuer/utodo/pkg/sqlType"
)
type Privilege struct {
Id int64 `json:"id" gorm:"column:id,primaryKey"`
CreatedAt int64 `json:"created_at" gorm:"column:created_at,autoCreateTime:milli"`
UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at,autoUpdateTime:milli"`
DeletedAt int64 `json:"deleted_at" gorm:"column:deleted_at"`
Role enum.UserRole `json:"role" gorm:"column:role;type:varchar(32);not null;unique"`
Privileges sqlType.SliceStr[enum.Privilege] `json:"privileges" gorm:"column:privileges"`
}

View File

@ -1,14 +1,40 @@
package model
import (
"loveuer/utodo/internal/model/enum"
"loveuer/utodo/pkg/jwt"
"loveuer/utodo/pkg/sqlType"
)
type User struct {
Id int64 `json:"id" gorm:"column:id,primaryKey"`
CreatedAt int64 `json:"created_at" gorm:"column:created_at,autoCreateTime:milli"`
UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at,autoUpdateTime:milli"`
DeletedAt int64 `json:"deleted_at" gorm:"column:deleted_at"`
Username string `json:"username" gorm:"column:username;type:varchar(255);not null"`
Nickname string `json:"nickname" gorm:"column:nickname;type:varchar(255);not null"`
Password string `json:"-" gorm:"column:password;type:varchar(255);not null"`
Avatar string `json:"avatar" gorm:"column:avatar;type:varchar(32);not null"`
Phone string `json:"phone" gorm:"column:phone;type:varchar(16);not null"`
Email string `json:"email" gorm:"column:email;type:varchar(255);not null"`
Id int64 `json:"id" gorm:"column:id;primaryKey"`
CreatedAt int64 `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
DeletedAt int64 `json:"deleted_at" gorm:"column:deleted_at"`
Username string `json:"username" gorm:"column:username;type:varchar(255);not null"`
Nickname string `json:"nickname" gorm:"column:nickname;type:varchar(255);not null"`
Password string `json:"-" gorm:"column:password;type:varchar(255);not null"`
ResetPassword uint8 `json:"reset_password" gorm:"column:reset_password;type:tinyint(1);default:0"`
Avatar string `json:"avatar" gorm:"column:avatar;type:varchar(32);not null"`
Phone string `json:"phone" gorm:"column:phone;type:varchar(16);not null"`
Email string `json:"email" gorm:"column:email;type:varchar(255);not null"`
TwoFactor enum.TwoFactor `json:"two_factor" gorm:"column:two_factor;type:varchar(16)"` // 2fa type
Roles sqlType.SliceStr[enum.UserRole] `json:"roles" gorm:"column:roles;not null"`
LastLoginAt int64 `json:"last_login_at" gorm:"column:last_login_at"`
}
func UserJwtPayload(u *User) map[string]any {
return map[string]any{
"id": u.Id,
"username": u.Username,
"nickname": u.Nickname,
"roles": u.Roles,
"last_login_at": u.LastLoginAt,
}
}
var (
UserJWT = jwt.New(
jwt.WithPayloadFn(UserJwtPayload),
)
)