package postgres import ( "context" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/logger" "github.com/break/junhong_cmp_fiber/pkg/middleware" "go.uber.org/zap" "gorm.io/gorm" ) // DataPermissionScope 数据权限过滤 Scope // 根据 context 中的用户信息自动过滤数据 // - root 用户跳过过滤 // - 普通用户只能查看自己和下级的数据 // - 同时限制 shop_id 相同 func DataPermissionScope(ctx context.Context, accountStore *AccountStore) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { // 1. 检查是否为 root 用户,root 用户跳过数据权限过滤 if middleware.IsRootUser(ctx) { return db } // 2. 获取当前用户 ID userID := middleware.GetUserIDFromContext(ctx) if userID == 0 { // 未登录用户返回空结果 logger.GetAppLogger().Warn("数据权限过滤:未获取到用户 ID") return db.Where("1 = 0") } // 3. 获取当前用户的 shop_id shopID := middleware.GetShopIDFromContext(ctx) // 4. 获取当前用户及所有下级的 ID subordinateIDs, err := accountStore.GetSubordinateIDs(ctx, userID) if err != nil { // 查询失败时,降级为只能看自己的数据 logger.GetAppLogger().Error("数据权限过滤:获取下级 ID 失败", zap.Uint("user_id", userID), zap.Error(err)) subordinateIDs = []uint{userID} } // 5. 应用数据权限过滤条件 // owner_id IN (用户自己及所有下级) AND shop_id = 当前用户 shop_id if len(subordinateIDs) == 0 { subordinateIDs = []uint{userID} } // 根据是否有 shop_id 过滤条件决定 SQL if shopID != 0 { return db.Where("owner_id IN ? AND shop_id = ?", subordinateIDs, shopID) } // 如果 shop_id 为 0,只根据 owner_id 过滤 return db.Where("owner_id IN ?", subordinateIDs) } } // WithoutDataPermission 跳过数据权限过滤的 Scope // 用于需要查询所有数据的场景(如管理后台统计、系统任务等) func WithoutDataPermission() func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { // 什么都不做,直接返回原 db return db } } // SoftDeleteScope 软删除过滤 Scope(GORM 默认已支持,此处作为示例) // 只查询未软删除的记录 func SoftDeleteScope() func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { return db.Where("deleted_at IS NULL") } } // StatusEnabledScope 状态启用过滤 Scope // 只查询状态为启用的记录 func StatusEnabledScope() func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { return db.Where("status = ?", constants.StatusEnabled) } }