✨ 新增保存菜单接口
This commit is contained in:
parent
13b121be3c
commit
1d1ca21815
24
api/admin/menu/save.go
Normal file
24
api/admin/menu/save.go
Normal file
@ -0,0 +1,24 @@
|
||||
package menu
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
menuParam "wechat-robot/model/param/menu"
|
||||
"wechat-robot/pkg/response"
|
||||
"wechat-robot/service/menu"
|
||||
)
|
||||
|
||||
// Save
|
||||
// @description: 保存菜单
|
||||
// @param ctx
|
||||
func Save(ctx *gin.Context) {
|
||||
var p menuParam.Save
|
||||
if err := ctx.ShouldBind(&p); err != nil {
|
||||
response.New(ctx).SetError(err).Fail()
|
||||
return
|
||||
}
|
||||
if err := menu.Save(p); err != nil {
|
||||
response.New(ctx).SetError(err).Fail()
|
||||
return
|
||||
}
|
||||
response.New(ctx).Success()
|
||||
}
|
148
internal/orm/sort.go
Normal file
148
internal/orm/sort.go
Normal file
@ -0,0 +1,148 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitee.ltd/lxh/logger/log"
|
||||
"gorm.io/gorm"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// @title checkHasDeletedAt
|
||||
// @description 检查指定表是否有id_del字段
|
||||
// @param tx *gorm.DB "已开启的事务对象"
|
||||
// @param tableName string "表名"
|
||||
// @return bool "是否包含"
|
||||
func checkHasDeletedAt(tx *gorm.DB, tableName string) bool {
|
||||
var columns []string
|
||||
// SQL语句
|
||||
sql := fmt.Sprintf("select COLUMN_NAME from information_schema.COLUMNS where table_name = '%s'", tableName)
|
||||
err := tx.Raw(sql).Scan(&columns).Error
|
||||
if err != nil {
|
||||
log.Errorf("查询表字段失败: %v", err.Error())
|
||||
return false
|
||||
}
|
||||
return slices.Contains(columns, "id_del")
|
||||
}
|
||||
|
||||
// @title checkHasUpdatedAt
|
||||
// @description 检查指定表是否有updated_at字段
|
||||
// @param tx *gorm.DB "已开启的事务对象"
|
||||
// @param tableName string "表名"
|
||||
// @return bool "是否包含"
|
||||
func checkHasUpdatedAt(tx *gorm.DB, tableName string) bool {
|
||||
var columns []string
|
||||
// SQL语句
|
||||
sql := fmt.Sprintf("select COLUMN_NAME from information_schema.COLUMNS where table_name = '%s'", tableName)
|
||||
err := tx.Raw(sql).Scan(&columns).Error
|
||||
if err != nil {
|
||||
log.Errorf("查询表字段失败: %v", err.Error())
|
||||
return false
|
||||
}
|
||||
return slices.Contains(columns, "updated_at")
|
||||
}
|
||||
|
||||
// UpdateSortBefore
|
||||
// @description 更新之前处理序号
|
||||
// @param tx *gorm.DB "已开启的事务对象"
|
||||
// @param model any "模型对象"
|
||||
// @return error "错误信息"
|
||||
func UpdateSortBefore(tx *gorm.DB, tableName, id string, sort int, param string) (err error) {
|
||||
// 查出原来的排序号
|
||||
var oldSort int
|
||||
err = tx.Table(tableName).Select("`sort`").Where("id = ?", id).Scan(&oldSort).Error
|
||||
if err != nil {
|
||||
log.Errorf("查询老数据失败: %v", err.Error())
|
||||
return
|
||||
}
|
||||
// 如果相等,啥都不干
|
||||
if oldSort == sort {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 查询是否包含 id_del 字段
|
||||
hasDeletedAt := checkHasDeletedAt(tx, tableName)
|
||||
|
||||
// 处理排序
|
||||
// 如果老的排序号小于新的,(老, 新]之间的排序号都要-1
|
||||
// 如果老的大于新的,[老, 新)排序号-1
|
||||
if oldSort < sort {
|
||||
// 老的小于新的,[老, 新) + 1
|
||||
sel := tx.Table(tableName).
|
||||
Where("sort <= ? AND sort > ?", sort, oldSort)
|
||||
if hasDeletedAt {
|
||||
sel.Where("id_del = 0")
|
||||
}
|
||||
if param != "" {
|
||||
sel.Where(param) // 自定义条件
|
||||
}
|
||||
err = sel.Update("sort", gorm.Expr("sort - 1")).Error
|
||||
} else {
|
||||
// 老的大于新的,[新, 老) + 1
|
||||
sel := tx.Table(tableName).
|
||||
Where("sort >= ? AND sort < ?", sort, oldSort)
|
||||
if hasDeletedAt {
|
||||
sel.Where("id_del = 0")
|
||||
}
|
||||
if param != "" {
|
||||
sel.Where(param) // 自定义条件
|
||||
}
|
||||
err = sel.Update("sort", gorm.Expr("sort + 1")).Error
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// CreateSortBefore
|
||||
// @description 新建之前处理序号
|
||||
// @param tx *gorm.DB "已开启的事务对象"
|
||||
// @param model any "模型对象"
|
||||
// @return error "错误信息"
|
||||
func CreateSortBefore(tx *gorm.DB, tableName string, sort int, param string) (err error) {
|
||||
// 查询是否包含 id_del 字段
|
||||
hasDeletedAt := checkHasDeletedAt(tx, tableName)
|
||||
|
||||
// 处理排序,如果没有传,就会是在最前面
|
||||
sel := tx.Table(tableName).Where("sort >= ?", sort)
|
||||
if hasDeletedAt {
|
||||
sel.Where("id_del = 0")
|
||||
}
|
||||
if param != "" {
|
||||
sel.Where(param)
|
||||
}
|
||||
err = sel.Update("sort", gorm.Expr("sort + 1")).Error
|
||||
if err != nil {
|
||||
log.Errorf("处理前置排序失败:%v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DealSortAfter
|
||||
// @description 处理序号之后
|
||||
// @param tx *gorm.DB "已开启的事务对象"
|
||||
// @param modelName string "表名"
|
||||
// @return error "错误信息"
|
||||
func DealSortAfter(tx *gorm.DB, modelName, param string) (err error) {
|
||||
// 保存成功,刷新排序
|
||||
if param != "" {
|
||||
param = " AND " + param
|
||||
}
|
||||
|
||||
// 查询是否包含 id_del 字段
|
||||
hasDeletedAt := checkHasDeletedAt(tx, modelName)
|
||||
if hasDeletedAt {
|
||||
param += " AND id_del = 0"
|
||||
}
|
||||
|
||||
// 如果有更新时间字段,也更新一下值
|
||||
updateParam := ""
|
||||
if checkHasUpdatedAt(tx, modelName) {
|
||||
updateParam = ",updated_at = NOW()"
|
||||
}
|
||||
|
||||
sql := fmt.Sprintf("UPDATE %s a, (SELECT (@i := @i + 1) i, id FROM %s WHERE 1=1 %s order by sort ASC) i, "+
|
||||
"(SELECT @i := 0) ir SET a.sort = i.i %s WHERE a.id = i.id", modelName, modelName, param, updateParam)
|
||||
err = tx.Exec(sql).Error
|
||||
if err != nil {
|
||||
log.Errorf("刷新排序失败: %v", err.Error())
|
||||
}
|
||||
return
|
||||
}
|
16
model/param/menu/save.go
Normal file
16
model/param/menu/save.go
Normal file
@ -0,0 +1,16 @@
|
||||
package menu
|
||||
|
||||
import "wechat-robot/pkg/types"
|
||||
|
||||
// Save
|
||||
// @description: 保存菜单入参
|
||||
type Save struct {
|
||||
Id string `json:"id" form:"id" comment:"菜单Id"`
|
||||
Type types.MenuType `json:"type" form:"type" comment:"菜单类型(菜单或按钮)" validate:"oneof=MENU BUTTON"`
|
||||
Name string `json:"name" form:"name" comment:"页面组件名称"`
|
||||
Path string `json:"path" form:"path" comment:"访问路径"`
|
||||
Title string `json:"title" form:"title" comment:"菜单标题"`
|
||||
Icon string `json:"icon" form:"icon" comment:"菜单图标"`
|
||||
Sort int `json:"sort" form:"sort" comment:"排序值(数字越小越靠前)"`
|
||||
ParentId string `json:"parentId" form:"parentId" comment:"父级菜单ID"`
|
||||
}
|
@ -9,5 +9,6 @@ import (
|
||||
// @description: 菜单相关
|
||||
// @param g
|
||||
func menu(g *gin.RouterGroup) {
|
||||
g.GET("/self", menuApi.GetUserMenuTree)
|
||||
g.GET("/self", menuApi.GetUserMenuTree) // 获取当前用户菜单
|
||||
g.POST("", menuApi.Save) // 保存菜单
|
||||
}
|
||||
|
77
service/menu/save.go
Normal file
77
service/menu/save.go
Normal file
@ -0,0 +1,77 @@
|
||||
package menu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"wechat-robot/internal/database"
|
||||
"wechat-robot/internal/orm"
|
||||
"wechat-robot/model/entity"
|
||||
menuParam "wechat-robot/model/param/menu"
|
||||
)
|
||||
|
||||
// Save
|
||||
// @description: 保存菜单
|
||||
// @param param menuParam.Save 菜单数据
|
||||
// @return err error 错误信息
|
||||
func Save(param menuParam.Save) (err error) {
|
||||
tx := database.Client.Begin()
|
||||
defer func() {
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
}()
|
||||
|
||||
// 提前梳理出参数
|
||||
paramSql := "parent_id IS NULL"
|
||||
if param.ParentId != "" {
|
||||
paramSql = fmt.Sprintf("parent_id = '%s'", param.ParentId)
|
||||
}
|
||||
|
||||
if param.Id == "" {
|
||||
// 新增
|
||||
var m entity.Menu
|
||||
// 预处理排序
|
||||
if err = orm.CreateSortBefore(tx, m.TableName(), param.Sort, paramSql); err != nil {
|
||||
return
|
||||
}
|
||||
// 组装参数
|
||||
m.Type = param.Type
|
||||
m.Name = param.Name
|
||||
m.Path = param.Path
|
||||
m.Title = param.Title
|
||||
m.Icon = param.Icon
|
||||
m.Sort = param.Sort
|
||||
if param.ParentId != "" {
|
||||
m.ParentId = ¶m.ParentId
|
||||
}
|
||||
err = tx.Create(&m).Error
|
||||
} else {
|
||||
// 修改
|
||||
// 预处理排序
|
||||
if err = orm.UpdateSortBefore(tx, entity.Menu{}.TableName(), param.Id, param.Sort, paramSql); err != nil {
|
||||
return
|
||||
}
|
||||
// 组装参数
|
||||
var m = make(map[string]any)
|
||||
m["type"] = param.Type
|
||||
m["name"] = param.Name
|
||||
m["path"] = param.Path
|
||||
m["title"] = param.Title
|
||||
m["icon"] = param.Icon
|
||||
m["sort"] = param.Sort
|
||||
if param.ParentId != "" {
|
||||
m["parent_id"] = ¶m.ParentId
|
||||
}
|
||||
err = tx.Model(&entity.Menu{}).Where("id = ?", param.Id).Updates(m).Error
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 处理排序
|
||||
err = orm.DealSortAfter(tx, entity.Menu{}.TableName(), paramSql)
|
||||
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue
Block a user