feat: complete Kra admin backend migration
This commit is contained in:
+209
-10
@@ -409,17 +409,101 @@ func menuFromPO(po menuPO) *biz.Menu {
|
||||
func menuToPO(v *biz.Menu) menuPO {
|
||||
return menuPO{ID: v.ID, ParentID: v.ParentID, Path: v.Path, Name: v.Name, Hidden: v.Hidden, Component: v.Component, Sort: v.Sort, ActiveName: v.ActiveName, KeepAlive: v.KeepAlive, DefaultMenu: v.DefaultMenu, Title: v.Title, Icon: v.Icon, CloseTab: v.CloseTab, TransitionType: v.TransitionType}
|
||||
}
|
||||
func (r *accessRepo) CreateMenu(ctx context.Context, v *biz.Menu) error {
|
||||
po := menuToPO(v)
|
||||
if err := r.data.gormDB.WithContext(ctx).Create(&po).Error; err != nil {
|
||||
func replaceMenuRelations(tx *gorm.DB, menu *biz.Menu) error {
|
||||
var oldButtonIDs []uint
|
||||
if err := tx.Model(&menuButtonPO{}).Where("sys_base_menu_id = ?", menu.ID).Pluck("id", &oldButtonIDs).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
v.ID = po.ID
|
||||
if len(oldButtonIDs) > 0 {
|
||||
if err := tx.Where("sys_base_menu_btn_id IN ?", oldButtonIDs).Delete(&authorityButtonPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tx.Where("sys_base_menu_id = ?", menu.ID).Delete(&menuButtonPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("sys_base_menu_id = ?", menu.ID).Delete(&menuParameterPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
buttons := make([]menuButtonPO, 0, len(menu.Buttons))
|
||||
for _, button := range menu.Buttons {
|
||||
buttons = append(buttons, menuButtonPO{Name: button.Name, Description: button.Description, MenuID: menu.ID})
|
||||
}
|
||||
if len(buttons) > 0 {
|
||||
if err := tx.Create(&buttons).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
parameters := make([]menuParameterPO, 0, len(menu.Parameters))
|
||||
for _, parameter := range menu.Parameters {
|
||||
parameters = append(parameters, menuParameterPO{MenuID: menu.ID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
}
|
||||
if len(parameters) > 0 {
|
||||
return tx.Create(¶meters).Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (r *accessRepo) CreateMenu(ctx context.Context, v *biz.Menu) error {
|
||||
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var count int64
|
||||
if err := tx.Model(&menuPO{}).Where("name = ?", v.Name).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("存在重复name,请修改name")
|
||||
}
|
||||
if v.ParentID != 0 {
|
||||
var parent menuPO
|
||||
if err := tx.First(&parent, v.ParentID).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("父菜单不存在")
|
||||
}
|
||||
return err
|
||||
}
|
||||
if err := tx.Model(&menuPO{}).Where("parent_id = ?", v.ParentID).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
if err := tx.Model(&authorityPO{}).Where("default_router = ?", parent.Name).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("父菜单已被其他角色的首页占用,请先释放父菜单的首页权限")
|
||||
}
|
||||
if err := tx.Where("sys_base_menu_id = ?", v.ParentID).Delete(&authorityMenuPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
po := menuToPO(v)
|
||||
if err := tx.Create(&po).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
v.ID = po.ID
|
||||
return replaceMenuRelations(tx, v)
|
||||
})
|
||||
}
|
||||
func (r *accessRepo) UpdateMenu(ctx context.Context, v *biz.Menu) error {
|
||||
po := menuToPO(v)
|
||||
return r.data.gormDB.WithContext(ctx).Model(&menuPO{}).Where("id = ?", v.ID).Updates(&po).Error
|
||||
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var old menuPO
|
||||
if err := tx.First(&old, v.ID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
var count int64
|
||||
if old.Name != v.Name {
|
||||
if err := tx.Model(&menuPO{}).Where("id <> ? AND name = ?", v.ID, v.Name).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("存在相同name修改失败")
|
||||
}
|
||||
}
|
||||
if err := replaceMenuRelations(tx, v); err != nil {
|
||||
return err
|
||||
}
|
||||
values := map[string]any{"parent_id": v.ParentID, "path": v.Path, "name": v.Name, "hidden": v.Hidden, "component": v.Component, "sort": v.Sort, "active_name": v.ActiveName, "keep_alive": v.KeepAlive, "default_menu": v.DefaultMenu, "title": v.Title, "icon": v.Icon, "close_tab": v.CloseTab, "transition_type": v.TransitionType}
|
||||
return tx.Model(&old).Updates(values).Error
|
||||
})
|
||||
}
|
||||
func (r *accessRepo) DeleteMenu(ctx context.Context, id uint) error {
|
||||
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
@@ -430,6 +514,29 @@ func (r *accessRepo) DeleteMenu(ctx context.Context, id uint) error {
|
||||
if count > 0 {
|
||||
return errors.New("此菜单存在子菜单不可删除")
|
||||
}
|
||||
var menu menuPO
|
||||
if err := tx.First(&menu, id).Error; err != nil {
|
||||
return errors.New("记录不存在")
|
||||
}
|
||||
if err := tx.Model(&authorityPO{}).Where("default_router = ?", menu.Name).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("此菜单有角色正在作为首页,不可删除")
|
||||
}
|
||||
var buttonIDs []uint
|
||||
if err := tx.Model(&menuButtonPO{}).Where("sys_base_menu_id = ?", id).Pluck("id", &buttonIDs).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("sys_menu_id = ?", id).Delete(&authorityButtonPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("sys_base_menu_id = ?", id).Delete(&menuButtonPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("sys_base_menu_id = ?", id).Delete(&menuParameterPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("sys_base_menu_id = ?", id).Delete(&authorityMenuPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -441,7 +548,22 @@ func (r *accessRepo) FindMenu(ctx context.Context, id uint) (*biz.Menu, error) {
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&po, id).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return menuFromPO(po), nil
|
||||
menu := menuFromPO(po)
|
||||
if err := r.loadMenuParameters(ctx, menu); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return menu, nil
|
||||
}
|
||||
func (r *accessRepo) loadMenuParameters(ctx context.Context, menu *biz.Menu) error {
|
||||
var pos []menuParameterPO
|
||||
if err := r.data.gormDB.WithContext(ctx).Where("sys_base_menu_id = ?", menu.ID).Order("id").Find(&pos).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
menu.Parameters = make([]*biz.MenuParameter, 0, len(pos))
|
||||
for _, po := range pos {
|
||||
menu.Parameters = append(menu.Parameters, &biz.MenuParameter{ID: po.ID, MenuID: po.MenuID, Type: po.Type, Key: po.Key, Value: po.Value})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (r *accessRepo) ListMenus(ctx context.Context) ([]*biz.Menu, error) {
|
||||
var pos []menuPO
|
||||
@@ -450,7 +572,11 @@ func (r *accessRepo) ListMenus(ctx context.Context) ([]*biz.Menu, error) {
|
||||
}
|
||||
out := make([]*biz.Menu, 0, len(pos))
|
||||
for _, po := range pos {
|
||||
out = append(out, menuFromPO(po))
|
||||
menu := menuFromPO(po)
|
||||
if err := r.loadMenuParameters(ctx, menu); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, menu)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -760,6 +886,9 @@ func (r *accessRepo) CreateDepartment(ctx context.Context, v *biz.Department) er
|
||||
return r.data.gormDB.WithContext(ctx).Create(&departmentPO{Name: v.Name, ParentID: v.ParentID, Ancestors: v.Ancestors, Sort: v.Sort, LeaderID: v.LeaderID, Status: v.Status}).Error
|
||||
}
|
||||
func (r *accessRepo) UpdateDepartment(ctx context.Context, v *biz.Department) error {
|
||||
if v.ParentID == v.ID {
|
||||
return errors.New("父部门不能是自己")
|
||||
}
|
||||
v.Ancestors = "0"
|
||||
if v.ParentID != 0 {
|
||||
var parent departmentPO
|
||||
@@ -771,12 +900,27 @@ func (r *accessRepo) UpdateDepartment(ctx context.Context, v *biz.Department) er
|
||||
return r.data.gormDB.WithContext(ctx).Model(&departmentPO{}).Where("id = ?", v.ID).Updates(map[string]any{"name": v.Name, "parent_id": v.ParentID, "ancestors": v.Ancestors, "sort": v.Sort, "leader_id": v.LeaderID, "status": v.Status}).Error
|
||||
}
|
||||
func (r *accessRepo) DeleteDepartment(ctx context.Context, id uint) error {
|
||||
if id == 0 {
|
||||
return errors.New("部门ID不能为空")
|
||||
}
|
||||
var count int64
|
||||
if err := r.data.gormDB.WithContext(ctx).Model(&departmentPO{}).Where("parent_id = ?", id).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("部门存在子部门")
|
||||
return errors.New("存在子部门,不允许删除")
|
||||
}
|
||||
if err := r.data.gormDB.WithContext(ctx).Model(&userPO{}).Where("dept_id = ?", id).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("该部门下存在用户,不允许删除")
|
||||
}
|
||||
if err := r.data.gormDB.WithContext(ctx).Model(&userDepartmentPO{}).Where("sys_department_id = ?", id).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("该部门下存在用户,不允许删除")
|
||||
}
|
||||
return r.data.gormDB.WithContext(ctx).Delete(&departmentPO{}, id).Error
|
||||
}
|
||||
@@ -820,7 +964,14 @@ func (r *accessRepo) SetDepartmentUsers(ctx context.Context, id uint, ids []uint
|
||||
return r.replaceUserDepartments(ctx, id, ids)
|
||||
}
|
||||
func (r *accessRepo) replaceUserDepartments(ctx context.Context, id uint, ids []uint) error {
|
||||
if id == 0 {
|
||||
return errors.New("部门ID不能为空")
|
||||
}
|
||||
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var current []uint
|
||||
if err := tx.Model(&userDepartmentPO{}).Where("sys_department_id = ?", id).Pluck("sys_user_id", ¤t).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("sys_department_id = ?", id).Delete(&userDepartmentPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -829,13 +980,39 @@ func (r *accessRepo) replaceUserDepartments(ctx context.Context, id uint, ids []
|
||||
links = append(links, userDepartmentPO{UserID: uid, DepartmentID: id})
|
||||
}
|
||||
if len(links) > 0 {
|
||||
return tx.Create(&links).Error
|
||||
if err := tx.Create(&links).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
target := make(map[uint]struct{}, len(ids))
|
||||
for _, uid := range ids {
|
||||
target[uid] = struct{}{}
|
||||
}
|
||||
removed := make([]uint, 0)
|
||||
for _, uid := range current {
|
||||
if _, ok := target[uid]; !ok {
|
||||
removed = append(removed, uid)
|
||||
}
|
||||
}
|
||||
if len(removed) > 0 {
|
||||
if err := tx.Model(&userPO{}).Where("dept_id = ? AND id IN ?", id, removed).Update("dept_id", 0).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(ids) > 0 {
|
||||
if err := tx.Model(&userPO{}).Where("dept_id = ? AND id IN ?", 0, ids).Update("dept_id", id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
func (r *accessRepo) SetUserDepartments(ctx context.Context, uid uint, ids []uint, primary uint) error {
|
||||
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var user userPO
|
||||
if err := tx.First(&user, uid).Error; err != nil {
|
||||
return errors.New("查询用户数据失败")
|
||||
}
|
||||
if err := tx.Where("sys_user_id = ?", uid).Delete(&userDepartmentPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -851,6 +1028,18 @@ func (r *accessRepo) SetUserDepartments(ctx context.Context, uid uint, ids []uin
|
||||
if primary == 0 && len(ids) > 0 {
|
||||
primary = ids[0]
|
||||
}
|
||||
if primary != 0 {
|
||||
inSet := false
|
||||
for _, id := range ids {
|
||||
if id == primary {
|
||||
inSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !inSet {
|
||||
return errors.New("主部门必须在归属部门范围内")
|
||||
}
|
||||
}
|
||||
return tx.Model(&userPO{}).Where("id = ?", uid).Update("dept_id", primary).Error
|
||||
})
|
||||
}
|
||||
@@ -865,6 +1054,16 @@ func (r *accessRepo) UpdatePosition(ctx context.Context, v *biz.Position) error
|
||||
return r.data.gormDB.WithContext(ctx).Model(&positionPO{}).Where("id = ?", v.ID).Updates(map[string]any{"name": v.Name, "code": v.Code, "sort": v.Sort, "status": v.Status, "remark": v.Remark}).Error
|
||||
}
|
||||
func (r *accessRepo) DeletePosition(ctx context.Context, id uint) error {
|
||||
if id == 0 {
|
||||
return errors.New("岗位ID不能为空")
|
||||
}
|
||||
var count int64
|
||||
if err := r.data.gormDB.WithContext(ctx).Model(&userPositionPO{}).Where("sys_position_id = ?", id).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("该岗位下存在用户,不允许删除")
|
||||
}
|
||||
return r.data.gormDB.WithContext(ctx).Delete(&positionPO{}, id).Error
|
||||
}
|
||||
func (r *accessRepo) FindPosition(ctx context.Context, id uint) (*biz.Position, error) {
|
||||
|
||||
Reference in New Issue
Block a user