diff --git a/app/controllers/admins/examination_authentications_controller.rb b/app/controllers/admins/examination_authentications_controller.rb index 8045644e1..c68c062b6 100644 --- a/app/controllers/admins/examination_authentications_controller.rb +++ b/app/controllers/admins/examination_authentications_controller.rb @@ -12,7 +12,7 @@ class Admins::ExaminationAuthenticationsController < Admins::BaseController ActiveRecord::Base.transaction do exam = ExaminationBank.find current_apply.container_id current_apply.update!(status: 1) - exam.update!(public: 0) + exam.update!(public: 1) end render_success_js end diff --git a/app/controllers/admins/item_authentications_controller.rb b/app/controllers/admins/item_authentications_controller.rb index 88d833ee9..8da9b232f 100644 --- a/app/controllers/admins/item_authentications_controller.rb +++ b/app/controllers/admins/item_authentications_controller.rb @@ -16,7 +16,7 @@ class Admins::ItemAuthenticationsController < Admins::BaseController ActiveRecord::Base.transaction do item = ItemBank.find current_apply.container_id current_apply.update!(status: 1) - item.update!(public: 0) + item.update!(public: 1) end render_success_js end diff --git a/app/controllers/examination_banks_controller.rb b/app/controllers/examination_banks_controller.rb index 9ffbd6630..251cd197f 100644 --- a/app/controllers/examination_banks_controller.rb +++ b/app/controllers/examination_banks_controller.rb @@ -50,8 +50,11 @@ class ExaminationBanksController < ApplicationController end def destroy - @exam.destroy! - render_ok + ActiveRecord::Base.transaction do + ApplyAction.where(container_type: "ExaminationBank", container_id: @exam.id).destroy_all + @exam.destroy! + render_ok + end end def set_public diff --git a/app/controllers/examination_intelligent_settings_controller.rb b/app/controllers/examination_intelligent_settings_controller.rb new file mode 100644 index 000000000..f4dcc1535 --- /dev/null +++ b/app/controllers/examination_intelligent_settings_controller.rb @@ -0,0 +1,102 @@ +class ExaminationIntelligentSettingsController < ApplicationController + before_action :require_login + before_action :find_exam, only: [:exchange_one_item, :exchange_items, :save_exam] + + def optinal_items + sub_discipline_id = params[:sub_discipline_id] + tag_discipline_id = params[:tag_discipline_id] + difficulty = params[:difficulty] + source = params[:source] + + items = OptionalItemQuery.call(sub_discipline_id, tag_discipline_id, difficulty, source) + @single_question_count = items.select{ |item| item.item_type == "SINGLE" }.size + @multiple_question_count = items.select{ |item| item.item_type == "MULTIPLE" }.size + @judgement_question_count = items.select{ |item| item.item_type == "JUDGMENT" }.size + @program_question_count = items.select{ |item| item.item_type == "PROGRAM" }.size + end + + def create + ActiveRecord::Base.transaction do + exam = ExaminationIntelligentSetting.new(user: current_user) + # 保存试卷基础信息 + exam = ExaminationIntelligentSettings::SaveSettingService.call(exam, form_params) + render_ok({exam_setting_id: exam.id}) + end + rescue ApplicationService::Error => ex + render_error(ex.message) + end + + def save_exam + new_exam = ExaminationBank.new(user: current_user) + # 保存试卷基础信息 + ExaminationIntelligentSettings::SaveExaminationService.call(new_exam, save_params, @exam) + render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) + end + + def exchange_one_item + item = @exam.item_baskets.find_by!(id: params[:item_id]) + exam_type_setting = @exam.examination_type_settings.find_by!(item_type: item.item_type) + + # 获取可选的题 + items = OptionalItemQuery.call(@exam.sub_discipline_id, @exam.tag_discipline_containers.pluck(:tag_discipline_id), @exam.difficulty, @exam.public) + type_items = items.select{ |t_item| t_item.item_type == item.item_type } + # 如果可选的题数小于等于设置的题数则提示无可换的题 + tip_exception("无可换的题") if type_items.size <= exam_type_setting.count + # 可选题中去掉已组卷的同题型试题 + optional_item_ids = type_items.pluck(:id) - @exam.item_baskets.where(item_type: item.item_type).pluck(:item_bank_id) + new_item = ItemBank.find optional_item_ids.sample(1).first + ActiveRecord::Base.transaction do + @exam.item_baskets << ItemBasket.new(item_bank_id: new_item.id, position: item.position, score: item.score, item_type: new_item.item_type) + item.destroy! + end + render_ok + end + + def exchange_items + exam_type_setting = @exam.examination_type_settings.find_by!(item_type: params[:item_type]) + choosed_items = @exam.item_baskets.where(item_type: params[:item_type]) + + # 获取可选的题 + items = OptionalItemQuery.call(@exam.sub_discipline_id, @exam.tag_discipline_containers.pluck(:tag_discipline_id), @exam.difficulty, @exam.public) + type_items = items.select{ |t_item| t_item.item_type == params[:item_type] } + # 如果可选的题数小于等于设置的题数则提示无可换的题 + tip_exception("无可换的题") if type_items.size <= exam_type_setting.count + # 可选题中去掉已组卷的同题型试题 + choosed_item_ids = choosed_items.pluck(:item_bank_id) + optional_item_ids = type_items.pluck(:id) - choosed_item_ids + + # 如果可选题数小于设置的题数n,则在原来的选题中随机选n个,确保换题时能选到新的题 + if optional_item_ids.size < exam_type_setting.count + absence_count = exam_type_setting.count - optional_item_ids.size + optional_item_ids = optional_item_ids + choosed_item_ids.sample(absence_count) + end + + ActiveRecord::Base.transaction do + # 取试题分数 + score = choosed_items.first&.score || (params[:item_type] == "PROGRAM" ? 10 : 5) + choosed_items.destroy_all + optional_item_ids.sample(exam_type_setting.count).each_with_index do |item_id, index| + new_item = ItemBank.find item_id + @exam.item_baskets << ItemBasket.new(item_bank_id: new_item.id, position: index+1, score: score, item_type: new_item.item_type) + end + end + render_ok + end + + private + + def find_exam + @exam = ExaminationIntelligentSetting.find_by!(id: params[:id]) + tip_exception(403,"无权限编辑") unless current_user.admin_or_business? || @exam.user_id == current_user.id + end + + def form_params + params.permit(:discipline_id, :sub_discipline_id, :difficulty, :source, tag_discipline_id: [], question_settings: %i[item_type count]) + end + + def save_params + params.permit(:name, :duration) + end +end \ No newline at end of file diff --git a/app/controllers/item_banks_controller.rb b/app/controllers/item_banks_controller.rb index 24d9c44a9..a0abffe6c 100644 --- a/app/controllers/item_banks_controller.rb +++ b/app/controllers/item_banks_controller.rb @@ -9,7 +9,14 @@ class ItemBanksController < ApplicationController @items_count = items.size @items = paginate items.includes(:item_analysis, :user, :container) exam = ExaminationBank.find_by(id: params[:exam_id]) if params[:exam_id].present? - @item_basket_ids = exam ? exam.examination_items.pluck(:item_bank_id) : current_user.item_baskets.pluck(:item_bank_id) + exam_setting = ExaminationIntelligentSetting.find_by(id: params[:exam_setting_id]) if params[:exam_setting_id].present? + @item_basket_ids = if exam + exam.examination_items.pluck(:item_bank_id) + elsif exam_setting + exam_setting.item_baskets.pluck(:item_bank_id) + else + current_user.item_baskets.pluck(:item_bank_id) + end end def create @@ -32,8 +39,11 @@ class ItemBanksController < ApplicationController end def destroy - @item.destroy! - render_ok + ActiveRecord::Base.transaction do + ApplyAction.where(container_type: "ItemBank", container_id: @item.id).destroy_all + @item.destroy! + render_ok + end end def set_public diff --git a/app/controllers/item_baskets_controller.rb b/app/controllers/item_baskets_controller.rb index 21203346b..dc5367378 100644 --- a/app/controllers/item_baskets_controller.rb +++ b/app/controllers/item_baskets_controller.rb @@ -4,7 +4,7 @@ class ItemBasketsController < ApplicationController helper_method :current_basket def index - @item_baskets = current_user.item_baskets + @item_baskets = basket_items @single_questions = @item_baskets.where(item_type: "SINGLE") @multiple_questions = @item_baskets.where(item_type: "MULTIPLE") @judgement_questions = @item_baskets.where(item_type: "JUDGMENT") @@ -22,41 +22,41 @@ class ItemBasketsController < ApplicationController end def create - ItemBaskets::SaveItemBasketService.call(current_user, create_params) + ItemBaskets::SaveItemBasketService.call(current_user, create_params, exam_setting) render_ok rescue ApplicationService::Error => ex render_error(ex.message) end def destroy - item = current_user.item_baskets.find_by!(item_bank_id: params[:id]) + item = basket_items.find_by!(item_bank_id: params[:id]) ActiveRecord::Base.transaction do - current_user.item_baskets.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1") + basket_items.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1") item.destroy! end render_ok end def delete_item_type - baskets = ItemBasket.where(item_type: params[:item_type]) + baskets = basket_items.where(item_type: params[:item_type]) baskets.destroy_all render_ok end def set_score current_basket.update_attributes!(score: params[:score]) - @questions_score = current_user.item_baskets.where(item_type: current_basket.item_type).pluck(:score).sum - @all_score = current_user.item_baskets.pluck(:score).sum + @questions_score = basket_items.where(item_type: current_basket.item_type).pluck(:score).sum + @all_score = basket_items.pluck(:score).sum end def batch_set_score - current_user.item_baskets.where(item_type: params[:item_type]).update_all(score: params[:score]) - @questions_score = current_user.item_baskets.where(item_type: params[:item_type]).pluck(:score).sum - @all_score = current_user.item_baskets.pluck(:score).sum + basket_items.where(item_type: params[:item_type]).update_all(score: params[:score]) + @questions_score = basket_items.where(item_type: params[:item_type]).pluck(:score).sum + @all_score = basket_items.pluck(:score).sum end def adjust_position - same_items = current_user.item_baskets.where(item_type: current_basket.item_type) + same_items = basket_items.where(item_type: current_basket.item_type) max_position = same_items.size tip_exception("position超出范围") unless params[:position].present? && params[:position].to_i <= max_position && params[:position].to_i >= 1 ActiveRecord::Base.transaction do @@ -79,8 +79,19 @@ class ItemBasketsController < ApplicationController params.permit(item_ids: []) end + def exam_setting + @_exam_setting = ExaminationIntelligentSetting.find_by(id: params[:exam_setting_id]) + end + + def basket_items + @_items = params[:exam_setting_id] ? exam_setting.item_baskets : current_user.item_baskets + end + def current_basket - @_current_basket = current_user.item_baskets.find_by!(id: params[:id]) + @_current_basket = ItemBasket.find_by!(id: params[:id]) + tip_exception(403, "无权限编辑") unless current_user.admin_or_business? || @_current_basket.user_id.to_i == current_user.id || + @_current_basket.examination_intelligent_setting&.user_id.to_i == current_user.id + @_current_basket end def validate_score diff --git a/app/forms/examination_intelligent_settings/save_exam_form.rb b/app/forms/examination_intelligent_settings/save_exam_form.rb new file mode 100644 index 000000000..ec4f17ad7 --- /dev/null +++ b/app/forms/examination_intelligent_settings/save_exam_form.rb @@ -0,0 +1,12 @@ +class ExaminationIntelligentSettings::SaveExamForm + include ActiveModel::Model + + attr_accessor :name, :duration + + validates :name, presence: true, length: { maximum: 60 } + validate :validate_duration + + def validate_duration + raise '时长应为大于0的整数' if duration.present? && duration.to_i < 1 + end +end \ No newline at end of file diff --git a/app/forms/examination_intelligent_settings/save_exam_setting_form.rb b/app/forms/examination_intelligent_settings/save_exam_setting_form.rb new file mode 100644 index 000000000..bbfb9eee8 --- /dev/null +++ b/app/forms/examination_intelligent_settings/save_exam_setting_form.rb @@ -0,0 +1,11 @@ +class ExaminationIntelligentSettings::SaveExamSettingForm + include ActiveModel::Model + + attr_accessor :discipline_id, :sub_discipline_id, :source, :difficulty, :tag_discipline_id, :question_settings + + validates :discipline_id, presence: true + validates :sub_discipline_id, presence: true + validates :source, presence: true + validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } + validates :question_settings, presence: true +end \ No newline at end of file diff --git a/app/forms/item_banks/save_item_form.rb b/app/forms/item_banks/save_item_form.rb index 7e788067e..d6d3a3e28 100644 --- a/app/forms/item_banks/save_item_form.rb +++ b/app/forms/item_banks/save_item_form.rb @@ -15,9 +15,9 @@ class ItemBanks::SaveItemForm return unless errors.blank? choices.each { |item| SubForm.new(item).validate! } if %W(SINGLE MULTIPLE JUDGMENT).include?(item_type) return unless errors.blank? - if [0, 2].include?(item_type) && choices.pluck(:is_answer).select{|item| item == 1}.length > 1 + if ["SINGLE", "JUDGMENT"].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 + elsif item_type == "MULTIPLE" && choices.pluck(:is_answer).select{|item| item == 1}.length <= 1 raise("多选题至少有两个正确答案") end end diff --git a/app/models/examination_bank.rb b/app/models/examination_bank.rb index f7b7cc0bf..824f0bb69 100644 --- a/app/models/examination_bank.rb +++ b/app/models/examination_bank.rb @@ -7,6 +7,10 @@ class ExaminationBank < ApplicationRecord has_many :examination_items, -> {order(position: :asc)}, dependent: :destroy + def apply? + !public && ApplyAction.where(container_type: "ExaminationBank", container_id: id, status: 0).exists? + end + def question_count examination_items.size end diff --git a/app/models/examination_intelligent_setting.rb b/app/models/examination_intelligent_setting.rb new file mode 100644 index 000000000..38c7fbe4b --- /dev/null +++ b/app/models/examination_intelligent_setting.rb @@ -0,0 +1,7 @@ +class ExaminationIntelligentSetting < ApplicationRecord + belongs_to :sub_discipline + belongs_to :user + has_many :examination_type_settings, dependent: :destroy + has_many :tag_discipline_containers, as: :container, dependent: :destroy + has_many :item_baskets, dependent: :destroy +end diff --git a/app/models/examination_type_setting.rb b/app/models/examination_type_setting.rb new file mode 100644 index 000000000..30f3e80b4 --- /dev/null +++ b/app/models/examination_type_setting.rb @@ -0,0 +1,4 @@ +class ExaminationTypeSetting < ApplicationRecord + enum item_type: { SINGLE: 0, MULTIPLE: 1, JUDGMENT: 2, COMPLETION: 3, SUBJECTIVE: 4, PRACTICAL: 5, PROGRAM: 6 } + belongs_to :examination_intelligent_setting +end diff --git a/app/models/item_bank.rb b/app/models/item_bank.rb index dcc0007e2..840f488d8 100644 --- a/app/models/item_bank.rb +++ b/app/models/item_bank.rb @@ -18,6 +18,10 @@ class ItemBank < ApplicationRecord item_analysis&.analysis end + def apply? + !public && ApplyAction.where(container_type: "ItemBank", container_id: id, status: 0).exists? + end + def type_string result = case item_type when "SINGLE" diff --git a/app/models/item_basket.rb b/app/models/item_basket.rb index a3ff865ba..eb849d403 100644 --- a/app/models/item_basket.rb +++ b/app/models/item_basket.rb @@ -2,13 +2,6 @@ class ItemBasket < ApplicationRecord enum item_type: { SINGLE: 0, MULTIPLE: 1, JUDGMENT: 2, COMPLETION: 3, SUBJECTIVE: 4, PRACTICAL: 5, PROGRAM: 6 } belongs_to :item_bank - belongs_to :user - - def all_score - User.current.item_baskets.map(&:score).sum - end - - def question_count - User.current.item_baskets.size - end + belongs_to :user, optional: true + belongs_to :examination_intelligent_setting, optional: true end diff --git a/app/models/user.rb b/app/models/user.rb index f1b8c3d23..2af43b6f5 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -156,6 +156,8 @@ class User < ApplicationRecord # 题库 has_many :item_banks, dependent: :destroy has_many :item_baskets, -> { order("item_baskets.position ASC") }, dependent: :destroy + has_many :examination_banks, dependent: :destroy + has_many :examination_intelligent_settings, dependent: :destroy # Groups and active users scope :active, lambda { where(status: STATUS_ACTIVE) } diff --git a/app/queries/optional_item_query.rb b/app/queries/optional_item_query.rb new file mode 100644 index 000000000..54cd0eed0 --- /dev/null +++ b/app/queries/optional_item_query.rb @@ -0,0 +1,35 @@ +class OptionalItemQuery < ApplicationQuery + attr_reader :sub_discipline_id, :tag_discipline_id, :difficulty, :source + + def initialize(sub_discipline_id, tag_discipline_id, difficulty, source) + @sub_discipline_id = sub_discipline_id + @tag_discipline_id = tag_discipline_id + @difficulty = difficulty + @source = source + end + + def call + items = ItemBank.all + if tag_discipline_id.present? && sub_discipline_id.present? + items = items.joins(:tag_discipline_containers).where(tag_discipline_containers: {tag_discipline_id: tag_discipline_id}) + hacks = Hack.joins(:tag_discipline_containers).where(tag_discipline_containers: {tag_discipline_id: tag_discipline_id}) + elsif sub_discipline_id.present? + items = items.where(sub_discipline_id: sub_discipline_id) + hacks = Hack.where(sub_discipline_id: sub_discipline_id) + end + + if hacks.present? + items = ItemBank.where(container_id: hacks.pluck(:id), container_type: "Hack").or(ItemBank.where(id: items.pluck(:id))) + end + + # 来源 + public = source.present? ? source.to_i : 1 + public = public == 2 ? [0, 1] : public + items = items.where(public: public) + + # 难度 + difficulty = difficulty ? difficulty.to_i : 1 + items = items.where(difficulty: difficulty) + items + end +end \ No newline at end of file diff --git a/app/services/examination_intelligent_settings/save_examination_service.rb b/app/services/examination_intelligent_settings/save_examination_service.rb new file mode 100644 index 000000000..d6f5e7406 --- /dev/null +++ b/app/services/examination_intelligent_settings/save_examination_service.rb @@ -0,0 +1,38 @@ +class ExaminationIntelligentSettings::SaveExaminationService < ApplicationService + attr_reader :exam, :params, :exam_setting + + def initialize(exam, params, exam_setting) + @exam = exam + @params = params + @exam_setting = exam_setting + end + + def call + ExaminationIntelligentSettings::SaveExamForm.new(params).validate! + + ActiveRecord::Base.transaction do + exam.name = params[:name].to_s.strip + exam.difficulty = exam_setting.difficulty + exam.duration = params[:duration].present? ? params[:duration].to_i : nil + exam.sub_discipline_id = exam_setting.sub_discipline_id + exam.intelligent = 1 + exam.save! + + # 知识点的创建 + exam_setting.tag_discipline_containers.each do |tag| + exam.tag_discipline_containers << TagDisciplineContainer.new(tag_discipline_id: tag.tag_discipline_id) + end + + # 试题的复制 + exam_setting.item_baskets.includes(:item_bank).each do |basket| + item = basket.item_bank + if item.present? + new_item = ExaminationItem.new + new_item.new_item(item, exam, basket.score, basket.position) + end + end + + exam_setting.destroy! + end + end +end \ No newline at end of file diff --git a/app/services/examination_intelligent_settings/save_setting_service.rb b/app/services/examination_intelligent_settings/save_setting_service.rb new file mode 100644 index 000000000..af22b3234 --- /dev/null +++ b/app/services/examination_intelligent_settings/save_setting_service.rb @@ -0,0 +1,63 @@ +class ExaminationIntelligentSettings::SaveSettingService < ApplicationService + attr_reader :exam, :params + + def initialize(exam, params) + @exam = exam + @params = params + end + + def call + ExaminationIntelligentSettings::SaveExamSettingForm.new(params).validate! + items = OptionalItemQuery.call(params[:sub_discipline_id], params[:tag_discipline_id], params[:difficulty], params[:source]) + params[:question_settings].each do |setting| + raise "超出可选题数范围" if items.select{ |item| item.item_type == setting[:item_type] }.size.to_i < setting[:count].to_i + end + + exam.difficulty = params[:difficulty] + exam.sub_discipline_id = params[:sub_discipline_id] + exam.public = params[:source].present? ? params[:source].to_i : 1 + exam.save! + + # 知识点的创建 + params[:tag_discipline_id].each do |tag_id| + exam.tag_discipline_containers << TagDisciplineContainer.new(tag_discipline_id: tag_id) + end + + # 智能选题的设置 + params[:question_settings].each do |setting| + if setting[:count].to_i > 0 + exam.examination_type_settings << ExaminationTypeSetting.new(item_type: setting[:item_type], count: setting[:count].to_i) + end + end + + # 选题 + choose_question items + + exam + end + + private + + def choose_question items + exam.examination_type_settings.each do |setting| + questions = items.select{ |item| item.item_type == setting.item_type } + questions.pluck(:id).sample(setting.count).each_with_index do |item_id, index| + item = ItemBank.find item_id + exam.item_baskets << ItemBasket.new(item_bank_id: item.id, position: index+1, score: item_score(item.item_type), item_type: item.item_type) + end + end + end + + def item_score item_type + score = + case item_type + when "SINGLE", "MULTIPLE", "JUDGMENT" + 5 + when "PROGRAM" + 10 + else + 5 + end + score + end +end \ No newline at end of file diff --git a/app/services/item_baskets/save_item_basket_service.rb b/app/services/item_baskets/save_item_basket_service.rb index cf6d3738b..debc7e2ed 100644 --- a/app/services/item_baskets/save_item_basket_service.rb +++ b/app/services/item_baskets/save_item_basket_service.rb @@ -1,9 +1,10 @@ class ItemBaskets::SaveItemBasketService < ApplicationService - attr_reader :user, :params + attr_reader :user, :params, :exam_setting - def initialize(user, params) + def initialize(user, params, exam_setting) @user = user @params = params + @exam_setting = exam_setting end def call @@ -13,9 +14,14 @@ class ItemBaskets::SaveItemBasketService < ApplicationService items = ItemBank.where(public: 1).or(ItemBank.where(user_id: user.id)) # 已选到过试题篮的不重复选用 - item_ids = params[:item_ids] - user.item_baskets.pluck(:item_bank_id) + item_ids = params[:item_ids] - basket_items.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 = ItemBasket.new(item_bank_id: item.id, item_type: item.item_type) + if exam_setting.present? + new_item.examination_intelligent_setting_id = exam_setting.id + else + new_item.user_id = user.id + end new_item.score = item_score item.item_type new_item.position = item_position item.item_type new_item.save! @@ -25,8 +31,8 @@ class ItemBaskets::SaveItemBasketService < ApplicationService 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 + if basket_items.where(item_type: item_type).last.present? + score = basket_items.where(item_type: item_type).last.score else score = case item_type @@ -42,6 +48,10 @@ class ItemBaskets::SaveItemBasketService < ApplicationService end def item_position item_type - user.item_baskets.where(item_type: item_type).last&.position.to_i + 1 + basket_items.where(item_type: item_type).last&.position.to_i + 1 + end + + def basket_items + exam_setting.present? ? exam_setting.item_baskets : user.item_baskets end end \ No newline at end of file diff --git a/app/views/examination_banks/index.json.jbuilder b/app/views/examination_banks/index.json.jbuilder index 75bd006fe..ae24a377c 100644 --- a/app/views/examination_banks/index.json.jbuilder +++ b/app/views/examination_banks/index.json.jbuilder @@ -1,8 +1,9 @@ json.exams @exams.each do |exam| - json.(exam, :id, :name, :difficulty, :quotes) + json.(exam, :id, :name, :difficulty, :quotes, :public) json.question_count exam.question_count json.total_score exam.total_score json.update_time exam.updated_at&.strftime("%Y-%m-%d %H:%M") + json.apply exam.apply? json.author do json.login exam.user&.login json.name exam.user&.full_name diff --git a/app/views/examination_intelligent_settings/optinal_items.json.jbuilder b/app/views/examination_intelligent_settings/optinal_items.json.jbuilder new file mode 100644 index 000000000..7d8ec7381 --- /dev/null +++ b/app/views/examination_intelligent_settings/optinal_items.json.jbuilder @@ -0,0 +1,4 @@ +json.single_question_count @single_question_count +json.multiple_question_count @multiple_question_count +json.judgement_question_count @judgement_question_count +json.program_question_count @program_question_count diff --git a/app/views/item_banks/index.json.jbuilder b/app/views/item_banks/index.json.jbuilder index 50a3e063c..c1695b866 100644 --- a/app/views/item_banks/index.json.jbuilder +++ b/app/views/item_banks/index.json.jbuilder @@ -3,6 +3,7 @@ json.items @items.each do |item| json.partial! "item_banks/item", locals: {item: item} json.update_time item.updated_at&.strftime("%Y-%m-%d %H:%M") json.choosed @item_basket_ids.include?(item.id) + json.apply item.apply? json.author do json.login item.user&.login json.name item.user&.full_name diff --git a/config/routes.rb b/config/routes.rb index 08df77eb9..a63776d44 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -96,6 +96,18 @@ Rails.application.routes.draw do end end + resources :examination_intelligent_settings do + collection do + get :optinal_items + end + + member do + post :save_exam + post :exchange_one_item + post :exchange_items + end + end + resources :hacks, path: :problems, param: :identifier do collection do get :unpulished_list diff --git a/db/migrate/20200107091630_create_examination_intelligent_settings.rb b/db/migrate/20200107091630_create_examination_intelligent_settings.rb new file mode 100644 index 000000000..f00f19c33 --- /dev/null +++ b/db/migrate/20200107091630_create_examination_intelligent_settings.rb @@ -0,0 +1,13 @@ +class CreateExaminationIntelligentSettings < ActiveRecord::Migration[5.2] + def change + create_table :examination_intelligent_settings do |t| + t.references :sub_discipline + t.integer :public, default: 1 + t.integer :difficulty, default: 1 + + t.timestamps + end + + add_index :examination_intelligent_settings, :sub_discipline_id, name: "index_on_sub_discipline_id" + end +end diff --git a/db/migrate/20200107091836_create_examination_type_settings.rb b/db/migrate/20200107091836_create_examination_type_settings.rb new file mode 100644 index 000000000..c2eb50e9e --- /dev/null +++ b/db/migrate/20200107091836_create_examination_type_settings.rb @@ -0,0 +1,13 @@ +class CreateExaminationTypeSettings < ActiveRecord::Migration[5.2] + def change + create_table :examination_type_settings do |t| + t.references :examination_intelligent_setting, index: false + t.integer :item_type + t.integer :count + + t.timestamps + end + + add_index :examination_type_settings, :examination_intelligent_setting_id, name: "index_on_examination_intelligent_setting" + end +end diff --git a/db/migrate/20200108030930_add_user_id_to_intelligent_settings.rb b/db/migrate/20200108030930_add_user_id_to_intelligent_settings.rb new file mode 100644 index 000000000..83d3b96b4 --- /dev/null +++ b/db/migrate/20200108030930_add_user_id_to_intelligent_settings.rb @@ -0,0 +1,5 @@ +class AddUserIdToIntelligentSettings < ActiveRecord::Migration[5.2] + def change + add_column :examination_intelligent_settings, :user_id, :integer, index: true + end +end diff --git a/db/migrate/20200108061139_add_intelligent_setting_id_to_item_baskets.rb b/db/migrate/20200108061139_add_intelligent_setting_id_to_item_baskets.rb new file mode 100644 index 000000000..9de17ee48 --- /dev/null +++ b/db/migrate/20200108061139_add_intelligent_setting_id_to_item_baskets.rb @@ -0,0 +1,5 @@ +class AddIntelligentSettingIdToItemBaskets < ActiveRecord::Migration[5.2] + def change + add_column :item_baskets, :examination_intelligent_setting_id, :integer, index: true + end +end diff --git a/db/migrate/20200109021528_add_intelligent_to_exam.rb b/db/migrate/20200109021528_add_intelligent_to_exam.rb new file mode 100644 index 000000000..fa4b16dd1 --- /dev/null +++ b/db/migrate/20200109021528_add_intelligent_to_exam.rb @@ -0,0 +1,5 @@ +class AddIntelligentToExam < ActiveRecord::Migration[5.2] + def change + add_column :examination_banks, :intelligent, :boolean, default: false + end +end diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index d8f642db3..535b19a94 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -42,7 +42,7 @@ if (isDev) { // 老师 //debugType="teacher"; // 学生 -debugType="student"; +//debugType="student"; function railsgettimes(proxy) { @@ -83,7 +83,7 @@ export function initAxiosInterceptors(props) { //proxy="http://47.96.87.25:48080" proxy="https://pre-newweb.educoder.net" proxy="https://test-newweb.educoder.net" - // proxy="https://test-jupyterweb.educoder.net" + //proxy="https://test-jupyterweb.educoder.net" //proxy="http://192.168.2.63:3001" // 在这里使用requestMap控制,避免用户通过双击等操作发出重复的请求; diff --git a/public/react/src/common/quillForEditor/README.md b/public/react/src/common/quillForEditor/README.md index 75b403590..c9c53b902 100644 --- a/public/react/src/common/quillForEditor/README.md +++ b/public/react/src/common/quillForEditor/README.md @@ -61,6 +61,7 @@ ### 使用 ```` + 编辑模式是放不大图片的 import QuillForEditor from 'xxx'; // 指定需要显示的工具栏信息, 不指定加载全部 diff --git a/public/react/src/modules/courses/exercise/new/SingleEditor.js b/public/react/src/modules/courses/exercise/new/SingleEditor.js index 0b1b7599a..8585e0a82 100644 --- a/public/react/src/modules/courses/exercise/new/SingleEditor.js +++ b/public/react/src/modules/courses/exercise/new/SingleEditor.js @@ -8,8 +8,9 @@ import { import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor'; import axios from 'axios' import update from 'immutability-helper' - import {getUrl, ActionBtn, DMDEditor, ConditionToolTip} from 'educoder'; +import QuillForEditor from "../../../../common/quillForEditor"; + const { TextArea } = Input; const confirm = Modal.confirm; const $ = window.$ @@ -47,6 +48,9 @@ class SingleEditor extends Component{ question_title: this.props.question_title || '', question_type: this.props.question_type || 0, question_score: this.props.question_score || this.props.init_question_score, + choice_editor: 'md', + quill_question_title: '', + quill_default_title: '' } } addOption = () => { @@ -205,8 +209,33 @@ class SingleEditor extends Component{ toShowMode = () => { } + + // 切换编辑器 + handleChangeEditor = (e) => { + const {quill_question_title} = this.state; + const value = e.target.value + if (value === 'quill') { + const _val = quill_question_title ? JSON.parse(quill_question_title) : ''; + this.setState({ + quill_default_title: _val + }) + } + this.setState({ + choice_editor: value + }); + } + + // quill编辑器内容变化时调用此接口 + handleCtxChange = (ctx) => { + console.log('编辑器内容', ctx); + // 保存编辑器内容 + this.setState({ + quill_question_title: JSON.stringify(ctx) + }); + } + render() { - let { question_title, question_score, question_type, question_choices, standard_answers } = this.state; + let { question_title, question_score, question_type, question_choices, standard_answers, choice_editor, quill_default_title } = this.state; let { question_id, index, exerciseIsPublish, // question_title, // question_type, @@ -245,18 +274,51 @@ class SingleEditor extends Component{ max-width: 1056px; word-break:break-all; } + .editor_area{ + display: inline-block; + float: right; + // line-height: 30px; + // height: 30px; + } + .editor_txt{ + margin-right: 10px; + font-size: 12px; + color: #999; + } + .radio_style{ + display: inline-block; + vertical: center; + } `}

{/* {!question_id ? '新建' : '编辑'} */} 选择题 (客观题,由系统自动评分,请设置标准答案) + {/* */} + {/*

+ 切换编辑器: + + MD + Quill + +
*/}

- this.setState({ question_title: val})} - ref="titleEditor" + {choice_editor === 'md' + ? this.setState({ question_title: val})} + ref="titleEditor" + > - > + : + } {question_choices.map( (item, index) => { const bg = standard_answers[index] ? 'check-option-bg' : '' diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js index 9db5d242f..b300156b7 100644 --- a/public/react/src/modules/question/NewMyShixunModel.js +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -34,7 +34,7 @@ class NewMyShixunModel extends Component { placement: 'right', modalsType: false, modalsTypes:false, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titilesms:"单选题", titbool: false, @@ -91,7 +91,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -117,7 +117,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } @@ -141,7 +141,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } @@ -156,7 +156,7 @@ class NewMyShixunModel extends Component { public: defaultActiveKey, page:1, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -209,7 +209,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -342,7 +342,7 @@ class NewMyShixunModel extends Component { page: pageNumber, per_page:10, oj_status:this.state.oj_status, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -386,7 +386,7 @@ class NewMyShixunModel extends Component { this.setState({ modalsType: true, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titbool: true, timuid: id @@ -461,7 +461,7 @@ class NewMyShixunModel extends Component { page:1, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -488,7 +488,7 @@ class NewMyShixunModel extends Component { per_page:10, keywords:null, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -543,7 +543,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:this.state.oj_status, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -567,7 +567,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } @@ -593,7 +593,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -661,7 +661,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdatasy(data); this.getbasket_listdata(); @@ -678,34 +678,57 @@ class NewMyShixunModel extends Component { let url=""; if(this.props.exam_id===undefined){ url=`/item_baskets/${id}.json`; + axios.delete(url) + .then((result) => { + if (result.data.status == 0) { + // this.props.showNotification(`撤销成功`); + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + this.getdatasy(data); + this.getbasket_listdata(); + } + }).catch((error) => { + //console.log(error); + }) }else{ - url=`/examination_banks/${id}/revoke_item.json`; + url=`/examination_banks/${this.props.exam_id}/revoke_item.json`; + axios.delete(url,{ data: { + item_id:id===undefined?"":parseInt(id), + }}) + .then((result) => { + if (result.data.status == 0) { + // this.props.showNotification(`撤销成功`); + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + this.getdatasy(data); + this.getbasket_listdata(); + } + }).catch((error) => { + //console.log(error); + }) } - axios.delete(url,{ data: { - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), - }}) - .then((result) => { - if (result.data.status == 0) { - // this.props.showNotification(`撤销成功`); - var data = { - discipline_id:this.state.discipline_id, - sub_discipline_id:this.state.sub_discipline_id, - tag_discipline_id:this.state.tag_discipline_id, - public: this.state.defaultActiveKey, - difficulty: this.state.difficulty, - item_type: this.state.item_type, - keywords: this.state.keywords, - page: this.state.page, - per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), - }; - this.getdatasy(data); - this.getbasket_listdata(); - } - }).catch((error) => { - //console.log(error); - }) + } //全选试题库 selectallquestionsonthispage=()=>{ @@ -739,7 +762,7 @@ class NewMyShixunModel extends Component { } const data={ item_ids:item_idsdata, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), } this.getitem_baskets(data); this.setState({ @@ -768,7 +791,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); this.getbasket_listdata(); @@ -806,7 +829,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:oj_status, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } diff --git a/public/react/src/modules/question/Paperreview_item.js b/public/react/src/modules/question/Paperreview_item.js index 9112aa248..a9747e8c2 100644 --- a/public/react/src/modules/question/Paperreview_item.js +++ b/public/react/src/modules/question/Paperreview_item.js @@ -426,8 +426,8 @@ class Paperreview_item extends Component { }}>
-

题数:{this.props.all_score}

-

总分:{this.props.all_questions_count}

+

题数:{this.props.all_questions_count}

+

总分:{this.props.all_score}

this.props.setnewmyshixunmodelbool(true)}> diff --git a/public/react/src/modules/question/Paperreview_items.js b/public/react/src/modules/question/Paperreview_items.js index 81ec320b5..8e86c514a 100644 --- a/public/react/src/modules/question/Paperreview_items.js +++ b/public/react/src/modules/question/Paperreview_items.js @@ -59,8 +59,8 @@ class Paperreview_items extends Component { let {paperreviewsingleindex,paperreviewsinglename,typenames,indexs,object,typenamesn}=this.props; // console.log(object); - console.log("Paperreview_items"); - console.log(object.item_id); + // console.log("Paperreview_items"); + // console.log(object.item_id); return (
{ diff --git a/public/react/src/modules/question/Paperreview_single.js b/public/react/src/modules/question/Paperreview_single.js index 5b64372a8..fdc9ff095 100644 --- a/public/react/src/modules/question/Paperreview_single.js +++ b/public/react/src/modules/question/Paperreview_single.js @@ -17,6 +17,7 @@ import Itembankstop from "./component/Itembankstop"; import NoneData from './component/NoneData'; import './questioncss/questioncom.css'; import '../tpm/newshixuns/css/Newshixuns.css'; +import QuillForEditor from "../../common/quillForEditor"; const tagArray = [ 'A.', 'B.', 'C.', 'D.', 'E.', 'F.', 'G.', 'H.', 'I.', @@ -69,13 +70,42 @@ class Paperreview_single extends Component { render() { let {questions, totalscore, total, items} = this.state; let {objectsingle, indexx, paperreviewsingleindex, indexxy,name} = this.props; + + + var itemssname=""; + try { + itemssname= JSON.parse(objectsingle.name); + }catch (e) { + } + if(itemssname===undefined){ + itemssname=objectsingle.name + } return (
this.props.showparagraphs(indexxy,name)} style={{ minHeight: "114px", }}> - + {/*顶部*/}
@@ -99,9 +129,35 @@ class Paperreview_single extends Component { ` } -
-
+ { + objectsingle.item_type==="PROGRAM"? +
+
+ ({objectsingle.score}分) +
+
+ +
+
+ : +
+
+ ({objectsingle.score}分) +
+
+ + +
+
+ } +
{/*内容*/}
@@ -114,7 +170,7 @@ class Paperreview_single extends Component { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { return (

- + {object.choice_text}

@@ -126,8 +182,17 @@ class Paperreview_single extends Component { objectsingle.item_type === "PROGRAM" ?

-

+ { + objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description? +

+ +

+ : + ""}

: @@ -137,8 +202,21 @@ class Paperreview_single extends Component { return (

{tagArray[index]} -

+

+ {object ? + object.choice_text === undefined || object.choice_text=== null || object.choice_text === "" ? + "" + : + object.choice_text.length>0? + + :"" + : + "" + } +

) }) diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index 171a2f2d7..3264c52fa 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -33,7 +33,7 @@ class Question extends Component { placement: 'right', modalsType: false, modalsTypes:false, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titilesms:"单选题", titbool: false, @@ -66,9 +66,28 @@ class Question extends Component { oj_status:null, isVisible: false, selectionbools:false, + chakanjiexiboolindex:"无", } } + + chakanjiexibool=(index)=>{ + debugger + if(this.state.chakanjiexiboolindex===index){ + this.setState({ + chakanjiexiboolindex:"无", + }) + return + } + this.setState({ + chakanjiexiboolindex:index, + }) + } + setmychakanjiexibool=(str)=>{ + this.setState({ + chakanjiexiboolindex:str, + }) + } setdiscipline_id=(discipline_id)=>{ this.setState({ discipline_id:discipline_id, @@ -338,6 +357,8 @@ class Question extends Component { oj_status:this.state.oj_status }; this.getdata(data); + this.setmychakanjiexibool("无") + } showDrawer = () => { if(this.state.visible===true){ @@ -378,7 +399,7 @@ class Question extends Component { this.setState({ modalsType: true, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titbool: true, timuid: id @@ -882,6 +903,8 @@ class Question extends Component { /> {/*头部*/} this.chakanjiexibool(e)} getitem_basketss={(id)=>this.getitem_basketss(id)} selectallquestionsonthispage={()=>this.selectallquestionsonthispage()} getitem_baskets={(e)=>this.getitem_baskets(e)} diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index 99a713d7f..93283c307 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -10,6 +10,7 @@ import axios from 'axios' import update from 'immutability-helper' import './../questioncss/questioncom.css'; import {getUrl, ActionBtn, DMDEditor, ConditionToolTip} from 'educoder'; +import QuillForEditor from '../../../common/quillForEditor'; const { TextArea } = Input; const confirm = Modal.confirm; const $ = window.$ @@ -70,10 +71,13 @@ class ChoquesEditor extends Component{ this.state = { question_choices: _question_choices || ['', '', '', ''], standard_answers: _standard_answers || [false, false, false, false], - question_title: this.props.question_title || '', + question_title: this.props.question_title!==undefined?JSON.parse(this.props.question_title):"", question_type: this.props.question_type || 0, question_score: this.props.question_score || this.props.init_question_score, - question_titles:this.props.question_titles||'', + question_titles: this.props.question_titles!==undefined?JSON.parse(this.props.question_titles):"", + question_titlesysl:this.props.question_titlesysl||'', + question_titleysl:this.props.question_title || '', + item_banksedit:[], } } addOption = () => { @@ -122,38 +126,33 @@ class ChoquesEditor extends Component{ } onSave = () => { var editordata=[]; - const {question_title, question_score, question_type,question_titles, question_choices, standard_answers } = this.state; + const {question_title, question_score,question_titleysl,question_titlesysl, question_type,question_titles, question_choices, standard_answers } = this.state; const { question_id_to_insert_after, question_id } = this.props // TODO check const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1); - if(!question_title) { - this.refs['titleEditor'].showError() + if(!question_titleysl) { this.props.showNotification('请您输入题干'); return editordata; } - if(!answerArray || answerArray.length == 0) { - this.props.showNotification('请先点击选择本选择题的正确选项'); - return editordata; - } - - if(!answerArray || answerArray.length < 2) { - this.props.showNotification('多选题最小正确选项为2个'); - return editordata; - } for(let i = 0; i < question_choices.length; i++) { if (!question_choices[i]) { - this.refs[`optionEditor${i}`].showError() this.props.showNotification(`请先输入 ${tagArray[i]} 选项的内容`); return editordata; } } - - if(!question_titles) { - this.refs['titleEditor2'].showError() - this.props.showNotification('请您输入题目解析'); + if(!answerArray || answerArray.length == 0) { + this.props.showNotification('请先点击选择本选择题的正确选项'); + return editordata; + } + if(!answerArray || answerArray.length < 2) { + this.props.showNotification('多选题最小正确选项为2个'); return editordata; } + // if(!question_titlesysl) { + // this.props.showNotification('请您输入题目解析'); + // return editordata; + // } /** { "question_title":"同学朋友间常用的沟通工具是什么?", @@ -162,7 +161,7 @@ class ChoquesEditor extends Component{ "question_choices":["a答案","b答案","c答案","d答案"], "standard_answers":[1] }*/ - editordata=[question_title,answerArray,question_choices,question_titles]; + editordata=[question_titleysl,answerArray,question_choices,question_titlesysl]; // question_title, // question_type: answerArray.length > 1 ? 1 : 0, // question_score, @@ -186,8 +185,10 @@ class ChoquesEditor extends Component{ try { this.setState({ item_banksedit:this.props.item_banksedit, - question_title:this.props.item_banksedit.name, - question_titles:this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titleysl:this.props.item_banksedit.name|| '', + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", + question_titlesysl:this.props.item_banksedit.analysis||'', mychoicess:this.props.item_banksedit.choices, }) @@ -205,8 +206,10 @@ class ChoquesEditor extends Component{ if(prevProps.item_banksedit !== this.props.item_banksedit) { this.setState({ item_banksedit: this.props.item_banksedit, - question_title: this.props.item_banksedit.name, - question_titles: this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titleysl:this.props.item_banksedit.name|| '', + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", + question_titlesysl:this.props.item_banksedit.analysis||'', mychoicess: this.props.item_banksedit.choices, }) @@ -217,15 +220,34 @@ class ChoquesEditor extends Component{ standard_answers[index] = !standard_answers[index] this.setState({ standard_answers }) } - onOptionContentChange = (value, index) => { + onOptionContentChange = (value,quill,index) => { if (index >= this.state.question_choices.length) { // TODO 新建,然后删除CD选项,再输入题干,会调用到这里,且index是3 return; } + var texts; + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + texts=""; + } else { + if(_text.length>=301){ + var result = _text.substring(0,300); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value); + texts=value; + } + } let question_choices = this.state.question_choices.slice(0); - question_choices[index] = value; - this.setState({ question_choices }) + question_choices[index] = texts; + console.log(question_choices); + this.setState({ question_choices }); } + on_question_score_change = (e) => { this.setState({ question_score: e }) } @@ -241,6 +263,57 @@ class ChoquesEditor extends Component{ toShowMode = () => { } + + onContentChange=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titleysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + var texts=""; + if(_text.length>=1001){ + var result = _text.substring(0,1000); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } + this.setState({ + question_titleysl:texts + }) + } + } + onContentChanges=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titlesysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + var texts=""; + if(_text.length>=1001){ + var result = _text.substring(0,1000); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } + this.setState({ + question_titlesysl:texts + }) + } + } + + render() { let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state; let { question_id, index, exerciseIsPublish, @@ -271,7 +344,7 @@ class ChoquesEditor extends Component{ flex:1 } .optionRow { - margin:0px!important; + /* margin:0px!important; */ /* margin-bottom: 20px!important; */ } .signleEditor .content_editorMd_show{ @@ -291,21 +364,26 @@ class ChoquesEditor extends Component{ 题干:

- this.setState({ question_title: val})} - ref="titleEditor" + + />
{/* {!question_id ? '新建' : '编辑'} */} * - 答案选项:点击答案可设置正确答案 + 答案选项:点击选项可设置正确答案
{question_choices.map( (item, index) => { const bg = standard_answers[index] ? 'check-option-bg' : '' - return
+ return
0?"df optionRow mt15": "df optionRow"} > {/* 点击设置答案 */} {/* TODO 加了tooltip后,会丢失掉span的class */} {/* */} @@ -317,13 +395,30 @@ class ChoquesEditor extends Component{ {/* */}
- this.onOptionContentChange(value, index)} - initValue={item} - > + + { + item===undefined||item===null||item===""? + this.onOptionContentChange(value,quill,index)} + /> + : + this.onOptionContentChange(value,quill,index)} + /> + + }
{exerciseIsPublish || index<=2? @@ -346,32 +441,21 @@ class ChoquesEditor extends Component{ -

+

{/* {!question_id ? '新建' : '编辑'} */} - * + 题目解析:

- - this.setState({ question_titles: val})} - ref="titleEditor2" - - > +
+
diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index 2c3ea6f36..da85ce0f7 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -25,7 +25,6 @@ class Contentpart extends Component { this.state = { page:1, chakanjiexibool:false, - chakanjiexiboolindex:"无", } } //初始化 @@ -35,18 +34,51 @@ class Contentpart extends Component { } chakanjiexibool=(index)=>{ - debugger - if(this.state.chakanjiexiboolindex===index){ - this.setState({ - chakanjiexiboolindex:"无", - }) - return - } - this.setState({ - chakanjiexiboolindex:index, - }) + this.props.chakanjiexibool(index); } + xinzenw=(e)=>{ + var urls="?"; + if(this.props.discipline_id){ + if(urls==="?"){ + urls=urls+`discipline_id=${this.props.discipline_id}` + }else { + urls=urls+`&discipline_id=${this.props.discipline_id}` + } + } + if(this.props.sub_discipline_id){ + if(urls==="?"){ + urls=urls+`sub_discipline_id=${this.props.sub_discipline_id}` + }else { + urls=urls+`&sub_discipline_id=${this.props.sub_discipline_id}` + } + } + if(this.props.tag_discipline_id){ + if(urls==="?"){ + urls=urls+`sub_discipline_id=${this.props.tag_discipline_id}` + }else { + urls=urls+`&sub_discipline_id=${this.props.tag_discipline_id}` + } + } + if(this.props.difficulty){ + if(urls==="?"){ + urls=urls+`difficulty=${this.props.difficulty}&` + }else { + urls=urls+`&difficulty=${this.props.difficulty}` + } + } + if(this.props.item_type){ + if(urls==="?"){ + urls=urls+`item_type=${this.props.item_type}` + }else { + urls=urls+`&item_type=${this.props.item_type}` + } + + } + + + this.props.history.push("/question/newitem"+urls); + } render() { let {page}=this.state; let {defaultActiveKey,item_type,booljupyterurls}=this.props; @@ -149,7 +181,7 @@ class Contentpart extends Component {
{ defaultActiveKey===0||defaultActiveKey==="0"? - + this.xinzenw(e)}>

新增

@@ -230,6 +262,7 @@ class Contentpart extends Component { : this.props.Contentdata.items.map((object, index) => { return ( this.chakanjiexibool(keindex)} listjihe={index+1} keindex={index} diff --git a/public/react/src/modules/question/component/Headplugselections.js b/public/react/src/modules/question/component/Headplugselections.js index 3cff40cc2..206b556e9 100644 --- a/public/react/src/modules/question/component/Headplugselections.js +++ b/public/react/src/modules/question/component/Headplugselections.js @@ -153,7 +153,7 @@ class Headplugselections extends Component { { item&&item.map((list,k)=>{ return( - +
diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 5192eca4e..046565356 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -19,6 +19,8 @@ import './../questioncss/questioncom.css'; import Newknledpots from './Newknledpots' const InputGroup = Input.Group; const {Option} = Select; +const queryString = require('query-string'); + const options = [ { value: '方向', @@ -41,7 +43,7 @@ const options = [ ], }, ]; - +//Comthetestpaperst试卷的 class Itembankstop extends Component { constructor(props) { super(props); @@ -53,12 +55,23 @@ class Itembankstop extends Component { knowledgepoints: [], knowledgepoints2:[], options: [], - NewknTypedel:false + NewknTypedel:false, + boolred:false, + } } + setboolred=(bool)=>{ + this.setState({ + boolred:bool + }) + + } + //初始化 componentDidMount() { + + try { this.props.getcontentMdRef(this); } catch (e) { @@ -68,7 +81,53 @@ class Itembankstop extends Component { options: this.props.disciplmy, }) + console.log("数据"); + console.log(this.props); + const parsed = queryString.parse(this.props.location.search); + console.log(parsed); + try { + if(JSON.stringify(parsed)==={}||JSON.stringify(parsed)==="{}"){ + + }else { + if(parsed.discipline_id){ + if(parsed.sub_discipline_id){ + this.setState({ + rbkc:[parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)] + }) + this.props.form.setFieldsValue({ + rbkc: [parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)], + }); + this.getdatasmyss(parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)); + + } + + } + + if(parsed.item_type){ + this.setState({ + rbtx:parsed.item_type, + }) + this.props.form.setFieldsValue({ + rbtx:parsed.item_type, + }); + this.props.setitem_type(parsed.item_type); + } + + if(parsed.difficulty){ + this.setState({ + rbnd:parsed.difficulty, + }) + this.props.form.setFieldsValue({ + rbnd:parsed.difficulty, + }); + } + + } + + }catch (e) { + + } } componentDidUpdate(prevProps) { @@ -79,6 +138,7 @@ class Itembankstop extends Component { }) } if(prevProps.disciplinesdata!== this.props.disciplinesdata){ + console.log("新增开始加载了") try { if(this.props.item_banksedit.discipline &&this.props.item_banksedit.sub_discipline){ const didata = this.props.disciplinesdata; @@ -110,6 +170,27 @@ class Itembankstop extends Component { knowledgepoints2: _result, }) } + + + try { + const parsed = queryString.parse(this.props.location.search); + if(JSON.stringify(parsed)==={}||JSON.stringify(parsed)==="{}"){ + + }else { + if(parsed.discipline_id){ + if(parsed.sub_discipline_id){ + this.setState({ + rbkc:[parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)] + }) + this.props.form.setFieldsValue({ + rbkc: [parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)], + }); + this.getdatasmyss(parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)); + } + } + } + }catch (e) { + } }catch (e) { } } @@ -125,6 +206,7 @@ class Itembankstop extends Component { this.handletag_disciplinesChange(this.props.item_banksedit.tag_disciplines); } try { + //初始化课程 this.handdisciplinesChange(this.props.item_banksedit.discipline,this.props.item_banksedit.sub_discipline); }catch (e) { @@ -175,7 +257,42 @@ class Itembankstop extends Component { } } } + getdatasmyss=(id,ids)=>{ + if(this.props.disciplinesdata){ + try { + if(id &&ids){ + var didata = this.props.disciplinesdata; + var knowledgepointsdata = []; + for (var i = 0; i < didata.length; i++) { + //方向 + if (id === didata[i].id) { + const fxdidata = didata[i].sub_disciplines; + for (var j = 0; j < fxdidata.length; j++) { + //课程 + if (ids === fxdidata[j].id) { + const zsddata = fxdidata[j].tag_disciplines; + for (var k = 0; k < zsddata.length; k++) { + //知识点 + knowledgepointsdata.push(zsddata[k]); + } + } + } + } + } + + + + this.setState({ + knowledgepoints:knowledgepointsdata, + knowledgepoints2: knowledgepointsdata, + }) + }else{ + } + }catch (e) { + } + } + } handdisciplinesChange =(name,title)=>{ this.setState({ rbkc:[name.id,title.id] @@ -413,6 +530,10 @@ class Itembankstop extends Component { } NewknTypedeldel=(bool)=>{ + if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ + this.props.showNotification(`请选择课程方向`); + return; + } this.setState({ NewknTypedel:bool }) @@ -420,21 +541,34 @@ class Itembankstop extends Component { } NewknTypedeltyoedel=(value)=>{ + var knowledgepointmys= this.state.knowledgepoints; + var konwbool=null; + for(let myda of knowledgepointmys) { + if(myda.name===value){ + konwbool="yes" + break; + } + } + if(konwbool!=null){ + this.props.showNotification(`重复的知识点`); + this.setboolred(true); + return + } + + if(value===null||value===""){ this.props.showNotification(`请输入知识点`); + this.setboolred(true); return } if(value.length===0){ this.props.showNotification(`请输入知识点`); + this.setboolred(true); return } - if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ - this.props.showNotification(`请选择课程方向`); - return; - } var data={ name:value, sub_discipline_id:this.state.rbkc[1] @@ -448,19 +582,37 @@ class Itembankstop extends Component { id: result.data.tag_discipline_id, name:value, } - this.state.knowledgepoints.push(leydata); - const _result =[]; - this.state.knowledgepoints.filter(item => { - if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { - _result.push(item); - } - }); - this.setState({ - Knowpoints: this.state.Knowpoints, - knowledgepoints: this.state.knowledgepoints, - knowledgepoints2: _result, - }) + if(this.state.Knowpoints.length>=5){ + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + }else{ + this.state.Knowpoints.push(leydata); + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + } + } }).catch((error) => { //console.log(error); @@ -476,6 +628,11 @@ class Itembankstop extends Component { let {page, options,NewknTypedel,knowledgepoints,knowledgepoints2,Knowpoints} = this.state; const {getFieldDecorator} = this.props.form; + console.log("this.state.rbkc"); + console.log(this.state.rbkc); + console.log(options); + + return (
@@ -512,6 +669,8 @@ class Itembankstop extends Component { { NewknTypedel? this.setboolred(bool)} NewknTypedeldel={(bool)=>this.NewknTypedeldel(bool)} NewknTypedeltyoedel={(value)=>this.NewknTypedeltyoedel(value)} > @@ -555,32 +714,34 @@ class Itembankstop extends Component { this.NewknTypedeldel(true)}/> -
+
+ )} + - {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { - return ( -
-

{object.name}

+
this.deletesobject(object, index)} src={getImageUrl("images/educoder/bzucha.png")}/> + }}> -
- ) - })} + {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { + return ( +
+

{object.name}

+ this.deletesobject(object, index)} src={getImageUrl("images/educoder/bzucha.png")}/> +
+ ) + })} -
-
- )} - + + +
{ var editordata=[]; - const {question_title, question_score, question_type,question_titles, zqda,question_choices, standard_answers } = this.state; + const {question_title, question_score,question_titleysl,question_titlesysl, question_type,question_titles, zqda,question_choices, standard_answers } = this.state; const { question_id_to_insert_after, question_id } = this.props // TODO check const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1); - if(!question_title) { - this.refs['titleEditor'].showError() + if(!question_titleysl) { this.props.showNotification('请您输入题干'); return editordata; } @@ -116,12 +119,11 @@ class JudquestionEditor extends Component{ - - if(!question_titles) { - this.refs['titleEditor2'].showError() - this.props.showNotification('请您输入题目解析'); - return editordata; - } + // + // if(!question_titlesysl) { + // this.props.showNotification('请您输入题目解析'); + // return editordata; + // } /** { "question_title":"同学朋友间常用的沟通工具是什么?", @@ -132,7 +134,7 @@ class JudquestionEditor extends Component{ }*/ - editordata=[question_title,zqda,question_titles]; + editordata=[question_titleysl,zqda,question_titlesysl]; // question_title, // question_type: answerArray.length > 1 ? 1 : 0, // question_score, @@ -156,10 +158,11 @@ class JudquestionEditor extends Component{ try { this.setState({ item_banksedit:this.props.item_banksedit, - question_title:this.props.item_banksedit.name, - question_titles:this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", mychoicess:this.props.item_banksedit.choices, - + question_titleysl:this.props.item_banksedit.name|| '', + question_titlesysl:this.props.item_banksedit.analysis||'', }) if(this.props.item_banksedit){ if(this.props.item_banksedit.choices){ @@ -194,9 +197,11 @@ class JudquestionEditor extends Component{ if(prevProps.item_banksedit !== this.props.item_banksedit){ this.setState({ item_banksedit:this.props.item_banksedit, - question_title:this.props.item_banksedit.name, - question_titles:this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", mychoicess:this.props.item_banksedit.choices, + question_titleysl:this.props.item_banksedit.name|| '', + question_titlesysl:this.props.item_banksedit.analysis||'', }) if(this.props.item_banksedit){ @@ -275,6 +280,55 @@ class JudquestionEditor extends Component{ }) } + + onContentChange=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titleysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + var texts=""; + if(_text.length>=1001){ + var result = _text.substring(0,1000); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } + this.setState({ + question_titleysl:texts + }) + } + } + onContentChanges=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titlesysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + var texts=""; + if(_text.length>=1001){ + var result = _text.substring(0,1000); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value =JSON.stringify(value); + texts=value; + } + this.setState({ + question_titlesysl:texts + }) + } + } render() { let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state; let { question_id, index, exerciseIsPublish, @@ -325,16 +379,21 @@ class JudquestionEditor extends Component{ 题干:

- this.setState({ question_title: val})} - ref="titleEditor" + + />
{/* {!question_id ? '新建' : '编辑'} */} * - 答案选项:点击答案可设置正确答案 + 答案选项:点击选项可设置正确答案
- this.setState({ question_titles: val})} - ref="titleEditor2" - > +
- +
) diff --git a/public/react/src/modules/question/component/Listjihe.js b/public/react/src/modules/question/component/Listjihe.js index f796a3f45..54cc82784 100644 --- a/public/react/src/modules/question/component/Listjihe.js +++ b/public/react/src/modules/question/component/Listjihe.js @@ -1,15 +1,18 @@ import React, {Component} from "react"; import {Link, NavLink} from 'react-router-dom'; -import {WordsBtn, ActionBtn,SnackbarHOC,getImageUrl,markdownToHTML} from 'educoder'; +import {WordsBtn, ActionBtn, SnackbarHOC, getImageUrl, markdownToHTML} from 'educoder'; import axios from 'axios'; import { notification, Spin, Table, Pagination, - Radio + Radio, + Tooltip } from "antd"; import './../questioncss/questioncom.css'; +import QuillForEditor from "../../../common/quillForEditor"; + const tagArray = [ 'A.', 'B.', 'C.', 'D.', 'E.', 'F.', 'G.', 'H.', 'I.', 'J.', 'K.', 'L.', 'M.', 'N.', 'O.', 'P.', 'Q.', 'R.', @@ -20,97 +23,144 @@ const tagArrays = [ 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ] + class Listjihe extends Component { constructor(props) { super(props); this.state = { - page:1, - name:"单选题", - nd:"简单", + page: 1, + name: "单选题", + nd: "简单", } } + //初始化 - componentDidMount(){ + componentDidMount() { } //选用 - Selectingpracticaltraining=(id)=>{ - let data={} - if(this.props.exam_id===undefined){ - data={ - item_ids:[id] + Selectingpracticaltraining = (id) => { + let data = {} + if (this.props.exam_id === undefined) { + data = { + item_ids: [id] } - }else{ - data={ - item_ids:[id], - exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + } else { + data = { + item_ids: [id], + exam_id: this.props.exam_id === undefined ? "" : parseInt(this.props.exam_id), } - } + } this.props.getitem_baskets(data); } //撤销 - Selectingpracticaltrainings=(id)=>{ + Selectingpracticaltrainings = (id) => { this.props.getitem_basketss(id); } - - - render() { - let {page,name,nd}=this.state; - let {defaultActiveKey,items,listjihe,chakanjiexiboolindex,keindex}=this.props; + let {page, name, nd} = this.state; + let {defaultActiveKey, items, listjihe, chakanjiexiboolindex, keindex} = this.props; // 编程答案 - var rightkey=null - - if(items){ - if(items.item_type){ - if(items.item_type==="PROGRAM"){ - - }else{ - if(items.item_type==="JUDGMENT") { - - - if(items.choices){ - if(items.choices.length>0){ - var arr= items.choices; - for(let data of arr) { - if(data.is_answer===true){ - rightkey=data.choice_text; - break; - } - } - } - } - }else { + var rightkey = null + var MULTIPLEkey = null; + if (items) { + if (items.item_type) { + if (items.item_type === "PROGRAM") { + + } else { + if (items.item_type === "JUDGMENT") { + //多选题 if (items.choices) { if (items.choices.length > 0) { var arr = items.choices; - for (var i = 0; i < arr.length; i++) { - if (arr[i].is_answer === true) { - rightkey = i; + for (let data of arr) { + if (data.is_answer === true) { + rightkey = data.choice_text; break; } } } } + } else { + // 单选题和判断题 + if(items.item_type === "MULTIPLE"){ + if (items.choices) { + if (items.choices.length > 0) { + var arr = items.choices; + for (var i = 0; i < arr.length; i++) { + if (arr[i].is_answer === true) { + if(MULTIPLEkey===null){ + MULTIPLEkey = tagArrays[i]; + + }else{ + MULTIPLEkey =MULTIPLEkey+ tagArrays[i]; + } + + } + } + } + } - + }else{ + if (items.choices) { + if (items.choices.length > 0) { + var arr = items.choices; + for (var i = 0; i < arr.length; i++) { + if (arr[i].is_answer === true) { + rightkey = i; + break; + } + } + } + } + } } } } } - + var itemssname=""; + try { + itemssname= JSON.parse(items.name); + }catch (e) { + } + if(itemssname===undefined){ + itemssname=items.name + } return ( -
+
{/*顶部*/} +
{ @@ -120,39 +170,89 @@ class Listjihe extends Component {
.
-
-
+ { + items.item_type==="PROGRAM"? + +
+
+ : +
+ { items===undefined||items===null||items===""?"": + items.name === undefined || items.name === null || items.name === "" ? + "" + : + items.name.length>0? + + :"" + } +
+ } +
{/*内容*/}
- {items.item_type==="JUDGMENT"? -

+ {items.item_type === "JUDGMENT" ? +

{ - items === undefined ||items === null? "" : items.choices.map((object, index) => { + items === undefined || items === null ? "" : items.choices.map((object, index) => { return ( -

- +

+ {object.choice_text}

) }) } -

: - items.item_type==="PROGRAM"? +

: + items.item_type === "PROGRAM" ?

-

-

+

+ { + items&&items.program_attr&&items.program_attr.description? +

+ + +

+ :"" + } + + +

: -

+

{ - items === undefined ||items === null? "" : items.choices.map((object, index) => { + items === undefined || items === null ? "" : items.choices.map((object, index) => { return ( -

- {tagArray[index]} -

+

+

{tagArray[index]}

+

+ {object ? + object.choice_text === undefined || object.choice_text=== null || object.choice_text === "" ? + + "" + : + object.choice_text.length>0? + + :"" + + + : + "" + } +

) }) @@ -163,91 +263,98 @@ class Listjihe extends Component {
-

难度:{items.difficulty===1?"简单":items.difficulty===2?"适中":items.difficulty===3?"困难":""}

-

题型:{items.item_type==="SINGLE"?"单选题":items.item_type==="MULTIPLE"?"多选题":items.item_type==="JUDGMENT"?"判断题":items.item_type==="PROGRAM"?"编程题":""}

+

难度:{items.difficulty === 1 ? "简单" : items.difficulty === 2 ? "适中" : items.difficulty === 3 ? "困难" : ""} +

+

题型:{items.item_type === "SINGLE" ? "单选题" : items.item_type === "MULTIPLE" ? "多选题" : items.item_type === "JUDGMENT" ? "判断题" : items.item_type === "PROGRAM" ? "编程题" : ""} +

{/*更新时间*/}

更新时间:{items.update_time}

{ - this.props.defaultActiveKey==="0"||this.props.defaultActiveKey===0? + this.props.defaultActiveKey === "0" || this.props.defaultActiveKey === 0 ? "" :

创建者:{items.author.name}

} { - items.item_type==="PROGRAM"? + items.item_type === "PROGRAM" ?

编程语言:{items.program_attr.language}

- :"" + : "" } { - items.item_type==="PROGRAM"? - items.program_attr.status===0? + items.item_type === "PROGRAM" ? + items.program_attr.status === 0 ?

未发布

- :"" - :"" + : "" + : "" }
{ - items.choosed===true? -

this.Selectingpracticaltrainings(items.id)}> + items.choosed === true ? +

this.Selectingpracticaltrainings(items.id)}> 撤销

: - items.item_type==="PROGRAM"? - items.program_attr.status===0? -

- - 选用 -

+ items.item_type === "PROGRAM" ? + items.program_attr.status === 0 ? + +

+ + 选用 +

+
+ : -

this.Selectingpracticaltraining(items.id)}> +

this.Selectingpracticaltraining(items.id)}> 选用

: -

this.Selectingpracticaltraining(items.id)}> +

this.Selectingpracticaltraining(items.id)}> 选用

} { - defaultActiveKey===0||defaultActiveKey==="0"? + defaultActiveKey === 0 || defaultActiveKey === "0" ?
-

this.props.showmodelysl(items.id)}> +

this.props.showmodelysl(items.id)}> 删除

{ - items.item_type==="PROGRAM"? + items.item_type === "PROGRAM" ? -

+

编辑

: -

+

编辑

} { - items.public===false? - items.item_type==="PROGRAM"? - items.program_attr.status===0? + items.public === false ? + items.item_type === "PROGRAM" ? + items.program_attr.status === 0 ? "" : -

this.props.showmodels(items.id)}> +

this.props.showmodels(items.id)}> 公开

: -

this.props.showmodels(items.id)}> +

this.props.showmodels(items.id)}> 公开

@@ -256,54 +363,73 @@ class Listjihe extends Component { }
- :"" + : "" } { - items.item_type==="PROGRAM"? + items.item_type === "PROGRAM" ? "" : -

this.props.chakanjiexibool(keindex)}> +

this.props.chakanjiexibool(keindex)}> 查看解析

} -
{ - chakanjiexiboolindex===keindex?
+ chakanjiexiboolindex === keindex ?
-
+
{ - items.item_type==="SINGLE" || items.item_type==="MULTIPLE"? + items.item_type === "SINGLE" ? +

+

+ : items.item_type === "MULTIPLE"?

+

:

}
- { - items&&items.analysis? - "" - :"" - } -
-

+

+ {items ? + items.analysis=== undefined || items.analysis=== null || items.analysis === "" ? + + "" + : + items.analysis.length>0? + + : + "" + : + "" + }

-
:"" +
: "" } @@ -313,4 +439,5 @@ class Listjihe extends Component { } } + export default Listjihe; diff --git a/public/react/src/modules/question/component/Newknledpots.js b/public/react/src/modules/question/component/Newknledpots.js index a097b7d79..4668c5e5a 100644 --- a/public/react/src/modules/question/component/Newknledpots.js +++ b/public/react/src/modules/question/component/Newknledpots.js @@ -14,10 +14,35 @@ class PaperDeletModel extends Component { } handleChange=(e)=>{ - this.setState({ - newkntypeinput: e.target.value - }) + // this.setState({ + // newkntypeinput: e.target.value + // }) + // console.log(e.target.value); + // console.log(e.target.value.length); + this.setState({ + newkntypeinput: e.target.value + }) + this.props.setboolred(false); + // + // debugger + // console.log(e); + // + // if(e.target.value.length>0){ + // if(e.target.value.length>=16){ + // var result = e.target.value.substring(0,15); + // this.setState({ + // newkntypeinput: result + // }) + // } + // } + } + mysinputOnBlur=(e)=>{ + console.log("失去焦点了"); + } + + inputOnFocus=(e)=>{ + console.log("获取焦点"); } render() { @@ -34,8 +59,8 @@ class PaperDeletModel extends Component { width="442px" >
-
- +
+
this.props.NewknTypedeldel(false)}>取消 diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index c111aa41b..36f9bc93a 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -75,10 +75,12 @@ class SingleEditor extends Component{ this.state = { question_choices: _question_choices || ['', '', '', ''], standard_answers: _standard_answers || [false, false, false, false], - question_title: this.props.question_title || '', + question_title: this.props.question_title!==undefined?JSON.parse(this.props.question_title):"", question_type: this.props.question_type || 0, question_score: this.props.question_score || this.props.init_question_score, - question_titles:this.props.question_titles||'', + question_titles: this.props.question_titles!==undefined?JSON.parse(this.props.question_titles):"", + question_titlesysl:this.props.question_titlesysl||'', + question_titleysl:this.props.question_title || '', item_banksedit:[], } } @@ -121,35 +123,44 @@ class SingleEditor extends Component{ } onSave = () => { var editordata=[]; - const {question_title, question_score, question_type,question_titles, question_choices, standard_answers } = this.state; + const {question_title, question_titleysl,question_score, question_type,question_titles,question_titlesysl, question_choices, standard_answers } = this.state; const { question_id_to_insert_after, question_id } = this.props // TODO check const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1); - if(!question_title) { - this.refs['titleEditor'].showError() - this.props.showNotification('请您输入题干'); - return editordata; - } - if(!answerArray || answerArray.length == 0) { - this.props.showNotification('请先点击选择本选择题的正确选项'); + // const _text = quill.getText(); + // const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + // if (!reg.test(_text)) { + // // 处理编辑器内容为空 + // } else { + // // 提交到后台的内容需要处理一下; + // value = JSON.stringify(value) + // } + if(!question_titleysl) { + // this.refs['titleEditor'].showError() + this.props.showNotification('请您输入题干'); return editordata; } - - for(let i = 0; i < question_choices.length; i++) { if (!question_choices[i]) { - this.refs[`optionEditor${i}`].showError() + // this.refs[`optionEditor${i}`].showError() this.props.showNotification(`请先输入 ${tagArray[i]} 选项的内容`); return editordata; } } - if(!question_titles) { - this.refs['titleEditor2'].showError() - this.props.showNotification('请您输入题目解析'); + if(!answerArray || answerArray.length == 0) { + this.props.showNotification('请先点击选择本选择题的正确选项'); return editordata; } + + + + + // if(!question_titlesysl) { + // this.props.showNotification('请您输入题目解析'); + // return editordata; + // } /** { "question_title":"同学朋友间常用的沟通工具是什么?", @@ -158,7 +169,7 @@ class SingleEditor extends Component{ "question_choices":["a答案","b答案","c答案","d答案"], "standard_answers":[1] }*/ - editordata=[question_title,answerArray,question_choices,question_titles]; + editordata=[question_titleysl,answerArray,question_choices,question_titlesysl]; // question_title, // question_type: answerArray.length > 1 ? 1 : 0, // question_score, @@ -184,8 +195,10 @@ class SingleEditor extends Component{ try { this.setState({ item_banksedit:this.props.item_banksedit, - question_title:this.props.item_banksedit.name, - question_titles:this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titleysl:this.props.item_banksedit.name|| '', + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", + question_titlesysl:this.props.item_banksedit.analysis||'', mychoicess:this.props.item_banksedit.choices, }) @@ -204,8 +217,10 @@ class SingleEditor extends Component{ if(prevProps.item_banksedit !== this.props.item_banksedit) { this.setState({ item_banksedit: this.props.item_banksedit, - question_title: this.props.item_banksedit.name, - question_titles: this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titleysl:this.props.item_banksedit.name|| '', + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", + question_titlesysl:this.props.item_banksedit.analysis||'', mychoicess: this.props.item_banksedit.choices, }) @@ -229,14 +244,31 @@ class SingleEditor extends Component{ // standard_answers[index] = !standard_answers[index]; this.setState({ standard_answers }) } - onOptionContentChange = (value, index) => { + onOptionContentChange = (value,quill,index) => { if (index >= this.state.question_choices.length) { // TODO 新建,然后删除CD选项,再输入题干,会调用到这里,且index是3 return; } + var texts; + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + texts=""; + } else { + if(_text.length>=301){ + var result = _text.substring(0,300); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + texts=value; + } + } let question_choices = this.state.question_choices.slice(0); - question_choices[index] = value; - this.setState({ question_choices }) + question_choices[index] = texts; + this.setState({ question_choices }); } on_question_score_change = (e) => { this.setState({ question_score: e }) @@ -254,11 +286,61 @@ class SingleEditor extends Component{ } - onContentChange=(e)=>{ - console.log(e); + onContentChange=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titleysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + var texts=""; + if(_text.length>=1001){ + var result = _text.substring(0,1000); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } + this.setState({ + question_titleysl:texts + }) + } + } + onContentChanges=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titlesysl:"" + }) + } else { + var texts=""; + if(_text.length>=1001){ + var result = _text.substring(0,1000); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } + this.setState({ + question_titlesysl:texts + }) + } } + handleShowImage = (url) => { + console.log("点击了图片放大"); + console.log(url); + alert(url); + } + render() { - let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state; + let { question_title, question_score, question_type, question_choices, standard_answers,question_titles,question_titlesysl} = this.state; let { question_id, index, exerciseIsPublish, // question_title, // question_type, @@ -279,7 +361,6 @@ class SingleEditor extends Component{ // ////console.log("xuanzheshijuan"); // ////console.log(answerTagArray); // ////console.log(!exerciseIsPublish); - return(
- this.setState({ question_titles: val})} - ref="titleEditor2" - - > +
+
diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpapers.js b/public/react/src/modules/question/comthetestpaper/Comthetestpapers.js deleted file mode 100644 index 29f482471..000000000 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpapers.js +++ /dev/null @@ -1,656 +0,0 @@ -import React, {Component} from "react"; -import {Link, NavLink} from 'react-router-dom'; -import {WordsBtn, ActionBtn, SnackbarHOC, getImageUrl} from 'educoder'; -import axios from 'axios'; -import { - notification, - Spin, - Table, - Pagination, - Radio, - Checkbox, - Form, - Input, - Select, - Cascader, - AutoComplete, - Col, Row, InputNumber, DatePicker, Button, Tag -} from "antd"; -import './../questioncss/questioncom.css'; - -const InputGroup = Input.Group; -const {Option} = Select; - -class Comthetestpapers extends Component { - constructor(props) { - super(props); - this.contentMdRef = React.createRef() - this.state = { - page: 1, - Knowpoints: [], - rbtx: undefined, - rbkc: undefined, - knowledgepoints: [], - options: [], - } - } - - //初始化 - componentDidMount() { - try { - this.props.getcontentMdRef(this); - } catch (e) { - - } - - this.setState({ - options: this.props.disciplmy, - knowledgepoints: this.props.knowledgepoints, - }) - - - } - - - handdisciplinesChange =(name,title)=>{ - this.setState({ - rbkc:[name.id,title.id] - }) - this.props.form.setFieldsValue({ - rbkc: [name.id,title.id], - }); - - if(this.props.item_banksedit.tag_disciplines.length===0){ - const didata = this.props.disciplinesdata; - const knowledgepointsdata = []; - - for (var i = 0; i < didata.length; i++) { - //方向 - if (name.id === didata[i].id) { - const fxdidata = didata[i].sub_disciplines; - for (var j = 0; j < fxdidata.length; j++) { - //课程 - if (title.id === fxdidata[j].id) { - const zsddata = fxdidata[j].tag_disciplines; - for (var k = 0; k < zsddata.length; k++) { - //知识点 - knowledgepointsdata.push(zsddata[k]); - - - } - - } - - } - } - - - } - - this.setState({ - Knowpoints: [], - knowledgepoints: knowledgepointsdata, - }) - - } - - - - - - - - - - - } - handletag_disciplinesChange = (data) => { - try { - var sju=data[data.length-1].name; - this.setState({ - rbzsd:sju, - Knowpoints:data, - }) - this.props.form.setFieldsValue({ - rbzsd: sju, - }); - }catch (e) { - - } - } - onChange = (e) => { - - } - Getdatas = () => { - return this.handleSubmits(); - } - handleSubmits = () => { - var data = []; - this.props.form.validateFields((err, values) => { - data = []; - if (!err) { - data.push({ - rbnd: parseInt(values.rbnd) - }) - data.push({ - rbtx: values.rbtx - }) - data.push({ - rbzsd: this.state.Knowpoints - }) - data.push({ - rbkc: values.rbkc - }) - data.push({ - classroom:values.classroom - }) - data.push({ - kssc:values.kssc - }) - - } - }); - - return data; - - } - handleSubmit = (e) => { - e.preventDefault(); - this.props.form.validateFields((err, values) => { - if (!err) { - ////console.log("获取的form 数据"); - ////console.log(values); - - } - - - }); - } - - handleFormLayoutChange = (value) => { - //难度塞选 - ////console.log("难度塞选"); - ////console.log(value); - this.props.form.setFieldsValue({ - rbnd: value + "", - }); - this.setState({ - rbnd: value + "", - }) - - } - handleFormkechen = (value) => { - //课程 - ////console.log("课程"); - ////console.log(value); - var valuename = undefined; - this.props.form.setFieldsValue({ - rbzsd: value, - }); - - var arr = this.state.knowledgepoints; - for (let data of arr) { - if (data.id === value) { - this.state.Knowpoints.push(data); - valuename = data.name; - } - } - - var tmp = JSON.parse(JSON.stringify(this.state.knowledgepoints)); - for (var i = 0; i < tmp.length; i++) { - if (tmp[i].id === value) { - this.state.knowledgepoints.splice(i, 1); - } - } - - this.setState({ - rbzsd: valuename, - Knowpoints: this.state.Knowpoints, - knowledgepoints: this.state.knowledgepoints, - }) - - } - - handleFormzhishidian = (value) => { - console.log("handleFormzhishidian 课程"); - console.log(value); - - //课程 - this.props.form.setFieldsValue({ - rbkc: value, - }); - this.setState({ - rbkc:value, - }) - // console.log("handleFormzhishidian"); - // console.log(this.props.disciplinesdata); - - const didata = this.props.disciplinesdata; - const knowledgepointsdata = []; - - for (var i = 0; i < didata.length; i++) { - //方向 - if (value[0] === didata[i].id) { - const fxdidata = didata[i].sub_disciplines; - for (var j = 0; j < fxdidata.length; j++) { - //课程 - if (value[1] === fxdidata[j].id) { - const zsddata = fxdidata[j].tag_disciplines; - for (var k = 0; k < zsddata.length; k++) { - //知识点 - knowledgepointsdata.push(zsddata[k]); - - - } - - } - - } - } - - - } - - this.setState({ - Knowpoints: [], - knowledgepoints: knowledgepointsdata, - }) - - this.props.form.setFieldsValue({ - rbzsd: undefined, - }); - this.setState({ - rbzsd: undefined, - }) - } - - handleFormtixing = (value) => { - //题型 - //console.log("题型"); - //console.log(value); - this.setState({ - rbtx: value + "", - }) - this.props.form.setFieldsValue({ - rbtx: value + "", - }); - this.props.setitem_type(value); - } - preventDefault = (e) => { - e.preventDefault(); - ////console.log('Clicked! But prevent default.'); - } - deletesobject = (item, index) => { - var arr = this.state.Knowpoints; - for (let data of arr) { - if (data.id === item.id) { - this.state.knowledgepoints.push(data); - } - } - - - var tmp = JSON.parse(JSON.stringify(this.state.Knowpoints)); - for (var i = 0; i < tmp.length; i++) { - if (i >= index) { - var pos = this.state.Knowpoints.indexOf(tmp[i]); - this.state.Knowpoints.splice(pos, 1); - } - } - - this.props.form.setFieldsValue({ - rbzsd: this.state.Knowpoints, - }); - - - this.setState({ - Knowpoints: this.state.Knowpoints, - }) - - if (this.state.Knowpoints.length === 0) { - this.setState({ - rbzsd: undefined, - }) - } else if (this.state.Knowpoints.length > 0) { - try { - const myknowda = this.state.Knowpoints; - this.setState({ - rbzsd: myknowda[this.state.Knowpoints.length - 1].name, - }) - } catch (e) { - - } - - } - - } - handleSearch=(value)=>{ - - - if(value!=""){ - this.props.form.setFieldsValue({ - classroom:value, - // course:value - }); - // this.Searchvalue(value) - } - - }; - - handleChange=(e)=>{ - console.log(e); - this.props.form.setFieldsValue({ - // course:value, - classroom:e.target.value, - }) - if(e.target.value){ - if(e.target.value.length>60){ - this.setState({ - bordebool:true, - }) - }else if(e.target.value.length===0){ - this.setState({ - bordebool:true, - }) - }else{ - this.setState({ - bordebool:false, - }) - } - }else{ - this.setState({ - bordebool:true - }) - - } - - }; - - render() { - let {page,options} = this.state; - const {getFieldDecorator} = this.props.form; - const optionss = this.state.searchlist && this.state.searchlist.map(d => ); - var addonAfterthree=this.props.form&&this.props.form.getFieldValue('classroom'); - var addonAfteronelens3=0; - if(addonAfterthree){ - addonAfteronelens3=String(addonAfterthree).length; - } - - return ( - -
- -
-
-
- - {getFieldDecorator("rbkc", - { - rules: [{required: true, message: '请选择课程'}], - } - )( -
- - - -
- )} -
-
- -
- - {getFieldDecorator("rbzsd" - )( -
- - - -
- - {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { - return ( -
-

{object.name}

- this.deletesobject(object, index)}> -
- ) - })} - -
-
- )} -
-
- -
- -
- - {getFieldDecorator('classroom', { - rules: [{required: true, message: "不能为空"}], - })( - - - - - )} -
-
-
- -
- -
- - - {getFieldDecorator('kssc')()} - 分钟 - -
- {/*
*/} - {/**/} - {/* {getFieldDecorator("rbtx",*/} - {/* {*/} - {/* rules: [{required: true, message: '请选择题型'}],*/} - {/* }*/} - {/* )(*/} - {/* */} - {/* */} - {/* */} - {/* )}*/} - {/**/} - {/*
*/} - - -
- - {getFieldDecorator('rbnd', - { - rules: [{required: true, message: '请选择难度'}], - } - )( - - 简单 - 适中 - 困难 - , - )} - -
- -
-
-
- ) - - } - - -} - -const Comthetestpaperss = Form.create({name: 'Itembankstops'})(Comthetestpapers); -export default Comthetestpaperss; diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js index 88d5b9725..50d2bb85f 100644 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js +++ b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js @@ -41,7 +41,7 @@ const options = [ ], }, ]; - +//Itembankstop 题库的 class Comthetestpaperst extends Component { constructor(props) { super(props); @@ -54,10 +54,16 @@ class Comthetestpaperst extends Component { knowledgepoints: [], knowledgepoints2:[], options: [], - NewknTypedel:false + NewknTypedel:false, + boolred:false, } } + setboolred=(bool)=>{ + this.setState({ + boolred:bool + }) + } //初始化 componentDidMount() { try { @@ -495,19 +501,32 @@ class Comthetestpaperst extends Component { } NewknTypedeltyoedel=(value)=>{ + var knowledgepointmys= this.state.knowledgepoints; + for(let myda of knowledgepointmys) { + if(myda.name===value){ + this.props.showNotification(`重复的知识点`); + this.setboolred(true); + break; + } + } if(value===null||value===""){ this.props.showNotification(`请输入知识点`); + this.setboolred(true); + return } if(value.length===0){ this.props.showNotification(`请输入知识点`); + this.setboolred(true); + return } if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ this.props.showNotification(`请选择课程方向`); + this.setboolred(true); return; } var data={ @@ -523,19 +542,36 @@ class Comthetestpaperst extends Component { id: result.data.tag_discipline_id, name:value, } - this.state.knowledgepoints.push(leydata); - const _result =[]; - this.state.knowledgepoints.filter(item => { - if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { - _result.push(item); - } - }); - this.setState({ - Knowpoints: this.state.Knowpoints, - knowledgepoints: this.state.knowledgepoints, - knowledgepoints2: _result, - }) + if(this.state.Knowpoints.length>=5){ + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + }else{ + this.state.Knowpoints.push(leydata); + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + } } }).catch((error) => { //console.log(error); @@ -609,6 +645,8 @@ class Comthetestpaperst extends Component { { NewknTypedel? this.setboolred(bool)} NewknTypedeldel={(bool)=>this.NewknTypedeldel(bool)} NewknTypedeltyoedel={(value)=>this.NewknTypedeltyoedel(value)} > @@ -656,32 +694,33 @@ class Comthetestpaperst extends Component { this.NewknTypedeldel(true)}/> -
+
+ )} + +
+
{ - return ( -
-

{object.name}

+ }}> - this.deletesobject(object, index)} src={getImageUrl("/images/educoder/bzucha.png")}/> + {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { + return ( +
+

{object.name}

-
- ) - })} + this.deletesobject(object, index)} src={getImageUrl("/images/educoder/bzucha.png")}/> + +
+ ) + })} -
-
- )} -
+
this.setnewmyshixunmodelbool(e)} all_score={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.all_questions_count} all_questions_count={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.all_score} difficulty={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.difficulty} > - - - +
- + {/*顶部*/}
@@ -100,29 +128,46 @@ class Paperlibraryseeid_items extends Component { } { - this.props.typenames==="PROGRAM"? -
-
+ objectsingle.item_type==="PROGRAM"? +
+
+ ({objectsingle.score}分) +
+
+ +
+
: -
+
+
+ ({objectsingle.score}分) +
+
+ + +
- } +
{/*内容*/}
- { objectsingle.item_type === "JUDGMENT" ?

{ objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { return ( -

- +

+ {object.choice_text}

@@ -134,8 +179,17 @@ class Paperlibraryseeid_items extends Component { objectsingle.item_type === "PROGRAM" ?

-

+ { + objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description? +

+ +

+ : + ""}

: @@ -143,10 +197,23 @@ class Paperlibraryseeid_items extends Component { { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { return ( -

+

{tagArray[index]} -

+

+ {object ? + object.choice_text === undefined || object.choice_text=== null || object.choice_text === "" ? + "" + : + object.choice_text.length>0? + + :"" + : + "" + } +

) }) @@ -154,7 +221,6 @@ class Paperlibraryseeid_items extends Component {

} -
diff --git a/public/react/src/modules/testpaper/testioncss/testioncss.css b/public/react/src/modules/testpaper/testioncss/testioncss.css index a1de362d1..c22c93f8a 100644 --- a/public/react/src/modules/testpaper/testioncss/testioncss.css +++ b/public/react/src/modules/testpaper/testioncss/testioncss.css @@ -548,7 +548,7 @@ height:32px; border-radius:2px; border:1px solid #DDDDDD; - margin-left: 20px; + margin-right: 20px; } .lh32{ line-height: 32px; @@ -892,3 +892,6 @@ width: 39px; height: 44px; } +.tites{ + color: #888888 !important; +} diff --git a/public/react/src/modules/tpm/NewHeader.js b/public/react/src/modules/tpm/NewHeader.js index 64787c72b..71b597747 100644 --- a/public/react/src/modules/tpm/NewHeader.js +++ b/public/react/src/modules/tpm/NewHeader.js @@ -948,6 +948,13 @@ submittojoinclass=(value)=>{ return (
+ {isRender===true?this.Modifyloginvalue()} @@ -1039,6 +1046,17 @@ submittojoinclass=(value)=>{ ` } +
  • + +
    +
    + 题库 +
    +
    +
    +
  • {/*
  • */} {/* */} {/*
    */} diff --git a/spec/models/examination_intelligent_setting_spec.rb b/spec/models/examination_intelligent_setting_spec.rb new file mode 100644 index 000000000..fb82f86ca --- /dev/null +++ b/spec/models/examination_intelligent_setting_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ExaminationIntelligentSetting, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/examination_type_setting_spec.rb b/spec/models/examination_type_setting_spec.rb new file mode 100644 index 000000000..916cb367d --- /dev/null +++ b/spec/models/examination_type_setting_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ExaminationTypeSetting, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end