From 621e96ef003e6f92df19443936c7dd0aa985f0a2 Mon Sep 17 00:00:00 2001 From: Han Joker <540090808@qq.com> Date: Fri, 26 Jul 2024 16:01:18 +0800 Subject: [PATCH] role delete and restore --- handlers/role/handler.go | 128 +++++++++++++++++++++++++++++++++++++-- handlers/role/message.go | 26 ++++++++ handlers/role/router.go | 12 +++- models/base.go | 7 +++ models/role.go | 82 ++++++++++++++++++++++++- 5 files changed, 247 insertions(+), 8 deletions(-) diff --git a/handlers/role/handler.go b/handlers/role/handler.go index 6b306e6..45beba9 100644 --- a/handlers/role/handler.go +++ b/handlers/role/handler.go @@ -4,11 +4,85 @@ import ( "ginCms/models" "ginCms/utils" "github.com/gin-gonic/gin" - "log" "net/http" ) +func Restore(ctx *gin.Context) { + // 1. 解析请求数据 + req := RestoreReq{} + if err := ctx.ShouldBindQuery(&req); err != nil { + // 记录日志 + utils.Logger().Error(err.Error()) + // 直接响应 + ctx.JSON(http.StatusOK, gin.H{ + "code": 100, + "message": err.Error(), + }) + return + } + + // 2. 还原数据 + rowsNum, err := models.RoleRestore(req.IDList) + if err != nil { + // 记录日志 + utils.Logger().Error(err.Error()) + // 直接响应 + ctx.JSON(http.StatusOK, gin.H{ + "code": 100, + "message": "数据还原错误", + }) + return + } + + // 3. 响应 + ctx.JSON(http.StatusOK, gin.H{ + "code": 0, + "data": rowsNum, + }) +} + +func Delete(ctx *gin.Context) { + // 1. 解析请求数据 + req := DeleteReq{} + if err := ctx.ShouldBindQuery(&req); err != nil { + // 记录日志 + utils.Logger().Error(err.Error()) + // 直接响应 + ctx.JSON(http.StatusOK, gin.H{ + "code": 100, + "message": err.Error(), + }) + return + } + //log.Println(req) + + // 2. 删除数据 + rowsNum, err := models.RoleDelete(req.IDList) + if err != nil { + // 记录日志 + utils.Logger().Error(err.Error()) + // 直接响应 + ctx.JSON(http.StatusOK, gin.H{ + "code": 100, + "message": "数据删除错误", + }) + return + } + + // 3. 响应 + ctx.JSON(http.StatusOK, gin.H{ + "code": 0, + "data": rowsNum, + }) +} + +func Recycle(ctx *gin.Context) { + list(ctx, models.SCOPE_DELETED, false) +} func GetList(ctx *gin.Context) { + list(ctx, models.SCOPE_UNDELETED, true) +} +func list(ctx *gin.Context, scope uint8, assoc bool) { // 1. 解析请求消息 req := GetListReq{} if err := ctx.ShouldBindQuery(&req); err != nil { @@ -25,10 +99,8 @@ func GetList(ctx *gin.Context) { // 2. 整理请求参数 req.Clean() - log.Println(*req.Keyword, *req.SortField, *req.SortMethod, *req.PageNum, *req.PageSize) - // 3. 基于model查询 - rows, err := models.RoleFetchList(false, req.RoleFilter, req.Sorter, req.Pager) + rows, err := models.RoleFetchList(req.RoleFilter, req.Sorter, req.Pager, scope, assoc) if err != nil { // 记录日志 utils.Logger().Error(err.Error()) @@ -48,6 +120,52 @@ func GetList(ctx *gin.Context) { } +func Add(ctx *gin.Context) { + // 1. 解析请求数据 + req := AddReq{} + if err := ctx.ShouldBind(&req); err != nil { + // 记录日志 + utils.Logger().Error(err.Error()) + // 直接响应 + ctx.JSON(http.StatusOK, gin.H{ + "code": 100, + "message": err.Error(), + }) + return + } + + // 2. 利用模型完成插入 + role := req.ToRole() + if err := models.RoleInsert(role); err != nil { + // 记录日志 + utils.Logger().Error(err.Error()) + // 直接响应 + ctx.JSON(http.StatusOK, gin.H{ + "code": 100, + "message": "数据插入错误", + }) + return + } + + // 3. 响应 + // 往往需要重新查询一边,获取最新的role信息 + row, err := models.RoleFetch(role.ID, false) + if err != nil { + // 记录日志 + utils.Logger().Error(err.Error()) + // 直接响应 + ctx.JSON(http.StatusOK, gin.H{ + "code": 100, + "message": "查询错误", + }) + return + } + ctx.JSON(http.StatusOK, gin.H{ + "code": 100, + "data": row, + }) +} + func GetRow(ctx *gin.Context) { // 1. 解析请求数据(消息) req := GetRowReq{} @@ -63,7 +181,7 @@ func GetRow(ctx *gin.Context) { } // 2. 利用模型完成查询 - row, err := models.RoleFetchRow(false, "`id` = ?", req.ID) + row, err := models.RoleFetch(req.ID, false) if err != nil { // 记录日志 utils.Logger().Error(err.Error()) diff --git a/handlers/role/message.go b/handlers/role/message.go index 1718391..4a3a21d 100644 --- a/handlers/role/message.go +++ b/handlers/role/message.go @@ -4,6 +4,32 @@ import ( "ginCms/models" ) +// RestoreReq 还原的请求消息 +type RestoreReq struct { + IDList []uint `form:"id" binding:"gt=0"` +} + +// DeleteReq 删除的请求消息 +type DeleteReq struct { + IDList []uint `form:"id" binding:"gt=0"` +} + +// 添加请求消息 +type AddReq struct { + models.Role + // 需要额外校验的字段 + Title string `json:"title" binding:"required"` + Key string `json:"key" binding:"required"` +} + +// AddReq to Role +func (req AddReq) ToRole() *models.Role { + row := req.Role + row.Title = req.Title + row.Key = req.Key + return &row +} + // GetRowReq GetRow接口的请求消息类型 type GetRowReq struct { // required, 必须的 diff --git a/handlers/role/router.go b/handlers/role/router.go index eee92b1..414f0c1 100644 --- a/handlers/role/router.go +++ b/handlers/role/router.go @@ -4,6 +4,16 @@ import "github.com/gin-gonic/gin" func Router(r *gin.Engine) { g := r.Group("role") - g.GET("", GetRow) // GET /role?id=21 + // 查询一条 + g.GET("", GetRow) // GET /role?id=21 + // 查询多条 g.GET("list", GetList) // GET /role/list? + // 添加 + g.POST("", Add) // POST /role + // 删除 + g.DELETE("", Delete) // DELETE /role?id=22&id=33&id=44 + // 查询回收站 + g.GET("recycle", Recycle) // GET /role/recycle? + // 回收站还原 + g.PUT("restore", Restore) // PUT /role?id=22&id=33&id=44 } diff --git a/models/base.go b/models/base.go index 31bc374..23df732 100644 --- a/models/base.go +++ b/models/base.go @@ -12,6 +12,13 @@ type Model struct { DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` } +// 查询范围的常量 +const ( + SCOPE_ALL = iota + SCOPE_UNDELETED + SCOPE_DELETED +) + // 通用的查询列表排序类型 type Sorter struct { // 排序字段 diff --git a/models/role.go b/models/role.go index 34ce210..3672a96 100644 --- a/models/role.go +++ b/models/role.go @@ -3,6 +3,7 @@ package models import ( "fmt" "ginCms/utils" + "gorm.io/gorm" "strings" ) @@ -16,6 +17,66 @@ type Role struct { Comment string `gorm:"type:text" json:"comment"` } +// RoleRestore 还原 +func RoleRestore(idList []uint) (int64, error) { + // 还原的记录数 + rowsNum := int64(0) + err := utils.DB().Transaction(func(tx *gorm.DB) error { + result := tx.Model(&Role{}).Unscoped().Where("`id` IN ?", idList).Update("deleted_at", nil) + if result.Error != nil { + return result.Error + } else { + // 更新成功 + rowsNum = result.RowsAffected + } + return nil + }) + + return rowsNum, err +} + +// RoleDelete 角色删除 +// @return 删除的记录数,error +func RoleDelete(idList []uint) (int64, error) { + // 将delete操作在事务里完成,删除时,有时会涉及到关联数据的处理 + rowsNum := int64(0) + err := utils.DB().Transaction(func(tx *gorm.DB) error { + result := tx.Delete(&Role{}, idList) + if result.Error != nil { + return result.Error + } else { + // 删除成功 + rowsNum = result.RowsAffected + } + return nil + }) + + return rowsNum, err +} + +//func RoleDelete(idList []uint) error { +// // 将delete操作在事务里完成,删除时,有时会涉及到关联数据的处理 +// return utils.DB().Transaction(func(tx *gorm.DB) error { +// if err := tx.Delete(&Role{}, idList).Error; err != nil { +// return err +// } +// return nil +// }) +//} + +// 角色插入 +func RoleInsert(row *Role) error { + // 将insert操作在事务里完成,插入时,有时会涉及到关联数据的处理。 + // 数据及关联数据的插入,放在一个事务中 + return utils.DB().Transaction(func(tx *gorm.DB) error { + // 完成插入 + if err := tx.Create(&row).Error; err != nil { + return err + } + return nil + }) +} + // 通用的查询列表过滤类型 type RoleFilter struct { // 指针类型表示该字段可以不填 @@ -33,17 +94,30 @@ func (f *RoleFilter) Clean() { } // RoleFetchList 查询列表 -// @param assoc bool 是否查询关联 // @param filter RoleFilter 过滤参数 // @param sorter Sorter 排序参数 // @param pager Pager 翻页参数 +// @param scope uint8 范围参数 +// @param assoc bool 是否查询关联 // @return []*Role Role列表 // @return error -func RoleFetchList(assoc bool, filter RoleFilter, sorter Sorter, pager Pager) ([]*Role, error) { +func RoleFetchList(filter RoleFilter, sorter Sorter, pager Pager, scope uint8, assoc bool) ([]*Role, error) { // 初始化query query := utils.DB().Model(&Role{}) // 1. 过滤 + // 查询范围 + switch scope { + case SCOPE_ALL: + query.Unscoped() + case SCOPE_DELETED: + query.Unscoped().Where("`deleted_at` IS NOT NULL") + case SCOPE_UNDELETED: + fallthrough + default: + // do nothing. default case + } + // 条件过滤 if *filter.Keyword != "" { query.Where("`title` LIKE ?", "%"+*filter.Keyword+"%") } @@ -74,6 +148,10 @@ func RoleFetchList(assoc bool, filter RoleFilter, sorter Sorter, pager Pager) ([ return rows, nil } +func RoleFetch(id uint, assoc bool) (*Role, error) { + return RoleFetchRow(assoc, "`id` = ?", id) +} + // RoleFetchRow 根据条件查询单条 // assoc 是否查询管理数据 // where, args 查询条件