任务三
This commit is contained in:
+5
-2
@@ -1,6 +1,9 @@
|
||||
package biz
|
||||
|
||||
import "github.com/google/wire"
|
||||
import (
|
||||
"github.com/google/wire"
|
||||
"kra/internal/biz/system"
|
||||
)
|
||||
|
||||
// ProviderSet is biz providers.
|
||||
var ProviderSet = wire.NewSet(NewAdminUsecase)
|
||||
var ProviderSet = wire.NewSet(system.NewUserUsecase)
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUserNotFound = errors.New("用户不存在")
|
||||
ErrUserAlreadyExists = errors.New("用户名已注册")
|
||||
ErrPasswordWrong = errors.New("密码错误")
|
||||
ErrOldPasswordWrong = errors.New("原密码错误")
|
||||
ErrUserNoAuthority = errors.New("该用户无此角色")
|
||||
ErrDefaultRouterEmpty = errors.New("找不到默认路由,无法切换本角色")
|
||||
)
|
||||
|
||||
// User 用户实体
|
||||
type User struct {
|
||||
ID uint
|
||||
UUID uuid.UUID
|
||||
Username string
|
||||
Password string
|
||||
NickName string
|
||||
SideMode string
|
||||
HeaderImg string
|
||||
BaseColor string
|
||||
AuthorityId uint
|
||||
Phone string
|
||||
Email string
|
||||
Enable int
|
||||
OriginSetting json.RawMessage
|
||||
Authority *Authority
|
||||
Authorities []*Authority
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// Authority 角色实体
|
||||
type Authority struct {
|
||||
AuthorityId uint
|
||||
AuthorityName string
|
||||
ParentId *uint
|
||||
DefaultRouter string
|
||||
}
|
||||
|
||||
// UserRepo 用户仓储接口
|
||||
type UserRepo interface {
|
||||
Create(ctx context.Context, user *User) error
|
||||
Update(ctx context.Context, user *User) error
|
||||
UpdateSelf(ctx context.Context, user *User) error
|
||||
UpdateSelfSetting(ctx context.Context, id uint, setting json.RawMessage) error
|
||||
Delete(ctx context.Context, id uint) error
|
||||
FindByID(ctx context.Context, id uint) (*User, error)
|
||||
FindByIDWithAuthorities(ctx context.Context, id uint) (*User, error)
|
||||
FindByUUID(ctx context.Context, uuid string) (*User, error)
|
||||
FindByUUIDWithAuthorities(ctx context.Context, uuid string) (*User, error)
|
||||
FindByUsername(ctx context.Context, username string) (*User, error)
|
||||
FindByUsernameWithAuthorities(ctx context.Context, username string) (*User, error)
|
||||
List(ctx context.Context, page, pageSize int, filters map[string]string) ([]*User, int64, error)
|
||||
UpdatePassword(ctx context.Context, id uint, password string) error
|
||||
UpdateAuthorityID(ctx context.Context, id uint, authorityId uint) error
|
||||
SetUserAuthorities(ctx context.Context, adminAuthorityID, userId uint, authorityIds []uint) error
|
||||
CheckUserHasAuthority(ctx context.Context, userId, authorityId uint) (bool, error)
|
||||
GetAuthorityMenuRouters(ctx context.Context, authorityId uint) ([]string, error)
|
||||
GetAuthorityDefaultRouter(ctx context.Context, authorityId uint) (string, error)
|
||||
}
|
||||
|
||||
// UserUsecase 用户用例
|
||||
type UserUsecase struct {
|
||||
repo UserRepo
|
||||
}
|
||||
|
||||
// NewUserUsecase 创建用户用例
|
||||
func NewUserUsecase(repo UserRepo) *UserUsecase {
|
||||
return &UserUsecase{repo: repo}
|
||||
}
|
||||
|
||||
// Register 用户注册
|
||||
func (uc *UserUsecase) Register(ctx context.Context, user *User) (*User, error) {
|
||||
// 检查用户名是否已存在
|
||||
existing, _ := uc.repo.FindByUsername(ctx, user.Username)
|
||||
if existing != nil {
|
||||
return nil, ErrUserAlreadyExists
|
||||
}
|
||||
|
||||
// 密码加密
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user.Password = string(hashedPassword)
|
||||
user.UUID = uuid.New()
|
||||
|
||||
if err := uc.repo.Create(ctx, user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// Login 用户登录(预加载Authorities)
|
||||
func (uc *UserUsecase) Login(ctx context.Context, username, password string) (*User, error) {
|
||||
user, err := uc.repo.FindByUsernameWithAuthorities(ctx, username)
|
||||
if err != nil {
|
||||
return nil, ErrUserNotFound
|
||||
}
|
||||
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
|
||||
return nil, ErrPasswordWrong
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// ChangePassword 修改密码
|
||||
func (uc *UserUsecase) ChangePassword(ctx context.Context, id uint, oldPassword, newPassword string) error {
|
||||
user, err := uc.repo.FindByID(ctx, id)
|
||||
if err != nil {
|
||||
return ErrUserNotFound
|
||||
}
|
||||
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(oldPassword)); err != nil {
|
||||
return ErrOldPasswordWrong
|
||||
}
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return uc.repo.UpdatePassword(ctx, id, string(hashedPassword))
|
||||
}
|
||||
|
||||
// ResetPassword 重置密码
|
||||
func (uc *UserUsecase) ResetPassword(ctx context.Context, id uint, newPassword string) error {
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return uc.repo.UpdatePassword(ctx, id, string(hashedPassword))
|
||||
}
|
||||
|
||||
// GetUserInfo 获取用户信息(预加载Authorities)
|
||||
func (uc *UserUsecase) GetUserInfo(ctx context.Context, uuid string) (*User, error) {
|
||||
return uc.repo.FindByUUIDWithAuthorities(ctx, uuid)
|
||||
}
|
||||
|
||||
// GetUserByID 通过ID获取用户
|
||||
func (uc *UserUsecase) GetUserByID(ctx context.Context, id uint) (*User, error) {
|
||||
return uc.repo.FindByID(ctx, id)
|
||||
}
|
||||
|
||||
// FindUserById 通过ID获取用户(GVA兼容)
|
||||
func (uc *UserUsecase) FindUserById(ctx context.Context, id uint) (*User, error) {
|
||||
return uc.repo.FindByID(ctx, id)
|
||||
}
|
||||
|
||||
// FindUserByUuid 通过UUID获取用户(GVA兼容)
|
||||
func (uc *UserUsecase) FindUserByUuid(ctx context.Context, uuid string) (*User, error) {
|
||||
return uc.repo.FindByUUID(ctx, uuid)
|
||||
}
|
||||
|
||||
// GetUserList 获取用户列表
|
||||
func (uc *UserUsecase) GetUserList(ctx context.Context, page, pageSize int, filters map[string]string) ([]*User, int64, error) {
|
||||
return uc.repo.List(ctx, page, pageSize, filters)
|
||||
}
|
||||
|
||||
// SetUserInfo 设置用户信息(管理员用)
|
||||
func (uc *UserUsecase) SetUserInfo(ctx context.Context, user *User) error {
|
||||
return uc.repo.Update(ctx, user)
|
||||
}
|
||||
|
||||
// SetSelfInfo 设置自己的信息(用户用)
|
||||
func (uc *UserUsecase) SetSelfInfo(ctx context.Context, user *User) error {
|
||||
return uc.repo.UpdateSelf(ctx, user)
|
||||
}
|
||||
|
||||
// SetSelfSetting 设置自己的配置
|
||||
func (uc *UserUsecase) SetSelfSetting(ctx context.Context, id uint, setting json.RawMessage) error {
|
||||
return uc.repo.UpdateSelfSetting(ctx, id, setting)
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (uc *UserUsecase) DeleteUser(ctx context.Context, id uint) error {
|
||||
return uc.repo.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// SetUserAuthority 设置用户角色(切换角色)
|
||||
func (uc *UserUsecase) SetUserAuthority(ctx context.Context, id uint, authorityId uint) error {
|
||||
// 检查用户是否拥有该角色
|
||||
hasAuthority, err := uc.repo.CheckUserHasAuthority(ctx, id, authorityId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !hasAuthority {
|
||||
return ErrUserNoAuthority
|
||||
}
|
||||
|
||||
// 获取角色的默认路由
|
||||
defaultRouter, err := uc.repo.GetAuthorityDefaultRouter(ctx, authorityId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取角色的菜单路由列表
|
||||
menuRouters, err := uc.repo.GetAuthorityMenuRouters(ctx, authorityId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查默认路由是否在菜单中
|
||||
hasMenu := false
|
||||
for _, router := range menuRouters {
|
||||
if router == defaultRouter {
|
||||
hasMenu = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasMenu {
|
||||
return ErrDefaultRouterEmpty
|
||||
}
|
||||
|
||||
return uc.repo.UpdateAuthorityID(ctx, id, authorityId)
|
||||
}
|
||||
|
||||
// SetUserAuthorities 设置用户多角色
|
||||
func (uc *UserUsecase) SetUserAuthorities(ctx context.Context, adminAuthorityID, userId uint, authorityIds []uint) error {
|
||||
return uc.repo.SetUserAuthorities(ctx, adminAuthorityID, userId, authorityIds)
|
||||
}
|
||||
@@ -28,6 +28,8 @@ type SysUser struct {
|
||||
Email *string `gorm:"column:email;type:varchar(191);comment:用户邮箱" json:"email"` // 用户邮箱
|
||||
Enable *int64 `gorm:"column:enable;type:bigint(20);default:1;comment:用户是否被冻结 1正常 2冻结" json:"enable"` // 用户是否被冻结 1正常 2冻结
|
||||
OriginSetting *string `gorm:"column:origin_setting;type:text;comment:配置" json:"origin_setting"` // 配置
|
||||
Authority SysAuthority `gorm:"foreignKey:AuthorityID;references:AuthorityID" json:"authority"`
|
||||
Authorities []SysAuthority `gorm:"joinForeignKey:SysUserID;joinReferences:SysAuthorityAuthorityID;many2many:sys_user_authority" json:"authorities"`
|
||||
}
|
||||
|
||||
// TableName SysUser's table name
|
||||
|
||||
@@ -42,6 +42,17 @@ func newSysUser(db *gorm.DB, opts ...gen.DOOption) sysUser {
|
||||
_sysUser.Email = field.NewString(tableName, "email")
|
||||
_sysUser.Enable = field.NewInt64(tableName, "enable")
|
||||
_sysUser.OriginSetting = field.NewString(tableName, "origin_setting")
|
||||
_sysUser.Authority = sysUserHasOneAuthority{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Authority", "model.SysAuthority"),
|
||||
}
|
||||
|
||||
_sysUser.Authorities = sysUserManyToManyAuthorities{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Authorities", "model.SysAuthority"),
|
||||
}
|
||||
|
||||
_sysUser.fillFieldMap()
|
||||
|
||||
@@ -66,6 +77,9 @@ type sysUser struct {
|
||||
Email field.String // 用户邮箱
|
||||
Enable field.Int64 // 用户是否被冻结 1正常 2冻结
|
||||
OriginSetting field.String // 配置
|
||||
Authority sysUserHasOneAuthority
|
||||
|
||||
Authorities sysUserManyToManyAuthorities
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@@ -120,7 +134,7 @@ func (s *sysUser) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (s *sysUser) fillFieldMap() {
|
||||
s.fieldMap = make(map[string]field.Expr, 14)
|
||||
s.fieldMap = make(map[string]field.Expr, 16)
|
||||
s.fieldMap["id"] = s.ID
|
||||
s.fieldMap["created_at"] = s.CreatedAt
|
||||
s.fieldMap["updated_at"] = s.UpdatedAt
|
||||
@@ -135,18 +149,187 @@ func (s *sysUser) fillFieldMap() {
|
||||
s.fieldMap["email"] = s.Email
|
||||
s.fieldMap["enable"] = s.Enable
|
||||
s.fieldMap["origin_setting"] = s.OriginSetting
|
||||
|
||||
}
|
||||
|
||||
func (s sysUser) clone(db *gorm.DB) sysUser {
|
||||
s.sysUserDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
s.Authority.db = db.Session(&gorm.Session{Initialized: true})
|
||||
s.Authority.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
s.Authorities.db = db.Session(&gorm.Session{Initialized: true})
|
||||
s.Authorities.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
return s
|
||||
}
|
||||
|
||||
func (s sysUser) replaceDB(db *gorm.DB) sysUser {
|
||||
s.sysUserDo.ReplaceDB(db)
|
||||
s.Authority.db = db.Session(&gorm.Session{})
|
||||
s.Authorities.db = db.Session(&gorm.Session{})
|
||||
return s
|
||||
}
|
||||
|
||||
type sysUserHasOneAuthority struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthority) Where(conds ...field.Expr) *sysUserHasOneAuthority {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthority) WithContext(ctx context.Context) *sysUserHasOneAuthority {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthority) Session(session *gorm.Session) *sysUserHasOneAuthority {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthority) Model(m *model.SysUser) *sysUserHasOneAuthorityTx {
|
||||
return &sysUserHasOneAuthorityTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthority) Unscoped() *sysUserHasOneAuthority {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type sysUserHasOneAuthorityTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a sysUserHasOneAuthorityTx) Find() (result *model.SysAuthority, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthorityTx) Append(values ...*model.SysAuthority) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthorityTx) Replace(values ...*model.SysAuthority) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthorityTx) Delete(values ...*model.SysAuthority) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthorityTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthorityTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a sysUserHasOneAuthorityTx) Unscoped() *sysUserHasOneAuthorityTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type sysUserManyToManyAuthorities struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthorities) Where(conds ...field.Expr) *sysUserManyToManyAuthorities {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthorities) WithContext(ctx context.Context) *sysUserManyToManyAuthorities {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthorities) Session(session *gorm.Session) *sysUserManyToManyAuthorities {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthorities) Model(m *model.SysUser) *sysUserManyToManyAuthoritiesTx {
|
||||
return &sysUserManyToManyAuthoritiesTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthorities) Unscoped() *sysUserManyToManyAuthorities {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type sysUserManyToManyAuthoritiesTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a sysUserManyToManyAuthoritiesTx) Find() (result []*model.SysAuthority, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthoritiesTx) Append(values ...*model.SysAuthority) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthoritiesTx) Replace(values ...*model.SysAuthority) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthoritiesTx) Delete(values ...*model.SysAuthority) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthoritiesTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthoritiesTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a sysUserManyToManyAuthoritiesTx) Unscoped() *sysUserManyToManyAuthoritiesTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type sysUserDo struct{ gen.DO }
|
||||
|
||||
type ISysUserDo interface {
|
||||
|
||||
@@ -73,11 +73,9 @@ func (r *userRepo) UpdateSelfSetting(ctx context.Context, id uint, setting json.
|
||||
|
||||
func (r *userRepo) Delete(ctx context.Context, id uint) error {
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 删除用户
|
||||
if err := tx.Where("id = ?", id).Delete(&model.SysUser{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除用户角色关联
|
||||
if err := tx.Where("sys_user_id = ?", id).Delete(&model.SysUserAuthority{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -94,16 +92,15 @@ func (r *userRepo) FindByID(ctx context.Context, id uint) (*system.User, error)
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByIDWithAuthorities(ctx context.Context, id uint) (*system.User, error) {
|
||||
var m model.SysUser
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("Authorities").
|
||||
Preload("Authority").
|
||||
Where("id = ?", id).
|
||||
First(&m).Error
|
||||
m, err := query.SysUser.WithContext(ctx).
|
||||
Preload(query.SysUser.Authority).
|
||||
Preload(query.SysUser.Authorities).
|
||||
Where(query.SysUser.ID.Eq(int64(id))).
|
||||
First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toModelUserWithAuthorities(&m), nil
|
||||
return toModelUserWithAuthorities(m), nil
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByUUID(ctx context.Context, uuidStr string) (*system.User, error) {
|
||||
@@ -115,16 +112,15 @@ func (r *userRepo) FindByUUID(ctx context.Context, uuidStr string) (*system.User
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByUUIDWithAuthorities(ctx context.Context, uuidStr string) (*system.User, error) {
|
||||
var m model.SysUser
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("Authorities").
|
||||
Preload("Authority").
|
||||
Where("uuid = ?", uuidStr).
|
||||
First(&m).Error
|
||||
m, err := query.SysUser.WithContext(ctx).
|
||||
Preload(query.SysUser.Authority).
|
||||
Preload(query.SysUser.Authorities).
|
||||
Where(query.SysUser.UUID.Eq(uuidStr)).
|
||||
First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toModelUserWithAuthorities(&m), nil
|
||||
return toModelUserWithAuthorities(m), nil
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByUsername(ctx context.Context, username string) (*system.User, error) {
|
||||
@@ -136,49 +132,48 @@ func (r *userRepo) FindByUsername(ctx context.Context, username string) (*system
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByUsernameWithAuthorities(ctx context.Context, username string) (*system.User, error) {
|
||||
var m model.SysUser
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("Authorities").
|
||||
Preload("Authority").
|
||||
Where("username = ?", username).
|
||||
First(&m).Error
|
||||
m, err := query.SysUser.WithContext(ctx).
|
||||
Preload(query.SysUser.Authority).
|
||||
Preload(query.SysUser.Authorities).
|
||||
Where(query.SysUser.Username.Eq(username)).
|
||||
First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toModelUserWithAuthorities(&m), nil
|
||||
return toModelUserWithAuthorities(m), nil
|
||||
}
|
||||
|
||||
func (r *userRepo) List(ctx context.Context, page, pageSize int, filters map[string]string) ([]*system.User, int64, error) {
|
||||
db := r.db.WithContext(ctx).Model(&model.SysUser{})
|
||||
u := query.SysUser
|
||||
q := u.WithContext(ctx)
|
||||
|
||||
if v, ok := filters["username"]; ok && v != "" {
|
||||
db = db.Where("username LIKE ?", "%"+v+"%")
|
||||
q = q.Where(u.Username.Like("%" + v + "%"))
|
||||
}
|
||||
if v, ok := filters["nick_name"]; ok && v != "" {
|
||||
db = db.Where("nick_name LIKE ?", "%"+v+"%")
|
||||
q = q.Where(u.NickName.Like("%" + v + "%"))
|
||||
}
|
||||
if v, ok := filters["phone"]; ok && v != "" {
|
||||
db = db.Where("phone LIKE ?", "%"+v+"%")
|
||||
q = q.Where(u.Phone.Like("%" + v + "%"))
|
||||
}
|
||||
if v, ok := filters["email"]; ok && v != "" {
|
||||
db = db.Where("email LIKE ?", "%"+v+"%")
|
||||
q = q.Where(u.Email.Like("%" + v + "%"))
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
total, err := q.Count()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var list []model.SysUser
|
||||
offset := (page - 1) * pageSize
|
||||
err := db.Preload("Authorities").Preload("Authority").Offset(offset).Limit(pageSize).Find(&list).Error
|
||||
list, err := q.Preload(u.Authority).Preload(u.Authorities).Offset(offset).Limit(pageSize).Find()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
users := make([]*system.User, len(list))
|
||||
for i := range list {
|
||||
users[i] = toModelUserWithAuthorities(&list[i])
|
||||
users[i] = toModelUserWithAuthorities(list[i])
|
||||
}
|
||||
return users, total, nil
|
||||
}
|
||||
@@ -193,20 +188,16 @@ func (r *userRepo) UpdateAuthorityID(ctx context.Context, id uint, authorityId u
|
||||
|
||||
func (r *userRepo) SetUserAuthorities(ctx context.Context, adminAuthorityID, userId uint, authorityIds []uint) error {
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 查询用户是否存在
|
||||
var user model.SysUser
|
||||
if err := tx.Where("id = ?", userId).First(&user).Error; err != nil {
|
||||
return errors.New("查询用户数据失败")
|
||||
}
|
||||
|
||||
// 删除旧的用户角色关联
|
||||
if err := tx.Where("sys_user_id = ?", userId).Delete(&model.SysUserAuthority{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查管理员权限并创建新的用户角色关联
|
||||
for _, aid := range authorityIds {
|
||||
// 检查管理员是否有权限分配该角色
|
||||
if err := checkAuthorityIDAuth(tx, adminAuthorityID, aid); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -219,7 +210,6 @@ func (r *userRepo) SetUserAuthorities(ctx context.Context, adminAuthorityID, use
|
||||
}
|
||||
}
|
||||
|
||||
// 更新用户默认角色
|
||||
if len(authorityIds) > 0 {
|
||||
if err := tx.Model(&model.SysUser{}).Where("id = ?", userId).Update("authority_id", authorityIds[0]).Error; err != nil {
|
||||
return err
|
||||
@@ -229,13 +219,10 @@ func (r *userRepo) SetUserAuthorities(ctx context.Context, adminAuthorityID, use
|
||||
})
|
||||
}
|
||||
|
||||
// checkAuthorityIDAuth 检查管理员是否有权限分配该角色
|
||||
func checkAuthorityIDAuth(tx *gorm.DB, adminAuthorityID, targetAuthorityID uint) error {
|
||||
// 如果是超级管理员(888),直接通过
|
||||
if adminAuthorityID == 888 {
|
||||
return nil
|
||||
}
|
||||
// 检查目标角色是否是管理员的子角色
|
||||
var authority model.SysAuthority
|
||||
if err := tx.Where("authority_id = ? AND parent_id = ?", targetAuthorityID, adminAuthorityID).First(&authority).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -255,7 +242,6 @@ func (r *userRepo) CheckUserHasAuthority(ctx context.Context, userId, authorityI
|
||||
}
|
||||
|
||||
func (r *userRepo) GetAuthorityMenuRouters(ctx context.Context, authorityId uint) ([]string, error) {
|
||||
// 获取角色的菜单ID列表
|
||||
var authorityMenus []model.SysAuthorityMenu
|
||||
if err := r.db.WithContext(ctx).Where("sys_authority_authority_id = ?", authorityId).Find(&authorityMenus).Error; err != nil {
|
||||
return nil, err
|
||||
@@ -265,13 +251,11 @@ func (r *userRepo) GetAuthorityMenuRouters(ctx context.Context, authorityId uint
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
// 获取菜单ID
|
||||
menuIDs := make([]string, len(authorityMenus))
|
||||
menuIDs := make([]int64, len(authorityMenus))
|
||||
for i, am := range authorityMenus {
|
||||
menuIDs[i] = am.MenuID
|
||||
menuIDs[i] = am.SysBaseMenuID
|
||||
}
|
||||
|
||||
// 获取菜单的name(路由)
|
||||
var menus []model.SysBaseMenu
|
||||
if err := r.db.WithContext(ctx).Where("id IN ?", menuIDs).Find(&menus).Error; err != nil {
|
||||
return nil, err
|
||||
@@ -337,15 +321,9 @@ func toModelUser(m *model.SysUser) *system.User {
|
||||
if m.NickName != nil {
|
||||
u.NickName = *m.NickName
|
||||
}
|
||||
if m.SideMode != nil {
|
||||
u.SideMode = *m.SideMode
|
||||
}
|
||||
if m.HeaderImg != nil {
|
||||
u.HeaderImg = *m.HeaderImg
|
||||
}
|
||||
if m.BaseColor != nil {
|
||||
u.BaseColor = *m.BaseColor
|
||||
}
|
||||
if m.AuthorityID != nil {
|
||||
u.AuthorityId = uint(*m.AuthorityID)
|
||||
}
|
||||
@@ -374,16 +352,14 @@ func toModelUserWithAuthorities(m *model.SysUser) *system.User {
|
||||
u := toModelUser(m)
|
||||
|
||||
// 转换Authority
|
||||
if m.Authority != nil {
|
||||
u.Authority = &system.Authority{
|
||||
AuthorityId: uint(m.Authority.AuthorityID),
|
||||
AuthorityName: safeString(m.Authority.AuthorityName),
|
||||
DefaultRouter: safeString(m.Authority.DefaultRouter),
|
||||
}
|
||||
if m.Authority.ParentID != nil {
|
||||
pid := uint(*m.Authority.ParentID)
|
||||
u.Authority.ParentId = &pid
|
||||
}
|
||||
u.Authority = &system.Authority{
|
||||
AuthorityId: uint(m.Authority.AuthorityID),
|
||||
AuthorityName: safeString(m.Authority.AuthorityName),
|
||||
DefaultRouter: safeString(m.Authority.DefaultRouter),
|
||||
}
|
||||
if m.Authority.ParentID != nil {
|
||||
pid := uint(*m.Authority.ParentID)
|
||||
u.Authority.ParentId = &pid
|
||||
}
|
||||
|
||||
// 转换Authorities
|
||||
|
||||
@@ -3,4 +3,4 @@ package service
|
||||
import "github.com/google/wire"
|
||||
|
||||
// ProviderSet is service providers.
|
||||
var ProviderSet = wire.NewSet(NewAdminService)
|
||||
var ProviderSet = wire.NewSet()
|
||||
|
||||
@@ -0,0 +1,558 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
"kra/internal/server/middleware"
|
||||
"kra/pkg/jwt"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/errors"
|
||||
"github.com/go-kratos/kratos/v2/transport/http"
|
||||
)
|
||||
|
||||
// UserService 用户服务
|
||||
type UserService struct {
|
||||
uc *system.UserUsecase
|
||||
jwtPkg *jwt.JWT
|
||||
}
|
||||
|
||||
// NewUserService 创建用户服务
|
||||
func NewUserService(uc *system.UserUsecase, jwtPkg *jwt.JWT) *UserService {
|
||||
return &UserService{uc: uc, jwtPkg: jwtPkg}
|
||||
}
|
||||
|
||||
// LoginRequest 登录请求
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Captcha string `json:"captcha"`
|
||||
CaptchaId string `json:"captchaId"`
|
||||
}
|
||||
|
||||
// LoginResponse 登录响应
|
||||
type LoginResponse struct {
|
||||
User *UserInfo `json:"user"`
|
||||
Token string `json:"token"`
|
||||
ExpiresAt int64 `json:"expiresAt"`
|
||||
}
|
||||
|
||||
// UserInfo 用户信息
|
||||
type UserInfo struct {
|
||||
ID uint `json:"id"`
|
||||
UUID string `json:"uuid"`
|
||||
Username string `json:"username"`
|
||||
NickName string `json:"nickName"`
|
||||
SideMode string `json:"sideMode"`
|
||||
HeaderImg string `json:"headerImg"`
|
||||
BaseColor string `json:"baseColor"`
|
||||
AuthorityId uint `json:"authorityId"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
Enable int `json:"enable"`
|
||||
OriginSetting json.RawMessage `json:"originSetting,omitempty"`
|
||||
Authority *AuthorityInfo `json:"authority,omitempty"`
|
||||
Authorities []*AuthorityInfo `json:"authorities,omitempty"`
|
||||
}
|
||||
|
||||
// AuthorityInfo 角色信息
|
||||
type AuthorityInfo struct {
|
||||
AuthorityId uint `json:"authorityId"`
|
||||
AuthorityName string `json:"authorityName"`
|
||||
ParentId *uint `json:"parentId,omitempty"`
|
||||
DefaultRouter string `json:"defaultRouter"`
|
||||
}
|
||||
|
||||
// Login 用户登录
|
||||
func (s *UserService) Login(ctx context.Context, req *LoginRequest) (*LoginResponse, error) {
|
||||
user, err := s.uc.Login(ctx, req.Username, req.Password)
|
||||
if err != nil {
|
||||
return nil, errors.Unauthorized("LOGIN_FAILED", err.Error())
|
||||
}
|
||||
|
||||
if user.Enable != 1 {
|
||||
return nil, errors.Forbidden("USER_DISABLED", "用户被禁止登录")
|
||||
}
|
||||
|
||||
// 生成 JWT token
|
||||
claims := s.jwtPkg.CreateClaims(jwt.BaseClaims{
|
||||
UUID: user.UUID.String(),
|
||||
ID: uint(user.ID),
|
||||
Username: user.Username,
|
||||
NickName: user.NickName,
|
||||
AuthorityID: user.AuthorityId,
|
||||
})
|
||||
token, err := s.jwtPkg.CreateToken(claims.BaseClaims)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer("TOKEN_ERROR", "生成token失败")
|
||||
}
|
||||
|
||||
return &LoginResponse{
|
||||
User: toUserInfo(user),
|
||||
Token: token,
|
||||
ExpiresAt: claims.ExpiresAt.UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RegisterRequest 注册请求
|
||||
type RegisterRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
NickName string `json:"nickName"`
|
||||
HeaderImg string `json:"headerImg"`
|
||||
AuthorityId uint `json:"authorityId"`
|
||||
AuthorityIds []uint `json:"authorityIds"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
Enable int `json:"enable"`
|
||||
}
|
||||
|
||||
// Register 用户注册
|
||||
func (s *UserService) Register(ctx context.Context, req *RegisterRequest) (*UserInfo, error) {
|
||||
user := &system.User{
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
NickName: req.NickName,
|
||||
HeaderImg: req.HeaderImg,
|
||||
AuthorityId: req.AuthorityId,
|
||||
Phone: req.Phone,
|
||||
Email: req.Email,
|
||||
Enable: req.Enable,
|
||||
}
|
||||
|
||||
created, err := s.uc.Register(ctx, user)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequest("REGISTER_FAILED", err.Error())
|
||||
}
|
||||
|
||||
return toUserInfo(created), nil
|
||||
}
|
||||
|
||||
// ChangePasswordRequest 修改密码请求
|
||||
type ChangePasswordRequest struct {
|
||||
Password string `json:"password"`
|
||||
NewPassword string `json:"newPassword"`
|
||||
}
|
||||
|
||||
// ChangePassword 修改密码
|
||||
func (s *UserService) ChangePassword(ctx context.Context, userID uint, req *ChangePasswordRequest) error {
|
||||
return s.uc.ChangePassword(ctx, userID, req.Password, req.NewPassword)
|
||||
}
|
||||
|
||||
// ResetPasswordRequest 重置密码请求
|
||||
type ResetPasswordRequest struct {
|
||||
ID uint `json:"id"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// ResetPassword 重置密码
|
||||
func (s *UserService) ResetPassword(ctx context.Context, req *ResetPasswordRequest) error {
|
||||
return s.uc.ResetPassword(ctx, req.ID, req.Password)
|
||||
}
|
||||
|
||||
// GetUserInfo 获取用户信息
|
||||
func (s *UserService) GetUserInfo(ctx context.Context, uuid string) (*UserInfo, error) {
|
||||
user, err := s.uc.GetUserInfo(ctx, uuid)
|
||||
if err != nil {
|
||||
return nil, errors.NotFound("USER_NOT_FOUND", err.Error())
|
||||
}
|
||||
return toUserInfo(user), nil
|
||||
}
|
||||
|
||||
// GetUserListRequest 获取用户列表请求
|
||||
type GetUserListRequest struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
Username string `json:"username"`
|
||||
NickName string `json:"nickName"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// GetUserListResponse 获取用户列表响应
|
||||
type GetUserListResponse struct {
|
||||
List []*UserInfo `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
|
||||
// GetUserList 获取用户列表
|
||||
func (s *UserService) GetUserList(ctx context.Context, req *GetUserListRequest) (*GetUserListResponse, error) {
|
||||
filters := make(map[string]string)
|
||||
if req.Username != "" {
|
||||
filters["username"] = req.Username
|
||||
}
|
||||
if req.NickName != "" {
|
||||
filters["nick_name"] = req.NickName
|
||||
}
|
||||
if req.Phone != "" {
|
||||
filters["phone"] = req.Phone
|
||||
}
|
||||
if req.Email != "" {
|
||||
filters["email"] = req.Email
|
||||
}
|
||||
|
||||
users, total, err := s.uc.GetUserList(ctx, req.Page, req.PageSize, filters)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer("LIST_ERROR", err.Error())
|
||||
}
|
||||
|
||||
list := make([]*UserInfo, len(users))
|
||||
for i, u := range users {
|
||||
list[i] = toUserInfo(u)
|
||||
}
|
||||
|
||||
return &GetUserListResponse{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: req.Page,
|
||||
PageSize: req.PageSize,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetUserInfoRequest 设置用户信息请求(管理员用)
|
||||
type SetUserInfoRequest struct {
|
||||
ID uint `json:"id"`
|
||||
NickName string `json:"nickName"`
|
||||
HeaderImg string `json:"headerImg"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
Enable int `json:"enable"`
|
||||
AuthorityIds []uint `json:"authorityIds"`
|
||||
}
|
||||
|
||||
// SetUserInfo 设置用户信息
|
||||
func (s *UserService) SetUserInfo(ctx context.Context, req *SetUserInfoRequest) error {
|
||||
user := &system.User{
|
||||
ID: req.ID,
|
||||
NickName: req.NickName,
|
||||
HeaderImg: req.HeaderImg,
|
||||
Phone: req.Phone,
|
||||
Email: req.Email,
|
||||
Enable: req.Enable,
|
||||
}
|
||||
return s.uc.SetUserInfo(ctx, user)
|
||||
}
|
||||
|
||||
// SetSelfInfoRequest 设置自己信息请求(用户用)
|
||||
type SetSelfInfoRequest struct {
|
||||
NickName string `json:"nickName"`
|
||||
HeaderImg string `json:"headerImg"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
SideMode string `json:"sideMode"`
|
||||
BaseColor string `json:"baseColor"`
|
||||
}
|
||||
|
||||
// SetSelfInfo 设置自己的信息
|
||||
func (s *UserService) SetSelfInfo(ctx context.Context, userID uint, req *SetSelfInfoRequest) error {
|
||||
user := &system.User{
|
||||
ID: userID,
|
||||
NickName: req.NickName,
|
||||
HeaderImg: req.HeaderImg,
|
||||
Phone: req.Phone,
|
||||
Email: req.Email,
|
||||
SideMode: req.SideMode,
|
||||
BaseColor: req.BaseColor,
|
||||
}
|
||||
return s.uc.SetSelfInfo(ctx, user)
|
||||
}
|
||||
|
||||
// SetSelfSetting 设置自己的配置
|
||||
func (s *UserService) SetSelfSetting(ctx context.Context, userID uint, setting json.RawMessage) error {
|
||||
return s.uc.SetSelfSetting(ctx, userID, setting)
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (s *UserService) DeleteUser(ctx context.Context, id uint) error {
|
||||
return s.uc.DeleteUser(ctx, id)
|
||||
}
|
||||
|
||||
// SetUserAuthorityRequest 设置用户角色请求
|
||||
type SetUserAuthorityRequest struct {
|
||||
AuthorityId uint `json:"authorityId"`
|
||||
}
|
||||
|
||||
// SetUserAuthority 设置用户角色(切换角色)
|
||||
func (s *UserService) SetUserAuthority(ctx context.Context, userID uint, req *SetUserAuthorityRequest) error {
|
||||
return s.uc.SetUserAuthority(ctx, userID, req.AuthorityId)
|
||||
}
|
||||
|
||||
// SetUserAuthoritiesRequest 设置用户多角色请求
|
||||
type SetUserAuthoritiesRequest struct {
|
||||
ID uint `json:"id"`
|
||||
AuthorityIds []uint `json:"authorityIds"`
|
||||
}
|
||||
|
||||
// SetUserAuthorities 设置用户多角色
|
||||
func (s *UserService) SetUserAuthorities(ctx context.Context, adminAuthorityID uint, req *SetUserAuthoritiesRequest) error {
|
||||
return s.uc.SetUserAuthorities(ctx, adminAuthorityID, req.ID, req.AuthorityIds)
|
||||
}
|
||||
|
||||
// 转换函数
|
||||
func toUserInfo(u *system.User) *UserInfo {
|
||||
info := &UserInfo{
|
||||
ID: u.ID,
|
||||
UUID: u.UUID.String(),
|
||||
Username: u.Username,
|
||||
NickName: u.NickName,
|
||||
SideMode: u.SideMode,
|
||||
HeaderImg: u.HeaderImg,
|
||||
BaseColor: u.BaseColor,
|
||||
AuthorityId: u.AuthorityId,
|
||||
Phone: u.Phone,
|
||||
Email: u.Email,
|
||||
Enable: u.Enable,
|
||||
OriginSetting: u.OriginSetting,
|
||||
}
|
||||
|
||||
if u.Authority != nil {
|
||||
info.Authority = &AuthorityInfo{
|
||||
AuthorityId: u.Authority.AuthorityId,
|
||||
AuthorityName: u.Authority.AuthorityName,
|
||||
ParentId: u.Authority.ParentId,
|
||||
DefaultRouter: u.Authority.DefaultRouter,
|
||||
}
|
||||
}
|
||||
|
||||
if len(u.Authorities) > 0 {
|
||||
info.Authorities = make([]*AuthorityInfo, len(u.Authorities))
|
||||
for i, a := range u.Authorities {
|
||||
info.Authorities[i] = &AuthorityInfo{
|
||||
AuthorityId: a.AuthorityId,
|
||||
AuthorityName: a.AuthorityName,
|
||||
ParentId: a.ParentId,
|
||||
DefaultRouter: a.DefaultRouter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
// RegisterRoutes 注册路由
|
||||
func (s *UserService) RegisterRoutes(srv *http.Server) {
|
||||
r := srv.Route("/")
|
||||
|
||||
// 公开接口
|
||||
r.POST("/base/login", s.handleLogin)
|
||||
|
||||
// 需要认证的接口
|
||||
r.POST("/user/register", s.handleRegister)
|
||||
r.POST("/user/changePassword", s.handleChangePassword)
|
||||
r.POST("/user/resetPassword", s.handleResetPassword)
|
||||
r.GET("/user/getUserInfo", s.handleGetUserInfo)
|
||||
r.POST("/user/getUserList", s.handleGetUserList)
|
||||
r.PUT("/user/setUserInfo", s.handleSetUserInfo)
|
||||
r.PUT("/user/setSelfInfo", s.handleSetSelfInfo)
|
||||
r.PUT("/user/setSelfSetting", s.handleSetSelfSetting)
|
||||
r.DELETE("/user/deleteUser", s.handleDeleteUser)
|
||||
r.POST("/user/setUserAuthority", s.handleSetUserAuthority)
|
||||
r.POST("/user/setUserAuthorities", s.handleSetUserAuthorities)
|
||||
}
|
||||
|
||||
// HTTP Handlers
|
||||
func (s *UserService) handleLogin(ctx http.Context) error {
|
||||
var req LoginRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := s.Login(ctx, &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "登录成功",
|
||||
"data": resp,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleRegister(ctx http.Context) error {
|
||||
var req RegisterRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := s.Register(ctx, &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "注册成功",
|
||||
"data": resp,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleChangePassword(ctx http.Context) error {
|
||||
var req ChangePasswordRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
userID := middleware.GetUserID(ctx)
|
||||
if userID == 0 {
|
||||
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
|
||||
}
|
||||
if err := s.ChangePassword(ctx, userID, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "修改成功",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleResetPassword(ctx http.Context) error {
|
||||
var req ResetPasswordRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.ResetPassword(ctx, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "重置成功",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleGetUserInfo(ctx http.Context) error {
|
||||
claims, ok := middleware.GetClaims(ctx)
|
||||
if !ok {
|
||||
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
|
||||
}
|
||||
resp, err := s.GetUserInfo(ctx, claims.UUID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "获取成功",
|
||||
"data": map[string]any{"userInfo": resp},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleGetUserList(ctx http.Context) error {
|
||||
var req GetUserListRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := s.GetUserList(ctx, &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "获取成功",
|
||||
"data": resp,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleSetUserInfo(ctx http.Context) error {
|
||||
var req SetUserInfoRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.SetUserInfo(ctx, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "设置成功",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleSetSelfInfo(ctx http.Context) error {
|
||||
var req SetSelfInfoRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
userID := middleware.GetUserID(ctx)
|
||||
if userID == 0 {
|
||||
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
|
||||
}
|
||||
if err := s.SetSelfInfo(ctx, userID, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "设置成功",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleSetSelfSetting(ctx http.Context) error {
|
||||
var req json.RawMessage
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
userID := middleware.GetUserID(ctx)
|
||||
if userID == 0 {
|
||||
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
|
||||
}
|
||||
if err := s.SetSelfSetting(ctx, userID, req); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "设置成功",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleDeleteUser(ctx http.Context) error {
|
||||
var req struct {
|
||||
ID uint `json:"id"`
|
||||
}
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
// 不能删除自己
|
||||
userID := middleware.GetUserID(ctx)
|
||||
if userID == req.ID {
|
||||
return errors.BadRequest("DELETE_SELF", "删除失败, 无法删除自己")
|
||||
}
|
||||
if err := s.DeleteUser(ctx, req.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "删除成功",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleSetUserAuthority(ctx http.Context) error {
|
||||
var req SetUserAuthorityRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
userID := middleware.GetUserID(ctx)
|
||||
if userID == 0 {
|
||||
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
|
||||
}
|
||||
if err := s.SetUserAuthority(ctx, userID, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "修改成功",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *UserService) handleSetUserAuthorities(ctx http.Context) error {
|
||||
var req SetUserAuthoritiesRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
adminAuthorityID := middleware.GetAuthorityID(ctx)
|
||||
if adminAuthorityID == 0 {
|
||||
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
|
||||
}
|
||||
if err := s.SetUserAuthorities(ctx, adminAuthorityID, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Result(200, map[string]any{
|
||||
"code": 0,
|
||||
"msg": "修改成功",
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user