mirror of
https://github.com/go-admin-team/go-admin.git
synced 2026-09-29 12:31:11 +00:00
WithContextDb and the five CRUD actions passed the *gin.Context itself to GORM as the query's context. database/sql watches the context of a query that returns rows inside a transaction from a goroutine of its own, which can still read it after the handler returns - and gin hands that Context to the next request as soon as the handler returns. GORM wraps every write in a transaction, and an INSERT on SQLite or PostgreSQL returns the new key as a row, so any write raced with the next request's reset. The race detector reports it on the second of two sequential requests. They now pass c.Request.Context(), which belongs to one request only and is cancelled when its client goes away.
62 lines
1.5 KiB
Go
62 lines
1.5 KiB
Go
package actions
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/go-admin-team/go-admin-core/v2/jwtauth/user"
|
|
log "github.com/go-admin-team/go-admin-core/v2/logger"
|
|
"github.com/go-admin-team/go-admin-core/v2/response"
|
|
"github.com/go-admin-team/go-admin-core/v2/sdk/pkg"
|
|
|
|
"go-admin/common/dto"
|
|
"go-admin/common/models"
|
|
)
|
|
|
|
// DeleteAction 通用删除动作
|
|
func DeleteAction(control dto.Control) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
db, err := pkg.GetOrm(c)
|
|
if err != nil {
|
|
log.Error(err)
|
|
return
|
|
}
|
|
|
|
msgID := pkg.GenerateMsgIDFromContext(c)
|
|
//删除操作
|
|
req := control.Generate()
|
|
err = req.Bind(c)
|
|
if err != nil {
|
|
log.Errorf("MsgID[%s] Bind error: %s", msgID, err)
|
|
response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
|
|
return
|
|
}
|
|
var object models.ActiveRecord
|
|
object, err = req.GenerateM()
|
|
if err != nil {
|
|
response.Error(c, 500, err, "模型生成失败")
|
|
return
|
|
}
|
|
|
|
object.SetUpdateBy(user.GetUserId(c))
|
|
|
|
//数据权限检查
|
|
p := GetPermissionFromContext(c)
|
|
|
|
db = db.WithContext(c.Request.Context()).Scopes(
|
|
Permission(object.TableName(), p),
|
|
).Where(req.GetId()).Delete(object)
|
|
if err = db.Error; err != nil {
|
|
log.Errorf("MsgID[%s] Delete error: %s", msgID, err)
|
|
response.Error(c, 500, err, "删除失败")
|
|
return
|
|
}
|
|
if db.RowsAffected == 0 {
|
|
response.Error(c, http.StatusForbidden, nil, "无权删除该数据")
|
|
return
|
|
}
|
|
response.OK(c, object.GetId(), "删除成功")
|
|
c.Next()
|
|
}
|
|
}
|