diff --git a/Gemfile b/Gemfile index 28df2328c..ac2778c59 100644 --- a/Gemfile +++ b/Gemfile @@ -96,3 +96,5 @@ gem 'searchkick' gem 'aasm' gem 'enumerize' + +gem 'diffy' diff --git a/Gemfile.lock b/Gemfile.lock index 6a4a7e08f..aabf3ffba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -98,6 +98,7 @@ GEM connection_pool (2.2.2) crass (1.0.4) diff-lcs (1.3) + diffy (3.3.0) elasticsearch (7.2.0) elasticsearch-api (= 7.2.0) elasticsearch-transport (= 7.2.0) @@ -368,6 +369,7 @@ DEPENDENCIES byebug capybara (>= 2.15, < 4.0) chromedriver-helper + diffy enumerize faraday (~> 0.15.4) font-awesome-sass (= 4.7.0) diff --git a/app/controllers/admins/carousels_controller.rb b/app/controllers/admins/carousels_controller.rb index 67518174c..cd693d2fd 100644 --- a/app/controllers/admins/carousels_controller.rb +++ b/app/controllers/admins/carousels_controller.rb @@ -77,4 +77,4 @@ class Admins::CarouselsController < Admins::BaseController rescue Base64ImageConverter::Error => ex render_error(ex.message) end -end \ No newline at end of file +end diff --git a/app/jobs/create_diff_record_job.rb b/app/jobs/create_diff_record_job.rb new file mode 100644 index 000000000..fbe8cbff2 --- /dev/null +++ b/app/jobs/create_diff_record_job.rb @@ -0,0 +1,12 @@ +class CreateDiffRecordJob < ApplicationJob + queue_as :default + + def perform(user_id, obj_id, obj_klass, column_name, before, after) + user = User.find_by(id: user_id) + obj = obj_klass.constantize.find_by(id: obj_id) + + return if user.blank? || obj.blank? + + CreateDiffRecordService.call(user, obj, column_name, before, after) + end +end \ No newline at end of file diff --git a/app/models/challenge.rb b/app/models/challenge.rb index 455fd1b6a..da88b0fca 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -28,6 +28,8 @@ class Challenge < ApplicationRecord scope :fields_for_list, -> { select([:id, :subject, :st, :score, :position, :shixun_id]) } + after_commit :create_diff_record + def next_challenge position = self.position + 1 Challenge.where(:position => position, :shixun_id => self.shixun).first @@ -126,4 +128,11 @@ class Challenge < ApplicationRecord end # 关卡评测文件 + + private + + def create_diff_record + return unless task_pass_previously_changed? + CreateDiffRecordJob.perform_later(User.current.id, id, 'Challenge', 'task_pass', task_pass_before_last_save, task_pass) + end end diff --git a/app/models/diff_record.rb b/app/models/diff_record.rb new file mode 100644 index 000000000..afbb9dd9c --- /dev/null +++ b/app/models/diff_record.rb @@ -0,0 +1,8 @@ +class DiffRecord < ApplicationRecord + belongs_to :user + belongs_to :container, polymorphic: true + + has_one :diff_record_content, dependent: :destroy + + delegate :content, to: :diff_record_content +end \ No newline at end of file diff --git a/app/models/diff_record_content.rb b/app/models/diff_record_content.rb new file mode 100644 index 000000000..ce5e1d354 --- /dev/null +++ b/app/models/diff_record_content.rb @@ -0,0 +1,3 @@ +class DiffRecordContent < ApplicationRecord + belongs_to :diff_record +end \ No newline at end of file diff --git a/app/models/shixun_info.rb b/app/models/shixun_info.rb index 542e0222d..74a49412e 100644 --- a/app/models/shixun_info.rb +++ b/app/models/shixun_info.rb @@ -2,4 +2,13 @@ class ShixunInfo < ApplicationRecord belongs_to :shixun validates_uniqueness_of :shixun_id validates_presence_of :shixun_id + + after_commit :create_diff_record + + private + + def create_diff_record + return unless description_previously_changed? + CreateDiffRecordJob.perform_later(User.current.id, id, 'ShixunInfo', 'description', description_before_last_save, description) + end end diff --git a/app/services/create_diff_record_service.rb b/app/services/create_diff_record_service.rb new file mode 100644 index 000000000..87f3d0b24 --- /dev/null +++ b/app/services/create_diff_record_service.rb @@ -0,0 +1,30 @@ +class CreateDiffRecordService < ApplicationService + attr_reader :user, :obj, :column_name, :after, :before + + def initialize(user, obj, column_name, before, after) + @user = user + @obj = obj + @before = before + @after = after + @column_name = column_name + end + + def call + ActiveRecord::Base.transaction do + diff_record = DiffRecord.create!(user: user, container: obj, column_name: column_name) + diff_record.create_diff_record_content!(content: diff_content) + end + end + + private + + def diff_content + content = '' + Diffy::Diff.new(before, after).each do |line| + next unless line =~ /^[\+-]/ + + content += line + end + content + end +end \ No newline at end of file diff --git a/db/migrate/20190930032241_create_diff_records.rb b/db/migrate/20190930032241_create_diff_records.rb new file mode 100644 index 000000000..3e02e0a2b --- /dev/null +++ b/db/migrate/20190930032241_create_diff_records.rb @@ -0,0 +1,11 @@ +class CreateDiffRecords < ActiveRecord::Migration[5.2] + def change + create_table :diff_records do |t| + t.references :user + t.references :container, polymorphic: true + t.string :column_name + + t.timestamps + end + end +end diff --git a/db/migrate/20190930032255_create_diff_record_contents.rb b/db/migrate/20190930032255_create_diff_record_contents.rb new file mode 100644 index 000000000..f3d56b8b2 --- /dev/null +++ b/db/migrate/20190930032255_create_diff_record_contents.rb @@ -0,0 +1,9 @@ +class CreateDiffRecordContents < ActiveRecord::Migration[5.2] + def change + create_table :diff_record_contents do |t| + t.references :diff_record + + t.text :content + end + end +end