Compare commits

...

2 Commits

Author SHA1 Message Date
Han Joker 621e96ef00 role delete and restore
2 months ago
Han Joker 676fa16ae2 role get
2 months ago

@ -0,0 +1 @@
package common

@ -1,6 +1,7 @@
package handlers
import (
"ginCms/handlers/role"
"ginCms/handlers/system"
"github.com/gin-gonic/gin"
)
@ -12,6 +13,7 @@ func InitEngine() *gin.Engine {
// 2. 注册不同模块的路由
system.Router(r)
role.Router(r)
return r
}

@ -0,0 +1,201 @@
package role
import (
"ginCms/models"
"ginCms/utils"
"github.com/gin-gonic/gin"
"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 {
// 记录日志
utils.Logger().Error(err.Error())
// 直接响应
ctx.JSON(http.StatusOK, gin.H{
"code": 100,
"message": err.Error(),
})
return
}
// 2. 整理请求参数
req.Clean()
// 3. 基于model查询
rows, err := models.RoleFetchList(req.RoleFilter, req.Sorter, req.Pager, scope, assoc)
if err != nil {
// 记录日志
utils.Logger().Error(err.Error())
// 直接响应
ctx.JSON(http.StatusOK, gin.H{
"code": 100,
"message": "查询错误",
})
return
}
// 4. 响应
ctx.JSON(http.StatusOK, gin.H{
"code": 0,
"data": rows,
})
}
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{}
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. 利用模型完成查询
row, err := models.RoleFetch(req.ID, false)
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": row,
})
}

@ -0,0 +1,55 @@
package role
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, 必须的
// gt, 数值 > 0
ID uint `form:"id" binding:"required,gt=0"`
}
// GetListReq GetList请求参数类型
type GetListReq struct {
// 过滤
models.RoleFilter
// 排序
models.Sorter
// 翻页
models.Pager
}
// Clean 查询列表参数清理
func (req *GetListReq) Clean() {
req.RoleFilter.Clean()
req.Sorter.Clean()
req.Pager.Clean()
}

@ -0,0 +1,19 @@
package role
import "github.com/gin-gonic/gin"
func Router(r *gin.Engine) {
g := r.Group("role")
// 查询一条
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
}

@ -11,3 +11,64 @@ type Model struct {
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
// 查询范围的常量
const (
SCOPE_ALL = iota
SCOPE_UNDELETED
SCOPE_DELETED
)
// 通用的查询列表排序类型
type Sorter struct {
// 排序字段
SortField *string `form:"sortField" binding:"omitempty,gt=0"`
// 排序方式 asc,desc
// oneof多个选项之一
SortMethod *string `form:"sortMethod" binding:"omitempty,oneof=asc desc"`
}
// 通用的查询列表翻页类型
type Pager struct {
// 页码索引
PageNum *int `form:"pageNum" binding:"omitempty,gt=0"`
// 每页记录数
PageSize *int `form:"pageSize" binding:"omitempty,gt=0"`
}
const (
PageNumDefault = 1
PageSizeDefault = 10
PageSizeMax = 100
SortFieldDefault = "id"
SortMethodDefault = "DESC"
)
// Clean 整理Sorter
func (s *Sorter) Clean() {
if s.SortField == nil {
temp := SortFieldDefault
s.SortField = &temp
}
if s.SortMethod == nil {
temp := SortMethodDefault
s.SortMethod = &temp
}
}
// Clean 整理Pager
func (p *Pager) Clean() {
if p.PageNum == nil || *p.PageNum == 0 {
temp := PageNumDefault
p.PageNum = &temp
}
if p.PageSize == nil {
temp := PageSizeDefault
p.PageSize = &temp
}
if *p.PageSize > PageSizeMax {
temp := PageSizeMax
p.PageSize = &temp
}
}

@ -1,6 +1,11 @@
package models
import "ginCms/utils"
import (
"fmt"
"ginCms/utils"
"gorm.io/gorm"
"strings"
)
// Role 角色模型
type Role struct {
@ -12,6 +17,158 @@ 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 {
// 指针类型表示该字段可以不填
// omitempty, 非零值才校验
// gt, 字符串长度>0
Keyword *string `form:"keyword" binding:"omitempty,gt=0"`
}
// Clean 整理Filter
func (f *RoleFilter) Clean() {
if f.Keyword == nil {
temp := ""
f.Keyword = &temp
}
}
// RoleFetchList 查询列表
// @param filter RoleFilter 过滤参数
// @param sorter Sorter 排序参数
// @param pager Pager 翻页参数
// @param scope uint8 范围参数
// @param assoc bool 是否查询关联
// @return []*Role Role列表
// @return 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+"%")
}
// 其他字段过滤
// 2. 排序
query.Order(fmt.Sprintf("`%s` %s", *sorter.SortField, strings.ToUpper(*sorter.SortMethod)))
// 3. 翻页 offset limit
// 在pagesize>0时才进行翻页
if *pager.PageSize > 0 {
// 偏移 ==(当前页码 - 1 乘以 每页记录数
offset := (*pager.PageNum - 1) * *pager.PageSize
query.Offset(offset).Limit(*pager.PageSize)
}
// 4. 查询
var rows []*Role
if err := query.Find(&rows).Error; err != nil {
return nil, err
}
// 5. 关联查询
if assoc {
}
// 返回
return rows, nil
}
func RoleFetch(id uint, assoc bool) (*Role, error) {
return RoleFetchRow(assoc, "`id` = ?", id)
}
// RoleFetchRow 根据条件查询单条
// assoc 是否查询管理数据
// where, args 查询条件
func RoleFetchRow(assoc bool, where any, args ...any) (*Role, error) {
// 查询本条
row := &Role{}
if err := utils.DB().Where(where, args...).First(&row).Error; err != nil {
return nil, err
}
// 关联查询
if assoc {
}
return row, nil
}
// 填充数据
func roleSeed() {
// 构建数据

Loading…
Cancel
Save