feat:完善项目信息

This commit is contained in:
henry
2022-01-07 16:12:43 +08:00
parent 657fdc5750
commit 2bf3c01702
21 changed files with 379 additions and 129 deletions

View File

@ -10,7 +10,42 @@ import (
type Auth struct{} type Auth struct{}
type authForm struct {
ParentID string `json:"parent_id" form:"parent_id"`
Kind int `json:"kind" form:"kind" binding:"required"`
Name string `json:"name" form:"name" binding:"required"`
Auth string `json:"auth" form:"auth" binding:"required"`
Sort int `json:"sort" form:"sort"`
Remark string `json:"remark" form:"remark"`
}
func (*Auth) Index(c *gin.Context) { func (*Auth) Index(c *gin.Context) {
data, err := auth.NewInstance()(api.GetSession()(c).(*session.Admin)).Index() data, err := auth.NewInstance()(api.GetSession()(c).(*session.Admin)).Index()
api.APIResponse(err, data)(c) api.APIResponse(err, data)(c)
} }
func (*Auth) Add(c *gin.Context) {
form := &struct {
RoleID string `json:"role_id" form:"role_id" binding:"required"`
AuthIDs []string `json:"auth_ids" form:"auth_ids" binding:"required"`
}{}
if err := api.Bind(form)(c); err != nil {
api.APIFailure(err.(error))(c)
return
}
}
func (*Auth) Edit(c *gin.Context) {
form := &struct {
RoleID string `json:"role_id" form:"role_id" binding:"required"`
AuthIDs []string `json:"auth_ids" form:"auth_ids" binding:"required"`
}{}
if err := api.Bind(form)(c); err != nil {
api.APIFailure(err.(error))(c)
return
}
}
func (*Auth) Delete(c *gin.Context) {
}

View File

@ -4,7 +4,6 @@ import (
"SciencesServer/app/api/admin/controller/department" "SciencesServer/app/api/admin/controller/department"
"SciencesServer/app/basic/api" "SciencesServer/app/basic/api"
"SciencesServer/app/session" "SciencesServer/app/session"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -13,14 +12,21 @@ type Department struct{}
type departmentForm struct { type departmentForm struct {
ParentID string `json:"parent_id" form:"parent_id"` ParentID string `json:"parent_id" form:"parent_id"`
Name string `json:"name" form:"name" binding:"required"` Name string `json:"name" form:"name" binding:"required"`
Contact string `json:"contact" form:"contact_title"` Contact string `json:"contact" form:"contact"`
ContactMobile string `json:"contact_mobile" form:"contact_mobile"` ContactMobile string `json:"contact_mobile" form:"contact_mobile"`
Status int `json:"status" form:"status" binding:"required"` Status int `json:"status" form:"status" binding:"required"`
Remark string `json:"remark" form:"remark"` Remark string `json:"remark" form:"remark"`
} }
func (a *Department) Index(c *gin.Context) { func (a *Department) Index(c *gin.Context) {
data, err := department.NewInstance()(api.GetSession()(c).(*session.Admin)).Index() form := &struct {
FilterID string `json:"filter_id" form:"filter_id"`
}{}
if err := api.Bind(form)(c); err != nil {
api.APIFailure(err.(error))(c)
return
}
data, err := department.NewInstance()(api.GetSession()(c).(*session.Admin)).Index((&api.IDStringForm{ID: form.FilterID}).Convert())
api.APIResponse(err, data)(c) api.APIResponse(err, data)(c)
} }

View File

@ -19,7 +19,7 @@ type (
Link string `json:"path" form:"path"` Link string `json:"path" form:"path"`
Component string `json:"component" form:"component"` Component string `json:"component" form:"component"`
Icon string `json:"icon" form:"icon"` Icon string `json:"icon" form:"icon"`
Auth int `json:"auth" form:"auth"` Auth string `json:"auth" form:"auth"`
Sort int `json:"sort" form:"sort"` Sort int `json:"sort" form:"sort"`
IsCache int `json:"is_cache" form:"is_cache"` IsCache int `json:"is_cache" form:"is_cache"`
Hidden int `json:"hidden" form:"hidden"` Hidden int `json:"hidden" form:"hidden"`

View File

@ -107,38 +107,48 @@ func (a *Tenant) MemberBind(c *gin.Context) {
func (a *Tenant) Menu(c *gin.Context) { func (a *Tenant) Menu(c *gin.Context) {
form := &struct { form := &struct {
TenantID uint64 `json:"tenant_id" form:"tenant_id" binding:"required"` TenantID string `json:"tenant_id" form:"tenant_id" binding:"required"`
}{} }{}
if err := api.Bind(form)(c); err != nil { if err := api.Bind(form)(c); err != nil {
api.APIFailure(err.(error))(c) api.APIFailure(err.(error))(c)
return return
} }
data, err := tenant.NewMenu()(api.GetSession()(c).(*session.Admin)).List(form.TenantID) data, err := tenant.NewMenu()(api.GetSession()(c).(*session.Admin)).List((&api.IDStringForm{ID: form.TenantID}).Convert())
api.APIResponse(err, data)(c) api.APIResponse(err, data)(c)
} }
func (a *Tenant) MenuBind(c *gin.Context) { func (a *Tenant) MenuBind(c *gin.Context) {
form := &struct { form := &struct {
TenantID uint64 `json:"tenant_id" form:"tenant_id" binding:"required"` TenantID string `json:"tenant_id" form:"tenant_id" binding:"required"`
MenuIDs []uint64 `json:"menu_ids" form:"menu_ids" binding:"required"` MenuIDs []string `json:"menu_ids" form:"menu_ids" binding:"required"`
}{} }{}
if err := api.Bind(form)(c); err != nil { if err := api.Bind(form)(c); err != nil {
api.APIFailure(err.(error))(c) api.APIFailure(err.(error))(c)
return return
} }
err := tenant.NewMenu()(api.GetSession()(c).(*session.Admin)).Bind(form.TenantID, form.MenuIDs) menuIDs := make([]uint64, 0)
for _, v := range form.MenuIDs {
menuIDs = append(menuIDs, (&api.IDStringForm{ID: v}).Convert())
}
err := tenant.NewMenu()(api.GetSession()(c).(*session.Admin)).Bind((&api.IDStringForm{ID: form.TenantID}).Convert(), menuIDs)
api.APIResponse(err)(c) api.APIResponse(err)(c)
} }
func (a *Tenant) AuthBind(c *gin.Context) { func (a *Tenant) AuthBind(c *gin.Context) {
form := &struct { form := &struct {
TenantID uint64 `json:"tenant_id" form:"tenant_id" binding:"required"` TenantID string `json:"tenant_id" form:"tenant_id" binding:"required"`
AuthIDs []uint64 `json:"auth_ids" form:"auth_ids" binding:"required"` AuthIDs []string `json:"auth_ids" form:"auth_ids" binding:"required"`
}{} }{}
if err := api.Bind(form)(c); err != nil { if err := api.Bind(form)(c); err != nil {
api.APIFailure(err.(error))(c) api.APIFailure(err.(error))(c)
return return
} }
err := tenant.NewAuth()(api.GetSession()(c).(*session.Admin)).Bind(form.TenantID, form.AuthIDs) authIDs := make([]uint64, 0)
for _, v := range form.AuthIDs {
authIDs = append(authIDs, (&api.IDStringForm{ID: v}).Convert())
}
err := tenant.NewAuth()(api.GetSession()(c).(*session.Admin)).Bind((&api.IDStringForm{ID: form.TenantID}).Convert(), authIDs)
api.APIResponse(err)(c) api.APIResponse(err)(c)
} }

View File

@ -11,12 +11,14 @@ import (
type User struct{} type User struct{}
type userForm struct { type userForm struct {
Account string `json:"account" form:"account" binding:"required"` Account string `json:"account" form:"account"`
Name string `json:"name" form:"name" binding:"required"` Name string `json:"name" form:"name" binding:"required"`
Mobile string `json:"mobile" form:"mobile" binding:"required"` Mobile string `json:"mobile" form:"mobile" binding:"required"`
Gender int `json:"gender" form:"gender" binding:"required"` Gender int `json:"gender" form:"gender" binding:"required"`
Status int `json:"status" form:"status" binding:"required"`
DepartmentID string `json:"department_id" form:"department_id"` DepartmentID string `json:"department_id" form:"department_id"`
RoleIDs []string `json:"role_ids" form:"role_ids"` RoleIDs []string `json:"role_ids" form:"role_ids"`
Email string `json:"email" form:"email"`
Remark string `json:"remark" form:"remark"` Remark string `json:"remark" form:"remark"`
} }
@ -81,8 +83,8 @@ func (a *User) Add(c *gin.Context) {
return return
} }
err := user.NewInstance()(api.GetSession()(c).(*session.Admin)).Add(&user.InstanceForm{ err := user.NewInstance()(api.GetSession()(c).(*session.Admin)).Add(&user.InstanceForm{
Account: form.Account, Name: form.Name, Mobile: form.Mobile, Password: form.Password, Account: form.Account, Name: form.Name, Mobile: form.Mobile, Password: form.Password, Status: form.Status,
Remark: form.Remark, Gender: form.Gender, DepartmentID: form.departmentInfo(), RoleIDs: form.RoleInfo(), Email: form.Email, Remark: form.Remark, Gender: form.Gender, DepartmentID: form.departmentInfo(), RoleIDs: form.RoleInfo(),
}) })
api.APIResponse(err)(c) api.APIResponse(err)(c)
} }
@ -97,8 +99,8 @@ func (a *User) Edit(c *gin.Context) {
return return
} }
err := user.NewInstance()(api.GetSession()(c).(*session.Admin)).Edit(&user.InstanceForm{ err := user.NewInstance()(api.GetSession()(c).(*session.Admin)).Edit(&user.InstanceForm{
ID: form.Convert(), Account: form.Account, Name: form.Name, Mobile: form.Mobile, ID: form.Convert(), Account: form.Account, Name: form.Name, Mobile: form.Mobile, Status: form.Status,
Remark: form.Remark, Gender: form.Gender, DepartmentID: form.departmentInfo(), RoleIDs: form.RoleInfo(), Email: form.Email, Remark: form.Remark, Gender: form.Gender, DepartmentID: form.departmentInfo(), RoleIDs: form.RoleInfo(),
}) })
api.APIResponse(err)(c) api.APIResponse(err)(c)
} }
@ -107,7 +109,7 @@ func (a *User) Password(c *gin.Context) {
form := &struct { form := &struct {
api.IDStringForm api.IDStringForm
Password string `json:"password" form:"password" binding:"required"` Password string `json:"password" form:"password" binding:"required"`
RepeatPwd string `json:"repeat_pwd" form:"repeat_pwd" binding:"required"` RepeatPwd string `json:"repeat_pwd" form:"repeat_pwd"`
}{} }{}
if err := api.Bind(form)(c); err != nil { if err := api.Bind(form)(c); err != nil {
api.APIFailure(err.(error))(c) api.APIFailure(err.(error))(c)

View File

@ -4,19 +4,26 @@ import (
"SciencesServer/app/api/admin/model" "SciencesServer/app/api/admin/model"
model2 "SciencesServer/app/common/model" model2 "SciencesServer/app/common/model"
"SciencesServer/app/session" "SciencesServer/app/session"
"errors"
) )
type Instance struct{ *session.Admin } type Instance struct{ *session.Admin }
type InstanceHandle func(session *session.Admin) *Instance type InstanceHandle func(session *session.Admin) *Instance
type InstanceParams struct {
ID, ParentID uint64
Kind, Sort int
Name, Auth, Remark string
}
// Index 列表信息 // Index 列表信息
func (c *Instance) Index() ([]*Tree, error) { func (c *Instance) Index() ([]*Tree, error) {
mSysAuth := model.NewSysAuth() mSysAuth := model.NewSysAuth()
where := []*model2.ModelWhereOrder{ where := []*model2.ModelWhereOrder{
&model2.ModelWhereOrder{Order: model2.NewOrder("sort", model2.OrderModeToAsc)},
&model2.ModelWhereOrder{Order: model2.NewOrder("parent_id", model2.OrderModeToAsc)}, &model2.ModelWhereOrder{Order: model2.NewOrder("parent_id", model2.OrderModeToAsc)},
&model2.ModelWhereOrder{Order: model2.NewOrder("sort", model2.OrderModeToDesc)},
} }
out := make([]*model2.SysAuth, 0) out := make([]*model2.SysAuth, 0)
@ -26,6 +33,44 @@ func (c *Instance) Index() ([]*Tree, error) {
return tree(out, 0), nil return tree(out, 0), nil
} }
// Form 数据操作
func (c *Instance) Form(params *InstanceParams) error {
mSysAuth := model.NewSysAuth()
if params.ID > 0 {
mSysAuth.ID = params.ID
if isExist, err := model2.First(mSysAuth.SysAuth); err != nil {
return err
} else if !isExist {
return errors.New("操作错误,权限信息不存在")
}
}
mSysAuth.ParentID = params.ParentID
mSysAuth.Kind = model2.SysAuthKind(params.Kind)
mSysAuth.Name = params.Name
mSysAuth.Auth = params.Auth
mSysAuth.Sort = params.Sort
mSysAuth.Remark = params.Remark
if mSysAuth.ID > 0 {
return model2.Updates(mSysAuth.SysAuth, mSysAuth.SysAuth)
}
return model2.Create(mSysAuth.SysAuth)
}
func (c *Instance) Delete(id uint64) error {
mSysAuth := model.NewSysAuth()
mSysAuth.ID = id
err := model2.Delete(mSysAuth.SysAuth)
if err != nil {
return err
}
return nil
}
func NewInstance() InstanceHandle { func NewInstance() InstanceHandle {
return func(session *session.Admin) *Instance { return func(session *session.Admin) *Instance {
return &Instance{Admin: session} return &Instance{Admin: session}

View File

@ -49,18 +49,26 @@ func (c *Instance) tree(src []*model2.SysDepartment, parentID uint64) []*Instanc
return out return out
} }
func (c *Instance) Index() ([]*InstanceTreeInfo, error) { func (c *Instance) Index(filterID uint64) ([]*InstanceTreeInfo, error) {
mSysDepartment := model.NewSysDepartment() mSysDepartment := model.NewSysDepartment()
out := make([]*model2.SysDepartment, 0) out := make([]*model2.SysDepartment, 0)
if err := model2.Scan(mSysDepartment.SysDepartment, &out, &model2.ModelWhereOrder{ where := []*model2.ModelWhereOrder{
Where: model2.NewWhere("tenant_id", c.TenantID),
Order: model2.NewOrder("parent_id", model2.OrderModeToAsc)},
&model2.ModelWhereOrder{ &model2.ModelWhereOrder{
Order: model2.NewOrder("id", model2.OrderModeToDesc)}); err != nil { Where: model2.NewWhere("tenant_id", c.TenantID),
Order: model2.NewOrder("parent_id", model2.OrderModeToAsc)},
&model2.ModelWhereOrder{
Order: model2.NewOrder("id", model2.OrderModeToAsc)},
}
if filterID > 0 {
where = append(where, &model2.ModelWhereOrder{Where: model2.NewWhereCondition("id", "!=", filterID)},
&model2.ModelWhereOrder{Where: model2.NewWhereCondition("parent_id", "!=", filterID)})
}
if err := model2.Scan(mSysDepartment.SysDepartment, &out, where...); err != nil {
return nil, err return nil, err
} }
return c.tree(out, 0), nil return c.tree(out, 0), nil
} }
@ -73,7 +81,7 @@ func (c *Instance) Select() ([]*InstanceTreeInfo, error) {
Where: model2.NewWhere("tenant_id", c.TenantID), Where: model2.NewWhere("tenant_id", c.TenantID),
Order: model2.NewOrder("parent_id", model2.OrderModeToAsc)}, &model2.ModelWhereOrder{ Order: model2.NewOrder("parent_id", model2.OrderModeToAsc)}, &model2.ModelWhereOrder{
Where: model2.NewWhere("status", 1), Where: model2.NewWhere("status", 1),
Order: model2.NewOrder("id", model2.OrderModeToDesc)}); err != nil { Order: model2.NewOrder("id", model2.OrderModeToAsc)}); err != nil {
return nil, err return nil, err
} }
return c.tree(out, 0), nil return c.tree(out, 0), nil

View File

@ -16,11 +16,11 @@ type InstanceHandle func(session *session.Admin) *Instance
type ( type (
// InstanceParams 菜单参数 // InstanceParams 菜单参数
InstanceParams struct { InstanceParams struct {
ID, ParentID uint64 ID, ParentID uint64
Kind, Auth int Kind int
Name, Link, Component, Icon string Name, Link, Auth, Component, Icon string
Sort, IsCache, IsHidden, Status int Sort, IsCache, IsHidden, Status int
Remark string Remark string
} }
) )
@ -50,7 +50,7 @@ func (c *Instance) Form(params *InstanceParams) error {
IsHidden: model2.SysMenuHiddenStatus(params.IsHidden), IsHidden: model2.SysMenuHiddenStatus(params.IsHidden),
Icon: params.Icon, Icon: params.Icon,
}, },
Auth: model2.SysMenuAuth(params.Auth), Auth: params.Auth,
Sort: params.Sort, Sort: params.Sort,
Status: model2.SysMenuStatus(params.Status), Status: model2.SysMenuStatus(params.Status),
Remark: params.Remark, Remark: params.Remark,
@ -72,7 +72,7 @@ func (c *Instance) Form(params *InstanceParams) error {
out.Link = params.Link out.Link = params.Link
out.Component = params.Component out.Component = params.Component
out.Icon = params.Icon out.Icon = params.Icon
out.Auth = model2.SysMenuAuth(params.Auth) out.Auth = params.Auth
out.IsCache = model2.SysMenuCacheStatus(params.IsCache) out.IsCache = model2.SysMenuCacheStatus(params.IsCache)
out.IsHidden = model2.SysMenuHiddenStatus(params.IsHidden) out.IsHidden = model2.SysMenuHiddenStatus(params.IsHidden)
out.Sort = params.Sort out.Sort = params.Sort

View File

@ -25,7 +25,7 @@ type (
} }
// InstanceBasicInfo 角色基本信息 // InstanceBasicInfo 角色基本信息
InstanceBasicInfo struct { InstanceBasicInfo struct {
ID uint64 `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
} }
) )
@ -77,12 +77,20 @@ func (c *Instance) Select() ([]*InstanceBasicInfo, error) {
Order: model2.NewOrder("id", model2.OrderModeToDesc), Order: model2.NewOrder("id", model2.OrderModeToDesc),
}, },
} }
out := make([]*InstanceBasicInfo, 0) out := make([]*model2.SysRole, 0)
if err := model2.Scan(mSysRole.SysRole, &out, where...); err != nil { if err := model2.Scan(mSysRole.SysRole, &out, where...); err != nil {
return nil, err return nil, err
} }
return out, nil list := make([]*InstanceBasicInfo, 0)
for _, v := range out {
list = append(list, &InstanceBasicInfo{
ID: v.GetEncodeID(),
Name: v.Name,
})
}
return list, nil
} }
// Form 数据操作 // Form 数据操作
@ -152,11 +160,10 @@ func (c *Instance) Delete(id uint64) error {
return err return err
} }
go utils.TryCatch(func() { go utils.TryCatch(func() {
permission := service.NewPermission( if _, err = service.NewPermission(
service.WithAuthTenant(fmt.Sprintf("%d", mSysRole.TenantID)), service.WithAuthTenant(fmt.Sprintf("%d", mSysRole.TenantID)),
service.WithAuthRoles([]string{fmt.Sprintf("%d", id)}), service.WithAuthRoles([]string{fmt.Sprintf("%d", id)}),
) ).RemoveSingleRolePolicy(); err != nil {
if _, err = permission.RemoveRolePolicy(); err != nil {
logger.ErrorF("Casbin 删除租户【%d】下角色【%d】权限信息错误%v", mSysRole.TenantID, id, err) logger.ErrorF("Casbin 删除租户【%d】下角色【%d】权限信息错误%v", mSysRole.TenantID, id, err)
return return
} }

View File

@ -6,8 +6,6 @@ import (
model2 "SciencesServer/app/common/model" model2 "SciencesServer/app/common/model"
"SciencesServer/app/session" "SciencesServer/app/session"
"SciencesServer/serve/orm" "SciencesServer/serve/orm"
"errors"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -24,16 +22,7 @@ func (c *Menu) Index(roleID uint64) ([]*menu2.TreeChecked, error) {
// Bind 绑定菜单 // Bind 绑定菜单
func (c *Menu) Bind(roleID uint64, menuIDs []uint64) error { func (c *Menu) Bind(roleID uint64, menuIDs []uint64) error {
if len(menuIDs) > 0 { if len(menuIDs) > 0 {
var count int64
mSysMenu := model.NewSysMenu()
if err := model2.Count(mSysMenu.SysMenu, &count, model2.NewWhereIn("id", menuIDs),
model2.NewWhere("auth", model2.SysMenuAuthForSystem)); err != nil {
return err
} else if count > 0 {
return errors.New("不可设置超管菜单")
}
} }
mSysRoleMenu := model.NewSysRoleMenu() mSysRoleMenu := model.NewSysRoleMenu()
@ -54,9 +43,7 @@ func (c *Menu) Bind(roleID uint64, menuIDs []uint64) error {
if _, has := mark[v]; has { if _, has := mark[v]; has {
continue continue
} }
menus = append(menus, &model2.SysRoleMenu{ menus = append(menus, &model2.SysRoleMenu{RoleID: roleID, MenuID: v})
ModelTenant: model2.ModelTenant{TenantID: c.TenantID}, RoleID: roleID, MenuID: v,
})
mark[v] = v mark[v] = v
} }
if err = model2.Creates(mSysRoleMenu.SysRoleMenu, menus, tx); err != nil { if err = model2.Creates(mSysRoleMenu.SysRoleMenu, menus, tx); err != nil {

View File

@ -3,12 +3,11 @@ package tenant
import ( import (
"SciencesServer/app/api/admin/controller/menu" "SciencesServer/app/api/admin/controller/menu"
"SciencesServer/app/api/admin/model" "SciencesServer/app/api/admin/model"
model3 "SciencesServer/app/api/enterprise/model"
model2 "SciencesServer/app/common/model" model2 "SciencesServer/app/common/model"
"SciencesServer/app/service"
"SciencesServer/app/session" "SciencesServer/app/session"
"SciencesServer/serve/orm" "SciencesServer/serve/orm"
"errors" "fmt"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -16,6 +15,16 @@ type Menu struct{ *session.Admin }
type MenuHandle func(session *session.Admin) *Menu type MenuHandle func(session *session.Admin) *Menu
func (c *Menu) auth(tenantID string, roleIDs []string, request []*service.AuthRequest) error {
permission := service.NewPermission(
service.WithAuthTenant(tenantID),
service.WithAuthRoles(roleIDs),
service.WithAuthRequest(request),
)
_, err := permission.RemoveRolePolicies()
return err
}
// List 菜单列表 // List 菜单列表
func (c *Menu) List(tenantID uint64) ([]*menu.TreeChecked, error) { func (c *Menu) List(tenantID uint64) ([]*menu.TreeChecked, error) {
mSysMenu := model.NewSysMenu() mSysMenu := model.NewSysMenu()
@ -24,60 +33,112 @@ func (c *Menu) List(tenantID uint64) ([]*menu.TreeChecked, error) {
// Bind 绑定菜单 // Bind 绑定菜单
func (c *Menu) Bind(tenantID uint64, menuIDs []uint64) error { func (c *Menu) Bind(tenantID uint64, menuIDs []uint64) error {
if len(menuIDs) > 0 { // 查询菜单信息
var count int64
mSysMenu := model3.NewSysMenu()
if err := model2.Count(mSysMenu.SysMenu, &count, model2.NewWhereIn("id", menuIDs),
model2.NewWhere("auth", model2.SysMenuAuthForSystem)); err != nil {
return err
} else if count > 0 {
return errors.New("不可设置超管菜单")
}
}
mSysTenantMenu := model.NewSysTenantMenu() mSysTenantMenu := model.NewSysTenantMenu()
// 当前租户的信息
out := make([]*model2.SysTenantMenu, 0)
err := model2.ScanFields(mSysTenantMenu.SysTenantMenu, &out, []string{"id", "menu_id"})
if err != nil {
return err
}
_menus := make(map[uint64]uint64, 0)
// 应保存的菜单
insertMenus := make([]*model2.SysTenantMenu, 0)
// 应删除的菜单
deleteMenuIDs := make([]uint64, 0)
for _, v := range menuIDs {
_menus[v] = v
}
return orm.GetDB().Transaction(func(tx *gorm.DB) error { return orm.GetDB().Transaction(func(tx *gorm.DB) error {
// TODO先全部删除后期考虑局部删除 // 无菜单信息
err := model2.DeleteWhere(mSysTenantMenu.SysTenantMenu, []*model2.ModelWhere{model2.NewWhere("tenant_id", tenantID)}, tx) if len(_menus) <= 0 {
for _, v := range out {
deleteMenuIDs = append(deleteMenuIDs, v.MenuID)
}
goto NEXT
}
// 租户原本含有菜单信息
for _, v := range out {
_, has := _menus[v.MenuID]
if err != nil { if !has {
deleteMenuIDs = append(deleteMenuIDs, v.MenuID)
continue
}
delete(_menus, v.MenuID)
}
for k := range _menus {
insertMenus = append(insertMenus, &model2.SysTenantMenu{
ModelTenant: model2.ModelTenant{TenantID: tenantID},
MenuID: k,
})
}
if len(insertMenus) > 0 {
if err = model2.Creates(mSysTenantMenu.SysTenantMenu, insertMenus); err != nil {
return err
}
}
NEXT:
// 删除操作
if len(deleteMenuIDs) <= 0 {
return nil
}
// 删除租户的菜单信息
if err = model2.DeleteWhere(mSysTenantMenu.SysTenantMenu, []*model2.ModelWhere{model2.NewWhere("tenant_id", tenantID),
model2.NewWhereIn("menu_id", deleteMenuIDs)}, tx); err != nil {
return err return err
} }
// 租户角色的菜单 // 查询租户下所有角色信息
mSysRole := model.NewSysRole()
roleIDs := make([]uint64, 0)
if err = model2.Pluck(mSysRole.SysRole, "id", &roleIDs, model2.NewWhere("tenant_id", tenantID)); err != nil {
return err
}
// 删除租户下角色的菜单
mSysRoleMenu := model.NewSysRoleMenu() mSysRoleMenu := model.NewSysRoleMenu()
if len(menuIDs) <= 0 { if len(menuIDs) <= 0 {
if err = model2.DeleteWhere(mSysRoleMenu.SysRoleMenu, []*model2.ModelWhere{model2.NewWhere("tenant_id", tenantID)}, tx); err != nil { if err = model2.DeleteWhere(mSysRoleMenu.SysRoleMenu, []*model2.ModelWhere{
model2.NewWhereIn("role_id", roleIDs), model2.NewWhereIn("menu_id", deleteMenuIDs),
}, tx); err != nil {
return err return err
} }
return nil return nil
} }
menus := make([]*model2.SysTenantMenu, 0) // 查询菜单信息,关闭角色的权限信息
mSysMenu := model.NewSysMenu()
mark := make(map[uint64]uint64, 0) menus := make([]*model2.SysMenu, 0)
for _, v := range menuIDs { if err = model2.ScanFields(mSysMenu.SysMenu, &menus, []string{"kind", "auth"},
if _, has := mark[v]; has { &model2.ModelWhereOrder{Where: model2.NewWhereIn("id", deleteMenuIDs)}); err != nil {
return err
}
// 同步权限
_roleIDs := make([]string, 0)
for _, v := range roleIDs {
_roleIDs = append(_roleIDs, fmt.Sprintf("%d", v))
}
request := make([]*service.AuthRequest, 0)
for _, v := range menus {
if v.Kind == model2.SysMenuKindForCatalogue || v.Auth == "" {
continue continue
} }
menus = append(menus, &model2.SysTenantMenu{ mSysMenu.Auth = v.Auth
ModelTenant: model2.ModelTenant{TenantID: tenantID}, MenuID: v,
request = append(request, &service.AuthRequest{
Url: mSysMenu.FilterAuth(),
Method: "*",
}) })
mark[v] = v
} }
if err = model2.Creates(mSysTenantMenu.SysTenantMenu, menus, tx); err != nil { return c.auth(fmt.Sprintf("%d", tenantID), _roleIDs, request)
return err
}
// 删除租户下角色不存在的菜单
if err = model2.DeleteWhere(mSysRoleMenu.SysRoleMenu, []*model2.ModelWhere{
model2.NewWhere("tenant_id", tenantID),
model2.NewWhereNotIn("menu_id", menuIDs),
}); err != nil {
return err
}
return nil
}) })
} }

View File

@ -26,12 +26,15 @@ type (
InstanceInfo struct { InstanceInfo struct {
ID string `json:"id"` ID string `json:"id"`
InstanceUserInfo InstanceUserInfo
Account string `json:"account"`
Gender model2.GenderKind `json:"gender"` Gender model2.GenderKind `json:"gender"`
IsAdmin model2.SysUserAdministrator `json:"is_admin"` IsAdmin model2.SysUserAdministrator `json:"is_admin"`
Status model2.SysUserStatus `json:"status"` Status model2.SysUserStatus `json:"status"`
Department *InstanceDepartmentInfo `json:"department"` Department *InstanceDepartmentInfo `json:"department"`
Role *InstanceRoleInfo `json:"role"` //Role *InstanceRoleInfo `json:"role"`
CreatedAt time.Time `json:"created_at"` RoleIDs []string `json:"role_ids"`
Remark string `json:"remark"`
CreatedAt time.Time `json:"created_at"`
} }
// InstanceUserInfo 用户信息 // InstanceUserInfo 用户信息
InstanceUserInfo struct { InstanceUserInfo struct {
@ -55,11 +58,11 @@ type (
// InstanceForm 表单信息 // InstanceForm 表单信息
type InstanceForm struct { type InstanceForm struct {
ID uint64 ID uint64
Account, Name, Mobile, Password, Remark string Account, Name, Mobile, Password, Email, Remark string
Gender int Gender, Status int
DepartmentID uint64 DepartmentID uint64
RoleIDs []uint64 RoleIDs []uint64
} }
func (c *InstanceForm) sync(tx *gorm.DB, first bool, uid, tenantID uint64) error { func (c *InstanceForm) sync(tx *gorm.DB, first bool, uid, tenantID uint64) error {
@ -171,7 +174,10 @@ func (c *Instance) Index(name, mobile string, departmentIDs []uint64, status, pa
InstanceUserInfo: InstanceUserInfo{ InstanceUserInfo: InstanceUserInfo{
UID: v.UUIDString(), Avatar: v.Avatar, Name: v.Name, Email: v.Email, Mobile: v.Mobile, UID: v.UUIDString(), Avatar: v.Avatar, Name: v.Name, Email: v.Email, Mobile: v.Mobile,
}, },
Gender: v.Gender.Gender, IsAdmin: v.IsAdmin, Status: v.Status, CreatedAt: v.CreatedAt, Account: v.Account, Gender: v.Gender.Gender, IsAdmin: v.IsAdmin, Status: v.Status, CreatedAt: v.CreatedAt,
//Role: make([]*InstanceRoleInfo, 0),
RoleIDs: make([]string, 0),
Remark: v.Remark,
} }
if v.DepartmentID > 0 { if v.DepartmentID > 0 {
@ -188,11 +194,11 @@ func (c *Instance) Index(name, mobile string, departmentIDs []uint64, status, pa
obj.ID = utils.StringToUnit64(v) obj.ID = utils.StringToUnit64(v)
roleIDs = append(roleIDs, obj.GetEncodeID()) roleIDs = append(roleIDs, obj.GetEncodeID())
} }
roles := &InstanceRoleInfo{ //roles := &InstanceRoleInfo{
IDs: roleIDs, // IDs: roleIDs,
Names: strings.Split(v.RoleNames, "&&"), //Names: strings.Split(v.RoleNames, "&&"),
} //}
data.Role = roles data.RoleIDs = roleIDs
} }
list = append(list, data) list = append(list, data)
} }
@ -201,7 +207,7 @@ func (c *Instance) Index(name, mobile string, departmentIDs []uint64, status, pa
// Add 添加用户 // Add 添加用户
func (c *Instance) Add(params *InstanceForm) error { func (c *Instance) Add(params *InstanceForm) error {
if utils.ValidateMobile(params.Mobile) { if !utils.ValidateMobile(params.Mobile) {
return errors.New("操作错误,手机号码格式错误") return errors.New("操作错误,手机号码格式错误")
} }
mSysUser := model.NewSysUser() mSysUser := model.NewSysUser()
@ -213,15 +219,18 @@ func (c *Instance) Add(params *InstanceForm) error {
if err != nil { if err != nil {
return err return err
} else if count > 0 {
return errors.New("操作错误,当前手机号码已注册")
} }
return orm.GetDB().Transaction(func(tx *gorm.DB) error { return orm.GetDB().Transaction(func(tx *gorm.DB) error {
mSysUser.TenantID = c.TenantID mSysUser.TenantID = c.TenantID
mSysUser.Account = params.Account mSysUser.Account = params.Account
mSysUser.Name = params.Name mSysUser.Name = params.Name
mSysUser.Mobile = params.Mobile mSysUser.Mobile = params.Mobile
mSysUser.Email = params.Email
mSysUser.Gender.Gender = model2.GenderKind(params.Gender) mSysUser.Gender.Gender = model2.GenderKind(params.Gender)
mSysUser.Password = params.Password mSysUser.Password = params.Password
mSysUser.Status = model2.SysUserStatus(params.Status)
mSysUser.Remark = params.Remark mSysUser.Remark = params.Remark
if err = model2.Create(mSysUser.SysUser, tx); err != nil { if err = model2.Create(mSysUser.SysUser, tx); err != nil {
@ -250,7 +259,7 @@ func (c *Instance) Edit(params *InstanceForm) error {
return errors.New("操作错误,无权限操作") return errors.New("操作错误,无权限操作")
} }
if mSysUser.Mobile != params.Mobile { if mSysUser.Mobile != params.Mobile {
if utils.ValidateMobile(params.Mobile) { if !utils.ValidateMobile(params.Mobile) {
return errors.New("操作错误,手机号码格式错误") return errors.New("操作错误,手机号码格式错误")
} }
var count int64 var count int64
@ -263,8 +272,8 @@ func (c *Instance) Edit(params *InstanceForm) error {
} }
mSysUser.Mobile = params.Mobile mSysUser.Mobile = params.Mobile
} }
mSysUser.Account = params.Account
mSysUser.Name = params.Name mSysUser.Name = params.Name
mSysUser.Email = params.Email
mSysUser.Gender.Gender = model2.GenderKind(params.Gender) mSysUser.Gender.Gender = model2.GenderKind(params.Gender)
mSysUser.Remark = params.Remark mSysUser.Remark = params.Remark
@ -280,10 +289,11 @@ func (c *Instance) Edit(params *InstanceForm) error {
} }
func (c *Instance) Password(id uint64, password, repeatPwd string) error { func (c *Instance) Password(id uint64, password, repeatPwd string) error {
if password != repeatPwd { //if password != repeatPwd {
return errors.New("操作错误,两次密码输入不一致") // return errors.New("操作错误,两次密码输入不一致")
} //}
mSysUser := model.NewSysUser() mSysUser := model.NewSysUser()
mSysUser.ID = id
isExist, err := model2.FirstField(mSysUser.SysUser, []string{"id", "uuid", "is_admin"}) isExist, err := model2.FirstField(mSysUser.SysUser, []string{"id", "uuid", "is_admin"})

View File

@ -4,6 +4,7 @@ import (
"SciencesServer/app/common/model" "SciencesServer/app/common/model"
"SciencesServer/serve/orm" "SciencesServer/serve/orm"
"fmt" "fmt"
"strings"
) )
type SysMenu struct { type SysMenu struct {
@ -16,6 +17,10 @@ type SysMenuScene struct {
SceneID uint64 `json:"scene_id"` // 场景(租户,角色) SceneID uint64 `json:"scene_id"` // 场景(租户,角色)
} }
func (m *SysMenu) FilterAuth() string {
return "/" + strings.ReplaceAll(m.Auth, ":", "/")
}
// Recursion 递归查询子菜单 // Recursion 递归查询子菜单
func (m *SysMenu) Recursion(id uint64) { func (m *SysMenu) Recursion(id uint64) {
//SELECT //SELECT

View File

@ -38,7 +38,8 @@ func (m *SysUser) GetByAccountOrMobile(account string, tenantID uint64) (bool, e
db := orm.GetDB().Table(m.TableName()). db := orm.GetDB().Table(m.TableName()).
Select("id", "uuid", "tenant_id", "name", "mobile", "password", "salt", "is_admin", "status"). Select("id", "uuid", "tenant_id", "name", "mobile", "password", "salt", "is_admin", "status").
Where("tenant_id = ?", tenantID). Where("tenant_id = ?", tenantID).
Where("(account = ? OR mobile = ?)", account, account). //Where("(email = ? OR mobile = ?)", account, account).
Where("mobile = ?", account).
Where("is_deleted = ?", model.DeleteStatusForNot) Where("is_deleted = ?", model.DeleteStatusForNot)
if err := db.First(m.SysUser).Error; err != nil { if err := db.First(m.SysUser).Error; err != nil {
@ -50,6 +51,23 @@ func (m *SysUser) GetByAccountOrMobile(account string, tenantID uint64) (bool, e
return true, nil return true, nil
} }
func (m *SysUser) CheckByAccountOrMobile(account string, tenantID uint64) (bool, error) {
db := orm.GetDB().Table(m.TableName()).
Where("tenant_id = ?", tenantID).
Where("(account = ? OR mobile = ?)", account, account).
Where("is_deleted = ?", model.DeleteStatusForNot)
var count int64
if err := db.Count(&count).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return false, nil
}
return false, err
}
return true, nil
}
// Users 用户信息 // Users 用户信息
func (m *SysUser) Users(page, pageSize int, count *int64, where ...*model.ModelWhere) ([]*SysUserInfo, error) { func (m *SysUser) Users(page, pageSize int, count *int64, where ...*model.ModelWhere) ([]*SysUserInfo, error) {
db := orm.GetDB().Table(m.TableName()+" AS u"). db := orm.GetDB().Table(m.TableName()+" AS u").

View File

@ -48,8 +48,8 @@ func mysql() *gorm.DB {
orm.WithMaxOpenConns(2000), orm.WithMaxOpenConns(2000),
orm.WithMaxLifetime(1000), orm.WithMaxLifetime(1000),
orm.WithMysqlOption(&logic.Mysql{ orm.WithMysqlOption(&logic.Mysql{
User: "appuser", Password: "ABCabc01!", Host: "192.168.0.188", Port: 3306, Username: "appuser", Password: "ABCabc01!", Host: "192.168.0.188", Port: 3306,
DBName: "sciences", Parameters: "charset=utf8mb4,utf8&parseTime=True&loc=Local", Database: "sciences", Parameters: "charset=utf8mb4,utf8&parseTime=True&loc=Local",
}), }),
).Init() ).Init()
return instance.Engine return instance.Engine

View File

@ -6,7 +6,7 @@ type SysDepartment struct {
ModelTenant ModelTenant
ParentID uint64 `gorm:"column:parent_id;type:int;default:0;comment:父级ID" json:"-"` ParentID uint64 `gorm:"column:parent_id;type:int;default:0;comment:父级ID" json:"-"`
Name string `gorm:"column:name;type:varchar(20);default:'';comment:部门名称" json:"name"` Name string `gorm:"column:name;type:varchar(20);default:'';comment:部门名称" json:"name"`
Contact string `gorm:"column:contact_name;type:varchar(20);default:'';comment:联系人" json:"contact_name"` Contact string `gorm:"column:contact;type:varchar(20);default:'';comment:联系人" json:"contact"`
ContactMobile string `gorm:"column:contact_mobile;type:varchar(15);default:'';comment:联系方式" json:"contact_mobile"` ContactMobile string `gorm:"column:contact_mobile;type:varchar(15);default:'';comment:联系方式" json:"contact_mobile"`
Status int `gorm:"column:status;type:tinyint(1);default:1;comment:状态1正常2禁用" json:"status"` Status int `gorm:"column:status;type:tinyint(1);default:1;comment:状态1正常2禁用" json:"status"`
Remark string `gorm:"column:remark;type:varchar(255);default:'';comment:备注信息" json:"remark"` Remark string `gorm:"column:remark;type:varchar(255);default:'';comment:备注信息" json:"remark"`

View File

@ -3,7 +3,7 @@ package model
type SysMenu struct { type SysMenu struct {
Model Model
SysMenuBasic SysMenuBasic
Auth SysMenuAuth `gorm:"column:auth;type:tinyint(1);default:0;comment:查看权限0通用1超管" json:"-"` Auth string `gorm:"column:auth;type:varchar(100);default:'';comment:权限/路由" json:"auth"`
Sort int `gorm:"column:sort;type:tinyint(3);default:0;comment:排序,数值越大,优先排序" json:"sort"` Sort int `gorm:"column:sort;type:tinyint(3);default:0;comment:排序,数值越大,优先排序" json:"sort"`
Remark string `gorm:"column:remark;type:varchar(255);default:'';comment:菜单备注" json:"remark"` Remark string `gorm:"column:remark;type:varchar(255);default:'';comment:菜单备注" json:"remark"`
Status SysMenuStatus `gorm:"column:status;type:tinyint(1);default:1;comment:状态" json:"status"` Status SysMenuStatus `gorm:"column:status;type:tinyint(1);default:1;comment:状态" json:"status"`
@ -34,16 +34,6 @@ const (
SysMenuKindForEvent SysMenuKindForEvent
) )
// SysMenuAuth 菜单权限
type SysMenuAuth int
const (
// SysMenuAuthForOrdinary 普通权限
SysMenuAuthForOrdinary SysMenuAuth = iota
// SysMenuAuthForSystem 系统权限
SysMenuAuthForSystem
)
// SysMenuStatus 菜单状态 // SysMenuStatus 菜单状态
type SysMenuStatus int type SysMenuStatus int

View File

@ -2,7 +2,6 @@ package model
type SysRoleMenu struct { type SysRoleMenu struct {
Model Model
ModelTenant
RoleID uint64 `gorm:"column:role_id;type:int;default:0;comment:角色ID" json:"-"` RoleID uint64 `gorm:"column:role_id;type:int;default:0;comment:角色ID" json:"-"`
MenuID uint64 `gorm:"column:menu_id;type:int;default:0;comment:菜单ID" json:"-"` MenuID uint64 `gorm:"column:menu_id;type:int;default:0;comment:菜单ID" json:"-"`
ModelDeleted ModelDeleted

View File

@ -168,8 +168,28 @@ func (this *Permission) AddPolicies() (bool, error) {
return auth.enforcer.AddPolicies(rules) return auth.enforcer.AddPolicies(rules)
} }
// RemoveRolePolicy 删除角色的所有规则 // RemoveRolePolicies 删除角色指定规则
func (this *Permission) RemoveRolePolicy() (bool, error) { func (this *Permission) RemoveRolePolicies() (bool, error) {
if len(this.roles) <= 0 {
return false, errors.New("not role")
}
rules := make([][]string, 0)
tenantFormat := this.tenantFormat()
for _, v := range this.roleFormat() {
for _, request := range this.request {
rules = append(rules, []string{
v, tenantFormat, request.Url, request.Method,
})
}
}
return auth.enforcer.RemovePolicies(rules)
}
// RemoveSingleRolePolicy 删除角色的所有规则
func (this *Permission) RemoveSingleRolePolicy() (bool, error) {
if len(this.roles) <= 0 { if len(this.roles) <= 0 {
return false, errors.New("not role") return false, errors.New("not role")
} }

47
app/service/auth_test.go Normal file
View File

@ -0,0 +1,47 @@
package service
import (
"SciencesServer/app/common/model"
"SciencesServer/serve/orm"
"SciencesServer/serve/orm/logic"
"gorm.io/gorm"
"testing"
)
func mysql() *gorm.DB {
instance := orm.NewInstance(
orm.WithDebug(false),
orm.WithDBMode("mysql"),
orm.WithTablePrefix(""),
orm.WithSingularTable(false),
orm.WithMaxIdleConns(3600),
orm.WithMaxOpenConns(2000),
orm.WithMaxLifetime(1000),
orm.WithMysqlOption(&logic.Mysql{
Username: "appuser", Password: "ABCabc01", Host: "192.168.0.188", Port: 3306,
Database: "sciences", Parameters: "charset=utf8mb4,utf8&parseTime=True&loc=Local",
}),
).Init()
return instance.Engine
}
func TestNewPermission(t *testing.T) {
mysql := mysql()
NewAuth().Register()("mysql", mysql, model.NewSysAuthRule().TableName())
permission := NewPermission(
WithAuthTenant("0"),
WithAuthUser("123"),
WithAuthRoles([]string{"1", "2"}),
WithAuthRequest([]*AuthRequest{&AuthRequest{
Url: "/admin/123",
Method: "*",
}}),
)
//status, err := permission.AddPolicies()
//status, err := permission.AddRoleForUser()
//status, err := permission.RemoveRolePolicies()
status, err := permission.Enforce()
t.Log(status)
t.Log(err)
}

View File

@ -4,6 +4,6 @@ import "testing"
func TestSha256String(t *testing.T) { func TestSha256String(t *testing.T) {
//t.Log(Md5String("9f735e0df9a1ddc702bf0a1a7b83033f9f7153a00c29de82cedadc9957289b05")) //t.Log(Md5String("9f735e0df9a1ddc702bf0a1a7b83033f9f7153a00c29de82cedadc9957289b05"))
t.Log(HASHIDEncode(123)) t.Log(HASHIDEncode(2))
t.Log(HASHIDDecode("lV5OBJ")) t.Log(HASHIDDecode("lV5OBJ"))
} }