559 lines
15 KiB
Go
559 lines
15 KiB
Go
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": "修改成功",
|
|
})
|
|
}
|