censor_bear 0.1.14 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8f5e80bfe3be4dc22e9c8fc14932f6c830a87efc0ee15d5588bd258f0311e0e
4
- data.tar.gz: bc47827fb4f09f2cd875d20db1c4593168917709b0174d0780237c503c156e5e
3
+ metadata.gz: 775cd9c238b951f9b9d5ce8564ae76e3e4b5d38fb3e9b71dc599d6a75bc04f5e
4
+ data.tar.gz: f8daa1001d2682697143aec92e6098d1e291d3c4d8cb7c9d28f60455fee7e6b4
5
5
  SHA512:
6
- metadata.gz: fc58e6353da8c5697b92f2c4857a7dcaa948a6e03c367d14aed8960b015c0809cc33094628efc1983f07865f270ae646bbf05c942dda7a58b425db54f3434f00
7
- data.tar.gz: d080b530b575ece289451d58079a40e3a85ad0f7721e8707cac299d141ea066047f5b36c13a9a5a7a133edf0e70707d28b85ea622ea4fe20f5309cc5be132462
6
+ metadata.gz: 3bd8ea39fb05994a01083fdaf574501657bf085238a1c9a24b883bddadf374a8a441f910a95594f7a42081d981a2800b9b2b02c9b3cc578e200536faa52ed4b8
7
+ data.tar.gz: 6ee79015b14bf37b4f070e041c91738d906bb3d1f8c39b215a94ccf6fbe89ccc0816a9d919e1436ee3689b3bb62bd9be2df1a025afbe1090e09ee9bf0be1022d
data/README.md CHANGED
@@ -50,10 +50,12 @@ rails censor_bear:install:migrations
50
50
 
51
51
  ## 🦆 Methods
52
52
  ```ruby
53
- censor_delete # 删除内容
53
+ censor_remove # 删除内容
54
+ censor_cancel # 撤销删除
54
55
  censor_approve # 通过审核
55
56
  censor_show_path # 详情路由
56
57
  censor_ban_user # 封禁用户
58
+
57
59
  ```
58
60
 
59
61
  ## Exceptions
@@ -63,6 +65,22 @@ censor_ban_user # 封禁用户
63
65
  class NotPassedException < StandardError; end
64
66
  ```
65
67
 
68
+ ## 初始化配置
69
+ 详细配置项可在`lib/censor_bear/configuration.rb`中查看。
70
+
71
+ ```ruby
72
+ CensorBear.configure do |config|
73
+ config.user_class = 'User'
74
+ config.user_name_method = 'nickname'
75
+
76
+ config.aliyun_green_access_key_id = 'access key id'
77
+ config.aliyun_green_access_key_secret = 'access key secret'
78
+ config.aliyun_green_enable_internal = false
79
+
80
+ config.main_app_root_path_method = 'root_path'
81
+ end
82
+ ```
83
+
66
84
  ## 注意事项
67
85
  1. 为 MOD 时,表示需要人工审核,需要被审查对象(UGC内容)支持`is_approved`字段(默认为`true`),此时内容自己能看到,别人暂时看不到,需审核通过后可见。
68
86
  2. 被审查对象可以通过软删实现,隐藏(目的是防止错判,撤销),删除的内容对自己和别人都是不可见的。
@@ -1,28 +1,23 @@
1
- require_dependency "censor_bear/application_controller"
1
+ require_dependency 'censor_bear/application_controller'
2
2
 
3
3
  module CensorBear
4
4
  class ModLogsController < ApplicationController
5
- before_action :set_mod_log, only: %i[show edit update destroy ignore approve ban delete]
5
+ before_action :set_mod_log, only: %i[show edit update destroy suspend ban pass undo reject]
6
6
 
7
- # GET /mod_logs
8
7
  def index
9
8
  load_mod_logs
10
9
  end
11
10
 
12
- # GET /mod_logs/1
13
11
  def show
14
12
  end
15
13
 
16
- # GET /mod_logs/new
17
14
  def new
18
15
  @mod_log = ModLog.new
19
16
  end
20
17
 
21
- # GET /mod_logs/1/edit
22
18
  def edit
23
19
  end
24
20
 
25
- # POST /mod_logs
26
21
  def create
27
22
  @mod_log = ModLog.new(mod_log_params)
28
23
 
@@ -33,7 +28,6 @@ module CensorBear
33
28
  end
34
29
  end
35
30
 
36
- # PATCH/PUT /mod_logs/1
37
31
  def update
38
32
  if @mod_log.update(mod_log_params)
39
33
  redirect_to @mod_log, notice: 'Mod log was successfully updated.'
@@ -42,7 +36,6 @@ module CensorBear
42
36
  end
43
37
  end
44
38
 
45
- # DELETE /mod_logs/1
46
39
  def destroy
47
40
  @mod_log.destroy
48
41
 
@@ -53,23 +46,29 @@ module CensorBear
53
46
  end
54
47
 
55
48
 
56
- def ignore
49
+ def suspend
57
50
  @mod_log.suspend!
58
51
 
59
52
  redirect_to mod_logs_url, notice: 'Mod log was successfully ignored.'
60
53
  end
61
54
 
62
- def delete
63
- # TODO: 判断参数不能为空
64
- @mod_log.delete(params[:reason])
55
+ def pass
56
+ @mod_log.approve
65
57
 
66
- redirect_to mod_logs_url, notice: 'Mod log was successfully deleted.'
58
+ redirect_to mod_logs_url, notice: 'Mod log was successfully ignored.'
67
59
  end
68
60
 
69
- def approve
70
- @mod_log.approve
61
+ def undo
62
+ # TODO: 判断状态,确定是撤销通过呢还是撤销删除
63
+ @mod_log.cancel
64
+
65
+ redirect_to mod_logs_url, notice: 'Mod log was successfully ignored.'
66
+ end
67
+
68
+ def reject
69
+ @mod_log.remove(params[:reason])
71
70
 
72
- redirect_to mod_logs_url, notice: 'Mod log was successfully approved.'
71
+ redirect_to mod_logs_url, notice: 'Mod log was successfully ignored.'
73
72
  end
74
73
 
75
74
  def ban
@@ -80,8 +79,11 @@ module CensorBear
80
79
 
81
80
  def load_mod_logs
82
81
  builder ||= mod_log_scope.includes(:record)
83
- builder = builder.where("content ilike ?", "%#{params[:q]}%") if params[:q].present?
84
-
82
+ builder = builder.where('content ilike ?', "%#{params[:q]}%") if params[:q].present?
83
+ if params[:filter] != 'all'
84
+ builder = builder.pending
85
+ builder = builder.unscope(where: :aasm_state).where(aasm_state: params[:state]) if params[:state].present?
86
+ end
85
87
  builder = builder.order(id: :desc)
86
88
 
87
89
  @pagy, @mod_logs = pagy(builder)
@@ -89,7 +91,6 @@ module CensorBear
89
91
 
90
92
  private
91
93
 
92
- # Use callbacks to share common setup or constraints between actions.
93
94
  def set_mod_log
94
95
  @mod_log = ModLog.find(params[:id] || params[:mod_log_id])
95
96
  end
@@ -98,7 +99,6 @@ module CensorBear
98
99
  ModLog
99
100
  end
100
101
 
101
- # Only allow a list of trusted parameters through.
102
102
  def mod_log_params
103
103
  params.require(:mod_log).permit(:record_id, :record_type, :mod_words, :user_id, :reason)
104
104
  end
@@ -1,6 +1,8 @@
1
1
  module CensorBear
2
2
  class ModLog < ApplicationRecord
3
- REASONS = %w(无 广告/SPAM 恶意灌水 违规内容 文不对题 重复发布 其它)
3
+ include AASM
4
+
5
+ REASONS = %w(无 广告/SPAM 恶意灌水 违规内容 文不对题 重复发布 其它).freeze
4
6
  belongs_to :record, polymorphic: true, required: false
5
7
 
6
8
  def record_path
@@ -9,14 +11,14 @@ module CensorBear
9
11
  record.censor_show_path
10
12
  end
11
13
 
12
- def delete(reason)
14
+ def remove(reason)
13
15
  return if record.blank?
14
16
  return if record.discarded?
15
17
  # ugc内容需要开软删,便于撤销&查看统计,可以定时删除统计并删除软删内容,类似回收站机制
16
- raise NoMethodError.new("undefined censor_delete for record") unless record.respond_to?(:censor_delete)
18
+ raise NoMethodError, 'undefined censor_remove for record' unless record.respond_to?(:censor_remove)
17
19
 
18
- ret = record.censor_delete
19
- handled!(reason) if ret
20
+ ret = record.censor_remove
21
+ reject!(reason) if ret
20
22
  end
21
23
 
22
24
  def approve
@@ -24,7 +26,15 @@ module CensorBear
24
26
  raise NoMethodError unless record.respond_to?(:censor_approve)
25
27
 
26
28
  ret = record.censor_approve
27
- handled! if ret
29
+ pass! if ret
30
+ end
31
+
32
+ def cancel
33
+ return if record.blank?
34
+ raise NoMethodError unless record.respond_to?(:censor_cancel)
35
+
36
+ ret = record.censor_cancel
37
+ undo! if ret
28
38
  end
29
39
 
30
40
  def ban_user
@@ -32,23 +42,36 @@ module CensorBear
32
42
  raise NoMethodError unless record.respond_to?(:censor_ban_user)
33
43
 
34
44
  ret = record.censor_ban_user
35
- delete if ret
45
+ reject!('已被封禁该用户') if ret
36
46
  end
37
47
 
38
- scope :pending, -> { where(status: 0) }
39
- scope :handled, -> { where(status: 1) }
40
- scope :suspended, -> { where(status: 2) }
48
+ aasm do
49
+ state :pending, initial: true
50
+ state :rejected, :passed, :suspended
51
+
52
+ event :reject do
53
+ transitions from: %i[pending suspended], to: :rejected, after: Proc.new {|*args| set_reason(*args) }
54
+ end
55
+
56
+ event :pass do
57
+ transitions from: %i[pending suspended], to: :passed
58
+ end
59
+
60
+ event :suspend do
61
+ transitions from: :pending, to: :suspended, after: :unset_reason
62
+ end
41
63
 
42
- def handled!(reason = nil)
43
- update_columns(status: 1, reason: reason)
64
+ event :undo do
65
+ transitions from: %i[passed rejected], to: :pending, after: :unset_reason
66
+ end
44
67
  end
45
68
 
46
- def pend!
47
- update_columns(status: 0)
69
+ def unset_reason
70
+ update_columns(reason: nil)
48
71
  end
49
72
 
50
- def suspend!
51
- update_columns(status: 2)
73
+ def set_reason(reason)
74
+ update_columns(reason: reason)
52
75
  end
53
76
  end
54
77
  end
@@ -2,44 +2,49 @@
2
2
  %div{class: "flex flex-col"}
3
3
  %div{class: "border rounded-md mb-2 p-2 flex flex-col space-y-1"}
4
4
  %div{class: "flex justify-between"}
5
- %div{class: ""}
5
+ %div{class: "text-sm"}
6
6
  = link_to mod_log.record_path, data: { turbo: false }, target: "_blank" do
7
- %span{class: "text-sm bg-indigo-100 text-indigo-600 py-1 px-2 rounded-lg"}="#{mod_log.record_type.upcase}##{mod_log.record_id}"
8
- - unless mod_log.labels.blank?
9
- - mod_log.labels.each do |label|
10
- %span{class: "text-sm bg-red-100 text-red-600 py-1 px-2 rounded-lg"}=t("censor_log.label.#{label}")
11
- - unless mod_log.mod_words.blank?
12
- - mod_log.mod_words.each do |word|
13
- %span{class: "text-sm bg-yellow-100 text-yellow-600 py-1 px-2 rounded-lg"}="##{word}"
14
- %span{class: "text-sm bg-gray-100 text-gray-600 py-1 px-2 rounded-lg"}= mod_log.created_at
15
- %div{class: "flex space-x-2 items-center"}
7
+ %span{class: "bg-indigo-100 text-indigo-600 py-1 px-2 rounded-lg"}="#{mod_log.record_type.upcase}##{mod_log.record_id}"
8
+ %span{class: "bg-yellow-100 text-yellow-600 rounded-md p-1"}=t("censor_log.aasm_state.#{mod_log.aasm_state}")
9
+ %div{class: "flex space-x-2 items-center text-sm"}
16
10
  - if mod_log.reason
17
11
  %span{class: "bg-red-100 text-red-600 p-1 rounded-lg"}
18
12
  = mod_log.reason
19
- %span{class: "bg-green-100 text-green-600 rounded-md p-1"}
20
- - if mod_log.status == 0
21
- = "待审"
22
- - if mod_log.status == 1
23
- = "已处理"
24
- - if mod_log.status == 2
25
- = "暂缓"
26
- %span
27
- = link_to "详情", mod_log, data: { turbo: false }, target: "_blank"
28
- %span
29
- = button_to '删除', mod_log, method: :delete, data: { confirm: 'Are you sure?'}, class: "text-red-600 rounded-md px-2 py-0.5"
30
- %div{class: "flex justify-between items-center"}
31
- %div{class: "flex flex-col"}
32
- %div{class: "text-sm border rounded-lg border-black p-2"}
33
- %div= mod_log.content
34
- %div
35
- %div{class: "flex space-x-2"}
36
- %span{class: "text-yellow-600"}
37
- = link_to "忽略", mod_log_ignore_path(mod_log)
38
- %span{class: "text-green-600"}
39
- = link_to "通过", mod_log_approve_path(mod_log)
40
- %div
41
- = form_with(url: mod_log_delete_path(mod_log), method: :get, class: "space-x-1 flex items-center") do |f|
42
- = f.submit "删除", class: "rounded-md px-2 py-1 text-sm bg-red-600 text-white cursor-pointer"
43
- = f.text_field :reason, value: mod_log.reason, placeholder: "不通过原因", class: "border rounded-md m py-0.5 px-1"
44
- -#%span{class: "text-red-600 font-bold"}
45
- -# = link_to "封禁用户!", mod_log_ban_path(mod_log)
13
+ %span{class: "bg-gray-100 text-gray-600 py-1 px-2 rounded-lg"}= mod_log.created_at
14
+ - if current_user.admin?
15
+ = button_to '删除', mod_log, method: :delete, data: { confirm: 'Are you sure?'}, class: "bg-red-600 text-white rounded-md px-2 py-0.5 cursor-pointer"
16
+ %div{class: "flex justify-between items-center py-2 w-full"}
17
+ %div{class: "flex flex-col rounded-lg bg-gray-50 p-3 text-sm space-y-4 w-full"}
18
+ -unless mod_log.record
19
+ %h3{class: "text-2xl text-red-600"} 对应条目已被永久删除,当前审核请求已无效,请删除
20
+ - else
21
+ %div
22
+ %span{class: "border border-pink-600 text-pink-600 rounded-lg text-xs p-0.5"}=mod_log.record.is_private ? "隐私" : "公开"
23
+ %span{class: "border border-blue-600 text-blue-600 rounded-lg text-xs p-0.5"}=mod_log.record.is_approved ? "审核通过" : "审核中..."
24
+ - if mod_log.record.discarded?
25
+ %div{class: "text-gray-900 leading-relaxed"}
26
+ %del= mod_log.record.content
27
+ - else
28
+ %div{class: "text-gray-900 leading-relaxed"}= mod_log.record.content
29
+ %div
30
+ - mod_log.record.pictures.each do |pic|
31
+ = image_tag pic.full_url, class: "w-16 rounded-md"
32
+ %div
33
+ - unless mod_log.labels.blank?
34
+ - mod_log.labels.each do |label|
35
+ %span{class: "text-xs bg-gray-200 text-gray-600 py-0.5 px-1 rounded-lg"}=t("censor_log.label.#{label}")
36
+ - unless mod_log.mod_words.blank?
37
+ - mod_log.mod_words.each do |word|
38
+ %span{class: "text-sm bg-gray-100 text-gray-600 py-0.5 px-1 rounded-lg"}="##{word}"
39
+ %div{class: "flex space-x-2 items-center justify-end"}
40
+ - if mod_log.may_suspend?
41
+ = link_to "忽略", mod_log_suspend_path(mod_log), class: "text-yellow-600 cursor-pointer"
42
+ - if mod_log.may_pass?
43
+ = link_to "通过", mod_log_pass_path(mod_log), class: "text-green-600 cursor-pointer"
44
+ - if mod_log.may_undo?
45
+ = link_to "撤销", mod_log_undo_path(mod_log), class: "text-red-600 cursor-pointer"
46
+ - if mod_log.may_reject?
47
+ = form_with(url: mod_log_reject_path(mod_log), method: :get, class: "space-x-1 flex items-center") do |f|
48
+ = f.submit "拒绝", class: "text-red-600 bg-transparent cursor-pointer"
49
+ = f.text_field :reason, value: mod_log.reason, placeholder: "不通过原因", class: "border rounded-md m py-0.5 px-1 text-sm"
50
+
@@ -6,8 +6,18 @@
6
6
  = f.text_field :q, value: params[:q], placeholder: "关键词", class: "border rounded-md m py-0.5 px-1"
7
7
  = f.submit "检索", class: "rounded-md px-2 py-1 text-sm bg-black text-white cursor-pointer"
8
8
  = link_to "重置", mod_logs_path, class: "text-sm"
9
-
10
- %div{class: "text-sm text-gray-600"}="共 #{@pagy.count} 条"
9
+ %div{class: "flex items-center space-x-2"}
10
+ %div{class: "text-sm text-gray-600"}="共 #{@pagy.count} 条"
11
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:filter] == "all" ? 'font-bold' : ''}"}
12
+ = link_to "全部", request.params.merge(filter: "all", state: "")
13
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:state].blank? && params[:filter].blank? ? 'font-bold' : ''}"}
14
+ = link_to "待处理", request.params.merge(state: "", filter: "")
15
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:state] == 'rejected' ? 'font-bold' : ''}"}
16
+ = link_to "被驳回", request.params.merge(state: "rejected", filter: "")
17
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:state] == 'passed' ? 'font-bold' : ''}"}
18
+ = link_to "通过", request.params.merge(state: "passed", filter: "")
19
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:state] == 'suspended' ? 'font-bold' : ''}"}
20
+ = link_to "暂缓处理", request.params.merge(state: "suspended", filter: "")
11
21
  %div
12
22
  - if @mod_logs.blank?
13
23
  %div{class: "flex justify-center text-gray-500 p-8 border rounded-md"} 空空如也
@@ -8,6 +8,10 @@ en:
8
8
  block: 禁用
9
9
  pass: 忽略
10
10
  review: 审核
11
+ aasm_state:
12
+ pending: 待审
13
+ handled: 已处理
14
+ suspended: 暂缓处理
11
15
  stage:
12
16
  check_search: 搜索检查
13
17
  aliyun_check: 阿里云检查
data/config/routes.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  CensorBear::Engine.routes.draw do
2
2
  resources :mod_logs do
3
- get :ignore
4
- get :approve
5
- get :delete
3
+ get :suspend
4
+ get :reject
5
+ get :pass
6
+ get :undo
6
7
  get :ban
7
8
  end
8
9
  resources :logs
@@ -0,0 +1,5 @@
1
+ class AddAasmStateToCensorBearModLogs < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :censor_bear_mod_logs, :aasm_state, :string
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module CensorBear
2
- VERSION = '0.1.14'.freeze
2
+ VERSION = '0.1.15'.freeze
3
3
  end
data/lib/censor_bear.rb CHANGED
@@ -3,6 +3,7 @@ require 'censor_bear/engine'
3
3
  require 'censor_bear/censor'
4
4
  require 'censor_bear/configuration'
5
5
 
6
+ require 'aasm'
6
7
  require 'hamlit'
7
8
  require 'pagy'
8
9
  require 'aliyun_green'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: censor_bear
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.14
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - 42up
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 6.0.4.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: aasm
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: aliyun_green
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -169,6 +183,7 @@ files:
169
183
  - db/migrate/20211206092626_add_ip_to_censor_bear_logs.rb
170
184
  - db/migrate/20211208041114_add_labels_to_censor_bear_logs.rb
171
185
  - db/migrate/20211209093050_add_response_to_censor_bear_logs.rb
186
+ - db/migrate/20211209113710_add_aasm_state_to_censor_bear_mod_logs.rb
172
187
  - lib/censor_bear.rb
173
188
  - lib/censor_bear/censor.rb
174
189
  - lib/censor_bear/configuration.rb