yslnewtiku
cxt 5 years ago
parent 02b6646bd2
commit c564e68a97

@ -1,6 +1,8 @@
class ItemBanksController < ApplicationController
include PaginateHelper
before_action :require_login
before_action :find_item, except: [:index, :create]
before_action :edit_auth, only: [:update, :destroy, :set_public]
def index
items = ItemBankQuery.call(params)
@ -10,12 +12,46 @@ class ItemBanksController < ApplicationController
def create
item = ItemBank.new(user: current_user)
ItemBank::SaveItemService.call(item, form_params)
ItemBanks::SaveItemService.call(item, form_params)
render_ok
rescue ApplicationService::Error => ex
render_error(ex.message)
end
def edit
end
def update
ItemBanks::SaveItemService.call(@item, form_params)
render_ok
rescue ApplicationService::Error => ex
render_error(ex.message)
end
def destroy
@item.destroy!
render_ok
end
def set_public
tip_exception(-1, "该试题已公开") if @item.public?
@item.update_attributes!(public: 1)
render_ok
end
private
def find_item
@item = ItemBank.find_by!(id: params[:id])
end
def edit_auth
current_user.admin_or_business? || @item.user == current_user
end
def form_params
params.permit(:repertoire_id, :sub_repertoire_id, :item_type, :difficulty, :name, tag_repertoire_id: [], choices: [])
params.permit(:repertoire_id, :sub_repertoire_id, :item_type, :difficulty, :name, :analysis, tag_repertoire_id: [], choices: %i[choice_text is_answer])
end
end

@ -0,0 +1,30 @@
class ItemBasketsController < ApplicationController
before_action :require_login
def index
end
def create
ItemBaskets::SaveItemBasketService.call(current_user, create_params)
end
def destroy
item = current_user.item_baskets.find_by!(item_bank_id: params[:id])
ActiveRecord::Base.transaction do
current_user.item_baskets.where("item_type = #{item.item_type} and position > #{item.position}").update_all("position = position -1")
item.destroy!
end
render_ok
end
def delete_item_type
# tip_exception() unless
end
private
def create_params
params.permit(item_ids: [])
end
end

@ -1,13 +1,33 @@
class ItemBank::SaveItemForm
class ItemBanks::SaveItemForm
include ActiveModel::Model
attr_accessor :repertoire_id, :sub_repertoire_id, :item_type, :difficulty, :name, :tag_repertoire_id, :choices
attr_accessor :repertoire_id, :sub_repertoire_id, :item_type, :difficulty, :name, :analysis, :tag_repertoire_id, :choices
validates :repertoire_id, presence: true
validates :sub_repertoire_id, presence: true
validates :item_type, presence: true
validates :difficulty, presence: true
validates :name, presence: true
validates :item_type, presence: true, inclusion: {in: 0..6}, numericality: { only_integer: true }
validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true }
validates :name, presence: true, length: { maximum: 1000 }
validates :analysis, length: { maximum: 1000 }
def validate!
super
return unless errors.blank?
choices.each { |item| SubForm.new(item).validate! } if item_type < 3
return unless errors.blank?
if [0, 2].include?(item_type) && choices.pluck(:is_answer).select{|item| item == 1}.length > 1
raise("正确答案只能有一个")
elsif item_type == 1 && choices.pluck(:is_answer).select{|item| item == 1}.length <= 1
raise("多选题至少有两个正确答案")
end
end
class SubForm
include ActiveModel::Model
attr_accessor :choice_text, :is_answer
validates :choice_text, presence: true, length: { maximum: 100 }
validates :is_answer, presence: true, inclusion: {in: 0..1}, numericality: { only_integer: true }
end
end

@ -17,8 +17,9 @@ class ItemBank < ApplicationRecord
has_many :item_choices, dependent: :destroy
has_many :item_baskets, dependent: :destroy
has_many :item_bank_tag_repertoires, dependent: :destroy
has_many :tag_repertoires, through: :item_bank_tag_repertoires
def analysisi
def analysis
item_analysis&.analysis
end
end

@ -153,6 +153,10 @@ class User < ApplicationRecord
has_many :hacks, dependent: :destroy
has_many :hack_user_lastest_codes, dependent: :destroy
# 题库
has_many :item_banks, dependent: :destroy
has_many :item_baskets, -> { order("item_baskets.position ASC") }, dependent: :destroy
# Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) }

@ -1,4 +1,4 @@
class ItemBank::SaveItemService < ApplicationService
class ItemBanks::SaveItemService < ApplicationService
attr_reader :item, :params
def initialize(item, params)
@ -7,7 +7,52 @@ class ItemBank::SaveItemService < ApplicationService
end
def call
Competitions::SaveTeamForm.new(params).validate!
new_record = item.new_record?
raise("不能更改题型") if !new_record && item.item_type != params[:item_type]
ItemBanks::SaveItemForm.new(params).validate!
ActiveRecord::Base.transaction do
item.item_type = params[:item_type] if new_record
item.difficulty = params[:difficulty]
item.sub_repertoire_id = params[:sub_repertoire_id]
item.name = params[:name].strip
item.save!
analysis = item.item_analysis || ItemAnalysis.new(item_bank_id: item.id)
analysis.analysis = params[:analysis].blank? ? nil : params[:analysis].strip
analysis.save
# 知识点的创建
new_tag_repertoire_ids = params[:tag_repertoire_id]
old_tag_repertoire_ids = item.item_bank_tag_repertoires.pluck(:tag_repertoire_id)
delete_tag_repertoire_ids = old_tag_repertoire_ids - new_tag_repertoire_ids
create_tag_repertoire_ids = new_tag_repertoire_ids - old_tag_repertoire_ids
item.item_bank_tag_repertoires.where(tag_repertoire_id: delete_tag_repertoire_ids).destroy_all
create_tag_repertoire_ids.each do |tag_id|
item.item_bank_tag_repertoires << ItemBankTagRepertoire.new(tag_repertoire_id: tag_id)
end
# 选项的创建
if item.item_type < 3
old_choices = item.item_choices
new_choices = params[:choices]
new_choices.each_with_index do |choice, index|
choice_item = old_choices[index] || ItemChoice.new(item_bank_id: item.id)
choice_item.choice_text = choice[:choice_text]
choice_item.is_answer = choice[:is_answer]
choice_item.save!
end
if old_choices.length > new_choices.length
old_choices[new_choices.length..(old_choices.length-1)].each do |old_choice|
old_choice.destroy
end
end
end
end
item
end
end

@ -0,0 +1,47 @@
class ItemBaskets::SaveItemBasketService < ApplicationService
attr_reader :user, :params
def initialize(user, params)
@user = user
@params = params
end
def call
raise("请选择试题") if params[:item_ids].blank?
# 只能选用公共题库或是自己的题库
items = ItemBank.where(public: 1).or(ItemBank.where(user_id: user.id))
# 已选到过试题篮的不重复选用
item_ids = params[:item_ids] - user.item_baskets.pluck(:item_bank_id)
items.where(id: item_ids).each do |item|
new_item = ItemBasket.new(user_id: user.id, item_bank_id: item.id, item_type: item.item_type)
new_item.score = item_score item.item_type
new_item.position = item_position item.item_type
new_item.save!
end
end
private
def item_score item_type
if user.item_baskets.where(item_type: item_type).last.present?
score = user.item_baskets.where(item_type: item_type).last.score
else
score =
case item_type
when 0, 1, 2
5
when 6
10
else
5
end
end
score
end
def item_position item_type
user.item_baskets.where(item_type: item_type).last&.position.to_i + 1
end
end

@ -0,0 +1,15 @@
json.repertoire do
json.(@item.sub_repertoire&.repertoire, :id, :name)
end
json.sub_repertoire do
json.(@item.sub_repertoire, :id, :name)
end
json.tag_repertoires @item.tag_repertoires do |tag|
json.(tag, :id, :name)
end
json.(@item, :id, :name, :item_type, :difficulty)
json.analysis @item.analysis
json.choices @item.item_choices do |choice|
json.choice_text choice.choice_text
json.is_answer choice.is_answer
end

@ -1,6 +1,6 @@
json.items @items.each do |item|
json.(item, :id, :name, :item_type, :difficulty, :public, :quotes)
json.analysisi item.analysisi
json.analysis item.analysis
json.update_time item.updated_at&.strftime("%Y-%m-%d %H:%M")
json.author do
json.login item.user&.login

@ -49,6 +49,12 @@ Rails.application.routes.draw do
end
resources :item_banks do
member do
post :set_public
end
end
resources :item_baskets do
end

@ -0,0 +1,7 @@
class AddPositionScoreToBasket < ActiveRecord::Migration[5.2]
def change
add_column :item_baskets, :position, :integer, default: 0
add_column :item_baskets, :score, :float, default: 0
add_column :item_baskets, :item_type, :integer, default: 0
end
end
Loading…
Cancel
Save