无法在 Discourse 3.5.0.beta5-dev 的 Rails 控制台中批量暂停/停用用户

大家好,

我正在尝试通过 Rails 控制台批量暂停/停用我的 Discourse 实例(版本 3.5.0.beta5-dev)上的用户,但遇到了一个持续存在的问题。 我试图排除我的管理员帐户 (hoangthai,用户 ID 100),并以自定义理由“Chưa gia hạn tài khoản”(帐户续订待定)永久暂停所有其他活跃的非管理员/非版主用户。

我已经尝试了几种基于常用 Discourse 控制台命令和调试建议的方法,但即使 suspended_atsuspended_till 可能会被设置,帐户仍然 active: true

以下是我尝试过的方法以及错误/结果的细分:

我的目标: 永久暂停所有用户(除了 hoangthai,ID 100),理由是“Chưa gia hạn tài khoản”(帐户续订待定)。

尝试与问题:

  1. 初始尝试(直接设置 suspend_reasonsuspended_atsuspended_till):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active? && !user.admin? && !user.moderator?
        user.suspend_reason = "Tài khoản tạm khóa do nghỉ phép dài hạn." # 第一次尝试的原因
        user.suspended_at = Time.current
        user.suspended_till = Time.current + 100.years
        user.save!
        puts "Khóa tài khoản: #{user.username}"
      end
    end
    
    • 结果: NoMethodError: undefined method 'suspend_reason=' for an instance of User(建议使用 suspended_at=)。 这表明 suspend_reason 不是正确的属性。
  2. 第二次尝试(使用为较新版本建议的 UserSuspension.suspend_user):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active? && !user.admin? && !user.moderator?
        UserSuspension.suspend_user(
            user,
            Time.current + 100.years,
            nil, # suspend_reason_id
            "Tài khoản tạm khóa: Nghỉ phép dài hạn。", # custom_suspend_reason
            Discourse.system_user
        )
        puts "Đã khóa tài khoản: #{user.username}"
      end
    end
    
    • 结果: NameError: uninitialized constant UserSuspension(建议使用 UserSuspender)。 这表明类名不正确。
  3. 第三次尝试(将类名更正为 UserSuspender):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active? && !user.admin? && !user.moderator?
        UserSuspender.suspend_user( # 仍在尝试 suspend_user
            user,
            Time.current + 100.years,
            nil,
            "Tài khoản tạm khóa: Nghỉ phép dài hạn。",
            Discourse.system_user
        )
        puts "Đã khóa tài khoản: #{user.username}"
      end
    end
    
    • 结果: NoMethodError: undefined method 'suspend_user' for class UserSuspender(建议使用 UserSuspended?)。 这表明方法名也不正确。
  4. 第四次尝试(使用 UserSuspender.new(...).suspend 作为服务对象模式):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active?  !user.admin?  !user.moderator?
        begin
            UserSuspender.new(
                user,
                Discourse.system_user,
                reason: "帐户临时锁定:长期休假。",
                suspended_till: nil # For permanent suspension
            ).suspend
            puts "已锁定帐户:#{user.username}"
        rescue => e
            puts "锁定帐户 #{user.username} 时出错:#{e.message}"
        end
      end
    end
    
    • 结果: 此命令在控制台中没有错误地运行。 它打印了“Đã khóa tài khoản: [username]”。
    • 但是,当在管理用户界面中检查用户状态或直接在控制台中查询 user.active 时,用户仍然显示 active: true。 只有 suspended_atsuspended_till 被更新(例如,suspended_at: "2025-05-26 00:37:01.406064419 +0000", suspended_till: nil)。 这些帐户仍然能够登录。
  5. 第五次尝试(直接设置 active = false 以及停权字段):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active?  !user.admin?  !user.moderator?
        begin
            user.suspended_at = Time.current
            user.suspended_till = nil # Permanent
            user.custom_suspension_reason = "Chưa gia hạn tài khoản" # Custom reason
            user.active = false # Crucial part
            user.save!
            puts "已**永久锁定**和停用帐户:#{user.username}"
        rescue => e
            puts "处理帐户 #{user.username} 时出现**错误**:#{e.message}"
        end
      end
    end
    
    • 结果: 此命令也没有错误地运行,并打印了成功消息。
    • 但是,结果相同: active: true 保持不变,并且 suspended_at/suspended_till 已更新,但帐户实际上被禁用……
1 个赞

我不认为停用是用户暂停流程的一部分。在用户界面中,如果您希望已暂停并重新登录的用户重新验证其电子邮件,则需要单独按下“停用”按钮。

决定您是否需要这样做,并将其作为一项单独的操作来处理,可能会取得更好的结果。:crossed_fingers:

如果这对您有帮助,此主题中有一些关于批量暂停的指南:Administrative Bulk Operations

不过,如果您尝试这样做并发现它已过时,请告知他们,他们应该能够相应地更新指南。

1 个赞