初始化2
This commit is contained in:
@@ -0,0 +1,260 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
tokenx "bj_power_mes/common/token"
|
||||
"bj_power_mes/ent"
|
||||
"bj_power_mes/ent/permission"
|
||||
"bj_power_mes/ent/role"
|
||||
"bj_power_mes/ent/user"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// ------ 请求/返回 DTO ------
|
||||
|
||||
type LoginReq struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type LoginResp struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
AccessExpire int64 `json:"accessExpire"`
|
||||
}
|
||||
|
||||
type RefreshReq struct {
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
}
|
||||
|
||||
type UserInfoResp struct {
|
||||
UserId int `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Name string `json:"name"`
|
||||
RoleId int `json:"roleId"`
|
||||
RoleCode string `json:"roleCode"`
|
||||
RoleName string `json:"roleName"`
|
||||
Menus []permissionItem `json:"menus"`
|
||||
PermissionCodes []string `json:"permissionCodes"`
|
||||
}
|
||||
|
||||
type permissionItem struct {
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Icon string `json:"icon"`
|
||||
}
|
||||
|
||||
// currentToken 生成 access + refresh 双 token
|
||||
func (s *Service) issueTokens(usr *ent.User, roleEntity *ent.Role) (LoginResp, error) {
|
||||
claims := tokenx.Claims{UserId: usr.ID, Username: usr.Username, Name: usr.Name, RoleId: usr.RoleId}
|
||||
if roleEntity != nil {
|
||||
claims.RoleCode = roleEntity.Code
|
||||
claims.RoleName = roleEntity.Name
|
||||
} else {
|
||||
claims.RoleCode = ""
|
||||
claims.RoleName = ""
|
||||
}
|
||||
access, err := tokenx.Issue(s.ctx.Config.Auth.AccessSecret, time.Duration(s.ctx.Config.Auth.AccessExpire)*time.Second, claims)
|
||||
if err != nil {
|
||||
return LoginResp{}, err
|
||||
}
|
||||
refresh, err := tokenx.Issue(s.ctx.Config.Auth.AccessSecret, time.Duration(s.ctx.Config.Auth.RefreshExpire)*time.Second, claims)
|
||||
if err != nil {
|
||||
return LoginResp{}, err
|
||||
}
|
||||
return LoginResp{AccessToken: access, RefreshToken: refresh, AccessExpire: s.ctx.Config.Auth.AccessExpire}, nil
|
||||
}
|
||||
|
||||
// Login 登录
|
||||
func (s *Service) Login(ctx context.Context, req LoginReq) (LoginResp, error) {
|
||||
var resp LoginResp
|
||||
usr, err := s.ctx.EntClient.User.Query().Where(user.Username(req.Username)).First(ctx)
|
||||
if err != nil {
|
||||
return resp, errors.New("用户名或密码错误")
|
||||
}
|
||||
if usr.Status != "ENABLED" {
|
||||
return resp, errors.New("账号已禁用")
|
||||
}
|
||||
if bcrypt.CompareHashAndPassword([]byte(usr.Password), []byte(req.Password)) != nil {
|
||||
return resp, errors.New("用户名或密码错误")
|
||||
}
|
||||
roleEntity, _ := s.ctx.EntClient.Role.Get(ctx, usr.RoleId)
|
||||
return s.issueTokens(usr, roleEntity)
|
||||
}
|
||||
|
||||
// Refresh 刷新访问令牌(滑动续签)
|
||||
func (s *Service) Refresh(ctx context.Context, req RefreshReq) (LoginResp, error) {
|
||||
var resp LoginResp
|
||||
claims, err := tokenx.Parse(s.ctx.Config.Auth.AccessSecret, req.RefreshToken)
|
||||
if err != nil {
|
||||
return resp, errors.New("刷新令牌无效或已过期")
|
||||
}
|
||||
usr, err := s.ctx.EntClient.User.Get(ctx, claims.UserId)
|
||||
if err != nil {
|
||||
return resp, errors.New("用户不存在")
|
||||
}
|
||||
if usr.Status != "ENABLED" {
|
||||
return resp, errors.New("账号已禁用")
|
||||
}
|
||||
roleEntity, _ := s.ctx.EntClient.Role.Get(ctx, usr.RoleId)
|
||||
return s.issueTokens(usr, roleEntity)
|
||||
}
|
||||
|
||||
// UserInfo 当前用户信息 + 菜单权限
|
||||
func (s *Service) UserInfo(ctx context.Context, userId int) (UserInfoResp, error) {
|
||||
var out UserInfoResp
|
||||
usr, err := s.ctx.EntClient.User.Get(ctx, userId)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.UserId = usr.ID
|
||||
out.Username = usr.Username
|
||||
out.Name = usr.Name
|
||||
out.RoleId = usr.RoleId
|
||||
|
||||
roleEntity, err := s.ctx.EntClient.Role.Get(ctx, usr.RoleId)
|
||||
if err != nil {
|
||||
roleEntity = nil
|
||||
}
|
||||
if roleEntity != nil {
|
||||
out.RoleCode = roleEntity.Code
|
||||
out.RoleName = roleEntity.Name
|
||||
out.PermissionCodes = roleEntity.PermissionCodes
|
||||
}
|
||||
// 取所拥有权限对应的菜单
|
||||
perms, err := s.ctx.EntClient.Permission.Query().
|
||||
Where(permission.Type("MENU")).
|
||||
Order(ent.Asc(permission.FieldSort)).All(ctx)
|
||||
if err != nil {
|
||||
return out, nil
|
||||
}
|
||||
owned := map[string]bool{}
|
||||
for _, c := range out.PermissionCodes {
|
||||
owned[c] = true
|
||||
}
|
||||
for _, p := range perms {
|
||||
if roleEntity == nil {
|
||||
continue
|
||||
}
|
||||
if roleEntity.Code == "SUPER_ADMIN" || owned[p.Code] || owned["*"] {
|
||||
out.Menus = append(out.Menus, permissionItem{Code: p.Code, Name: p.Name, Path: p.Path, Icon: p.Icon})
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ------ 用户 / 角色 / 权限 管理 ------
|
||||
|
||||
type UserReq struct {
|
||||
Id int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Name string `json:"name"`
|
||||
RoleId int `json:"roleId"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
func (s *Service) CreateUser(ctx context.Context, req UserReq) error {
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
status := req.Status
|
||||
if status == "" {
|
||||
status = "ENABLED"
|
||||
}
|
||||
return s.ctx.EntClient.User.Create().
|
||||
SetUsername(req.Username).
|
||||
SetPassword(string(hash)).
|
||||
SetName(req.Name).
|
||||
SetRoleId(req.RoleId).
|
||||
SetStatus(status).
|
||||
Exec(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateUser(ctx context.Context, req UserReq) error {
|
||||
u := s.ctx.EntClient.User.UpdateOneID(req.Id).SetRoleId(req.RoleId).SetName(req.Name)
|
||||
if req.Password != "" {
|
||||
hash, _ := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
u.SetPassword(string(hash))
|
||||
}
|
||||
if req.Status != "" {
|
||||
u.SetStatus(req.Status)
|
||||
}
|
||||
return u.Exec(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) DeleteUser(ctx context.Context, id int) error {
|
||||
if id == 1 {
|
||||
return errors.New("不能删除超级管理员")
|
||||
}
|
||||
return s.ctx.EntClient.User.DeleteOneID(id).Exec(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) ListUsers(ctx context.Context) ([]*ent.User, error) {
|
||||
return s.ctx.EntClient.User.Query().Order(ent.Asc(user.FieldID)).All(ctx)
|
||||
}
|
||||
|
||||
type RoleReq struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Remark string `json:"remark"`
|
||||
PermissionCodes []string `json:"permissionCodes"`
|
||||
}
|
||||
|
||||
func (s *Service) CreateRole(ctx context.Context, req RoleReq) error {
|
||||
return s.ctx.EntClient.Role.Create().
|
||||
SetName(req.Name).SetCode(req.Code).SetRemark(req.Remark).
|
||||
SetPermissionCodes(req.PermissionCodes).Exec(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateRole(ctx context.Context, req RoleReq) error {
|
||||
return s.ctx.EntClient.Role.UpdateOneID(req.Id).
|
||||
SetName(req.Name).SetCode(req.Code).SetRemark(req.Remark).
|
||||
SetPermissionCodes(req.PermissionCodes).Exec(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) DeleteRole(ctx context.Context, id int) error {
|
||||
return s.ctx.EntClient.Role.DeleteOneID(id).Exec(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) ListRoles(ctx context.Context) ([]*ent.Role, error) {
|
||||
return s.ctx.EntClient.Role.Query().Order(ent.Asc(role.FieldID)).All(ctx)
|
||||
}
|
||||
|
||||
type PermissionReq struct {
|
||||
Id int `json:"id"`
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Path string `json:"path"`
|
||||
Icon string `json:"icon"`
|
||||
Sort int `json:"sort"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
func (s *Service) CreatePermission(ctx context.Context, req PermissionReq) error {
|
||||
return s.ctx.EntClient.Permission.Create().
|
||||
SetCode(req.Code).SetName(req.Name).SetType(req.Type).
|
||||
SetPath(req.Path).SetIcon(req.Icon).SetSort(req.Sort).SetRemark(req.Remark).Exec(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) UpdatePermission(ctx context.Context, req PermissionReq) error {
|
||||
return s.ctx.EntClient.Permission.UpdateOneID(req.Id).
|
||||
SetCode(req.Code).SetName(req.Name).SetType(req.Type).
|
||||
SetPath(req.Path).SetIcon(req.Icon).SetSort(req.Sort).SetRemark(req.Remark).Exec(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) DeletePermission(ctx context.Context, id int) error {
|
||||
return s.ctx.EntClient.Permission.DeleteOneID(id).Exec(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) ListPermissions(ctx context.Context) ([]*ent.Permission, error) {
|
||||
return s.ctx.EntClient.Permission.Query().Order(ent.Asc(permission.FieldSort), ent.Asc(permission.FieldID)).All(ctx)
|
||||
}
|
||||
Reference in New Issue
Block a user