全局软删除
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 4m21s

This commit is contained in:
2026-01-21 14:37:02 +08:00
parent 2291f7740d
commit 3b1fd91709

View File

@@ -44,6 +44,10 @@ type ShopStoreInterface interface {
// 5. 个人客户只能查看自己的数据(基于 creator 字段或 customer_id 字段) // 5. 个人客户只能查看自己的数据(基于 creator 字段或 customer_id 字段)
// 6. 通过 SkipDataPermission(ctx) 可以绕过权限过滤 // 6. 通过 SkipDataPermission(ctx) 可以绕过权限过滤
// //
// 软删除过滤规则:
// 1. 所有查询自动排除 deleted_at IS NOT NULL 的记录
// 2. 使用 db.Unscoped() 可以查询包含已删除的记录
//
// 注意: // 注意:
// - Callback 根据表的字段自动选择过滤策略 // - Callback 根据表的字段自动选择过滤策略
// - 必须在初始化 Store 之前注册 // - 必须在初始化 Store 之前注册
@@ -62,6 +66,12 @@ func RegisterDataPermissionCallback(db *gorm.DB, shopStore ShopStoreInterface) e
return return
} }
// 0. 软删除过滤(优先处理,确保所有查询都过滤已删除记录)
// 检查表是否有 deleted_at 字段,且未使用 Unscoped()
if hasDeletedAtField(tx.Statement.Schema) && !tx.Statement.Unscoped {
tx.Where("deleted_at IS NULL")
}
// 1. 检查是否跳过数据权限过滤 // 1. 检查是否跳过数据权限过滤
if skip, ok := ctx.Value(SkipDataPermissionKey).(bool); ok && skip { if skip, ok := ctx.Value(SkipDataPermissionKey).(bool); ok && skip {
return return
@@ -281,3 +291,12 @@ func hasCustomerIDField(s *schema.Schema) bool {
_, ok := s.FieldsByDBName["customer_id"] _, ok := s.FieldsByDBName["customer_id"]
return ok return ok
} }
// hasDeletedAtField 检查 Schema 是否包含 deleted_at 字段
func hasDeletedAtField(s *schema.Schema) bool {
if s == nil {
return false
}
_, ok := s.FieldsByDBName["deleted_at"]
return ok
}