diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f68784db8..e0639de3f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -25,9 +25,9 @@ class ApplicationController < ActionController::Base def check_sign if !Rails.env.development? && EduSetting.get("host_name") != "https://test-newweb.educoder.net" Rails.logger.info("66666 #{params}") - suffix = request.url.split(".").last.split("?").first - suffix_arr = ["xls", "xlsx", "pdf"] # excel文件先注释 - unless suffix_arr.include?(suffix) + # suffix = request.url.split(".").last.split("?").first + # suffix_arr = ["xls", "xlsx", "pdf", "zip"] # excel文件先注释 + # unless suffix_arr.include?(suffix) if params[:client_key].present? randomcode = params[:randomcode] # tip_exception(501, "请求不合理") unless (Time.now.to_i - randomcode.to_i).between?(0,5) @@ -38,7 +38,7 @@ class ApplicationController < ActionController::Base else tip_exception(501, "请求不合理") end - end + # end end end diff --git a/app/controllers/concerns/git_helper.rb b/app/controllers/concerns/git_helper.rb index 7c031f24c..d8479d458 100644 --- a/app/controllers/concerns/git_helper.rb +++ b/app/controllers/concerns/git_helper.rb @@ -46,6 +46,12 @@ module GitHelper content: content, author_name: username, author_email: mail) end + def update_file_base64_content(content, repo_path, path, mail, username, message) + content = Base64.encode64(content) + GitService.update_file_base64(repo_path: repo_path, file_path: path, message: message, + content: content, author_name: username, author_email: mail) + end + # 添加目录 def git_add_folder(folder_path, author_name, author_email, message) GitService.add_tree(file_path: folder_path, message: message, author_name: author_name, author_email: author_email) diff --git a/app/controllers/course_second_categories_controller.rb b/app/controllers/course_second_categories_controller.rb index 2de1637f2..b295c0f9f 100644 --- a/app/controllers/course_second_categories_controller.rb +++ b/app/controllers/course_second_categories_controller.rb @@ -21,7 +21,7 @@ class CourseSecondCategoriesController < ApplicationController else @course_module.course_second_categories.where("position > #{@category.position} and position <= ?", params[:position]).update_all("position = position - 1") end - @category.update_attributes(position: params[:position]) + @category.update!(position: params[:position]) normal_status(0, "移动成功") else normal_status(-1, "位置没有变化") diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index da9f8240a..8eefe5ff5 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -292,8 +292,8 @@ class CoursesController < ApplicationController if next_inform.blank? render_error('已经到达最顶部') else - inform.update_attribute(:position, (inform.position + 1)) - next_inform.update_attribute(:position, inform.position - 1) + inform.update!(position: (inform.position + 1)) + next_inform.update!(position: inform.position - 1) render_ok end end @@ -306,8 +306,8 @@ class CoursesController < ApplicationController if last_inform.blank? render_error('已经到达最底部') else - inform.update_attribute(:position, (inform.position - 1)) - last_inform.update_attribute(:position, inform.position + 1) + inform.update!(position: (inform.position - 1)) + last_inform.update!(position: inform.position + 1) render_ok end end @@ -353,7 +353,7 @@ class CoursesController < ApplicationController # 邀请码停用/启用 def set_invite_code_halt begin - @course.update_attribute('invite_code_halt', @course.invite_code_halt == 0 ? 1 : 0) + @course.update!(invite_code_halt: @course.invite_code_halt == 0 ? 1 : 0) normal_status(0, "成功") rescue => e uid_logger_error(e.message) @@ -364,7 +364,7 @@ class CoursesController < ApplicationController # 设置课堂私有/公有 def set_public_or_private begin - @course.update_attribute('is_public', @course.is_public == 1 ? 0 : 1) + @course.update!(is_public: @course.is_public == 1 ? 0 : 1) normal_status(0, "成功") rescue => e uid_logger_error(e.message) @@ -394,6 +394,7 @@ class CoursesController < ApplicationController # 教师列表以及教师搜索 def teachers + tip_exception(403, "无权限访问") if @course.excellent && @user_course_identity > Course::ASSISTANT_PROFESSOR @search_str = params[:search].present? ? params[:search].strip : "" if @course.try(:id) != 1309 || current_user.admin_or_business? || current_user.try(:id) == 15582 @@ -551,7 +552,7 @@ class CoursesController < ApplicationController graduation_group_id = GraduationGroup.find(params[:graduation_group_id].to_i).id @course_member_list.each do |course_member| course_member = CourseMember.find(course_member[:course_member_id].to_i) - course_member.update_attributes(graduation_group_id: graduation_group_id) + course_member.update!(graduation_group_id: graduation_group_id) end normal_status(0, "成功") rescue => e @@ -711,7 +712,7 @@ class CoursesController < ApplicationController CourseDeleteStudentNotifyJob.perform_later(@course.id, [course_member.user_id], current_user.id) course_member.destroy! - course_student.update_attributes(is_active: 1) if course_student.present? && !course_student.is_active + course_student.update!(is_active: 1) if course_student.present? && !course_student.is_active normal_status(0, "删除成功") rescue => e uid_logger_error(e.message) @@ -726,8 +727,8 @@ class CoursesController < ApplicationController tip_exception("切换失败") unless course_member.STUDENT? course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[CREATOR PROFESSOR], course_id: @course.id) - course_member.update_attributes(is_active: 0) - course_teacher.update_attributes(is_active: 1) + course_member.update!(is_active: 0) + course_teacher.update!(is_active: 1) normal_status(0, "切换成功") rescue => e uid_logger_error(e.message) @@ -742,8 +743,8 @@ class CoursesController < ApplicationController tip_exception("切换失败") unless course_member.STUDENT? course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[ASSISTANT_PROFESSOR], course_id: @course.id) - course_member.update_attributes(is_active: 0) - course_teacher.update_attributes(is_active: 1) + course_member.update!(is_active: 0) + course_teacher.update!(is_active: 1) normal_status(0, "切换成功") rescue => e uid_logger_error(e.message) @@ -782,7 +783,7 @@ class CoursesController < ApplicationController # 课堂如果还有其他身份的用户则更新is_active course_teacher = CourseMember.find_by(user_id: current_user.id, role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR], course_id: @course.id) course_student.destroy! - course_teacher.update_attributes(is_active: 1) if course_teacher.present? && !course_teacher.is_active + course_teacher.update!(is_active: 1) if course_teacher.present? && !course_teacher.is_active CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, [current_user.id]) normal_status(0, "退出成功") end @@ -850,6 +851,8 @@ class CoursesController < ApplicationController # 学生列表(包括各个子分班的学生列表)及搜索 def students + tip_exception(403, "无权限访问") if @course.excellent && @user_course_identity > Course::ASSISTANT_PROFESSOR + search = params[:search].present? ? params[:search].strip : nil order = params[:order].present? ? params[:order].to_i : 1 sort = params[:sort].present? ? params[:sort] : "asc" @@ -959,7 +962,7 @@ class CoursesController < ApplicationController member_teacher = CourseMember.find_by(user_id: course_member.user_id, course_id: @course.id, role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR]) student_ids << course_member.user_id course_member.destroy! - member_teacher.update_attributes(is_active: 1) if member_teacher.present? + member_teacher.update!(is_active: 1) if member_teacher.present? end end CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, student_ids) if student_ids.present? @@ -990,7 +993,7 @@ class CoursesController < ApplicationController if existing_course_member.present? if existing_course_member.STUDENT? - existing_course_member.update_attributes(course_group_id: course_group_id) + existing_course_member.update!(course_group_id: course_group_id) else new_student.is_active = 0 if existing_course_member.is_active new_student.save! @@ -1142,7 +1145,7 @@ class CoursesController < ApplicationController existing_student = CourseMember.find_by(course_id: course.id, role: %i[STUDENT], user_id: current_user.id) if existing_student.present? # 如果在该课堂已经存在学生身份,且邀请码为分班邀请码,则将其直接加入分班 - existing_student.update_attributes(course_group_id: course_group.id) if course_group.present? + existing_student.update!(course_group_id: course_group.id) if course_group.present? else correspond_teacher_exist = current_user.none_admin_teacher_of_course? course new_student = CourseMember.new(user_id: current_user.id, course_id: course.id, role: 4) diff --git a/app/controllers/examination_banks_controller.rb b/app/controllers/examination_banks_controller.rb index 7c1f950f3..251cd197f 100644 --- a/app/controllers/examination_banks_controller.rb +++ b/app/controllers/examination_banks_controller.rb @@ -2,7 +2,7 @@ class ExaminationBanksController < ApplicationController include PaginateHelper before_action :require_login before_action :find_exam, except: [:index, :create] - before_action :edit_auth, only: [:update, :destroy, :set_public] + before_action :edit_auth, only: [:update, :destroy, :set_public, :revoke_item] def index exams = ExaminationBankQuery.call(params) @@ -65,6 +65,15 @@ class ExaminationBanksController < ApplicationController render_ok end + def revoke_item + item = @exam.examination_items.find_by!(item_bank_id: params[:item_id]) + ActiveRecord::Base.transaction do + @exam.examination_items.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1") + item.destroy! + end + render_ok + end + private def form_params 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/exercise_answers_controller.rb b/app/controllers/exercise_answers_controller.rb index 238aaca17..158628475 100644 --- a/app/controllers/exercise_answers_controller.rb +++ b/app/controllers/exercise_answers_controller.rb @@ -4,83 +4,77 @@ class ExerciseAnswersController < ApplicationController include ExercisesHelper def create #每一次答案的点击,请求一次,实训题不在这里回答 - begin - q_type = @exercise_question.question_type #试卷的类型 - choice_id = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : "" - answer_text = params[:answer_text].present? ? params[:answer_text].strip : "" #为字符串 - if q_type < Exercise::SUBJECTIVE && (q_type != Exercise::MULTIPLE) && choice_id.blank? - normal_status(-1,"请选择序号") - else - ea = @exercise_question.exercise_answers.search_answer_users("user_id",current_user.id) #试卷的当前用户的答案 - if q_type == Exercise::SINGLE || q_type == Exercise::JUDGMENT #选择题(单选)/判断题 - if ea.exists? - ea.first.update_attribute(:exercise_choice_id,choice_id ) - else - answer_option = { - :user_id => current_user.id, - :exercise_question_id => @exercise_question.id, - :exercise_choice_id => choice_id, - :answer_text => "" - } - ex_a = ExerciseAnswer.new(answer_option) - ex_a.save! - end - elsif q_type == Exercise::MULTIPLE #多选题的 - choice_ids = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : [] - - ea_ids = ea.pluck(:exercise_choice_id) - common_answer_ids = choice_ids & ea_ids #已经存在的试卷选项id - new_ids = (choice_ids - common_answer_ids).uniq # 新增的id - old_ids = (ea_ids - common_answer_ids).uniq #没有选择的,则删掉 - if new_ids.size > 0 - new_ids.each do |e| - answer_option = { - :user_id => current_user.id, - :exercise_question_id => @exercise_question.id, - :exercise_choice_id => e, - :answer_text => "" - } - ex_a = ExerciseAnswer.new(answer_option) - ex_a.save! - end - end - if old_ids.size > 0 - ea_answer = ea.search_answer_users("exercise_choice_id",old_ids) - ea_answer.destroy_all - end - elsif q_type == Exercise::COMPLETION #填空题 - answer_option = { - :user_id => current_user.id, - :exercise_question_id => @exercise_question.id, - :exercise_choice_id => choice_id, - :answer_text => answer_text - } - ea_answer = ea.search_answer_users("exercise_choice_id",choice_id) - if ea.present? && ea_answer.present? - ea_answer.update(answer_option) - else - ex_new = ExerciseAnswer.new(answer_option) - ex_new.save! - end - elsif q_type == Exercise::SUBJECTIVE #简答题 + q_type = @exercise_question.question_type #试卷的类型 + choice_id = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : "" + answer_text = params[:answer_text].present? ? params[:answer_text].strip : "" #为字符串 + if q_type < Exercise::SUBJECTIVE && (q_type != Exercise::MULTIPLE) && choice_id.blank? + normal_status(-1,"请选择序号") + else + ea = @exercise_question.exercise_answers.search_answer_users("user_id",current_user.id) #试卷的当前用户的答案 + if q_type == Exercise::SINGLE || q_type == Exercise::JUDGMENT #选择题(单选)/判断题 + if ea.exists? + ea.first.update!(exercise_choice_id: choice_id ) + else answer_option = { - :user_id => current_user.id, - :exercise_question_id => @exercise_question.id + :user_id => current_user.id, + :exercise_question_id => @exercise_question.id, + :exercise_choice_id => choice_id, + :answer_text => "" } - if ea.present? #已经回答了的, - ea.first.update_attribute("answer_text",answer_text) - else - answer_option.merge!(answer_text:answer_text) + ex_a = ExerciseAnswer.new(answer_option) + ex_a.save! + end + elsif q_type == Exercise::MULTIPLE #多选题的 + choice_ids = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : [] + + ea_ids = ea.pluck(:exercise_choice_id) + common_answer_ids = choice_ids & ea_ids #已经存在的试卷选项id + new_ids = (choice_ids - common_answer_ids).uniq # 新增的id + old_ids = (ea_ids - common_answer_ids).uniq #没有选择的,则删掉 + if new_ids.size > 0 + new_ids.each do |e| + answer_option = { + :user_id => current_user.id, + :exercise_question_id => @exercise_question.id, + :exercise_choice_id => e, + :answer_text => "" + } ex_a = ExerciseAnswer.new(answer_option) ex_a.save! end end - normal_status(0,"回答成功") + if old_ids.size > 0 + ea_answer = ea.search_answer_users("exercise_choice_id",old_ids) + ea_answer.destroy_all + end + elsif q_type == Exercise::COMPLETION #填空题 + answer_option = { + :user_id => current_user.id, + :exercise_question_id => @exercise_question.id, + :exercise_choice_id => choice_id, + :answer_text => answer_text + } + ea_answer = ea.search_answer_users("exercise_choice_id",choice_id) + if ea.present? && ea_answer.present? + ea_answer.first.update!(answer_option) + else + ex_new = ExerciseAnswer.new(answer_option) + ex_new.save! + end + elsif q_type == Exercise::SUBJECTIVE #简答题 + answer_option = { + :user_id => current_user.id, + :exercise_question_id => @exercise_question.id + } + if ea.present? #已经回答了的, + ea.first.update!(answer_text: answer_text) + else + answer_option.merge!(answer_text:answer_text) + ex_a = ExerciseAnswer.new(answer_option) + ex_a.save! + end end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败!") - raise ActiveRecord::Rollback + normal_status(0,"回答成功") end end @@ -116,7 +110,7 @@ class ExerciseAnswersController < ApplicationController :score => total_score, :subjective_score => subjective_score } - @exercise_user.update_attributes(commit_option) + @exercise_user.update!(commit_option) normal_status(-1,"试卷提交时间已截止!") end end diff --git a/app/controllers/exercise_questions_controller.rb b/app/controllers/exercise_questions_controller.rb index aacef6bc7..ff45b34f0 100644 --- a/app/controllers/exercise_questions_controller.rb +++ b/app/controllers/exercise_questions_controller.rb @@ -44,7 +44,7 @@ class ExerciseQuestionsController < ApplicationController end end - if @exercise_question.save + if @exercise_question.save! #为选择题(包括单选和多选)的时候,创建问题选项 ques_type = @exercise_question.question_type if ques_type <= Exercise::MULTIPLE @@ -59,7 +59,7 @@ class ExerciseQuestionsController < ApplicationController :choice_text => choice.strip } question_choices = @exercise_question.exercise_choices.new(choice_option) - question_choices.save + question_choices.save! end #标准答案的存储,如:["1","2","3"..]等,1对应A,2对应B,3对应C。。。 standard_answer.each do |a| @@ -69,7 +69,7 @@ class ExerciseQuestionsController < ApplicationController :exercise_choice_id => choice_id #即为选择的位置参数 } question_standard_answer = ExerciseStandardAnswer.new(standard_option) - question_standard_answer.save + question_standard_answer.save! if standard_answer.count > 1 && ques_type == Exercise::SINGLE #当标准答案数大于1,且不为多选时,修改为多选 @exercise_question.update_attribute("question_type",Exercise::MULTIPLE) elsif standard_answer.count == 1 && ques_type == Exercise::MULTIPLE @@ -85,8 +85,8 @@ class ExerciseQuestionsController < ApplicationController :choice_position => c, :choice_text => choice.strip } - question_choices = @exercise_question.exercise_choices.create(choice_option) - question_choices.save + question_choices = @exercise_question.exercise_choices.create!(choice_option) + question_choices.save! end standard_answer = params[:standard_answers] #对应选项的id standard_option = { @@ -94,7 +94,7 @@ class ExerciseQuestionsController < ApplicationController :exercise_choice_id => standard_answer.first.to_i } question_standard_answer = ExerciseStandardAnswer.new(standard_option) - question_standard_answer.save + question_standard_answer.save! elsif ques_type == Exercise::COMPLETION #填空题,每空的参考答案有多个,那么以位置对应 standard_answer = params[:standard_answers] standard_answer.each do |a| @@ -107,7 +107,7 @@ class ExerciseQuestionsController < ApplicationController :answer_text => n } question_standard_answer = ExerciseStandardAnswer.new(standard_option) - question_standard_answer.save + question_standard_answer.save! end end elsif ques_type == Exercise::SUBJECTIVE #简答题 @@ -119,7 +119,7 @@ class ExerciseQuestionsController < ApplicationController :answer_text => a, } question_standard_answer = ExerciseStandardAnswer.new(standard_option) - question_standard_answer.save + question_standard_answer.save! end end elsif ques_type == Exercise::PRACTICAL #实训题 @@ -135,10 +135,10 @@ class ExerciseQuestionsController < ApplicationController :position => (index + 1), :question_score => shixun_scores[index].present? ? shixun_scores[index].to_f.round(1) : 5 } - ex_shixun_challenge = ExerciseShixunChallenge.create(shixun_option) + ex_shixun_challenge = ExerciseShixunChallenge.create!(shixun_option) question_score += ex_shixun_challenge.question_score # 问题的分数,为各个关卡分数的总和 end - @exercise_question.update_attributes(:question_score => question_score,:shixun_name=> shixun_name) + @exercise_question.update!(:question_score => question_score,:shixun_name=> shixun_name) end end rescue Exception => e @@ -188,7 +188,7 @@ class ExerciseQuestionsController < ApplicationController choices_array = params[:question_choices] stan_answer_params = params[:standard_answers] standard_answer = stan_answer_params.present? ? stan_answer_params.uniq.reject(&:blank?) : [] - @exercise_question.update_attributes(question_options) + @exercise_question.update!(question_options) #当选项存在时,可修改选项内容,但是不能更改选项的位置(即不能增删选项) if choices_array.present? ex_choices = @exercise_question.exercise_choices @@ -218,7 +218,7 @@ class ExerciseQuestionsController < ApplicationController :choice_text => choices_array[i-1].strip } question_choices = @exercise_question.exercise_choices.new(choice_option) - question_choices.save + question_choices.save! end end end @@ -243,7 +243,7 @@ class ExerciseQuestionsController < ApplicationController :exercise_choice_id => s.to_i #即为选择的位置参数 } question_standard_answer = ExerciseStandardAnswer.new(standard_option) - question_standard_answer.save + question_standard_answer.save! end end @@ -296,7 +296,7 @@ class ExerciseQuestionsController < ApplicationController :answer_text => null_choice_text[i-1] } question_standard_answer = ExerciseStandardAnswer.new(standard_option) - question_standard_answer.save + question_standard_answer.save! end end else @@ -323,7 +323,7 @@ class ExerciseQuestionsController < ApplicationController :answer_text => n } question_standard_answer = ExerciseStandardAnswer.new(standard_option) - question_standard_answer.save + question_standard_answer.save! end end end @@ -340,19 +340,19 @@ class ExerciseQuestionsController < ApplicationController :answer_text => main_standard_answer, } question_standard_answer = ExerciseStandardAnswer.new(standard_option) - question_standard_answer.save + question_standard_answer.save! end elsif @exercise_question.question_type == Exercise::PRACTICAL question_score = 0 shixun_name = params[:shixun_name] || @exercise_question.shixun_name @exercise_question.exercise_shixun_challenges.each_with_index do |challenge, index| challenge.question_score = params[:question_scores][index].to_f.round(1) - challenge.save + challenge.save! question_score += params[:question_scores][index].to_f.round(1) end @exercise_question.question_score = question_score @exercise_question.shixun_name = shixun_name - @exercise_question.save + @exercise_question.save! end #当试卷已发布时(试卷的总状态),当标准答案修改时,如有已提交的学生,需重新计算分数. @@ -397,7 +397,7 @@ class ExerciseQuestionsController < ApplicationController new_objective_score = objective_score + update_objective_score total_score = ex_user.score + update_objective_score total_score = total_score < 0.0 ? 0.0 : total_score - ex_user.update_attributes(objective_score:new_objective_score,score:total_score) + ex_user.update!(objective_score:new_objective_score,score:total_score) end end end @@ -526,7 +526,7 @@ class ExerciseQuestionsController < ApplicationController :score => @c_score, :answer_text => "" } - ExerciseAnswer.create(answer_option) + ExerciseAnswer.create!(answer_option) ex_answer_old = 0 end if ex_obj_score <= 0.0 @@ -545,7 +545,7 @@ class ExerciseQuestionsController < ApplicationController :objective_score => new_obj_score, :score => total_scores } - @exercise_current_user.update_attributes(ex_scores) + @exercise_current_user.update!(ex_scores) elsif @exercise_question.question_type == Exercise::COMPLETION #当为填空题,更新问题的总分, @@ -561,7 +561,7 @@ class ExerciseQuestionsController < ApplicationController :score => @c_score, :answer_text => "" } - ExerciseAnswer.create(answer_option) + ExerciseAnswer.create!(answer_option) new_obj_score = ex_obj_score + @c_score end @@ -575,7 +575,7 @@ class ExerciseQuestionsController < ApplicationController :objective_score => new_obj_score, :score => total_scores } - @exercise_current_user.update_attributes(ex_scores) + @exercise_current_user.update!(ex_scores) elsif @exercise_question.question_type == Exercise::SUBJECTIVE #当为主观题时 if ex_answers.exists? ex_answers_old_score = ex_answers.first.score > 0.0 ? ex_answers.first.score : 0.0 #原分数小于0,取0 @@ -588,7 +588,7 @@ class ExerciseQuestionsController < ApplicationController :score => @c_score, :answer_text => "" } - ExerciseAnswer.create(answer_option) + ExerciseAnswer.create!(answer_option) new_sub_score = ex_subj_score + @c_score end total_scores = ex_obj_score + new_sub_score @@ -601,7 +601,7 @@ class ExerciseQuestionsController < ApplicationController :subjective_score => new_sub_score, :score => total_scores } - @exercise_current_user.update_attributes(ex_scores) + @exercise_current_user.update!(ex_scores) elsif @exercise_question.question_type == Exercise::PRACTICAL ex_answers = @exercise_question.exercise_shixun_answers.where(user_id:@user_id,exercise_shixun_challenge_id:@shixun_a_id) @@ -618,7 +618,7 @@ class ExerciseQuestionsController < ApplicationController :score => @c_score, :status => 0 } - ExerciseShixunAnswer.create(ex_shixun_option) + ExerciseShixunAnswer.create!(ex_shixun_option) new_obj_score = ex_obj_score + @c_score end total_scores = new_obj_score + ex_subj_score @@ -631,7 +631,7 @@ class ExerciseQuestionsController < ApplicationController :objective_score => new_obj_score, :score => total_scores } - @exercise_current_user.update_attributes(ex_scores) + @exercise_current_user.update!(ex_scores) end comments = params[:comment] question_comment = @exercise_question.exercise_answer_comments&.first @@ -643,7 +643,7 @@ class ExerciseQuestionsController < ApplicationController :exercise_answer_id => ex_answers.present? ? ex_answers.first.id : nil, :user_id => current_user.id } - question_comment.update_attributes(comment_option) + question_comment.update!(comment_option) @exercise_comments = question_comment else ex_answer_comment_id = @exercise_question.exercise_answers.find_by(user_id: @user_id).try(:id) diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 48554111c..5b555cf4c 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1,55 +1,64 @@ class ExercisesController < ApplicationController before_action :require_login, :check_auth, except: [:index] - before_action :find_course,only: [:index,:new,:create,:my_exercises,:public_exercises,:set_public,:destroys, - :join_exercise_banks,:publish_modal,:publish,:end_modal,:end_exercise] #需要有课堂id参数的 - before_action :get_exercise,except: [:index,:new,:create,:my_exercises,:public_exercises,:set_public,:destroys, - :join_exercise_banks,:publish_modal,:publish,:end_modal,:end_exercise] + before_action :find_course, only: [:index, :new, :create, :my_exercises, :public_exercises, :set_public, :destroys, + :join_exercise_banks, :publish_modal, :publish, :end_modal, :end_exercise] #需要有课堂id参数的 + before_action :get_exercise, except: [:index, :new, :create, :my_exercises, :public_exercises, :set_public, :destroys, + :join_exercise_banks, :publish_modal, :publish, :end_modal, :end_exercise] before_action :user_course_identity - before_action :is_course_teacher,except: [:index,:start_answer,:exercise_setting,:commit_exercise,:exercise_lists,:review_exercise, - :exercise_result,:common_header,:cancel_exercise,:begin_commit] - before_action :get_left_banner_id,only:[:common_header,:start_answer,:review_exercise,:index,:new,:edit] - before_action :validates_exercise_params,only: [:create,:update] - before_action :get_exercise_question_counts,only: [:show,:edit,:start_answer,:review_exercise,:blank_exercise,:export_exercise] - before_action :validate_publish_time,only: [:commit_setting] #提交设置时,需判断时间是否符合 - before_action :check_course_public,only: [:set_public] - before_action :check_user_on_answer,only: [:show,:start_answer,:exercise_lists] #判断当前用户在试卷的权限/老师是否属于分班的权限 - before_action :only_student_in,only: [:start_answer] - before_action :check_user_id_start_answer,only: [:start_answer,:review_exercise] + before_action :is_course_teacher, except: [:index, :start_answer, :exercise_setting, :commit_exercise, :exercise_lists, :review_exercise, + :exercise_result, :common_header, :cancel_exercise, :begin_commit] + before_action :get_left_banner_id, only: [:common_header, :start_answer, :review_exercise, :index, :new, :edit] + before_action :validates_exercise_params, only: [:create, :update] + before_action :get_exercise_question_counts, only: [:show, :edit, :start_answer, :review_exercise, :blank_exercise, :export_exercise] + before_action :validate_publish_time, only: [:commit_setting] #提交设置时,需判断时间是否符合 + before_action :check_course_public, only: [:set_public] + before_action :check_user_on_answer, only: [:show, :start_answer, :exercise_lists] #判断当前用户在试卷的权限/老师是否属于分班的权限 + before_action :only_student_in, only: [:start_answer] + before_action :check_user_id_start_answer, only: [:start_answer, :review_exercise] # before_action :commit_user_exercise,only: [:start_answer,:exercise_lists,:review_exercise] #已有定时的任务 - before_action :check_exercise_time,only: [:commit_exercise] #提交试卷时,判断时间是否超过 - before_action :check_exercise_status,only: [:redo_modal,:redo_exercise] + before_action :check_exercise_time, only: [:commit_exercise] #提交试卷时,判断时间是否超过 + before_action :check_exercise_status, only: [:redo_modal, :redo_exercise] before_action :check_exercise_is_end, only: [:review_exercise] - before_action :check_exercise_public,only: [:exercise_result] #试卷是否为公开 - before_action :commit_shixun_present,only: [:commit_shixun] + before_action :check_exercise_public, only: [:exercise_result] #试卷是否为公开 + before_action :commit_shixun_present, only: [:commit_shixun] include ExportHelper include ExercisesHelper + # model validation error + rescue_from ActiveRecord::RecordInvalid do |ex| + render_error(ex.record.errors.full_messages.join(',')) + end + # form validation error + rescue_from ActiveModel::ValidationError do |ex| + render_error(ex.model.errors.full_messages.join(',')) + end + def index begin # 按发布时间或创建时间排序 @exercises_all = @course.exercises - member_show_exercises = @exercises_all.is_exercise_published #已发布的或已截止的试卷 + member_show_exercises = @exercises_all.is_exercise_published #已发布的或已截止的试卷 @current_user_ = current_user # 课堂的学生人数 @course_all_members = @course.students #当前课堂的全部学生 - @current_student = @course_all_members.course_find_by_ids("user_id",current_user.id) #当前用户是否为课堂的学生 + @current_student = @course_all_members.course_find_by_ids("user_id", current_user.id) #当前用户是否为课堂的学生 # exercises的不同用户群体的显示 - if @user_course_identity < Course::STUDENT # @is_teacher_or 1为老师/管理员/助教 + if @user_course_identity < Course::STUDENT # @is_teacher_or 1为老师/管理员/助教 @is_teacher_or = 1 - @exercises = @exercises_all #老师能看到全部的试卷,不管是已发布的/未发布的/已截止的/统一设置的/私有设置的(看到内容不同) - elsif @user_course_identity == Course::STUDENT # 2为课堂成员,能看到统一设置的和自己班级的 + @exercises = @exercises_all #老师能看到全部的试卷,不管是已发布的/未发布的/已截止的/统一设置的/私有设置的(看到内容不同) + elsif @user_course_identity == Course::STUDENT # 2为课堂成员,能看到统一设置的和自己班级的 @is_teacher_or = 2 - @member_group_id = @current_student.first.try(:course_group_id).to_i # 成员的分班id,默认为0 - if @member_group_id == 0 #表示是课堂的未分班成员,只能查看统一设置的试卷(已发布的/已截止的) + @member_group_id = @current_student.first.try(:course_group_id).to_i # 成员的分班id,默认为0 + if @member_group_id == 0 #表示是课堂的未分班成员,只能查看统一设置的试卷(已发布的/已截止的) @exercises = member_show_exercises.exists? ? member_show_exercises.unified_setting : [] - else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 + else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 # 已发布 当前用户班级分组的 试卷id publish_exercise_ids = @course.exercise_group_settings.exercise_group_published.where("course_group_id = #{@member_group_id}").pluck(:exercise_id) @exercises = member_show_exercises.unified_setting.or(member_show_exercises.where(id: publish_exercise_ids)) end - else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 + else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 @is_teacher_or = 0 @exercises = member_show_exercises.unified_setting end @@ -66,7 +75,7 @@ class ExercisesController < ApplicationController ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_not_published.pluck(:exercise_id) when 2 ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}") - .where("publish_time is not null and publish_time <= ? and end_time > ?",Time.now,Time.now).pluck(:exercise_id) + .where("publish_time is not null and publish_time <= ? and end_time > ?", Time.now, Time.now).pluck(:exercise_id) when 3 ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_ended.pluck(:exercise_id) end @@ -81,11 +90,11 @@ class ExercisesController < ApplicationController @exercises = @exercises.exercise_search(search_type) end - @exercises_select_count = @exercises.size # 全部页面,需返回 - @exercises = @exercises.distinct.order( "IF(ISNULL(publish_time),0,1), publish_time DESC,created_at DESC") #出现错误 + @exercises_select_count = @exercises.size # 全部页面,需返回 + @exercises = @exercises.distinct.order("IF(ISNULL(publish_time),0,1), publish_time DESC,created_at DESC") #出现错误 # 分页 - @page = params[:page] || 1 + @page = params[:page] || 1 @limit = params[:limit] || 15 @exercises = @exercises.page(@page).per(@limit) @exercises = @exercises&.includes(:published_settings) @@ -93,10 +102,10 @@ class ExercisesController < ApplicationController @exercises = [] end - @course_all_members_count = @course_all_members.size #当前课堂的学生数 - @exercises_count = @exercises_all.size # 全部页面,需返回 + @course_all_members_count = @course_all_members.size #当前课堂的学生数 + @exercises_count = @exercises_all.size # 全部页面,需返回 @exercises_unpublish_counts = @exercises_all.exercise_by_status(1).size #未发布的试卷数 - @exercises_published_counts = @exercises_count - @exercises_unpublish_counts # 已发布的试卷数,包含已截止的 + @exercises_published_counts = @exercises_count - @exercises_unpublish_counts # 已发布的试卷数,包含已截止的 rescue Exception => e uid_logger_error(e.message) @@ -119,108 +128,77 @@ class ExercisesController < ApplicationController def create ActiveRecord::Base.transaction do - begin - ex_name = params[:exercise_name] - ex_desc = params[:exercise_description] - exercise_options = { - :exercise_name => ex_name, - :exercise_description => ex_desc, - :user_id => current_user.id, - :course_id => @course.id, - :time => -1, - :exercise_status => 1 - } - @exercise = Exercise.create(exercise_options) - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷创建失败!") - raise ActiveRecord::Rollback - end + ex_name = params[:exercise_name] + ex_desc = params[:exercise_description] + exercise_options = { + :exercise_name => ex_name, + :exercise_description => ex_desc, + :user_id => current_user.id, + :course_id => @course.id, + :time => -1, + :exercise_status => 1 + } + @exercise = Exercise.create!(exercise_options) end end #试卷的内容,及试题/答案的内容编辑 def edit ActiveRecord::Base.transaction do - begin - @exercise_questions = @exercise.exercise_questions.order("question_number ASC") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷创建失败!") - raise ActiveRecord::Rollback - end + @exercise_questions = @exercise.exercise_questions.order("question_number ASC") end end def update ActiveRecord::Base.transaction do - begin - ex_name = params[:exercise_name] - ex_desc = params[:exercise_description] - exercise_options = { - :exercise_name => ex_name, - :exercise_description => ex_desc, - } - @exercise.update_attributes(exercise_options) - normal_status(0,"试卷更新成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷创建失败!") - raise ActiveRecord::Rollback - end + ex_name = params[:exercise_name] + ex_desc = params[:exercise_description] + exercise_options = { + :exercise_name => ex_name, + :exercise_description => ex_desc, + } + @exercise.update!(exercise_options) + normal_status(0, "试卷更新成功!") end end def show ActiveRecord::Base.transaction do - begin - if @user_course_identity < Course::STUDENT - @is_teacher_or = 1 #为老师/助教/管理员 - else - @is_teacher_or = 0 #为学生 - end - @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices,:exercise_shixun_challenges,:exercise_standard_answers).order("question_number ASC") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷创建失败!") - raise ActiveRecord::Rollback + if @user_course_identity < Course::STUDENT + @is_teacher_or = 1 #为老师/助教/管理员 + else + @is_teacher_or = 0 #为学生 end + @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices, :exercise_shixun_challenges, :exercise_standard_answers).order("question_number ASC") end end #试卷的公用头部 def common_header ActiveRecord::Base.transaction do - begin - @user_left_time = nil - if @user_course_identity > Course::ASSISTANT_PROFESSOR - @is_teacher_or = 0 - @user_exercise_answer = @exercise.check_user_answer_status(current_user) - @user_commit_counts = 0 - @user_left_time = get_exercise_left_time(@exercise,current_user) - else - @is_teacher_or = 1 - @user_exercise_answer = 3 #教师页面 - @user_commit_counts = @exercise.exercise_users.where(commit_status:1).size #已提交的用户数 - end - @ex_status = @exercise.get_exercise_status(current_user) + @user_left_time = nil + if @user_course_identity > Course::ASSISTANT_PROFESSOR + @is_teacher_or = 0 + @user_exercise_answer = @exercise.check_user_answer_status(current_user) + @user_commit_counts = 0 + @user_left_time = get_exercise_left_time(@exercise, current_user) + else + @is_teacher_or = 1 + @user_exercise_answer = 3 #教师页面 + @user_commit_counts = @exercise.exercise_users.where(commit_status: 1).size #已提交的用户数 + end + @ex_status = @exercise.get_exercise_status(current_user) - exercise_id_array = [@exercise.id] - @exercise_publish_count = get_user_permission_course(exercise_id_array,Exercise::PUBLISHED).size #是否存在已发布的 - @exercise_unpublish_count = get_user_permission_course(exercise_id_array,Exercise::UNPUBLISHED).size #是否存在未发布的 + exercise_id_array = [@exercise.id] + @exercise_publish_count = get_user_permission_course(exercise_id_array, Exercise::PUBLISHED).size #是否存在已发布的 + @exercise_unpublish_count = get_user_permission_course(exercise_id_array, Exercise::UNPUBLISHED).size #是否存在未发布的 - if (@exercise_publish_count == 0) && (@exercise_unpublish_count == 0) #即表示没有分班 - if @ex_status == Exercise::UNPUBLISHED - @exercise_unpublish_count = 1 #试卷未发布,且课堂没有分班的时候 - elsif @ex_status == Exercise::PUBLISHED - @exercise_publish_count = 1 #试卷未发布,且课堂没有分班的时候 - end + if (@exercise_publish_count == 0) && (@exercise_unpublish_count == 0) #即表示没有分班 + if @ex_status == Exercise::UNPUBLISHED + @exercise_unpublish_count = 1 #试卷未发布,且课堂没有分班的时候 + elsif @ex_status == Exercise::PUBLISHED + @exercise_publish_count = 1 #试卷未发布,且课堂没有分班的时候 end - - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback end end end @@ -228,381 +206,338 @@ class ExercisesController < ApplicationController #实训题目的选用 def choose_shixun ActiveRecord::Base.transaction do - begin - search = params[:search] - if @user_course_identity > Course::ADMIN #当不为管理员的时候 - user_school_id = current_user.school_id #当前用户的学校id - if user_school_id.present? - none_shixun_ids = ShixunSchool.where("school_id != #{user_school_id}").pluck(:shixun_id) - @publish_shixuns = Shixun.where.not(id: none_shixun_ids).unhidden - end - else - @publish_shixuns = Shixun.unhidden - end - if search.present? - @publish_shixuns = @publish_shixuns.search_by_name(search) + search = params[:search] + if @user_course_identity > Course::ADMIN #当不为管理员的时候 + user_school_id = current_user.school_id #当前用户的学校id + if user_school_id.present? + none_shixun_ids = ShixunSchool.where("school_id != #{user_school_id}").pluck(:shixun_id) + @publish_shixuns = Shixun.where.not(id: none_shixun_ids).unhidden end + else + @publish_shixuns = Shixun.unhidden + end + if search.present? + @publish_shixuns = @publish_shixuns.search_by_name(search) + end - @shixuns = @publish_shixuns.joins(:challenges).where("challenges.st != 0").distinct - # 全部页面,需返回 - @shixuns_count = @shixuns.count + @shixuns = @publish_shixuns.joins(:challenges).where("challenges.st != 0").distinct + # 全部页面,需返回 + @shixuns_count = @shixuns.count - # 分页 - @page = params[:page] || 1 - @limit = params[:limit] || 8 + # 分页 + @page = params[:page] || 1 + @limit = params[:limit] || 8 - @shixuns = @shixuns.page(@page).per(@limit) - rescue Exception => e - uid_logger_error(e.message) - tip_exception("实训选择失败!") - end + @shixuns = @shixuns.page(@page).per(@limit) end end #确认实训的选择 def commit_shixun ActiveRecord::Base.transaction do - begin - @shixun_challenges = @shixun.challenges - @shixun_challenges_count = @shixun_challenges.size - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败!") - raise ActiveRecord::Rollback - end + @shixun_challenges = @shixun.challenges + @shixun_challenges_count = @shixun_challenges.size end end # 首页批量或单独删除 def destroys ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id: params[:check_ids]) - check_ids.destroy_all - normal_status(0, "试卷已删除成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷删除失败!") - raise ActiveRecord::Rollback - end + check_ids = Exercise.where(id: params[:check_ids]) + check_ids.destroy_all + normal_status(0, "试卷已删除成功!") end end # 设为公开 def set_public ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id: params[:check_ids]) - check_ids.each do |exercise| - exercise.update_attribute('is_public', true) - end - normal_status(0, "试卷已设为公开!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷设为公开失败!") - raise ActiveRecord::Rollback + check_ids = Exercise.where(id: params[:check_ids]) + check_ids.each do |exercise| + exercise.update!(is_public: true) end + normal_status(0, "试卷已设为公开!") end end ## 加入题库 def join_exercise_banks ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id: params[:check_ids]) - check_ids.each do |exercise| - current_ex_bank = current_user.exercise_banks.find_by_container(exercise.id,"Exercise")&.first - if current_ex_bank.present? #当前用户的选择试卷是否已加入习题库,存在则更新习题库和问题库,否则新建习题库和问题库 - ex_params = { - :name => exercise.exercise_name, - :description => exercise.exercise_description, - :course_list_id => exercise.course.try(:course_list_id) - } - current_ex_bank.update_attributes(ex_params) - # question_bank = QuestionBank.ques_by_container(current_ex_bank.id,current_ex_bank.container_type).first #该习题库是否存在于问题库里 - # ques_params = { - # :name => current_ex_bank.name, - # :course_list_id => current_ex_bank.course_list_id - # } - # question_bank.update_attributes(ques_params) if question_bank.present? - current_ex_bank.exercise_bank_questions.destroy_all # 更新后,习题库的问题全部删除,后续重新再建 - else - ex_params = { - :name => exercise.exercise_name, - :description => exercise.exercise_description, - :user_id => current_user.id, - :is_public => 0, - :course_list_id => exercise.course.try(:course_list_id), - :container_id => exercise.id, - :container_type => "Exercise", - :quotes => 1 - } - current_ex_bank= ExerciseBank.new ex_params - current_ex_bank.save! #如果习题库保存成功,则会创建问题库question_bank - # if current_ex_bank.save - # ques_params = { - # :name => current_ex_bank.name, - # :container_id => current_ex_bank.id, - # :container_type => current_ex_bank.container_type, - # :quotes => current_ex_bank.quotes, - # :user_id => current_ex_bank.user_id, - # :is_public => current_ex_bank.is_public, - # :course_list_id => current_ex_bank.course_list_id - # } - # question_bank = QuestionBank.new ques_params - # question_bank.save - # end - exercise.update_attributes!(exercise_bank_id: current_ex_bank.id) - end - # 试卷的问题的输入 - exercise.exercise_questions.each do |q| - option = { - :question_title => q.question_title, - :question_type => q.question_type, - :question_number => q.question_number, - :question_score => q.question_score, + check_ids = Exercise.where(id: params[:check_ids]) + check_ids.each do |exercise| + current_ex_bank = current_user.exercise_banks.find_by_container(exercise.id, "Exercise")&.first + if current_ex_bank.present? #当前用户的选择试卷是否已加入习题库,存在则更新习题库和问题库,否则新建习题库和问题库 + ex_params = { + :name => exercise.exercise_name, + :description => exercise.exercise_description, + :course_list_id => exercise.course.try(:course_list_id) + } + current_ex_bank.update!(ex_params) + # question_bank = QuestionBank.ques_by_container(current_ex_bank.id,current_ex_bank.container_type).first #该习题库是否存在于问题库里 + # ques_params = { + # :name => current_ex_bank.name, + # :course_list_id => current_ex_bank.course_list_id + # } + # question_bank.update_attributes(ques_params) if question_bank.present? + current_ex_bank.exercise_bank_questions.destroy_all # 更新后,习题库的问题全部删除,后续重新再建 + else + ex_params = { + :name => exercise.exercise_name, + :description => exercise.exercise_description, + :user_id => current_user.id, + :is_public => 0, + :course_list_id => exercise.course.try(:course_list_id), + :container_id => exercise.id, + :container_type => "Exercise", + :quotes => 1 + } + current_ex_bank = ExerciseBank.new ex_params + current_ex_bank.save! #如果习题库保存成功,则会创建问题库question_bank + # if current_ex_bank.save + # ques_params = { + # :name => current_ex_bank.name, + # :container_id => current_ex_bank.id, + # :container_type => current_ex_bank.container_type, + # :quotes => current_ex_bank.quotes, + # :user_id => current_ex_bank.user_id, + # :is_public => current_ex_bank.is_public, + # :course_list_id => current_ex_bank.course_list_id + # } + # question_bank = QuestionBank.new ques_params + # question_bank.save + # end + exercise.update!(exercise_bank_id: current_ex_bank.id) + end + # 试卷的问题的输入 + exercise.exercise_questions.each do |q| + option = { + :question_title => q.question_title, + :question_type => q.question_type, + :question_number => q.question_number, + :question_score => q.question_score, + :shixun_id => q.shixun_id, + :shixun_name => q.shixun_name + } + exercise_bank_question = current_ex_bank.exercise_bank_questions.new option + exercise_bank_question.save! + ## 试卷选项的输入 + if q.question_type != Exercise::PRACTICAL #不为实训题时,试卷选项加入试题答案库 + ex_choices = q.exercise_choices + ex_standard = q.exercise_standard_answers + ex_choices.each do |c| + choice_option = { + :choice_position => c.choice_position, + :choice_text => c.choice_text + } + ex_bank_choice = exercise_bank_question.exercise_bank_choices.new choice_option + ex_bank_choice.save! + end + ex_standard.each do |s| + ex_stand = { + :exercise_bank_choice_id => s.exercise_choice_id, + :answer_text => s.answer_text + } + ex_stand_bank = exercise_bank_question.exercise_bank_standard_answers.new ex_stand + ex_stand_bank.save! + end + else #当为实训题时 + shixun_challenges = q.exercise_shixun_challenges + shixun_challenges.each do |c| + challenge_option = { + :position => c.position, + :challenge_id => c.challenge_id, :shixun_id => q.shixun_id, - :shixun_name => q.shixun_name - } - exercise_bank_question = current_ex_bank.exercise_bank_questions.new option - exercise_bank_question.save - ## 试卷选项的输入 - if q.question_type != Exercise::PRACTICAL #不为实训题时,试卷选项加入试题答案库 - ex_choices = q.exercise_choices - ex_standard = q.exercise_standard_answers - ex_choices.each do |c| - choice_option = { - :choice_position => c.choice_position, - :choice_text =>c.choice_text - } - ex_bank_choice = exercise_bank_question.exercise_bank_choices.new choice_option - ex_bank_choice.save - end - ex_standard.each do |s| - ex_stand = { - :exercise_bank_choice_id => s.exercise_choice_id, - :answer_text => s.answer_text - } - ex_stand_bank = exercise_bank_question.exercise_bank_standard_answers.new ex_stand - ex_stand_bank.save - end - else #当为实训题时 - shixun_challenges = q.exercise_shixun_challenges - shixun_challenges.each do |c| - challenge_option = { - :position => c.position, - :challenge_id => c.challenge_id, - :shixun_id => q.shixun_id, - :question_score => c.question_score - } - shixun_challenge_bank = exercise_bank_question.exercise_bank_shixun_challenges.new challenge_option - shixun_challenge_bank.save - end + :question_score => c.question_score + } + shixun_challenge_bank = exercise_bank_question.exercise_bank_shixun_challenges.new challenge_option + shixun_challenge_bank.save! end end - current_ex_bank.save end - normal_status(0, "题库更新成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("题库更新失败!") - raise ActiveRecord::Rollback + current_ex_bank.save! end + normal_status(0, "题库更新成功!") end end #试卷的设置页面 def exercise_setting ActiveRecord::Base.transaction do - begin - @user_permission = 2 - @user_course_groups = @course.teacher_group(current_user.id) #当前老师的分班 - @being_setting_course_ids = @exercise.common_published_ids(current_user.id) #当前用户已发布的班级的id - @user_published_setting = @exercise.exercise_group_settings - .find_in_exercise_group("course_group_id",@being_setting_course_ids) #当前用户已发布班级的试卷设置 - exercise_ids = [@exercise.id] - @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).count #判断当前用户是否有试卷已发布的分班,用于显示立即截止/撤销发布 - @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).count #判断当前用户是否有试卷未发布的分班,用户显示立即发布 - @exercise_users_count = @exercise.exercise_users.commit_exercise_by_status(1).count #判断当前试卷是否有已提交的 - # ## 需添加发送消息的接口,稍后添加 - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败!") - raise ActiveRecord::Rollback - end + @user_permission = 2 + @user_course_groups = @course.teacher_group(current_user.id) #当前老师的分班 + @being_setting_course_ids = @exercise.common_published_ids(current_user.id) #当前用户已发布的班级的id + @user_published_setting = @exercise.exercise_group_settings + .find_in_exercise_group("course_group_id", @being_setting_course_ids) #当前用户已发布班级的试卷设置 + exercise_ids = [@exercise.id] + @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).count #判断当前用户是否有试卷已发布的分班,用于显示立即截止/撤销发布 + @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).count #判断当前用户是否有试卷未发布的分班,用户显示立即发布 + @exercise_users_count = @exercise.exercise_users.commit_exercise_by_status(1).count #判断当前试卷是否有已提交的 + # ## 需添加发送消息的接口,稍后添加 end end #试卷的提交设置 def commit_setting ActiveRecord::Base.transaction do - begin - error_count = 0 # 判断循环里是否有已发布/已截止的,且时间更改了的分班。 - # course_group_ids = @course.teacher_course_group_ids(current_user.id) #当前老师的班级id数组 - course_group_ids = @course.charge_group_ids(current_user) #当前老师的班级id数组 + error_count = 0 # 判断循环里是否有已发布/已截止的,且时间更改了的分班。 + # course_group_ids = @course.teacher_course_group_ids(current_user.id) #当前老师的班级id数组 + course_group_ids = @course.charge_group_ids(current_user) #当前老师的班级id数组 - exercise_status = @exercise.get_exercise_status(current_user) + exercise_status = @exercise.get_exercise_status(current_user) + + if exercise_status == Exercise::UNPUBLISHED && course_group_ids.size > 0 # 试卷未发布,且老师的分班大于1 ,才可以修改统一设置,否则按试卷默认的来处理 + unified_setting = params[:unified_setting] + else + unified_setting = @exercise.unified_setting + end - if exercise_status == Exercise::UNPUBLISHED && course_group_ids.size > 0 # 试卷未发布,且老师的分班大于1 ,才可以修改统一设置,否则按试卷默认的来处理 - unified_setting = params[:unified_setting] + show_statistic = params[:show_statistic] ? true : false + exercise_time = params[:time].blank? ? -1 : params[:time] + question_random = params[:question_random] ? true : false #问题是否随机,0为不随机,1为随机 + choice_random = params[:choice_random] ? true : false + score_open = params[:score_open] ? true : false #分数是否公开 + answer_open = params[:answer_open] ? true : false #答案是否公开 + + # 统一设置或者分班为0,则更新试卷,并删除试卷分组 + if unified_setting || (course_group_ids.size == 0) + tip_exception("发布时间不能为空") if params[:publish_time].blank? + tip_exception("截止时间不能为空") if params[:end_time].blank? + tip_exception("截止时间不能早于发布时间") if params[:publish_time].to_time > params[:end_time].to_time + tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:end_time].to_time > @course.end_date.end_of_day + + params_publish_time = params[:publish_time].to_time + params_end_time = params[:end_time].to_time + + if (exercise_status != Exercise::UNPUBLISHED) && (@exercise.publish_time != params_publish_time) + normal_status(-1, "已发布/已截止,不允许修改发布时间") + elsif params_publish_time.present? && params_end_time.present? && params_end_time < params_publish_time + normal_status(-1, "截止时间不能小于发布时间") else - unified_setting = @exercise.unified_setting + #发布时间小于当前时间,则试卷显示为未发布,当截止时间大于当前时间,则显示为已截止 + exercise_status_n = set_exercise_status(params_publish_time, params_end_time) + exercise_params = { + :unified_setting => unified_setting, + :show_statistic => show_statistic, + :time => exercise_time, + :question_random => question_random, + :choice_random => choice_random, + :score_open => score_open, + :answer_open => answer_open, + :exercise_status => exercise_status_n, + :publish_time => params_publish_time, + :end_time => params_end_time + } + @exercise.update!(exercise_params) + @exercise.exercise_group_settings.destroy_all + normal_status(0, "试卷设置成功!") end - - show_statistic = params[:show_statistic] ? true :false - exercise_time = params[:time].blank? ? -1 : params[:time] - question_random = params[:question_random] ? true :false #问题是否随机,0为不随机,1为随机 - choice_random = params[:choice_random] ? true :false - score_open = params[:score_open] ? true : false #分数是否公开 - answer_open = params[:answer_open] ? true : false #答案是否公开 - - # 统一设置或者分班为0,则更新试卷,并删除试卷分组 - if unified_setting || (course_group_ids.size == 0) - tip_exception("发布时间不能为空") if params[:publish_time].blank? - tip_exception("截止时间不能为空") if params[:end_time].blank? - tip_exception("截止时间不能早于发布时间") if params[:publish_time].to_time > params[:end_time].to_time - tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if - @course.end_date.present? && params[:end_time].to_time > @course.end_date.end_of_day - - params_publish_time = params[:publish_time].to_time - params_end_time = params[:end_time].to_time - - if (exercise_status != Exercise::UNPUBLISHED) && (@exercise.publish_time != params_publish_time) - normal_status(-1,"已发布/已截止,不允许修改发布时间") - elsif params_publish_time.present? && params_end_time.present? && params_end_time < params_publish_time - normal_status(-1,"截止时间不能小于发布时间") - else - #发布时间小于当前时间,则试卷显示为未发布,当截止时间大于当前时间,则显示为已截止 - exercise_status_n = set_exercise_status(params_publish_time,params_end_time) - exercise_params = { - :unified_setting => unified_setting, - :show_statistic => show_statistic, - :time => exercise_time, - :question_random => question_random, - :choice_random => choice_random, - :score_open => score_open, - :answer_open => answer_open, - :exercise_status => exercise_status_n, - :publish_time => params_publish_time, - :end_time => params_end_time - } - @exercise.update_attributes(exercise_params) - @exercise.exercise_group_settings.destroy_all - normal_status(0, "试卷设置成功!") + else + params_times = params[:publish_time_groups] #分班返回的json数组{"publish_time_groups":[{"course_group_id":"1","publish_time":"xx","end_time":"xxx"}]} + exercise_groups = @exercise.exercise_group_settings.find_in_exercise_group("course_id", @course.id) #试卷的全部分班信息 + exercise_groups_ids = exercise_groups.pluck(:course_group_id) #问卷的全部分班id + total_common = params_times.map {|k| k[:course_group_id]}.sum.uniq #传入的所有分组的分班id + total_common_group = exercise_groups_ids & total_common #传入的分班与问卷已存在的分班的交集 + old_exercise_groups = exercise_groups_ids - total_common_group #后来传入的分班里,没有了的班级,即需要删除 + + params_times.each do |t| + tip_exception("发布时间不能为空") if t[:publish_time].blank? + tip_exception("截止时间不能为空") if t[:end_time].blank? + tip_exception("截止时间不能早于发布时间") if t[:publish_time].to_time > t[:end_time].to_time + tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && t[:end_time].to_time > @course.end_date.end_of_day + + course_id = t[:course_group_id] + exercise_publish_time = t[:publish_time].to_time + exercise_end_time = t[:end_time].to_time + + exercise_group = exercise_groups.find_in_exercise_group("course_group_id", course_id) #判断该分班是否存在 + if exercise_group.present? && (exercise_group.first.publish_time < Time.now) && (exercise_publish_time != exercise_group.first.publish_time) + error_count += 1 end - else - params_times = params[:publish_time_groups] #分班返回的json数组{"publish_time_groups":[{"course_group_id":"1","publish_time":"xx","end_time":"xxx"}]} - exercise_groups = @exercise.exercise_group_settings.find_in_exercise_group("course_id",@course.id) #试卷的全部分班信息 - exercise_groups_ids = exercise_groups.pluck(:course_group_id) #问卷的全部分班id - total_common = params_times.map{|k| k[:course_group_id]}.sum.uniq #传入的所有分组的分班id - total_common_group = exercise_groups_ids & total_common #传入的分班与问卷已存在的分班的交集 - old_exercise_groups = exercise_groups_ids - total_common_group #后来传入的分班里,没有了的班级,即需要删除 - - params_times.each do |t| - tip_exception("发布时间不能为空") if t[:publish_time].blank? - tip_exception("截止时间不能为空") if t[:end_time].blank? - tip_exception("截止时间不能早于发布时间") if t[:publish_time].to_time > t[:end_time].to_time - tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if - @course.end_date.present? && t[:end_time].to_time > @course.end_date.end_of_day - - course_id = t[:course_group_id] - exercise_publish_time = t[:publish_time].to_time - exercise_end_time = t[:end_time].to_time - - exercise_group = exercise_groups.find_in_exercise_group("course_group_id",course_id) #判断该分班是否存在 - if exercise_group.present? && (exercise_group.first.publish_time < Time.now) && (exercise_publish_time != exercise_group.first.publish_time) - error_count += 1 - end - if exercise_group.present? && (exercise_group.first.publish_time < Time.now && exercise_group.first.end_time > Time.now) && (exercise_end_time < Time.now) - error_count += 1 - end - if error_count == 0 - common_group = exercise_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的 - new_group_ids = course_id - common_group #新传入的班级id - if common_group.count > 0 #判断试卷的分班设置是否存在,存在则更新,负责则新建 - exercise_group_sets = exercise_groups.find_in_exercise_group("course_group_id",common_group) - exercise_group_sets.each do |the_group_setting| + if exercise_group.present? && (exercise_group.first.publish_time < Time.now && exercise_group.first.end_time > Time.now) && (exercise_end_time < Time.now) + error_count += 1 + end + if error_count == 0 + common_group = exercise_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的 + new_group_ids = course_id - common_group #新传入的班级id + if common_group.count > 0 #判断试卷的分班设置是否存在,存在则更新,负责则新建 + exercise_group_sets = exercise_groups.find_in_exercise_group("course_group_id", common_group) + exercise_group_sets.each do |the_group_setting| + ex_group_params = { + :publish_time => exercise_publish_time, + :end_time => exercise_end_time + } + + the_group_setting_status = set_exercise_status(the_group_setting.publish_time, the_group_setting.end_time) + if the_group_setting_status == 2 ex_group_params = { - :publish_time => exercise_publish_time, + :publish_time => the_group_setting.publish_time, + :end_time => exercise_end_time < Time.now ? the_group_setting.end_time : exercise_end_time + } + elsif the_group_setting_status == 3 + ex_group_params = { + :publish_time => the_group_setting.publish_time, :end_time => exercise_end_time } - - the_group_setting_status = set_exercise_status(the_group_setting.publish_time,the_group_setting.end_time) - if the_group_setting_status == 2 - ex_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => exercise_end_time < Time.now ? the_group_setting.end_time : exercise_end_time - } - elsif the_group_setting_status == 3 - ex_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => exercise_end_time - } - end - the_group_setting.update_attributes!(ex_group_params) end + the_group_setting.update!(ex_group_params) end - if new_group_ids.size > 0 - new_group_ids.each do |c| - exercise_group_params = { - :exercise_id => @exercise.id, - :course_group_id => c, - :course_id => @course.id, - :publish_time => exercise_publish_time, - :end_time => exercise_end_time - } - new_exercise_group = ExerciseGroupSetting.new(exercise_group_params) - new_exercise_group.save! - end + end + if new_group_ids.size > 0 + new_group_ids.each do |c| + exercise_group_params = { + :exercise_id => @exercise.id, + :course_group_id => c, + :course_id => @course.id, + :publish_time => exercise_publish_time, + :end_time => exercise_end_time + } + new_exercise_group = ExerciseGroupSetting.new(exercise_group_params) + new_exercise_group.save! end end end + end - if error_count > 0 - error_count == 0 - normal_status(-1,"试卷发布/截止时间不能小于当前时间") - else - # 未发布的分班设置才能删除 - if old_exercise_groups.size > 0 - old_all_ex_groups = exercise_groups.find_in_exercise_group("course_group_id",old_exercise_groups).exercise_group_not_published - old_all_ex_groups.destroy_all - end - #试卷更新为exercise_group_setting的发布时间最小,截止时间最大 - e_time_present = exercise_groups.end_time_no_null.map(&:end_time) - p_time_present = exercise_groups.publish_time_no_null.map(&:publish_time) - e_time = e_time_present.size > 0 ? e_time_present.max : nil - p_time = p_time_present.size > 0 ? p_time_present.min : nil + if error_count > 0 + error_count == 0 + normal_status(-1, "试卷发布/截止时间不能小于当前时间") + else + # 未发布的分班设置才能删除 + if old_exercise_groups.size > 0 + old_all_ex_groups = exercise_groups.find_in_exercise_group("course_group_id", old_exercise_groups).exercise_group_not_published + old_all_ex_groups.destroy_all + end + #试卷更新为exercise_group_setting的发布时间最小,截止时间最大 + e_time_present = exercise_groups.end_time_no_null.map(&:end_time) + p_time_present = exercise_groups.publish_time_no_null.map(&:publish_time) + e_time = e_time_present.size > 0 ? e_time_present.max : nil + p_time = p_time_present.size > 0 ? p_time_present.min : nil + exercise_status = 1 + if p_time.nil? #发布时间为空,则表示问卷未发布 exercise_status = 1 - if p_time.nil? #发布时间为空,则表示问卷未发布 - exercise_status = 1 - elsif p_time.present? && e_time.present? - exercise_status = set_exercise_status(p_time,e_time) - end - exercise_params = { - :unified_setting => unified_setting, - :show_statistic => show_statistic, - :time => exercise_time, - :question_random => question_random, - :choice_random => choice_random, - :score_open => score_open, - :answer_open => answer_open, - :exercise_status => exercise_status, - :publish_time => p_time, - :end_time => e_time - } - @exercise.update_attributes(exercise_params) - if @exercise.exercise_status == Exercise::PUBLISHED - if @exercise.course_acts.size == 0 - @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id,:course_id => @exercise.course_id) - end + elsif p_time.present? && e_time.present? + exercise_status = set_exercise_status(p_time, e_time) + end + exercise_params = { + :unified_setting => unified_setting, + :show_statistic => show_statistic, + :time => exercise_time, + :question_random => question_random, + :choice_random => choice_random, + :score_open => score_open, + :answer_open => answer_open, + :exercise_status => exercise_status, + :publish_time => p_time, + :end_time => e_time + } + @exercise.update!(exercise_params) + if @exercise.exercise_status == Exercise::PUBLISHED + if @exercise.course_acts.size == 0 + @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id, :course_id => @exercise.course_id) end - normal_status(0, "试卷设置成功!") end + normal_status(0, "试卷设置成功!") end - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - raise ActiveRecord::Rollback end end end @@ -629,10 +564,10 @@ class ExercisesController < ApplicationController objective_score = @exercise.objective_score > 0 ? params[:objective_score].to_f.round(2) : 0 score = subjective_score + objective_score if exercise_user.commit_status == 1 - exercise_user.update_attributes!(score: score, subjective_score: subjective_score, objective_score: objective_score) + exercise_user.update!(score: score, subjective_score: subjective_score, objective_score: objective_score) else - exercise_user.update_attributes!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: score, - subjective_score: subjective_score, objective_score: objective_score, commit_method: 5) + exercise_user.update!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: score, + subjective_score: subjective_score, objective_score: objective_score, commit_method: 5) end ExerciseUserScore.create!(exercise_id: @exercise.id, exercise_user_id: exercise_user.id, @@ -644,26 +579,20 @@ class ExercisesController < ApplicationController #我的题库 def my_exercises ActiveRecord::Base.transaction do - begin - ## 我的试卷题库 - @current_user_exercises = current_user.exercise_banks.find_by_c_type("Exercise") - if @current_user_exercises.present? + ## 我的试卷题库 + @current_user_exercises = current_user.exercise_banks.find_by_c_type("Exercise") + if @current_user_exercises.present? - if params[:search].present? - search_type = params[:search].to_s.strip - @current_user_exercises = @current_user_exercises.exercise_bank_search(search_type) - end - page = params[:page] || 1 - limit = params[:limit] || 15 - @my_exercises_count = @current_user_exercises.size - @current_user_exercises = @current_user_exercises.page(page).per(limit) - else - @current_user_exercises = [] + if params[:search].present? + search_type = params[:search].to_s.strip + @current_user_exercises = @current_user_exercises.exercise_bank_search(search_type) end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败!") - raise ActiveRecord::Rollback + page = params[:page] || 1 + limit = params[:limit] || 15 + @my_exercises_count = @current_user_exercises.size + @current_user_exercises = @current_user_exercises.page(page).per(limit) + else + @current_user_exercises = [] end end end @@ -671,32 +600,26 @@ class ExercisesController < ApplicationController # 公共题库 def public_exercises ActiveRecord::Base.transaction do - begin - if current_user.is_certification_teacher - @user_certification = 1 #用户已通过认证 - @public_exercises = ExerciseBank.find_by_c_type("Exercise").public_exercises - if @public_exercises.present? - if params[:search].present? - search_type = params[:search].to_s.strip - @public_exercises = @public_exercises.exercise_bank_search(search_type) - end - page = params[:page] || 1 - limit = params[:limit] || 15 - @public_exercises_count = @public_exercises.size - @public_exercises = @public_exercises.page(page).per(limit) - else - @public_exercises_count = 0 - @public_exercises = [] + if current_user.is_certification_teacher + @user_certification = 1 #用户已通过认证 + @public_exercises = ExerciseBank.find_by_c_type("Exercise").public_exercises + if @public_exercises.present? + if params[:search].present? + search_type = params[:search].to_s.strip + @public_exercises = @public_exercises.exercise_bank_search(search_type) end + page = params[:page] || 1 + limit = params[:limit] || 15 + @public_exercises_count = @public_exercises.size + @public_exercises = @public_exercises.page(page).per(limit) else - @user_certification = 0 #用户未通过认证 @public_exercises_count = 0 @public_exercises = [] end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("题库调用失败!") - raise ActiveRecord::Rollback + else + @user_certification = 0 #用户未通过认证 + @public_exercises_count = 0 + @public_exercises = [] end end end @@ -705,17 +628,11 @@ class ExercisesController < ApplicationController def publish_modal ActiveRecord::Base.transaction do - begin - exercise_ids = params[:check_ids] - if exercise_ids.count > 0 - @course_groups = get_user_permission_course(exercise_ids,1) - else - @course_groups = [] - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + exercise_ids = params[:check_ids] + if exercise_ids.count > 0 + @course_groups = get_user_permission_course(exercise_ids, 1) + else + @course_groups = [] end end end @@ -735,109 +652,95 @@ class ExercisesController < ApplicationController if params[:detail].blank? tip_exception("缺少截止时间参数") if params[:end_time].blank? tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) - tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if - @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) + tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) else - group_end_times = params[:group_end_times].reject(&:blank?).map{|time| time.to_time} + group_end_times = params[:group_end_times].reject(&:blank?).map {|time| time.to_time} tip_exception("缺少截止时间参数") if group_end_times.blank? tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length group_end_times.each do |time| tip_exception("分班截止时间不能早于当前时间") if time <= Time.now - tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if - @course.end_date.present? && time > @course.end_date.end_of_day + tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && time > @course.end_date.end_of_day end end ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id: params[:check_ids]) - ex_end_time = params[:end_time].blank? ? Time.at(((1.month.since.to_i)/3600.0).ceil * 3600) : params[:end_time].to_time - check_ids.each do |exercise| - if exercise.present? - if exercise.unified_setting - ex_status = exercise.exercise_status #则为试卷的状态 - else - ex_status = @course.course_groups.where(id: params[:group_ids]).size != - exercise.exercise_group_settings.where(course_group_id: params[:group_ids]).exercise_group_published.size ? 1 : 0 - end - if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过 - g_course = group_ids #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改 - tiding_group_ids = g_course - if g_course - user_course_groups = @course.course_groups.pluck(:id) - if g_course.map(&:to_i).sort == user_course_groups.sort && - ((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?) # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置 - exercise.exercise_group_settings.destroy_all - ex_unified = true - e_time = params[:detail] ? group_end_times.max : ex_end_time - tiding_group_ids = [] - else - ex_unified = false - g_course.each_with_index do |i, index| - exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id",i).first #根据课堂分班的id,寻找试卷所在的班级 - group_end_time = params[:detail] ? group_end_times[index] : ex_end_time - if exercise_group_setting.present? #如果该试卷分组存在,则更新,否则新建 - exercise_group_setting.update_attributes!(publish_time: Time.now, end_time: group_end_time) - else - p_course_group = { - :exercise_id => exercise.id, - :course_group_id => i, - :course_id => exercise.course.id, - :publish_time => Time.now, - :end_time => group_end_time, - } - new_exercise_group = exercise.exercise_group_settings.new p_course_group - new_exercise_group.save - end - end - # group_ids = params[:group_ids] - e_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time).max - end - else + check_ids = Exercise.where(id: params[:check_ids]) + ex_end_time = params[:end_time].blank? ? Time.at(((1.month.since.to_i) / 3600.0).ceil * 3600) : params[:end_time].to_time + check_ids.each do |exercise| + if exercise.present? + if exercise.unified_setting + ex_status = exercise.exercise_status #则为试卷的状态 + else + ex_status = @course.course_groups.where(id: params[:group_ids]).size != + exercise.exercise_group_settings.where(course_group_id: params[:group_ids]).exercise_group_published.size ? 1 : 0 + end + if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过 + g_course = group_ids #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改 + tiding_group_ids = g_course + if g_course + user_course_groups = @course.course_groups.pluck(:id) + if g_course.map(&:to_i).sort == user_course_groups.sort && + ((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?) # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置 exercise.exercise_group_settings.destroy_all ex_unified = true - e_time = ex_end_time + e_time = params[:detail] ? group_end_times.max : ex_end_time + tiding_group_ids = [] + else + ex_unified = false + g_course.each_with_index do |i, index| + exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id", i).first #根据课堂分班的id,寻找试卷所在的班级 + group_end_time = params[:detail] ? group_end_times[index] : ex_end_time + if exercise_group_setting.present? #如果该试卷分组存在,则更新,否则新建 + exercise_group_setting.update!(publish_time: Time.now, end_time: group_end_time) + else + p_course_group = { + :exercise_id => exercise.id, + :course_group_id => i, + :course_id => exercise.course.id, + :publish_time => Time.now, + :end_time => group_end_time, + } + new_exercise_group = exercise.exercise_group_settings.new p_course_group + new_exercise_group.save! + end + end + # group_ids = params[:group_ids] + e_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time).max end + else + exercise.exercise_group_settings.destroy_all + ex_unified = true + e_time = ex_end_time + end - ex_status = set_exercise_status(Time.now,e_time) - exercise_params = { - :publish_time => Time.now, - :end_time => e_time, - :exercise_status => ex_status, - :unified_setting => ex_unified - } - exercise.update_attributes(exercise_params) + ex_status = set_exercise_status(Time.now, e_time) + exercise_params = { + :publish_time => Time.now, + :end_time => e_time, + :exercise_status => ex_status, + :unified_setting => ex_unified + } + exercise.update!(exercise_params) - if exercise.course_acts.size == 0 - exercise.course_acts << CourseActivity.new(:user_id => exercise.user_id,:course_id => exercise.course_id) - end - ExercisePublishNotifyJob.perform_later(exercise.id, tiding_group_ids) + if exercise.course_acts.size == 0 + exercise.course_acts << CourseActivity.new(:user_id => exercise.user_id, :course_id => exercise.course_id) end + ExercisePublishNotifyJob.perform_later(exercise.id, tiding_group_ids) end end - normal_status(0, "试卷发布成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷发布失败") - raise ActiveRecord::Rollback end + normal_status(0, "试卷发布成功!") end end #立即截止的弹窗内容 def end_modal ActiveRecord::Base.transaction do - begin - exercise_ids = params[:check_ids] - if exercise_ids.count > 0 - @course_groups = get_user_permission_course(exercise_ids,3) - else - @course_groups = [] - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + exercise_ids = params[:check_ids] + if exercise_ids.count > 0 + @course_groups = get_user_permission_course(exercise_ids, 3) + else + @course_groups = [] end end end @@ -846,128 +749,116 @@ class ExercisesController < ApplicationController def end_exercise ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id:params[:check_ids]) - course_students = @course.students #课堂的全部学生数 - check_ids.each do |exercise| - exercise_status= exercise.get_exercise_status(current_user) - if exercise_status == Exercise::PUBLISHED #跳过已截止的或未发布的 - g_course = params[:group_ids] - if g_course.present? - teacher_course_group_ids = @course.charge_group_ids(current_user) - all_course_group_ids = @course.course_groups.pluck(:id) - if exercise.unified_setting && g_course.map(&:to_i).sort == all_course_group_ids.sort #开始为统一设置 - exercise.exercise_group_settings.destroy_all - new_ex_status = set_exercise_status(exercise.publish_time,Time.now) - exercise.update_attributes(:end_time => Time.now,:exercise_status => new_ex_status) - exercise_users = exercise.exercise_users - else - course_members_ids = course_students.course_find_by_ids("course_group_id",g_course).pluck(:user_id).uniq #该班级的全部学生 - exercise_users = exercise.exercise_users.exercise_commit_users(course_members_ids) #参与答题的学生数 - ex_group_setting = exercise.exercise_group_settings - old_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id",g_course) #试卷的分组设置 - left_course_groups = teacher_course_group_ids - g_course - left_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id",left_course_groups) - if left_exercise_groups.blank? && exercise.unified_setting - if left_course_groups.size > 0 #开始为统一设置,但是立即截止为分班。则创建没有立即截止的班级的exercise_group_setting - left_course_groups.each do |g| - ex_group_options = { - :exercise_id => exercise.id, - :course_group_id => g, - :course_id => @course.id, - :publish_time => exercise.publish_time, - :end_time => exercise.end_time - } - ExerciseGroupSetting.create(ex_group_options) - end - end - end - if old_exercise_groups.present? - old_exercise_groups.update_all(:end_time => Time.now) - else - g_course.each do |g| + check_ids = Exercise.where(id: params[:check_ids]) + course_students = @course.students #课堂的全部学生数 + check_ids.each do |exercise| + exercise_status = exercise.get_exercise_status(current_user) + if exercise_status == Exercise::PUBLISHED #跳过已截止的或未发布的 + g_course = params[:group_ids] + if g_course.present? + teacher_course_group_ids = @course.charge_group_ids(current_user) + all_course_group_ids = @course.course_groups.pluck(:id) + if exercise.unified_setting && g_course.map(&:to_i).sort == all_course_group_ids.sort #开始为统一设置 + exercise.exercise_group_settings.destroy_all + new_ex_status = set_exercise_status(exercise.publish_time, Time.now) + exercise.update!(:end_time => Time.now, :exercise_status => new_ex_status) + exercise_users = exercise.exercise_users + else + course_members_ids = course_students.course_find_by_ids("course_group_id", g_course).pluck(:user_id).uniq #该班级的全部学生 + exercise_users = exercise.exercise_users.exercise_commit_users(course_members_ids) #参与答题的学生数 + ex_group_setting = exercise.exercise_group_settings + old_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id", g_course) #试卷的分组设置 + left_course_groups = teacher_course_group_ids - g_course + left_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id", left_course_groups) + if left_exercise_groups.blank? && exercise.unified_setting + if left_course_groups.size > 0 #开始为统一设置,但是立即截止为分班。则创建没有立即截止的班级的exercise_group_setting + left_course_groups.each do |g| ex_group_options = { - :exercise_id => exercise.id, - :course_group_id => g, - :course_id => @course.id, - :publish_time => exercise.publish_time, - :end_time => Time.now + :exercise_id => exercise.id, + :course_group_id => g, + :course_id => @course.id, + :publish_time => exercise.publish_time, + :end_time => exercise.end_time } - ExerciseGroupSetting.create(ex_group_options) + ExerciseGroupSetting.create!(ex_group_options) end end - new_end_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time) # 试卷结束时间不为空的 - new_end_time_s = new_end_time.count > 0 ? new_end_time.max : Time.now - new_ex_status = set_exercise_status(exercise.publish_time,new_end_time_s) - exercise.update_attributes(:end_time => new_end_time_s,:exercise_status => new_ex_status,:unified_setting => false) end - else - exercise_users = exercise.exercise_users - exercise.update_attributes(:exercise_status => 3, :end_time => Time.now,:unified_setting => true) + if old_exercise_groups.present? + old_exercise_groups.update_all(:end_time => Time.now) + else + g_course.each do |g| + ex_group_options = { + :exercise_id => exercise.id, + :course_group_id => g, + :course_id => @course.id, + :publish_time => exercise.publish_time, + :end_time => Time.now + } + ExerciseGroupSetting.create!(ex_group_options) + end + end + new_end_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time) # 试卷结束时间不为空的 + new_end_time_s = new_end_time.count > 0 ? new_end_time.max : Time.now + new_ex_status = set_exercise_status(exercise.publish_time, new_end_time_s) + exercise.update!(:end_time => new_end_time_s, :exercise_status => new_ex_status, :unified_setting => false) end - - ex_user_ids = exercise_users.pluck(:id) - - EndExerciseCalculateJob.perform_later(ex_user_ids,exercise,Time.now.to_s) - # exercise_users.each do |user| - # if user.commit_status == 0 && user.start_at.present? - # objective_score = calculate_student_score(exercise,user.user)[:total_score] - # user_sub_score = user.subjective_score - # subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score - # total_score = objective_score + subjective_score - # commit_option = { - # :status => 1, - # :commit_status => 1, - # :end_at => Time.now, - # :objective_score => objective_score, - # :score => total_score, - # :subjective_score => user_sub_score - # } - # user.update_attributes(commit_option) - # end - # end + else + exercise_users = exercise.exercise_users + exercise.update!(:exercise_status => 3, :end_time => Time.now, :unified_setting => true) end + + ex_user_ids = exercise_users.pluck(:id) + + EndExerciseCalculateJob.perform_later(ex_user_ids, exercise, Time.now.to_s) + # exercise_users.each do |user| + # if user.commit_status == 0 && user.start_at.present? + # objective_score = calculate_student_score(exercise,user.user)[:total_score] + # user_sub_score = user.subjective_score + # subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score + # total_score = objective_score + subjective_score + # commit_option = { + # :status => 1, + # :commit_status => 1, + # :end_at => Time.now, + # :objective_score => objective_score, + # :score => total_score, + # :subjective_score => user_sub_score + # } + # user.update_attributes(commit_option) + # end + # end end - normal_status(0, "试卷截止成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("立即截止失败!") - raise ActiveRecord::Rollback end + normal_status(0, "试卷截止成功!") end end #学生撤销回答 def cancel_exercise ActiveRecord::Base.transaction do - begin - ex_question_ids = @exercise.exercise_questions.pluck(:id) - exercise_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first - if exercise_user.present? - if exercise_user.commit_status == 1 && @exercise.get_exercise_status(current_user) == Exercise::PUBLISHED #用户已提交且试卷提交中 - if @exercise.time == -1 || ((Time.now.to_i - exercise_user.start_at.to_i) < @exercise.time.to_i * 60) - exercise_user.update_attributes(:score => nil, :end_at => nil, :status => nil, :commit_status => 0, - :objective_score => 0.0, :subjective_score => -1.0) - exercise_user.user.exercise_shixun_answers.search_shixun_answers("exercise_question_id",ex_question_ids).destroy_all - exercise_answers = exercise_user.user.exercise_answers.search_answer_users("exercise_question_id",ex_question_ids) - exercise_answers.update_all(:score => -1.0) - all_answer_comment = ExerciseAnswerComment.search_answer_comments("exercise_question_id",ex_question_ids) - .search_answer_comments("exercise_answer_id",exercise_answers.pluck(:id)) - all_answer_comment.destroy_all - normal_status(0,"撤销回答成功") - else - normal_status(-1,"用户答题时间已到") - end + ex_question_ids = @exercise.exercise_questions.pluck(:id) + exercise_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first + if exercise_user.present? + if exercise_user.commit_status == 1 && @exercise.get_exercise_status(current_user) == Exercise::PUBLISHED #用户已提交且试卷提交中 + if @exercise.time == -1 || ((Time.now.to_i - exercise_user.start_at.to_i) < @exercise.time.to_i * 60) + exercise_user.update!(:score => nil, :end_at => nil, :status => nil, :commit_status => 0, + :objective_score => 0.0, :subjective_score => -1.0) + exercise_user.user.exercise_shixun_answers.search_shixun_answers("exercise_question_id", ex_question_ids).destroy_all + exercise_answers = exercise_user.user.exercise_answers.search_answer_users("exercise_question_id", ex_question_ids) + exercise_answers.update_all(:score => -1.0) + all_answer_comment = ExerciseAnswerComment.search_answer_comments("exercise_question_id", ex_question_ids) + .search_answer_comments("exercise_answer_id", exercise_answers.pluck(:id)) + all_answer_comment.destroy_all + normal_status(0, "撤销回答成功") else - normal_status(-1,"用户未提交/试卷不是提交中") + normal_status(-1, "用户答题时间已到") end else - normal_status(-1,"当前用户未答题") + normal_status(-1, "用户未提交/试卷不是提交中") end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败") - raise ActiveRecord::Rollback + else + normal_status(-1, "当前用户未答题") end end end @@ -975,170 +866,146 @@ class ExercisesController < ApplicationController #打回重做modal def redo_modal ActiveRecord::Base.transaction do - begin - #搜索 - if params[:realname].present? - search_name = params[:realname] - #搜索用户的nickname,如果存在则返回,否则继续查询用户的真实姓名或学生号 - @exercise_users = @exercise_users.includes(:user).where("LOWER(concat(users.lastname, users.firstname)) like ?", - "%#{search_name}%") - end - if params[:student_id].present? - search_st_id = params[:student_id].to_i - @exercise_users = @exercise_users.includes(user: [:user_extension]) - .where('user_extensions.student_id like ?',"%#{search_st_id}%") - end - sort = params[:sort] ? params[:sort] : "asc" - @exercise_users = @exercise_users.order("score #{sort}") - @exercise_users_size = @exercise_users.size - # 分页 - page = params[:page] || 1 - limit = params[:limit] || 15 - @exercise_users = @exercise_users.page(page).per(limit) - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + #搜索 + if params[:realname].present? + search_name = params[:realname] + #搜索用户的nickname,如果存在则返回,否则继续查询用户的真实姓名或学生号 + @exercise_users = @exercise_users.includes(:user).where("LOWER(concat(users.lastname, users.firstname)) like ?", + "%#{search_name}%") + end + if params[:student_id].present? + search_st_id = params[:student_id].to_i + @exercise_users = @exercise_users.includes(user: [:user_extension]) + .where('user_extensions.student_id like ?', "%#{search_st_id}%") end + sort = params[:sort] ? params[:sort] : "asc" + @exercise_users = @exercise_users.order("score #{sort}") + @exercise_users_size = @exercise_users.size + # 分页 + page = params[:page] || 1 + limit = params[:limit] || 15 + @exercise_users = @exercise_users.page(page).per(limit) end end #打回重做确认 def redo_exercise ActiveRecord::Base.transaction do - begin - user_ids = params[:user_ids] - if user_ids.present? - redo_option = { - :score => 0.0, - :start_at => nil, - :end_at => nil, - :status => nil, - :commit_status => 0, - :objective_score => 0.0, - :subjective_score => -1.0, - :commit_method => 0 - } - redo_exercise_users = @exercise_users.exercise_commit_users(user_ids) - redo_exercise_users.update_all(redo_option) - exercise_question_ids = @exercise.exercise_questions.pluck(:id).uniq - ExerciseAnswer.search_answer_users("user_id",user_ids) - .search_answer_users("exercise_question_id",exercise_question_ids).destroy_all - ExerciseShixunAnswer.search_shixun_answers("user_id",user_ids) - .search_shixun_answers("exercise_question_id",exercise_question_ids).destroy_all - - normal_status(0,"已成功打回重做!") - else - normal_status(-1,"请选择学生!") - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + user_ids = params[:user_ids] + if user_ids.present? + redo_option = { + :score => 0.0, + :start_at => nil, + :end_at => nil, + :status => nil, + :commit_status => 0, + :objective_score => 0.0, + :subjective_score => -1.0, + :commit_method => 0 + } + redo_exercise_users = @exercise_users.exercise_commit_users(user_ids) + redo_exercise_users.update_all(redo_option) + exercise_question_ids = @exercise.exercise_questions.pluck(:id).uniq + ExerciseAnswer.search_answer_users("user_id", user_ids) + .search_answer_users("exercise_question_id", exercise_question_ids).destroy_all + ExerciseShixunAnswer.search_shixun_answers("user_id", user_ids) + .search_shixun_answers("exercise_question_id", exercise_question_ids).destroy_all + + normal_status(0, "已成功打回重做!") + else + normal_status(-1, "请选择学生!") end end end #学生开始答题页面 def start_answer - begin - ex_users_current = ExerciseUser.where(user_id:@exercise_current_user_id,exercise_id:@exercise.id) #不能用@exercise.exercise_users,因为exercise_users删除时,只是状态改变,未删除 - @exercise_user_current = ex_users_current&.first - if ex_users_current.exists? - if @exercise_user_current.start_at.blank? - @exercise_user_current.update_attribute("start_at",Time.now) - end - else - if @user_course_identity > Course::ASSISTANT_PROFESSOR #当为老师的时候,不创建exercise_user表,理论上老师是不能进入答题的 - exercise_user_params = { - :user_id => @exercise_current_user_id, - :exercise_id => @exercise.id, - :start_at => Time.now - } - exercise_user_current = ExerciseUser.new(exercise_user_params) - exercise_user_current.save - end + ex_users_current = ExerciseUser.where(user_id: @exercise_current_user_id, exercise_id: @exercise.id) #不能用@exercise.exercise_users,因为exercise_users删除时,只是状态改变,未删除 + @exercise_user_current = ex_users_current&.first + if ex_users_current.exists? + if @exercise_user_current.start_at.blank? + @exercise_user_current.update!(start_at: Time.now) end - @t_user_exercise_status = @exercise.get_exercise_status(current_user) - - @user_left_time = nil - if @user_course_identity < Course::STUDENT || (@t_user_exercise_status == 3) || - (ex_users_current.exists? && @exercise_user_current.commit_status == 1) - @user_exercise_status = 1 #当前用户为老师/试卷已截止/试卷已提交不可编辑 - else - @user_left_time = get_exercise_left_time(@exercise,current_user) - @user_exercise_status = 0 #可编辑 + else + if @user_course_identity > Course::ASSISTANT_PROFESSOR #当为老师的时候,不创建exercise_user表,理论上老师是不能进入答题的 + exercise_user_params = { + :user_id => @exercise_current_user_id, + :exercise_id => @exercise.id, + :start_at => Time.now + } + exercise_user_current = ExerciseUser.new(exercise_user_params) + exercise_user_current.save! end + end + @t_user_exercise_status = @exercise.get_exercise_status(current_user) - @exercise_questions = @exercise.exercise_questions + @user_left_time = nil + if @user_course_identity < Course::STUDENT || (@t_user_exercise_status == 3) || + (ex_users_current.exists? && @exercise_user_current.commit_status == 1) + @user_exercise_status = 1 #当前用户为老师/试卷已截止/试卷已提交不可编辑 + else + @user_left_time = get_exercise_left_time(@exercise, current_user) + @user_exercise_status = 0 #可编辑 + end - if @exercise.question_random - @exercise_questions = @exercise_questions.order("RAND()") - else - @exercise_questions = @exercise_questions.order("question_number ASC") - end - # 判断问题是否已回答还是未回答 - @exercise_questions = @exercise_questions.includes(:exercise_shixun_challenges, - :exercise_shixun_answers, - :exercise_answers, - :exercise_standard_answers) - - if @t_user_exercise_status == Exercise::DEADLINE - get_each_student_exercise(@exercise.id,@exercise_questions,@exercise_current_user_id) - end - get_user_answer_status(@exercise_questions,@exercise_current_user_id,@exercise,@t_user_exercise_status) + @exercise_questions = @exercise.exercise_questions - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - raise ActiveRecord::Rollback + if @exercise.question_random + @exercise_questions = @exercise_questions.order("RAND()") + else + @exercise_questions = @exercise_questions.order("question_number ASC") end + # 判断问题是否已回答还是未回答 + @exercise_questions = @exercise_questions.includes(:exercise_shixun_challenges, + :exercise_shixun_answers, + :exercise_answers, + :exercise_standard_answers) + + if @t_user_exercise_status == Exercise::DEADLINE + get_each_student_exercise(@exercise.id, @exercise_questions, @exercise_current_user_id) + end + get_user_answer_status(@exercise_questions, @exercise_current_user_id, @exercise, @t_user_exercise_status) + end #提交试卷前的弹窗 def begin_commit ActiveRecord::Base.transaction do - begin - if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 - @exercise_questions = @exercise.exercise_questions - @shixun_undo = 0 - @ques_undo = 0 - ex_answer_time = @exercise.time.to_i - if ex_answer_time > 0 #有剩余时间的时候 - user_left_time = get_exercise_left_time(@exercise,current_user) - @ex_end_time = Time.now + user_left_time.to_i.seconds + if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 + @exercise_questions = @exercise.exercise_questions + @shixun_undo = 0 + @ques_undo = 0 + ex_answer_time = @exercise.time.to_i + if ex_answer_time > 0 #有剩余时间的时候 + user_left_time = get_exercise_left_time(@exercise, current_user) + @ex_end_time = Time.now + user_left_time.to_i.seconds + else + @ex_end_time = @exercise.get_exercise_end_time(current_user.id) + end + # @ex_end_time = @exercise.get_exercise_end_time(current_user.id) + # if ex_answer_time > 0 + # left_answer_time = Time.now + ex_answer_time.minutes #判断试卷的倒计时和截止时间哪个先到 + # if left_answer_time < @ex_end_time + # exercise_end_time = @exercise.exercise_users.exercise_commit_users(current_user.id) + # if exercise_end_time.present? + # ex_end_times = exercise_end_time.first.start_at.nil? ? Time.now : exercise_end_time.first.start_at + # @ex_end_time = ex_end_times + ex_answer_time.minutes + # end + # end + # end + @exercise_questions.each do |q| + if q.question_type == Exercise::PRACTICAL #当为实训题时 + user_myshixun = q.shixun.myshixuns.search_myshixun_user(current_user.id) + if user_myshixun.blank? || user_myshixun.first.status != Exercise::UNPUBLISHED #当前用户的实训是否做完 + @shixun_undo += 1 + end else - @ex_end_time = @exercise.get_exercise_end_time(current_user.id) - end - # @ex_end_time = @exercise.get_exercise_end_time(current_user.id) - # if ex_answer_time > 0 - # left_answer_time = Time.now + ex_answer_time.minutes #判断试卷的倒计时和截止时间哪个先到 - # if left_answer_time < @ex_end_time - # exercise_end_time = @exercise.exercise_users.exercise_commit_users(current_user.id) - # if exercise_end_time.present? - # ex_end_times = exercise_end_time.first.start_at.nil? ? Time.now : exercise_end_time.first.start_at - # @ex_end_time = ex_end_times + ex_answer_time.minutes - # end - # end - # end - @exercise_questions.each do |q| - if q.question_type == Exercise::PRACTICAL #当为实训题时 - user_myshixun = q.shixun.myshixuns.search_myshixun_user(current_user.id) - if user_myshixun.blank? || user_myshixun.first.status != Exercise::UNPUBLISHED #当前用户的实训是否做完 - @shixun_undo += 1 - end - else - ques_vote = q.exercise_answers.search_exercise_answer("user_id",current_user.id) - if ques_vote.blank? - @ques_undo += 1 - end + ques_vote = q.exercise_answers.search_exercise_answer("user_id", current_user.id) + if ques_vote.blank? + @ques_undo += 1 end end end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷提交失败!") - raise ActiveRecord::Rollback end end end @@ -1147,46 +1014,40 @@ class ExercisesController < ApplicationController def commit_exercise tip_exception(0, "试卷截止时间已到,系统已自动提交") if @answer_committed_user.commit_status == 1 ActiveRecord::Base.transaction do - begin - can_commit_exercise = false - user_left_time = nil - if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 - if params[:commit_method].to_i == 2 #自动提交时 - user_left_time = get_exercise_left_time(@exercise,current_user) - Rails.logger.info("######__________auto_commit_user_left_time_________################{user_left_time}") - if user_left_time.to_i <= 0 - can_commit_exercise = true - end - else + can_commit_exercise = false + user_left_time = nil + if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 + if params[:commit_method].to_i == 2 #自动提交时 + user_left_time = get_exercise_left_time(@exercise, current_user) + Rails.logger.info("######__________auto_commit_user_left_time_________################{user_left_time}") + if user_left_time.to_i <= 0 can_commit_exercise = true end - if can_commit_exercise - objective_score = calculate_student_score(@exercise,current_user,Time.now)[:total_score] - subjective_score = @answer_committed_user.subjective_score - total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score - total_score = objective_score + total_score_subjective_score - commit_option = { - :status => 1, - :commit_status => 1, - :end_at => Time.now, - :objective_score => objective_score, - :score => total_score, - :subjective_score => subjective_score, - :commit_method => @answer_committed_user&.commit_method.to_i > 0 ? @answer_committed_user&.commit_method.to_i : params[:commit_method].to_i - } - @answer_committed_user.update_attributes!(commit_option) - CommitExercsieNotifyJobJob.perform_later(@exercise.id, current_user.id) - normal_status(0,"试卷提交成功!") - else - normal_status(-2,"#{user_left_time.to_i}") - end else - normal_status(-1,"提交失败,当前用户不为课堂学生!") + can_commit_exercise = true end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷提交失败!") - raise ActiveRecord::Rollback + if can_commit_exercise + objective_score = calculate_student_score(@exercise, current_user, Time.now)[:total_score] + subjective_score = @answer_committed_user.subjective_score + total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score + total_score = objective_score + total_score_subjective_score + commit_option = { + :status => 1, + :commit_status => 1, + :end_at => Time.now, + :objective_score => objective_score, + :score => total_score, + :subjective_score => subjective_score, + :commit_method => @answer_committed_user&.commit_method.to_i > 0 ? @answer_committed_user&.commit_method.to_i : params[:commit_method].to_i + } + @answer_committed_user.update!(commit_option) + CommitExercsieNotifyJobJob.perform_later(@exercise.id, current_user.id) + normal_status(0, "试卷提交成功!") + else + normal_status(-2, "#{user_left_time.to_i}") + end + else + normal_status(-1, "提交失败,当前用户不为课堂学生!") end end end @@ -1194,184 +1055,172 @@ class ExercisesController < ApplicationController #教师评阅试卷 及学生查看试卷 def review_exercise ActiveRecord::Base.transaction do - begin - # 1 老师权限,0 学生权限 - @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 - @student_status = 2 - @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges,:exercise_standard_answers,:exercise_answers,:exercise_shixun_answers,:exercise_answer_comments).order("question_number ASC") - @question_status = [] - get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 - @ex_answer_status = @exercise.get_exercise_status(@ex_user&.user) #当前试卷用户的试卷状态 - if @ex_user.present? && @is_teacher_or == 0 - if get_exercise_status == Exercise::PUBLISHED #当前用户已提交,且试卷未截止 - if @ex_user.commit_status == 0 #学生未提交,且当前为学生 - @student_status = 0 - else - @student_status = 1 - get_user_answer_status(@exercise_questions,@exercise_current_user_id,@exercise,get_exercise_status) - end + # 1 老师权限,0 学生权限 + @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 + @student_status = 2 + @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges, :exercise_standard_answers, :exercise_answers, :exercise_shixun_answers, :exercise_answer_comments).order("question_number ASC") + @question_status = [] + get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 + @ex_answer_status = @exercise.get_exercise_status(@ex_user&.user) #当前试卷用户的试卷状态 + if @ex_user.present? && @is_teacher_or == 0 + if get_exercise_status == Exercise::PUBLISHED #当前用户已提交,且试卷未截止 + if @ex_user.commit_status == 0 #学生未提交,且当前为学生 + @student_status = 0 + else + @student_status = 1 + get_user_answer_status(@exercise_questions, @exercise_current_user_id, @exercise, get_exercise_status) end end - if @student_status == 2 - get_each_student_exercise(@exercise.id,@exercise_questions,@exercise_current_user_id) - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + end + if @student_status == 2 + get_each_student_exercise(@exercise.id, @exercise_questions, @exercise_current_user_id) end end end #答题列表 def exercise_lists - begin - @current_user_id = current_user.id - exercise_ids = [@exercise.id] - @exercise_status = @exercise.get_exercise_status(current_user) - @course_all_members = @course.students - @c_group_counts = @course.course_groups_count - question_types = @exercise.exercise_questions.pluck(:question_type).uniq - @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).count #判断是否有已发布的分班 - @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).count #判断是否有未发布的分班 - - if (question_types.size > 1) && question_types.include?(Exercise::SUBJECTIVE) #是否包含主观题,或者是否大于1 - @subjective_type = 1 + @current_user_id = current_user.id + exercise_ids = [@exercise.id] + @exercise_status = @exercise.get_exercise_status(current_user) + @course_all_members = @course.students + @c_group_counts = @course.course_groups_count + question_types = @exercise.exercise_questions.pluck(:question_type).uniq + @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).count #判断是否有已发布的分班 + @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).count #判断是否有未发布的分班 + + if (question_types.size > 1) && question_types.include?(Exercise::SUBJECTIVE) #是否包含主观题,或者是否大于1 + @subjective_type = 1 + else + @subjective_type = 0 + end + + #初始化值 + @exercise_users_list = [] #答题用户列表 + @exercise_course_groups = [] #当前用户有权限的班级 + @exercise_unanswers = 0 # 未答用户数 + @exercise_answers = 0 #已答用户数 + @exercise_users_count = 0 #全部用户数 + @teacher_review_count = 0 #已评数 + @teacher_unreview_count = 0 #未评数 + + #试卷的答题列表页的显示用户 + if @user_course_identity < Course::STUDENT #当前为老师,而且老师只能查看自己班级的/课堂的试卷 + @exercise_current_user_status = 0 + unless @exercise_status == Exercise::UNPUBLISHED + ex_common_ids = @exercise.common_published_ids(current_user.id) + @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) + @exercise_users_list = @exercise.all_exercise_users(current_user.id) #当前老师所在班级的全部学生 + get_exercise_answers(@exercise_users_list, @exercise_status) + end + else #当前为学生或者有过答题的 + @ex_user_end_time = @exercise.get_exercise_end_time(current_user.id) #当前用户所看到的剩余时间 + @exercise_all_users = @exercise.get_stu_exercise_users + get_exercise_answers(@exercise_all_users, @exercise_status) # 未答和已答的 + exercise_current_user = @exercise_all_users.exercise_commit_users(current_user.id) + if exercise_current_user.exists? #表示为课堂学生或已回答的 + @exercise_current_user_status = 1 + if @exercise.score_open && @exercise_status == Exercise::DEADLINE #勾选了成绩公开且试卷已截止的 + all_user_ids = @exercise_all_users.pluck(:user_id) + all_user_ids.delete(current_user.id) #删除了当前用户的ID + @exercise_users_list = @exercise_all_users.exercise_commit_users(all_user_ids).distinct + @current_user_ex_answers = exercise_current_user #当前用户的回答 else - @subjective_type = 0 + @exercise_users_list = exercise_current_user end + else #表示为未回答的,或未非课堂成员的 + @exercise_current_user_status = 2 #当前用户非课堂成员 + end + end - #初始化值 - @exercise_users_list = [] #答题用户列表 - @exercise_course_groups = [] #当前用户有权限的班级 - @exercise_unanswers = 0 # 未答用户数 - @exercise_answers = 0 #已答用户数 - @exercise_users_count = 0 #全部用户数 - @teacher_review_count = 0 #已评数 - @teacher_unreview_count = 0 #未评数 - - #试卷的答题列表页的显示用户 - if @user_course_identity < Course::STUDENT #当前为老师,而且老师只能查看自己班级的/课堂的试卷 - @exercise_current_user_status = 0 - unless @exercise_status == Exercise::UNPUBLISHED - ex_common_ids = @exercise.common_published_ids(current_user.id) - @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) - @exercise_users_list = @exercise.all_exercise_users(current_user.id) #当前老师所在班级的全部学生 - get_exercise_answers(@exercise_users_list, @exercise_status) - end - else #当前为学生或者有过答题的 - @ex_user_end_time = @exercise.get_exercise_end_time(current_user.id) #当前用户所看到的剩余时间 - @exercise_all_users = @exercise.get_stu_exercise_users - get_exercise_answers(@exercise_all_users, @exercise_status) # 未答和已答的 - exercise_current_user = @exercise_all_users.exercise_commit_users(current_user.id) - if exercise_current_user.exists? #表示为课堂学生或已回答的 - @exercise_current_user_status = 1 - if @exercise.score_open && @exercise_status == Exercise::DEADLINE #勾选了成绩公开且试卷已截止的 - all_user_ids = @exercise_all_users.pluck(:user_id) - all_user_ids.delete(current_user.id) #删除了当前用户的ID - @exercise_users_list = @exercise_all_users.exercise_commit_users(all_user_ids).distinct - @current_user_ex_answers = exercise_current_user #当前用户的回答 - else - @exercise_users_list = exercise_current_user - end - else #表示为未回答的,或未非课堂成员的 - @exercise_current_user_status = 2 #当前用户非课堂成员 - end - end + if @exercise_unanswers < 0 + @exercise_unanswers = 0 + end - if @exercise_unanswers < 0 - @exercise_unanswers = 0 + #筛选/分类,排序 + order = params[:order] + order_type = params[:order_type] || "desc" + + if @exercise_users_list.present? && @exercise_users_list.size > 0 + @exercise_users_count = @exercise_users_list.size #当前显示的全部成员数量 + teacher_reviews = @exercise_users_list.exercise_review + teacher_unreviews = @exercise_users_list.exercise_unreview + @teacher_review_count = teacher_reviews.size #已评阅 + @teacher_unreview_count = teacher_unreviews.size #未评阅 + + #是否评阅 + if params[:review].present? + review_type = params[:review].first.to_i #已评,则数据为1,未评,则数据为0,前端传过来的为数组 + if review_type == 1 + @exercise_users_list = teacher_reviews + else + @exercise_users_list = teacher_unreviews end + end - #筛选/分类,排序 - order = params[:order] - order_type = params[:order_type] || "desc" - - if @exercise_users_list.present? && @exercise_users_list.size > 0 - @exercise_users_count = @exercise_users_list.size #当前显示的全部成员数量 - teacher_reviews = @exercise_users_list.exercise_review - teacher_unreviews = @exercise_users_list.exercise_unreview - @teacher_review_count = teacher_reviews.size #已评阅 - @teacher_unreview_count = teacher_unreviews.size #未评阅 - - #是否评阅 - if params[:review].present? - review_type = params[:review].first.to_i #已评,则数据为1,未评,则数据为0,前端传过来的为数组 - if review_type == 1 - @exercise_users_list = teacher_reviews - else - @exercise_users_list = teacher_unreviews - end - end + #答题状态的选择 + if params[:commit_status].present? + choose_type = params[:commit_status] + @exercise_users_list = @exercise_users_list.commit_exercise_by_status(choose_type) + end - #答题状态的选择 - if params[:commit_status].present? - choose_type = params[:commit_status] - @exercise_users_list = @exercise_users_list.commit_exercise_by_status(choose_type) - end + #班级的选择 + if params[:exercise_group_id].present? + group_id = params[:exercise_group_id] + exercise_students = @course_all_members.course_find_by_ids("course_group_id", group_id) #试卷所分班的全部人数 + user_ids = exercise_students.pluck(:user_id).reject(&:blank?) + @exercise_users_list = @exercise_users_list.exercise_commit_users(user_ids) + end - #班级的选择 - if params[:exercise_group_id].present? - group_id = params[:exercise_group_id] - exercise_students = @course_all_members.course_find_by_ids("course_group_id",group_id) #试卷所分班的全部人数 - user_ids = exercise_students.pluck(:user_id).reject(&:blank?) - @exercise_users_list = @exercise_users_list.exercise_commit_users(user_ids) - end + #搜索 + if params[:search].present? + @exercise_users_list = @exercise_users_list.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%") + end - #搜索 - if params[:search].present? - @exercise_users_list = @exercise_users_list.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%") - end + exercise_user_joins = @exercise_users_list.joins(user: :user_extension) - exercise_user_joins = @exercise_users_list.joins(user: :user_extension) + if order == "student_id" + @exercise_users_list = exercise_user_joins.order("user_extensions.student_id #{order_type}") + elsif order == "score" + @exercise_users_list = exercise_user_joins.order("#{order} #{order_type}") + else + @exercise_users_list = exercise_user_joins.order("end_at #{order_type}, start_at #{order_type}") + end - if order == "student_id" - @exercise_users_list = exercise_user_joins.order("user_extensions.student_id #{order_type}") - elsif order == "score" - @exercise_users_list = exercise_user_joins.order("#{order} #{order_type}") - else - @exercise_users_list = exercise_user_joins.order("end_at #{order_type}, start_at #{order_type}") - end + @export_ex_users = @exercise_users_list - @export_ex_users = @exercise_users_list + @exercise_users_size = @exercise_users_list.size - @exercise_users_size = @exercise_users_list.size + # 分页 + @page = params[:page] || 1 + @limit = params[:limit] || 20 + @exercise_users_list = @exercise_users_list.page(@page).per(@limit) + else + @exercise_users_list = [] + @export_ex_users = @exercise_users_list + @exercise_users_size = 0 + end - # 分页 - @page = params[:page] || 1 - @limit = params[:limit] || 20 - @exercise_users_list = @exercise_users_list.page(@page).per(@limit) + if params[:format] == "xlsx" + if @user_course_identity > Course::ASSISTANT_PROFESSOR + tip_exception(403, "无权限操作") + elsif @exercise_status == Exercise::UNPUBLISHED + normal_status(-1, "试卷未发布") + elsif (@exercise_users_size == 0) || (@export_ex_users&.exercise_user_committed.size == 0) + normal_status(-1, "暂无用户提交") + elsif params[:export].present? && params[:export] + normal_status(0, "正在下载中") else - @exercise_users_list = [] - @export_ex_users = @exercise_users_list - @exercise_users_size = 0 - end - - if params[:format] == "xlsx" - if @user_course_identity > Course::ASSISTANT_PROFESSOR - tip_exception(403,"无权限操作") - elsif @exercise_status == Exercise::UNPUBLISHED - normal_status(-1,"试卷未发布") - elsif (@exercise_users_size == 0) || ( @export_ex_users&.exercise_user_committed.size == 0) - normal_status(-1,"暂无用户提交") - elsif params[:export].present? && params[:export] - normal_status(0,"正在下载中") - else - respond_to do |format| - format.xlsx{ - set_export_cookies - get_export_users(@exercise,@course,@export_ex_users) - exercise_export_name_ = - "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" - render xlsx: "#{exercise_export_name_.strip}",template: "exercises/exercise_lists.xlsx.axlsx",locals: {table_columns:@table_columns,exercise_users:@user_columns} - } - end + respond_to do |format| + format.xlsx { + set_export_cookies + get_export_users(@exercise, @course, @export_ex_users) + exercise_export_name_ = + "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" + render xlsx: "#{exercise_export_name_.strip}", template: "exercises/exercise_lists.xlsx.axlsx", locals: {table_columns: @table_columns, exercise_users: @user_columns} + } end end - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - raise ActiveRecord::Rollback end end @@ -1382,10 +1231,10 @@ class ExercisesController < ApplicationController filename_ = "#{@exercise.user.real_name}_#{@course.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf" stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css" if params[:export].present? && params[:export] - normal_status(0,"正在下载中") + normal_status(0, "正在下载中") else set_export_cookies - render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets, disposition: 'inline', type:"pdf_attachment.content_type",stream:false + render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets, disposition: 'inline', type: "pdf_attachment.content_type", stream: false end end @@ -1410,108 +1259,102 @@ class ExercisesController < ApplicationController #学生的统计结果 def exercise_result - begin - exercise_ids = [@exercise.id] - @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).size #判断是否有已发布的分班 - @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).size #判断是否有未发布的分班 - @course_all_members = @course.students #课堂的全部学生 - @exercise_all_users = @exercise.exercise_users - ex_common_ids = @exercise.common_published_ids(current_user.id) - @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) - - #班级的选择 - if params[:exercise_group_id].present? - group_id = params[:exercise_group_id] - exercise_students = @course_all_members.course_find_by_ids("course_group_id",group_id) # 试卷所分班的全部人数 - user_ids = exercise_students.pluck(:user_id).reject(&:blank?) - @exercise_all_users = @exercise.exercise_users.exercise_commit_users(user_ids) - @course_all_members_count = @exercise_all_users.size - else - @exercise_users_list = @exercise.all_exercise_users(current_user.id) - @course_all_members_count = @exercise_users_list.size - end - @exercise_commit_users = @exercise_all_users.commit_exercise_by_status(1) #试卷的已提交用户 - @exercise_commit_user_ids = @exercise_commit_users.pluck(:user_id).uniq #已提交试卷的全部用户id - @exercise_commit_user_counts = @exercise_commit_users.size #试卷的已提交用户人数 - @exercise_status = @exercise.get_exercise_status(current_user) - - #提交率 - if @course_all_members_count == 0 - commit_percent = 0.00 - min_score = 0.0 - max_score = 0.0 - average_score = 0.0 - fail_counts = 0 - pass_counts = 0 - good_counts = 0 - best_counts = 0 - else - commit_percent = (@exercise_commit_user_counts / @course_all_members_count.to_f).round(3) - exercise_scores = @exercise_commit_users.pluck(:score).reject(&:blank?) - min_score = exercise_scores.min.present? ? exercise_scores.min : 0.0 - max_score = exercise_scores.max.present? ? exercise_scores.max : 0.0 - total_score = exercise_scores.sum.present? ? exercise_scores.sum : 0.0 - average_score = @exercise_commit_user_counts > 0 ? (total_score.round(1) / @exercise_commit_user_counts).round(1) : 0.0 - question_scores = @exercise.question_scores - fail_score = question_scores * 0.6.round(2) - pass_score = question_scores * 0.7.round(2) - good_score = question_scores * 0.9.round(2) - - fail_counts = exercise_scores.count{|a| a < fail_score} - pass_counts = exercise_scores.count{|a| a < pass_score && a >= fail_score} - good_counts = exercise_scores.count{|a| a < good_score && a >= pass_score} - best_counts = exercise_scores.count{|a| a >= good_score && a <= question_scores} - end - @counts_array = { - :commit_percent => commit_percent, - :min_score => min_score.to_s, - :max_score => max_score.to_s, - :average_score => average_score.to_s, - :fail_counts => fail_counts, - :pass_counts => pass_counts, - :good_counts => good_counts, - :best_counts => best_counts, - } - - @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices,:exercise_answers,:exercise_standard_answers,:exercise_shixun_challenges,:exercise_shixun_answers) - - percent_sort = "desc" - - if params[:sort].present? - percent_sort = params[:sort] - end - # @paging_type = "percent" - # # 按题型排序 - # if params[:sort].present? - # @paging_type = params[:sort].to_s - # end - - ques_result_all = exercise_commit_result(@exercise_questions,@exercise_commit_user_ids) + exercise_ids = [@exercise.id] + @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).size #判断是否有已发布的分班 + @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).size #判断是否有未发布的分班 + @course_all_members = @course.students #课堂的全部学生 + @exercise_all_users = @exercise.exercise_users + ex_common_ids = @exercise.common_published_ids(current_user.id) + @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) + + #班级的选择 + if params[:exercise_group_id].present? + group_id = params[:exercise_group_id] + exercise_students = @course_all_members.course_find_by_ids("course_group_id", group_id) # 试卷所分班的全部人数 + user_ids = exercise_students.pluck(:user_id).reject(&:blank?) + @exercise_all_users = @exercise.exercise_users.exercise_commit_users(user_ids) + @course_all_members_count = @exercise_all_users.size + else + @exercise_users_list = @exercise.all_exercise_users(current_user.id) + @course_all_members_count = @exercise_users_list.size + end + @exercise_commit_users = @exercise_all_users.commit_exercise_by_status(1) #试卷的已提交用户 + @exercise_commit_user_ids = @exercise_commit_users.pluck(:user_id).uniq #已提交试卷的全部用户id + @exercise_commit_user_counts = @exercise_commit_users.size #试卷的已提交用户人数 + @exercise_status = @exercise.get_exercise_status(current_user) + + #提交率 + if @course_all_members_count == 0 + commit_percent = 0.00 + min_score = 0.0 + max_score = 0.0 + average_score = 0.0 + fail_counts = 0 + pass_counts = 0 + good_counts = 0 + best_counts = 0 + else + commit_percent = (@exercise_commit_user_counts / @course_all_members_count.to_f).round(3) + exercise_scores = @exercise_commit_users.pluck(:score).reject(&:blank?) + min_score = exercise_scores.min.present? ? exercise_scores.min : 0.0 + max_score = exercise_scores.max.present? ? exercise_scores.max : 0.0 + total_score = exercise_scores.sum.present? ? exercise_scores.sum : 0.0 + average_score = @exercise_commit_user_counts > 0 ? (total_score.round(1) / @exercise_commit_user_counts).round(1) : 0.0 + question_scores = @exercise.question_scores + fail_score = question_scores * 0.6.round(2) + pass_score = question_scores * 0.7.round(2) + good_score = question_scores * 0.9.round(2) + + fail_counts = exercise_scores.count {|a| a < fail_score} + pass_counts = exercise_scores.count {|a| a < pass_score && a >= fail_score} + good_counts = exercise_scores.count {|a| a < good_score && a >= pass_score} + best_counts = exercise_scores.count {|a| a >= good_score && a <= question_scores} + end + @counts_array = { + :commit_percent => commit_percent, + :min_score => min_score.to_s, + :max_score => max_score.to_s, + :average_score => average_score.to_s, + :fail_counts => fail_counts, + :pass_counts => pass_counts, + :good_counts => good_counts, + :best_counts => best_counts, + } + + @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices, :exercise_answers, :exercise_standard_answers, :exercise_shixun_challenges, :exercise_shixun_answers) + + percent_sort = "desc" + + if params[:sort].present? + percent_sort = params[:sort] + end + # @paging_type = "percent" + # # 按题型排序 + # if params[:sort].present? + # @paging_type = params[:sort].to_s + # end - #默认降序排列 - if percent_sort == "desc" - @question_result_hash = ques_result_all.sort_by{|s| s[:percent]}.reverse - else - @question_result_hash = ques_result_all.sort_by{|s| s[:percent]} - end + ques_result_all = exercise_commit_result(@exercise_questions, @exercise_commit_user_ids) - @exercise_questions_count = @exercise_questions.size - @page = params[:page] || 1 - @limit = params[:limit] || 10 - @question_result_hash = Kaminari.paginate_array(@question_result_hash).page(@page).per(@limit) - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + #默认降序排列 + if percent_sort == "desc" + @question_result_hash = ques_result_all.sort_by {|s| s[:percent]}.reverse + else + @question_result_hash = ques_result_all.sort_by {|s| s[:percent]} end + + @exercise_questions_count = @exercise_questions.size + @page = params[:page] || 1 + @limit = params[:limit] || 10 + @question_result_hash = Kaminari.paginate_array(@question_result_hash).page(@page).per(@limit) end private def exercise_params params.require(:exercise).permit(:exercise_name, :exercise_description, :course_id, :exercise_status, :user_id, :time, - :publish_time, :end_time, :show_result, :question_random, :choice_random, :is_public, - :score_open, :answer_open, :exercise_bank_id, :unified_setting, :show_statistic) + :publish_time, :end_time, :show_result, :question_random, :choice_random, :is_public, + :score_open, :answer_open, :exercise_bank_id, :unified_setting, :show_statistic) end def is_course_teacher @@ -1525,7 +1368,7 @@ class ExercisesController < ApplicationController normal_status(-1, "试卷标题不能为空!") if params[:exercise_name].blank? normal_status(-1, "试卷标题不能超过60个字符") if (params[:exercise_name].length > 60) normal_status(-1, "试卷须知不能超过100个字符") if (params[:exercise_description].present? && - params[:exercise_description].length > 100) + params[:exercise_description].length > 100) end #判断设置的时间是否合理 @@ -1534,39 +1377,39 @@ class ExercisesController < ApplicationController unified_setting = params[:unified_setting] publish_course = params[:publish_time_groups] if @course.is_end - normal_status(-1,"课堂已结束不能再修改") + normal_status(-1, "课堂已结束不能再修改") elsif unified_setting ex_group_settings = @exercise.exercise_group_settings if ex_group_settings.present? p_time_present = ex_group_settings.publish_time_no_null.map(&:publish_time).min if p_time_present && p_time_present < Time.now - normal_status(-1,"设置失败,存在已发布的分班") + normal_status(-1, "设置失败,存在已发布的分班") end elsif params[:publish_time].blank? - normal_status(-1,"发布时间不允许为空") + normal_status(-1, "发布时间不允许为空") end - elsif unified_setting.present? && !unified_setting #非统一设置,分班不能为空 + elsif unified_setting.present? && !unified_setting #非统一设置,分班不能为空 if publish_course.present? - course_ids = publish_course.map{|a| a[:course_group_id]}.sum - publish_t = publish_course.map{|a| a[:publish_time]} + course_ids = publish_course.map {|a| a[:course_group_id]}.sum + publish_t = publish_course.map {|a| a[:publish_time]} if course_ids.include?(nil) || course_ids.count == 0 - normal_status(-1,"请选择分班") + normal_status(-1, "请选择分班") elsif publish_t.include?(nil) || publish_t.count == 0 - normal_status(-1,"发布时间不允许为空") + normal_status(-1, "发布时间不允许为空") end else - normal_status(-1,"请选择分班") + normal_status(-1, "请选择分班") end end end def get_exercise - @exercise = Exercise.find_by(id:params[:id]) + @exercise = Exercise.find_by(id: params[:id]) if @exercise.blank? - normal_status(404,"试卷不存在") + normal_status(404, "试卷不存在") else @course = @exercise.course - normal_status(404,"课堂不存在") if @course.blank? + normal_status(404, "课堂不存在") if @course.blank? end end @@ -1576,65 +1419,65 @@ class ExercisesController < ApplicationController @exercise_ques_scores = exercise_questions.pluck(:question_score).sum #单选题的数量及分数 - exercise_single_ques = exercise_questions.find_by_custom("question_type",Exercise::SINGLE) + exercise_single_ques = exercise_questions.find_by_custom("question_type", Exercise::SINGLE) @exercise_single_ques_count = exercise_single_ques.size @exercise_single_ques_scores = exercise_single_ques.pluck(:question_score).sum #多选题的数量及分数 - exercise_double_ques = exercise_questions.find_by_custom("question_type",Exercise::MULTIPLE) + exercise_double_ques = exercise_questions.find_by_custom("question_type", Exercise::MULTIPLE) @exercise_double_ques_count = exercise_double_ques.size @exercise_double_ques_scores = exercise_double_ques.pluck(:question_score).sum # 判断题数量及分数 - exercise_ques_judge = exercise_questions.find_by_custom("question_type",Exercise::JUDGMENT) + exercise_ques_judge = exercise_questions.find_by_custom("question_type", Exercise::JUDGMENT) @exercise_ques_judge_count = exercise_ques_judge.size @exercise_ques_judge_scores = exercise_ques_judge.pluck(:question_score).sum #填空题数量及分数 - exercise_ques_null = exercise_questions.find_by_custom("question_type",Exercise::COMPLETION) + exercise_ques_null = exercise_questions.find_by_custom("question_type", Exercise::COMPLETION) @exercise_ques_null_count = exercise_ques_null.size @exercise_ques_null_scores = exercise_ques_null.pluck(:question_score).sum #简答题数量及分数 - exercise_ques_main = exercise_questions.find_by_custom("question_type",Exercise::SUBJECTIVE) + exercise_ques_main = exercise_questions.find_by_custom("question_type", Exercise::SUBJECTIVE) @exercise_ques_main_count = exercise_ques_main.size @exercise_ques_main_scores = exercise_ques_main.pluck(:question_score).sum #实训题数量及分数 - exercise_ques_shixun = exercise_questions.find_by_custom("question_type",Exercise::PRACTICAL) + exercise_ques_shixun = exercise_questions.find_by_custom("question_type", Exercise::PRACTICAL) @exercise_ques_shixun_count = exercise_ques_shixun.size @exercise_ques_shixun_scores = exercise_ques_shixun.pluck(:question_score).sum - @exercise_questions = @exercise_questions&.includes(:exercise_choices,:exercise_shixun_challenges,:exercise_answers,:exercise_shixun_answers,:exercise_answer_comments,:exercise_standard_answers) + @exercise_questions = @exercise_questions&.includes(:exercise_choices, :exercise_shixun_challenges, :exercise_answers, :exercise_shixun_answers, :exercise_answer_comments, :exercise_standard_answers) end #获取用户有权限的分班 - def get_user_permission_course(exercise_ids,status) + def get_user_permission_course(exercise_ids, status) exercise_status = status.to_i #传入的试卷发布状态 unpublish_group = [] course_groups = [] user_groups_id = @course.charge_group_ids(current_user) - exercises_all = Exercise.includes(:exercise_group_settings).where(id:exercise_ids) + exercises_all = Exercise.includes(:exercise_group_settings).where(id: exercise_ids) exercises_all.each do |exercise| if exercise.present? - if exercise.unified_setting #统一设置只有两种情况,全部发布,全部截止 - exercise_user_status = exercise.get_exercise_status(current_user) #当前用户的能看到的试卷 + if exercise.unified_setting #统一设置只有两种情况,全部发布,全部截止 + exercise_user_status = exercise.get_exercise_status(current_user) #当前用户的能看到的试卷 if (exercise_user_status == exercise_status) || exercise_status == Exercise::DEADLINE #未发布的情况 unpublish_group = unpublish_group + user_groups_id end else ex_all_group_settings = exercise.exercise_group_settings - ex_group_settings = ex_all_group_settings.exercise_group_published.pluck(:course_group_id).uniq #问卷设置的班级 + ex_group_settings = ex_all_group_settings.exercise_group_published.pluck(:course_group_id).uniq #问卷设置的班级 if exercise_status == Exercise::UNPUBLISHED - unpublish_group = user_groups_id - ex_group_settings + unpublish_group = user_groups_id - ex_group_settings elsif exercise_status == Exercise::DEADLINE ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq - ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 - unpublish_group = unpublish_group + ex_and_user - ex_ended_groups #已发布的全部班级减去截止的全部班级 + ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 + unpublish_group = unpublish_group + ex_and_user - ex_ended_groups #已发布的全部班级减去截止的全部班级 else ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq - ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 + ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 unpublish_group = unpublish_group + ex_and_user - ex_ended_groups end end @@ -1648,7 +1491,7 @@ class ExercisesController < ApplicationController course_groups end - def set_exercise_status(publish_time,end_time) + def set_exercise_status(publish_time, end_time) time_now_i = Time.now if publish_time.present? && (publish_time <= time_now_i) && (end_time > time_now_i) 2 @@ -1657,22 +1500,22 @@ class ExercisesController < ApplicationController elsif end_time.present? && (end_time <= time_now_i) 3 elsif end_time.present? && publish_time.present? && (end_time < publish_time) - normal_status(-1,"时间设置错误!") + normal_status(-1, "时间设置错误!") else 1 end end def check_course_public - unless @course.is_public == 1 # 0为私有,1为公开 - normal_status(403,"...") + unless @course.is_public == 1 # 0为私有,1为公开 + normal_status(403, "...") end end def check_user_id_start_answer #判断用户在开始答题时,是否有用户id传入,如果为老师,则id必需,否则为当前用户的id user_login = params[:login] - if user_login.blank? && @user_course_identity < Course::STUDENT #id不存在,且当前为老师/管理员等 - normal_status(-1,"请输入学生登陆名!") + if user_login.blank? && @user_course_identity < Course::STUDENT #id不存在,且当前为老师/管理员等 + normal_status(-1, "请输入学生登陆名!") else if @user_course_identity < Course::STUDENT || @exercise.score_open @ex_answerer = user_login.blank? ? current_user : User.find_by(login: user_login) @@ -1681,9 +1524,9 @@ class ExercisesController < ApplicationController end if @ex_answerer.blank? - normal_status(404,"答题用户不存在") + normal_status(404, "答题用户不存在") elsif @user_course_identity > Course::STUDENT && !@exercise.is_public - normal_status(403,"非公开试卷") + normal_status(403, "非公开试卷") else # @exercise_current_user_id = @ex_answerer.id || current_user.id @exercise_current_user_id = @ex_answerer.id @@ -1693,9 +1536,9 @@ class ExercisesController < ApplicationController ## 判断开始答题页面的用户权限 def check_user_on_answer - if @user_course_identity == Course::STUDENT && @exercise.get_exercise_status(current_user) == Exercise::UNPUBLISHED #试卷未发布,且当前用户不为老师/管理员 + if @user_course_identity == Course::STUDENT && @exercise.get_exercise_status(current_user) == Exercise::UNPUBLISHED #试卷未发布,且当前用户不为老师/管理员 normal_status(-1, "未发布试卷!") - elsif @user_course_identity > Course::STUDENT && (!@exercise.is_public || (@exercise.is_public && !@exercise.unified_setting)) ##不为课堂成员,且试卷不为公开的,或试卷公开,但不是统一设置的 + elsif @user_course_identity > Course::STUDENT && (!@exercise.is_public || (@exercise.is_public && !@exercise.unified_setting)) ##不为课堂成员,且试卷不为公开的,或试卷公开,但不是统一设置的 normal_status(-1, "试卷暂未公开!") end end @@ -1703,7 +1546,7 @@ class ExercisesController < ApplicationController def check_exercise_time @answer_committed_user = @exercise.exercise_users.exercise_commit_users(current_user.id)&.first if @answer_committed_user.blank? - normal_status(404,"答题用户不存在") + normal_status(404, "答题用户不存在") end end @@ -1711,9 +1554,9 @@ class ExercisesController < ApplicationController def check_exercise_status @exercise_users = @exercise.all_exercise_users(current_user.id).commit_exercise_by_status(1) #当前教师所在分班的全部已提交的学生数 if @exercise.get_exercise_status(current_user) != Exercise::PUBLISHED - normal_status(-1,"非提交中的试卷不允许打回重做!") + normal_status(-1, "非提交中的试卷不允许打回重做!") elsif @exercise_users.count < 1 - normal_status(-1,"暂无人提交试卷!") + normal_status(-1, "暂无人提交试卷!") end end @@ -1721,25 +1564,25 @@ class ExercisesController < ApplicationController #查看试题页面,当为学生时,除非试卷已截止,或已提交才可以查看 def check_exercise_is_end ex_status = @exercise.get_exercise_status(current_user) - @ex_user = @exercise.exercise_users.find_by(user_id:@exercise_current_user_id) #该试卷的回答者 + @ex_user = @exercise.exercise_users.find_by(user_id: @exercise_current_user_id) #该试卷的回答者 if @user_course_identity > Course::ASSISTANT_PROFESSOR if ex_status == Exercise::UNPUBLISHED - normal_status(-1,"试卷未发布") + normal_status(-1, "试卷未发布") elsif @ex_user.present? && @ex_user.commit_status == 0 - normal_status(-1,"试卷未提交") + normal_status(-1, "试卷未提交") elsif params[:user_id].present? && current_user.id != params[:user_id] - normal_status(-1,"不能查看他人的试卷") + normal_status(-1, "不能查看他人的试卷") end end end #查看试卷是否选择为公开统计 def check_exercise_public - if @user_course_identity > Course::ASSISTANT_PROFESSOR #当前为学生,试卷公开统计,且已截止,且已提交 + if @user_course_identity > Course::ASSISTANT_PROFESSOR #当前为学生,试卷公开统计,且已截止,且已提交 ex_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first unless @exercise.get_exercise_status(current_user) == Exercise::DEADLINE && ex_user.present? && ex_user.commit_status == 1 && - @exercise.show_statistic - normal_status(-1,"学生暂不能查看") + @exercise.show_statistic + normal_status(-1, "学生暂不能查看") end end end @@ -1750,16 +1593,16 @@ class ExercisesController < ApplicationController @left_banner_id = left_banner_content.first.id @left_banner_name = left_banner_content.first.module_name else - normal_status(404,"左侧导航不存在") + normal_status(404, "左侧导航不存在") end end - def get_user_answer_status(exercise_questions,user_id,exercise,exercise_user_status) + def get_user_answer_status(exercise_questions, user_id, exercise, exercise_user_status) @question_status = [] @exercise_all_questions = [] ex_question_random = exercise.question_random question_answered = 0 - exercise_questions.each_with_index do |q,index| + exercise_questions.each_with_index do |q, index| if ex_question_random && exercise_user_status != Exercise::DEADLINE ques_number = index + 1 else @@ -1767,19 +1610,19 @@ class ExercisesController < ApplicationController end ques_status = 0 if q.question_type != Exercise::PRACTICAL - ques_vote = q.exercise_answers.select{|answer| answer.user_id == user_id} + ques_vote = q.exercise_answers.select {|answer| answer.user_id == user_id} if ques_vote.present? #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 vote_answer_id = ques_vote.pluck(:exercise_choice_id).reject(&:blank?) vote_text_count = ques_vote.pluck(:answer_text).reject(&:blank?).size - if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 + if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 if vote_answer_id.size > 0 ques_status = 1 question_answered += 1 end else - if vote_text_count > 0 #主观题,必选有内容,才算回答 + if vote_text_count > 0 #主观题,必选有内容,才算回答 ques_status = 1 question_answered += 1 end @@ -1792,22 +1635,23 @@ class ExercisesController < ApplicationController end end question_status = { - :ques_id => q.id, - :ques_number => ques_number, #仅问题的显示位置变化,但是问题的question_number 不会变化,与之相关的choice/standard_answer/answer不会变化 - :ques_status => ques_status, + :ques_id => q.id, + :ques_number => ques_number, #仅问题的显示位置变化,但是问题的question_number 不会变化,与之相关的choice/standard_answer/answer不会变化 + :ques_status => ques_status, } question_options = { - :question => q, - :ques_number => ques_number, + :question => q, + :ques_number => ques_number, } @question_status = @question_status.push(question_status).sort_by {|k| k[:ques_number]} @exercise_all_questions = @exercise_all_questions.push(question_options).sort_by {|k| k[:ques_number]} end end + #下一步也有check_on_users再进行判断 def only_student_in if @user_course_identity < Course::STUDENT - normal_status(-1,"老师身份不允许进入") + normal_status(-1, "老师身份不允许进入") end end @@ -1817,9 +1661,9 @@ class ExercisesController < ApplicationController shixun_id = params[:shixun_id] @shixun = Shixun.find_by(id: shixun_id) if shixun_id.present? && question_shixun_ids.include?(shixun_id) - normal_status(-1,"该实训已选择!") + normal_status(-1, "该实训已选择!") elsif @shixun.blank? - normal_status(-1,"该实训不存在!") + normal_status(-1, "该实训不存在!") end end diff --git a/app/controllers/graduation_tasks_controller.rb b/app/controllers/graduation_tasks_controller.rb index dcb9a3bc3..cac763344 100644 --- a/app/controllers/graduation_tasks_controller.rb +++ b/app/controllers/graduation_tasks_controller.rb @@ -606,10 +606,10 @@ class GraduationTasksController < ApplicationController end def graduation_task_params - tip_exception("task_type参数不能为空") if params[:task_type].blank? - tip_exception("name参数不能为空") if params[:name].blank? - tip_exception("name参数不能超过60个字符") if params[:name].length > 60 #6.11 -hs - tip_exception("description参数不能为空") if params[:description].blank? + tip_exception("类型参数不能为空") if params[:task_type].blank? + tip_exception("名称不能为空") if params[:name].blank? + tip_exception("名称不能超过60个字符") if params[:name].length > 60 #6.11 -hs + tip_exception("描述不能为空") if params[:description].blank? params.require(:graduation_task).permit(:task_type, :name, :description) end diff --git a/app/controllers/graduation_works_controller.rb b/app/controllers/graduation_works_controller.rb index fd47df172..c041750cb 100644 --- a/app/controllers/graduation_works_controller.rb +++ b/app/controllers/graduation_works_controller.rb @@ -52,7 +52,7 @@ class GraduationWorksController < ApplicationController begin work = @task.graduation_works.find_by!(user_id: params[:user_id]) tip_exception("只有组长才能删除组员") if work.commit_user_id != current_user.id - work.update_attributes(description: nil, project_id: 0, late_penalty: 0, work_status: 0, commit_time: nil, + work.update!(description: nil, project_id: 0, late_penalty: 0, work_status: 0, commit_time: nil, update_time: nil, group_id: 0, commit_user_id: nil, final_score: nil, work_score: nil, teacher_score: nil, teaching_asistant_score: nil, update_user_id: nil) work.attachments.destroy_all @@ -89,12 +89,12 @@ class GraduationWorksController < ApplicationController GraduationWork.create(user_id: current_user.id, graduation_task_id: @task.id, course_id: @task.course_id) if work.work_status == 0 && work.project_id == 0 - work.update_attributes(project_id: project.id, update_time: Time.now) + work.update!(project_id: project.id, update_time: Time.now) # 将老师加入项目 project_member = project.members.where(user_id: @task.user_id).first if project_member.present? - project_member.member_roles.first.update_attributes(role_id: 3) if project_member.member_roles.first.present? + project_member.member_roles.first.update!(role_id: 3) if project_member.member_roles.first.present? else member = Member.create(user_id: @task.user_id, project_id: project.id) member.member_roles << MemberRole.new(role_id: 3) @@ -127,7 +127,7 @@ class GraduationWorksController < ApplicationController Tiding.where(user_id: @task.user_id, trigger_user_id: current_user.id, container_id: work.project.id, container_type: 'ManagerJoinProject').destroy_all - work.update_attributes(project_id: 0) + work.update!(project_id: 0) normal_status("取消关联成功") rescue Exception => e @@ -177,7 +177,7 @@ class GraduationWorksController < ApplicationController student_ids += members for i in 0 .. members.count-1 stu_work = @task.graduation_works.where(user_id: members[i].to_i).first || GraduationWork.new - stu_work.update_attributes(user_id: members[i].to_i, description: graduation_work.description, + stu_work.update!(user_id: members[i].to_i, description: graduation_work.description, graduation_task_id: @task.id, project_id: graduation_work.project_id, late_penalty: graduation_work.late_penalty, work_status: graduation_work.work_status, commit_time: Time.now, update_time: Time.now, group_id: graduation_work.group_id, @@ -238,7 +238,7 @@ class GraduationWorksController < ApplicationController # 原成员更新描述、更新时间以及附件 @task.graduation_works.where(group_id: @work.group_id, user_id: (work_user_ids & params_user_ids)).each do |work| - work.update_attributes(update_time: Time.now, description: @work.description, update_user_id: current_user.id) + work.update!(update_time: Time.now, description: @work.description, update_user_id: current_user.id) work.attachments.destroy_all @work.attachments.each do |attachment| att = attachment.copy @@ -264,7 +264,7 @@ class GraduationWorksController < ApplicationController (params_user_ids - work_user_ids).each do |user_id| stu_work = @task.graduation_works.where(user_id: user_id).empty? ? GraduationWork.new : @task.graduation_works.where(user_id: user_id).first - stu_work.update_attributes(user_id: user_id, description: @work.description, graduation_task_id: @task.id, + stu_work.update!(user_id: user_id, description: @work.description, graduation_task_id: @task.id, project_id: @work.project_id, late_penalty: @work.late_penalty, work_status: @work.work_status, commit_time: Time.now, update_time: Time.now, group_id: @work.group_id, commit_user_id: @work.commit_user_id, update_user_id: current_user.id) @@ -323,9 +323,9 @@ class GraduationWorksController < ApplicationController # 如果作品是未提交的状态则更新为已提交 if !new_score.score.nil? && @work.work_status == 0 - @work.update_attributes(work_status: 1, commit_time: Time.now) + @work.update!(work_status: 1, commit_time: Time.now) if @task.task_type == 2 - @work.update_attributes(group_id: @task.graduation_works.where("work_status != 0").select("distinct group_id").count + 1) + @work.update!(group_id: @task.graduation_works.where("work_status != 0").select("distinct group_id").count + 1) end end @@ -392,7 +392,7 @@ class GraduationWorksController < ApplicationController graduation_task_id: @task.id, comment: "使用调分功能调整了作业最终成绩:#{params[:comment]}", user_id: User.current.id, reviewer_role: 1, is_ultimate: 1) new_score.save! - @work.update_attributes(ultimate_score: 1, work_score: params[:score].to_f) + @work.update!(ultimate_score: 1, work_score: params[:score].to_f) Tiding.create!(user_id: @work.user_id, trigger_user_id: current_user.id, container_id: new_score.id, container_type: "AdjustScore", parent_container_id: @task.id, @@ -445,9 +445,9 @@ class GraduationWorksController < ApplicationController end Attachment.associate_container(params[:attachment_ids], @work.id, @work.class, 7) revise_attachment = Attachment.where(attachtype: 7, container_id: @work.id, container_type: "GraduationWork").last - revise_attachment.update_attributes(description: params[:description]) if revise_attachment.present? + revise_attachment.update!(description: params[:description]) if revise_attachment.present? - @work.update_attributes(update_time: Time.now) + @work.update!(update_time: Time.now) normal_status("提交成功") rescue Exception => e @@ -465,7 +465,7 @@ class GraduationWorksController < ApplicationController if @work_assign_teacher.present? # graduation_group_id: 已经是答辩组的需要 将答辩组清空 - @work_assign_teacher.update_attributes(graduation_group_id: 0) + @work_assign_teacher.update!(graduation_group_id: 0) else @work.graduation_work_comment_assignations << GraduationWorkCommentAssignation.new(graduation_task_id: @task.id, user_id: params[:user_id], diff --git a/app/controllers/hacks_controller.rb b/app/controllers/hacks_controller.rb index fb4f497bd..6eb454feb 100644 --- a/app/controllers/hacks_controller.rb +++ b/app/controllers/hacks_controller.rb @@ -62,9 +62,9 @@ class HacksController < ApplicationController ItemBank.create!(new_item_params) end render_ok({identifier: hack.identifier}) - rescue Exception => e + rescue => e logger.error("########create_hack_error: #{e.message}") - render_error("创建失败") + render_error("创建失败: #{e.message}") end end @@ -96,7 +96,7 @@ class HacksController < ApplicationController render_ok rescue Exception => e logger.error("####update_hack_error: #{e.message}") - render_error("更新失败") + render_error("更新失败: #{e.message}") end end @@ -232,7 +232,11 @@ class HacksController < ApplicationController hacks = Hack.select(select_sql).mine(current_user.id) else # 全部包括已经发布的,和我的未发布的 - hacks = Hack.select(select_sql).published.opening.or(Hack.select(select_sql).unpublish.mine(current_user.id)) + if current_user.admin_or_business? + hacks = Hack.select(select_sql) + else + hacks = Hack.select(select_sql).published.opening.or(Hack.select(select_sql).unpublish.mine(current_user.id)) + end end # 搜索 if params[:search] diff --git a/app/controllers/helps_controller.rb b/app/controllers/helps_controller.rb index 8d58663f6..10a073684 100644 --- a/app/controllers/helps_controller.rb +++ b/app/controllers/helps_controller.rb @@ -26,14 +26,14 @@ class HelpsController < ApplicationController def feedback if params[:url].blank? - content = "

[#{params[:question_kind]}]

#{params[:description]}" + content = "[#{params[:question_kind]}]
#{params[:description]}
" if params[:attachment_ids] params[:attachment_ids].each do |attachment_id| - content += "![](/api/attachments/#{attachment_id})↵" + content += "![](/api/attachments/#{attachment_id})
" end end else - content = "

[#{params[:question_kind]}]

问题页面网址:#{params[:url]}

#{params[:description]}" + content = "[#{params[:question_kind]}]
问题页面网址:#{params[:url]}
#{params[:description]}" end ActiveRecord::Base.transaction do diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index 1d47fa293..96a73b08b 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -306,7 +306,7 @@ class HomeworkCommonsController < ApplicationController def alter_name tip_exception("作业名称不能为空") if params[:name].blank? - @homework.update_attributes(name: params[:name].strip) + @homework.update_attributes!(name: params[:name].strip) normal_status("更新成功") end @@ -348,7 +348,7 @@ class HomeworkCommonsController < ApplicationController end def update_explanation - @homework.update_attributes(explanation: params[:explanation]) + @homework.update_attributes!(explanation: params[:explanation]) normal_status(0, "更新成功") end @@ -416,7 +416,7 @@ class HomeworkCommonsController < ApplicationController ActiveRecord::Base.transaction do begin - @homework.update_attributes(homework_params) + @homework.update_attributes!(homework_params) if @homework.homework_type == "group" homework_detail_group = @homework.homework_detail_group @@ -521,7 +521,7 @@ class HomeworkCommonsController < ApplicationController score = challenge[:challenge_score] if setting && setting.score != score score_change = true - setting.update_attributes(score: score) + setting.update_attributes!(score: score) elsif setting.blank? score_change = true HomeworkChallengeSetting.create!(homework_common_id: @homework.id, challenge_id: challenge[:challenge_id], @@ -976,7 +976,7 @@ class HomeworkCommonsController < ApplicationController elsif homework.max_group_end_time homework.end_time = homework.max_group_end_time end - homework.homework_detail_manual.update_attribute('comment_status', 1) + homework.homework_detail_manual.update_attributes!(comment_status: 1) if homework.course_acts.size == 0 homework.course_acts << CourseActivity.new(user_id: homework.user_id, course_id: homework.course_id) @@ -1004,7 +1004,7 @@ class HomeworkCommonsController < ApplicationController if homework.end_time > Time.now && homework.homework_detail_manual.try(:comment_status) > 1 - homework.homework_detail_manual.update_attribute("comment_status", 1) + homework.homework_detail_manual.update_attributes!(comment_status: 1) end # 补交结束时间 @@ -1071,7 +1071,7 @@ class HomeworkCommonsController < ApplicationController homework.end_time = homework.max_group_end_time if homework.end_time > time && homework_detail_manual.try(:comment_status) > 1 - homework_detail_manual.update_attribute("comment_status", 1) + homework_detail_manual.update_attributes!(comment_status: 1) end # 统一设置 @@ -1080,7 +1080,7 @@ class HomeworkCommonsController < ApplicationController homework.end_time = time end - homework_detail_manual.update_attribute("comment_status", 2) if homework.end_time <= time + homework_detail_manual.update_attributes!(comment_status: 2) if homework.end_time <= time # 实训作业的作品需要计算是否迟交 if homework.homework_type == "practice" @@ -1159,11 +1159,11 @@ class HomeworkCommonsController < ApplicationController if homework_bank.present? # 如果作业加入过题库则更新参数 if homework_bank.homework_type == 1 - homework_bank.update_attributes(name: homework.name, description: homework.description, + homework_bank.update_attributes!(name: homework.name, description: homework.description, reference_answer: homework.reference_answer, course_list_id: @course.course_list_id) elsif homework_bank.homework_type == 3 homework_detail_group = homework.homework_detail_group - homework_bank.update_attributes(name: homework.name, description: homework.description, + homework_bank.update_attributes!(name: homework.name, description: homework.description, reference_answer: homework.reference_answer, course_list_id: @course.course_list_id, min_num: homework_detail_group.min_num, max_num: homework_detail_group.max_num, base_on_project: homework_detail_group.base_on_project) @@ -1449,9 +1449,9 @@ class HomeworkCommonsController < ApplicationController # 如果用户已有查重记录则更新相似度 否则新建一条记录 user_review = homework.homework_review_results.find_by(:user_id => user) if user_review.present? - user_review.update_attributes(:code_rate => user_rate) + user_review.update_attributes!(:code_rate => user_rate) else - homework.homework_review_results.create(:user_id => user, :code_rate => user_rate) + homework.homework_review_results.create!(:user_id => user, :code_rate => user_rate) end end nuser_ids = results.user_lists.map(&:user_id).uniq diff --git a/app/controllers/item_banks_controller.rb b/app/controllers/item_banks_controller.rb index 221e754a4..a0abffe6c 100644 --- a/app/controllers/item_banks_controller.rb +++ b/app/controllers/item_banks_controller.rb @@ -8,7 +8,15 @@ class ItemBanksController < ApplicationController items = ItemBankQuery.call(params) @items_count = items.size @items = paginate items.includes(:item_analysis, :user, :container) - @item_basket_ids = current_user.item_baskets.pluck(:item_bank_id) + exam = ExaminationBank.find_by(id: params[:exam_id]) if params[:exam_id].present? + 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 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/controllers/memos_controller.rb b/app/controllers/memos_controller.rb index 3c76972b8..c0ea8d601 100644 --- a/app/controllers/memos_controller.rb +++ b/app/controllers/memos_controller.rb @@ -1,6 +1,6 @@ class MemosController < ApplicationController before_action :require_login, except: [:show, :index] - before_action :check_account, only: [:new, :create] + before_action :check_account, only: [:new, :create, :reply] before_action :set_memo, only: [:show, :edit, :update, :destroy, :sticky_or_cancel, :hidden, :more_reply] before_action :validate_memo_params, only: [:create, :update] before_action :owner_or_admin, only: [:edit, :update, :destroy] @@ -144,7 +144,7 @@ class MemosController < ApplicationController def reply tip_exception("parent_id不能为空") if params[:parent_id].blank? tip_exception("content不能为空") if params[:content].blank? - tip_exception("content不能超过1000字符") if params[:content].length > 1000 + tip_exception("内容不能超过2000字符") if params[:content].length > 2000 ActiveRecord::Base.transaction do begin diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 7b096f1ec..0e28ccb4f 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -62,8 +62,8 @@ class MessagesController < ApplicationController end def reply - return normal_status(2, "回复内容不能为空") if params[:content].blank? - return normal_status(2, "回复内容不能超过1000字符") if params[:content].length > 1000 + return normal_status(-1, "回复内容不能为空") if params[:content].blank? + return normal_status(-1, "回复内容不能超过2000字符") if params[:content].length > 2000 @reply = Message.create!(board: @message.board, root_id: @message.root_id || @message.id, author: current_user, parent: @message, message_detail_attributes: { diff --git a/app/controllers/myshixuns_controller.rb b/app/controllers/myshixuns_controller.rb index 7847d58ed..350ee581f 100644 --- a/app/controllers/myshixuns_controller.rb +++ b/app/controllers/myshixuns_controller.rb @@ -3,7 +3,7 @@ class MyshixunsController < ApplicationController before_action :find_myshixun, :except => [:training_task_status, :code_runinng_message] before_action :find_repo_name, :except => [:training_task_status, :code_runinng_message] skip_before_action :verify_authenticity_token, :only => [:html_content] - skip_before_action :check_sign, only: [:training_task_status, :code_runinng_message] + skip_before_action :check_sign, only: [:training_task_status, :code_runinng_message, :html_content] ## TPI关卡列表 def challenges diff --git a/app/controllers/poll_questions_controller.rb b/app/controllers/poll_questions_controller.rb index 411961e96..c60eaff38 100644 --- a/app/controllers/poll_questions_controller.rb +++ b/app/controllers/poll_questions_controller.rb @@ -44,7 +44,7 @@ class PollQuestionsController < ApplicationController @poll.poll_questions.insert_question(ques_num).update_all("question_number = question_number + 1") end end - if @poll_question.save + if @poll_question.save! if params[:question_type] != 3 p_answer = params[:question_answers] p_other_answer = params[:question_other_answer] @@ -56,7 +56,7 @@ class PollQuestionsController < ApplicationController :answer_text => answer } poll_answers = @poll_question.poll_answers.new question_option - poll_answers.save + poll_answers.save! end # 新增答案的其他选项 if p_other_answer @@ -65,7 +65,7 @@ class PollQuestionsController < ApplicationController :answer_text => '' } poll_answers = @poll_question.poll_answers.new question_option - poll_answers.save + poll_answers.save! end end end @@ -118,7 +118,7 @@ class PollQuestionsController < ApplicationController if answer # 判断该位置的answer是否存在,存在则更新.不存在则跳到下一步 answer.answer_text = p_answer[i-1] answer.answer_position = i - answer.save + answer.save! else answer_options = { :answer_position => i, @@ -137,12 +137,12 @@ class PollQuestionsController < ApplicationController @poll_question.poll_answers.new question_option else other_answer.answer_position = p_answer_count + 1 - other_answer.save + other_answer.save! end end end - @poll_question.update_attributes(poll_questions_params) + @poll_question.update!(poll_questions_params) rescue Exception => e uid_logger_error(e.message) tip_exception("更新失败") @@ -198,8 +198,8 @@ class PollQuestionsController < ApplicationController if opr.to_s == "up" last_q_p = @poll.poll_questions.find_by(question_number: (current_q_p-1)) #当前问题的前一个问题 if last_q_p.present? - @poll_question.update_attribute("question_number", (current_q_p - 1)) - last_q_p.update_attribute("question_number", current_q_p) # 重新获取当前问题的位置 + @poll_question.update!(question_number: (current_q_p - 1)) + last_q_p.update!(question_number: current_q_p) # 重新获取当前问题的位置 normal_status(0, "问题上移成功!") else normal_status(-1, "移动失败,已经是第一个问题了!") @@ -207,8 +207,8 @@ class PollQuestionsController < ApplicationController elsif opr.to_s == "down" next_q_p = @poll.poll_questions.find_by(question_number: (current_q_p+1)) #当前问题的后一个问题 if next_q_p.present? - @poll_question.update_attribute("question_number", (current_q_p + 1)) - next_q_p.update_attribute("question_number", current_q_p) + @poll_question.update!(question_number: (current_q_p + 1)) + next_q_p.update!(question_number: current_q_p) normal_status(0, "问题下移成功!") else diff --git a/app/controllers/poll_votes_controller.rb b/app/controllers/poll_votes_controller.rb index 17223a955..42dbbe3df 100644 --- a/app/controllers/poll_votes_controller.rb +++ b/app/controllers/poll_votes_controller.rb @@ -31,24 +31,24 @@ class PollVotesController < ApplicationController current_user_answer = user_votes.first if current_user_answer&.poll_answer_id != question_answer_id #如果说更换了答案,则以前的答案删除,并新建记录 current_user_answer.destroy - PollVote.create(vote_answer_params) + PollVote.create!(vote_answer_params) else if question_answer_text.present? - current_user_answer.update_attribute("vote_text", question_answer_text) + current_user_answer.update!(vote_text: question_answer_text) end end else - PollVote.create(vote_answer_params) + PollVote.create!(vote_answer_params) end elsif question_type == 2 #多选题的话,答案应该是1个以上 question_answer_ids = params[:poll_answer_id] ? params[:poll_answer_id] : [] #该答案的id if question_answer_ids.present? if question_answer_text.present? #有文字输入,但是不存在其他选项的 ques_vote_id = question_answer_ids.map(&:to_i).max - if user_votes.find_vote_text.present? - current_vote_text = user_votes.find_vote_text.first - current_vote_text.update_attribute("vote_text", question_answer_text) + ques_vote = user_votes.find_by(poll_answer_id: ques_vote_id) + if ques_vote.present? + ques_vote.update!(vote_text: question_answer_text) else answer_option = { :user_id => current_user.id, @@ -56,7 +56,9 @@ class PollVotesController < ApplicationController :poll_answer_id => ques_vote_id, :vote_text => question_answer_text } - PollVote.create(answer_option) + PollVote.create!(answer_option) + # 重新取一次poll_votes + user_votes = @poll_question.poll_votes.find_current_vote("user_id",current_user.id) end # if current_vote_text.present? #已有其他输入文字的选项 # current_vote_text.update_attribute("vote_text", question_answer_text) @@ -91,14 +93,14 @@ class PollVotesController < ApplicationController else #主观题的输入 # current_vote_text = user_votes.find_vote_text if user_votes.present? - user_votes.first.update_attribute("vote_text", question_answer_text) + user_votes.first.update!(vote_text: question_answer_text) # if question_answer_text.present? # user_votes.first.update_attribute("vote_text", question_answer_text) # else # user_votes.destroy_all # end else - PollVote.create(vote_answer_params) + PollVote.create!(vote_answer_params) end end @current_question_number = @poll_question.question_number diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 3e6914dee..c9c9cc567 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -137,7 +137,7 @@ class PollsController < ApplicationController :polls_status => 1, :polls_type => "Course", } - @poll = Poll.create(poll_options) + @poll = Poll.create!(poll_options) rescue Exception => e uid_logger_error(e.message) tip_exception("问卷创建失败!") @@ -167,7 +167,7 @@ class PollsController < ApplicationController :polls_name => poll_name, :polls_description => poll_des } - @poll.update_attributes(poll_params) + @poll.update!(poll_params) normal_status(0,"问卷更新成功!") rescue Exception => e uid_logger_error(e.message) @@ -297,7 +297,7 @@ class PollsController < ApplicationController poll_group_setting = poll.poll_group_settings.find_in_poll_group("course_group_id",i).first #根据课堂分班的id,寻找问卷所在的班级 group_end_time = params[:detail] ? group_end_times[index] : ex_end_time if poll_group_setting.present? #如果该问卷分组存在,则更新,否则新建 - poll_group_setting.update_attributes!(publish_time: Time.now, end_time: group_end_time) + poll_group_setting.update!(publish_time: Time.now, end_time: group_end_time) else p_course_group = { :poll_id => poll.id, @@ -326,7 +326,7 @@ class PollsController < ApplicationController :polls_status => poll_status, :unified_setting => poll_unified } - poll.update_attributes(poll_params) + poll.update!(poll_params) if poll.course_acts.size == 0 poll.course_acts << CourseActivity.new(:user_id => poll.user_id,:course_id => poll.course_id) end @@ -390,10 +390,10 @@ class PollsController < ApplicationController new_end_time = poll_group_setting.end_time_present.map(&:end_time) # 问卷结束时间不为空的 new_end_time_s = new_end_time.size > 0 ? new_end_time.max : Time.now new_poll_status = set_poll_status(poll.publish_time,new_end_time_s) - poll.update_attributes(:end_time => new_end_time_s,:polls_status => new_poll_status,:unified_setting => poll_unified) + poll.update!(:end_time => new_end_time_s,:polls_status => new_poll_status,:unified_setting => poll_unified) elsif poll.unified_setting poll_users = poll.poll_users - poll.update_attributes(:polls_status => 3, :end_time => Time.now) + poll.update!(:polls_status => 3, :end_time => Time.now) end poll_users = poll_users.where("commit_status = 0 and start_at is not null") poll_users.update_all(:commit_status => 1, :end_at => Time.now) @@ -470,7 +470,7 @@ class PollsController < ApplicationController :publish_time => p_time, :end_time => e_time } - @poll.update_attributes(poll_options) + @poll.update!(poll_options) normal_status(0,"分班问卷撤销发布成功!") else normal_status(-1,"请选择撤销发布班级!") @@ -490,7 +490,7 @@ class PollsController < ApplicationController :end_time => nil, :unified_setting => true } - @poll.update_attributes(poll_new_params) + @poll.update!(poll_new_params) @poll.poll_group_settings.destroy_all normal_status(0,"问卷撤销发布成功!") @@ -531,7 +531,7 @@ class PollsController < ApplicationController begin check_ids = Poll.where(id:params[:check_ids]) check_ids.each do |poll| - poll.update_attribute('is_public', true) + poll.update!(is_public: true) end normal_status(0, "问卷已设为公开!") rescue Exception => e @@ -555,13 +555,13 @@ class PollsController < ApplicationController :description => poll.polls_description, :course_list_id => poll.course.try(:course_list_id) } - current_ex_bank.update_attributes(ex_params) + current_ex_bank.update!(ex_params) question_bank = QuestionBank.ques_by_container(current_ex_bank.id,current_ex_bank.container_type) #该习题库是否存在于问题库里 ques_params = { :name => current_ex_bank.name, :course_list_id => current_ex_bank.course_list_id } - question_bank.first.update_attributes(ques_params) if question_bank.present? + question_bank.first.update!(ques_params) if question_bank.present? current_ex_bank.exercise_bank_questions.destroy_all # 更新后,习题库的问题全部删除,后续重新再建 else ex_params = { @@ -575,7 +575,7 @@ class PollsController < ApplicationController :quotes => 1 } current_ex_bank= ExerciseBank.new ex_params - if current_ex_bank.save #如果习题库保存成功,则会创建问题库question_bank + if current_ex_bank.save! #如果习题库保存成功,则会创建问题库question_bank ques_params = { :name => current_ex_bank.name, :container_id => current_ex_bank.id, @@ -586,9 +586,9 @@ class PollsController < ApplicationController :course_list_id => current_ex_bank.course_list_id } question_bank = QuestionBank.new ques_params - question_bank.save + question_bank.save! end - poll.update_attributes!(exercise_bank_id: current_ex_bank.id) + poll.update!(exercise_bank_id: current_ex_bank.id) end # 问卷的问题的输入 poll.poll_questions.each do |f| @@ -601,7 +601,7 @@ class PollsController < ApplicationController :min_choices => f.min_choices } exercise_bank_question = current_ex_bank.exercise_bank_questions.new option - exercise_bank_question.save + exercise_bank_question.save! ## 问卷答案的输入 f.poll_answers.each do |a| choice_option = { @@ -609,7 +609,7 @@ class PollsController < ApplicationController :choice_text => a.answer_text } exercise_bank_c = exercise_bank_question.exercise_bank_choices.new choice_option - exercise_bank_c.save + exercise_bank_c.save! end end end @@ -746,7 +746,7 @@ class PollsController < ApplicationController :publish_time => params_publish_time, :end_time => params_end_time } - @poll.update_attributes(poll_params) + @poll.update!(poll_params) @poll.poll_group_settings.destroy_all normal_status(0, "问卷设置成功!") end @@ -800,7 +800,7 @@ class PollsController < ApplicationController :end_time => poll_end_time } end - the_group_setting.update_attributes(poll_group_params) + the_group_setting.update!(poll_group_params) end end if new_group_ids.size > 0 @@ -813,7 +813,7 @@ class PollsController < ApplicationController :end_time => poll_end_time } new_poll_group = PollGroupSetting.new(poll_group_params) - new_poll_group.save + new_poll_group.save! end end end @@ -848,7 +848,7 @@ class PollsController < ApplicationController :publish_time => p_time, :end_time => e_time } - @poll.update_attributes(poll_params) + @poll.update!(poll_params) if @poll.polls_status == 2 if @poll.course_acts.size == 0 @poll.course_acts << CourseActivity.new(:user_id => @poll.user_id,:course_id => @poll.course_id) @@ -880,10 +880,10 @@ class PollsController < ApplicationController :start_at => Time.now, :commit_status => 0 } - PollUser.create(poll_user_params) + PollUser.create!(poll_user_params) end elsif poll_user_current.start_at.nil? - poll_user_current.update_attributes(:start_at => Time.now) + poll_user_current.update!(:start_at => Time.now) end if @user_course_identity < Course::STUDENT || (@poll_status == 3) || (poll_user_current.present? && poll_user_current.commit_status == 1) @@ -963,7 +963,7 @@ class PollsController < ApplicationController :commit_status => 1, :end_at => Time.now } - poll_user_current.update_attributes(poll_user_params) + poll_user_current.update!(poll_user_params) CommitPollNotifyJobJob.perform_later(@poll.id, current_user.id) normal_status(0, "问卷提交成功!") end diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 7009726d8..de69bf033 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -888,13 +888,15 @@ class ShixunsController < ApplicationController def upload_git_file upload_file = params["file"] - uid_logger("#########################file_params####{params["#{params[:file]}"]}") + uid_logger("#########################file_params##: #{params["file"]}") raise "未上传文件" unless upload_file content = upload_file.tempfile.read + uid_logger("#########################content####{content}") author_name = current_user.real_name author_email = current_user.git_mail message = params[:message] || "upload file by browser" - update_file_content(content, @repo_path, @path, author_email, author_name, message) + uid_logger("-----author_email: #{author_email}") + update_file_base64_content(content, @repo_path, @path, author_email, author_name, message) render_ok end diff --git a/app/controllers/student_works_controller.rb b/app/controllers/student_works_controller.rb index 734229501..59da73703 100644 --- a/app/controllers/student_works_controller.rb +++ b/app/controllers/student_works_controller.rb @@ -68,7 +68,7 @@ class StudentWorksController < ApplicationController begin work = @homework.student_works.find_by!(user_id: params[:user_id]) tip_exception("只有组长才能删除组员") if work.commit_user_id != current_user.id - work.update_attributes(description: nil, project_id: 0, + work.update_attributes!(description: nil, project_id: 0, late_penalty: 0, work_status: 0, commit_time: nil, update_time: nil, group_id: 0, commit_user_id: nil, final_score: nil, work_score: nil, teacher_score: nil, teaching_asistant_score: nil) @@ -112,7 +112,7 @@ class StudentWorksController < ApplicationController student_ids += members for i in 0 .. members.count-1 stu_work = @homework.student_works.find_or_initialize_by(user_id: members[i].to_i) - stu_work.update_attributes(user_id: members[i].to_i, description: student_work.description, + stu_work.update_attributes!(user_id: members[i].to_i, description: student_work.description, homework_common_id: @homework.id, project_id: student_work.project_id, late_penalty: student_work.late_penalty, work_status: student_work.work_status, commit_time: Time.now, update_time: Time.now, group_id: student_work.group_id, @@ -177,7 +177,7 @@ class StudentWorksController < ApplicationController # 原成员更新描述、更新时间以及附件 @homework.student_works.where(group_id: @work.group_id, user_id: (work_user_ids & params_user_ids)).each do |work| # work.update_attributes(update_time: Time.now, description: @work.description, commit_user_id: current_user.id) - work.update_attributes(update_time: Time.now, description: @work.description, update_user_id: current_user.id) + work.update_attributes!(update_time: Time.now, description: @work.description, update_user_id: current_user.id) work.attachments.destroy_all @work.attachments.each do |attachment| att = attachment.copy @@ -202,7 +202,7 @@ class StudentWorksController < ApplicationController # 新增加的成员 (params_user_ids - work_user_ids).each do |user_id| stu_work = @homework.student_works.find_or_initialize_by(user_id: user_id) - stu_work.update_attributes(user_id: user_id, description: @work.description, homework_common_id: @homework.id, + stu_work.update_attributes!(user_id: user_id, description: @work.description, homework_common_id: @homework.id, project_id: @work.project_id, late_penalty: @work.late_penalty, work_status: @work.work_status, commit_time: Time.now, update_time: Time.now, group_id: @work.group_id, commit_user_id: @work.commit_user_id, update_user_id: current_user.id) @@ -257,14 +257,14 @@ class StudentWorksController < ApplicationController work = @homework.student_works.find_or_create_by(user_id: current_user.id) if work.work_status == 0 && work.project_id == 0 - work.update_attributes(project_id: project.id, update_time: Time.now) + work.update_attributes!(project_id: project.id, update_time: Time.now) # 将老师加入项目 project_member = project.members.find_by_user_id(@homework.user_id) if project_member.present? - project_member.member_roles.take.update_attributes(role_id: 3) if project_member.member_roles.take.present? + project_member.member_roles.take.update_attributes!(role_id: 3) if project_member.member_roles.take.present? else - member = Member.create(user_id: @homework.user_id, project_id: project.id) + member = Member.create!(user_id: @homework.user_id, project_id: project.id) member.member_roles << MemberRole.new(role_id: 3) Tiding.create(user_id: @homework.user_id, trigger_user_id: current_user.id, container_id: project.id, container_type: 'ManagerJoinProject', belong_container_id: project.id, @@ -295,7 +295,7 @@ class StudentWorksController < ApplicationController Tiding.where(user_id: @homework.user_id, trigger_user_id: current_user.id, container_id: work.project.id, container_type: 'ManagerJoinProject').destroy_all - work.update_attributes(project_id: 0) + work.update_attributes!(project_id: 0) normal_status(0,"取消关联成功") rescue Exception => e @@ -329,9 +329,9 @@ class StudentWorksController < ApplicationController # end Attachment.associate_container(params[:attachment_ids], @work.id, @work.class, 7) revise_attachment = Attachment.where(attachtype: 7, container_id: @work.id, container_type: "StudentWork").last - revise_attachment.update_attributes(description: params[:description]) if revise_attachment.present? + revise_attachment.update_attributes!(description: params[:description]) if revise_attachment.present? - @work.update_attributes(update_time: Time.now) + @work.update_attributes!(update_time: Time.now) # 补交附件时给评阅过作品的教师、助教发消息 unless @work.student_works_scores.where.not(score: nil).where(reviewer_role: [1, 2]).pluck(:user_id).uniq.blank? @@ -376,9 +376,9 @@ class StudentWorksController < ApplicationController # 如果作品是未提交的状态则更新为已提交 if @user_course_identity < Course::STUDENT && !new_score.score.nil? && @work.work_status == 0 - @work.update_attributes(work_status: 1, commit_time: Time.now) + @work.update_attributes!(work_status: 1, commit_time: Time.now) # 分组作业更新分组id - @work.update_attributes(group_id: @homework.max_group_id) if @homework.homework_type == "group" + @work.update_attributes!(group_id: @homework.max_group_id) if @homework.homework_type == "group" end new_score.reviewer_role = reviewer_role @@ -442,7 +442,7 @@ class StudentWorksController < ApplicationController # 实训作品的总结 def update_des - @work.update_attributes(des_params) + @work.update_attributes!(des_params) tip_exception(0, "提交成功") end @@ -590,7 +590,7 @@ class StudentWorksController < ApplicationController begin score = @work.student_works_scores.find_by!(id: params[:score_id]) jour = score.journals_for_messages.new(user_id: current_user.id, notes: params[:comment], reply_id: score.user_id) - jour.save + jour.save! normal_status(0,"回复成功") rescue Exception => e uid_logger(e.message) @@ -624,7 +624,7 @@ class StudentWorksController < ApplicationController score_appeal = nil ActiveRecord::Base.transaction do begin - score.update_attributes(appeal_status: 1) + score.update_attributes!(appeal_status: 1) score_appeal = StudentWorksScoresAppeal.create!(user_id: current_user.id, student_works_score_id: score.id, comment: params[:comment], appeal_status: 1) @@ -645,9 +645,9 @@ class StudentWorksController < ApplicationController if score.present? && score.appeal_status == 1 ActiveRecord::Base.transaction do begin - score.update_attributes(appeal_status: 2) + score.update_attributes!(appeal_status: 2) score_appeal = score.student_works_scores_appeal - score_appeal.update_attributes(appeal_status: 2) + score_appeal.update_attributes!(appeal_status: 2) score_appeal.tidings.destroy_all normal_status(0,"撤销成功") rescue Exception => e @@ -670,18 +670,18 @@ class StudentWorksController < ApplicationController ActiveRecord::Base.transaction do begin # 更新appeal_status的值 - score.update_attributes(appeal_status: params[:status].to_i) + score.update_attributes!(appeal_status: params[:status].to_i) score_appeal = score.student_works_scores_appeal - score_appeal.update_attributes(appeal_status: params[:status].to_i) + score_appeal.update_attributes!(appeal_status: params[:status].to_i) score_appeal.tidings.update_all(status: 1) if params[:status].to_i == 3 # 申诉成功后该评分失效 - score.update_attributes(is_invalid: 1) + score.update_attributes!(is_invalid: 1) # 申诉成功后 扣匿评学生的违规匿评扣分 sw = @homework.student_works.find_by(user_id: score.user_id) - sw.update_attribute("appeal_penalty", @homework.homework_detail_manual.appeal_penalty + sw.appeal_penalty) if sw.present? + sw.update_attributes!(appeal_penalty: @homework.homework_detail_manual.appeal_penalty + sw.appeal_penalty) if sw.present? # 申诉成功 重新计算申诉者的匿评分 if @work.student_works_scores.where("reviewer_role = 3 AND appeal_status != 3").count > 0 @@ -689,7 +689,7 @@ class StudentWorksController < ApplicationController else @work.student_score = nil end - @work.save + @work.save! end # todo tiding @@ -737,7 +737,7 @@ class StudentWorksController < ApplicationController else comment = "根据实训报告中最终提交的代码调整第#{challenge.position}关分数" end - challenge_score = @work.challenge_work_scores.create(challenge_id: params[:challenge_id], user_id: current_user.id, score: params[:score], + challenge_score = @work.challenge_work_scores.create!(challenge_id: params[:challenge_id], user_id: current_user.id, score: params[:score], comment: comment) challenge_score.create_tiding current_user.id if @work.work_status != 0 && @work.myshixun @@ -862,7 +862,7 @@ class StudentWorksController < ApplicationController else st_work.student_score = student_work.student_score end - st_work.save + st_work.save! Tiding.create(user_id: st_work.user_id, trigger_user_id: current_user.id, container_id: st_score.id, container_type: "StudentWorksScore", parent_container_id: st_work.id, parent_container_type: "StudentWork", diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index 8e23590ef..47863a3a0 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -5,7 +5,7 @@ class SubjectsController < ApplicationController before_action :find_subject, except: [:index, :create, :new, :append_to_stage, :add_shixun_to_stage] before_action :allowed, only: [:update, :edit, :destroy, :publish, :cancel_publish, :cancel_has_publish, :search_members, :add_subject_members, :statistics, :shixun_report, :school_report, - :up_member_position, :down_member_position, :update_team_title] + :up_member_position, :down_member_position, :update_team_title, :statistics_info] before_action :require_admin, only: [:copy_subject] before_action :shixun_marker, only: [:add_shixun_to_stage] @@ -13,6 +13,7 @@ class SubjectsController < ApplicationController include ApplicationHelper include SubjectsHelper include GitCommon + include CustomSortable def index @tech_system = current_laboratory.subject_repertoires @@ -92,7 +93,7 @@ class SubjectsController < ApplicationController @is_creator = current_user.creator_of_subject?(@subject) @is_manager = @user.manager_of_subject?(@subject) # 合作团队 - @shixuns = @subject.shixuns.published.pluck(:id) + # @shixuns = @subject.shixuns.published.pluck(:id) @courses = @subject.courses if @subject.excellent @members = @subject.subject_members.includes(:user) @@ -456,7 +457,7 @@ class SubjectsController < ApplicationController end end - def statistics_new + def statistics_info # data = Subjects::DataStatisticService.new(@subject) # Rails.logger.info("study_count: #{data.study_count}") # Rails.logger.info("course_study_count: #{ data.course_study_count}") @@ -470,9 +471,19 @@ class SubjectsController < ApplicationController # data_2 = Subjects::ShixunUsedInfoService.call(@subject) # Rails.logger.info("study_count: #{data_2}") - data_3 = Subjects::UserUsedInfoService.call(@subject) - Rails.logger.info("study_count: #{data_3}") - render_ok() + # data_3 = Subjects::UserUsedInfoService.call(@subject) + # Rails.logger.info("study_count: #{data_3}") + + @data = + if params[:type] == "shixun_info" + @subject.subject_shixun_infos + elsif params[:type] == "user_info" + @subject.subject_user_infos + else + @subject.subject_course_records + end + @data = paginate custom_sort(@data, params[:sort_by], params[:sort_direction]) + end def shixun_report diff --git a/app/controllers/tag_disciplines_controller.rb b/app/controllers/tag_disciplines_controller.rb index 2650f51eb..c978762ad 100644 --- a/app/controllers/tag_disciplines_controller.rb +++ b/app/controllers/tag_disciplines_controller.rb @@ -2,7 +2,10 @@ class TagDisciplinesController < ApplicationController before_action :require_login def create + tip_exception("请输入知识点") if params[:name].blank? + tip_exception("输入字符长度限制在15个以内") if params[:name].length > 15 sub_discipline = SubDiscipline.find_by!(id: params[:sub_discipline_id]) + tip_exception("重复的知识点") if sub_discipline.tag_disciplines.exists?(name: params[:name].to_s.strip) tag_discipline = TagDiscipline.create!(name: params[:name].to_s.strip, sub_discipline: sub_discipline, user_id: current_user.id) render_ok({tag_discipline_id: tag_discipline.id}) end diff --git a/app/controllers/users/interests_controller.rb b/app/controllers/users/interests_controller.rb index 93f2345f1..06470f553 100644 --- a/app/controllers/users/interests_controller.rb +++ b/app/controllers/users/interests_controller.rb @@ -9,18 +9,18 @@ class Users::InterestsController < Users::BaseController extension = current_user.user_extension || current_user.build_user_extension return render_error('请选择职业') unless %w(teacher student professional).include?(identity) - interest_ids = Array.wrap(params[:interest_ids]).map(&:to_i) - return render_error('请选择兴趣') if interest_ids.blank? + # interest_ids = Array.wrap(params[:interest_ids]).map(&:to_i) + # return render_error('请选择兴趣') if interest_ids.blank? ActiveRecord::Base.transaction do extension.update_column(:identity, identity) # 兴趣 - UserInterest.bulk_insert(:user_id, :repertoire_id) do |worker| - (Repertoire.pluck(:id) & interest_ids).each do |repertoire_id| - worker.add(user_id: current_user.id, repertoire_id: repertoire_id) - end - end + # UserInterest.bulk_insert(:user_id, :repertoire_id) do |worker| + # (Repertoire.pluck(:id) & interest_ids).each do |repertoire_id| + # worker.add(user_id: current_user.id, repertoire_id: repertoire_id) + # end + # end end render_ok diff --git a/app/controllers/weapps/verification_codes_controller.rb b/app/controllers/weapps/verification_codes_controller.rb index 7590c49f7..1876014db 100644 --- a/app/controllers/weapps/verification_codes_controller.rb +++ b/app/controllers/weapps/verification_codes_controller.rb @@ -19,11 +19,10 @@ class Weapps::VerificationCodesController < Weapps::BaseController return render_error('请输入正确的邮箱或手机号') end - code = %W(0 1 2 3 4 5 6 7 8 9) - verification_code = code.sample(6).join send_type = login =~ /^1\d{10}$/ ? 1 : 8 - # 记录验证码 - check_verification_code(verification_code, send_type, login) + + # 发送验证码 + send_code(send_type, login) render_ok end @@ -40,12 +39,21 @@ class Weapps::VerificationCodesController < Weapps::BaseController return render_error('请输入正确的邮箱或手机号') end + send_type = login =~ /^1\d{10}$/ ? 2 : 3 + + # 发送验证码 + send_code(send_type, login) + + render_ok + end + + def send_code send_type, login code = %W(0 1 2 3 4 5 6 7 8 9) verification_code = code.sample(6).join - send_type = login =~ /^1\d{10}$/ ? 2 : 3 # 记录验证码 - check_verification_code(verification_code, send_type, login) + sign = Digest::MD5.hexdigest("#{OPENKEY}#{login}") + tip_exception(501, "请求不合理") if sign != params[:smscode] - render_ok + check_verification_code(verification_code, send_type, login) end end \ No newline at end of file diff --git a/app/forms/examination_banks/save_exam_form.rb b/app/forms/examination_banks/save_exam_form.rb index b84b32eb1..d066300be 100644 --- a/app/forms/examination_banks/save_exam_form.rb +++ b/app/forms/examination_banks/save_exam_form.rb @@ -6,7 +6,7 @@ class ExaminationBanks::SaveExamForm validates :discipline_id, presence: true validates :sub_discipline_id, presence: true validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } - validates :name, presence: true, length: { maximum: 60 } + validates :name, presence: true, length: { maximum: 60, too_long: "不能超过60个字符" } validate :validate_duration def validate_duration 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 2bfd99fc3..b10835266 100644 --- a/app/forms/item_banks/save_item_form.rb +++ b/app/forms/item_banks/save_item_form.rb @@ -7,17 +7,17 @@ class ItemBanks::SaveItemForm validates :sub_discipline_id, presence: true validates :item_type, presence: true, inclusion: {in: %W(SINGLE MULTIPLE JUDGMENT COMPLETION SUBJECTIVE PRACTICAL PROGRAM)} validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } - validates :name, presence: true, length: { maximum: 1000 } - validates :analysis, length: { maximum: 1000 } + validates :name, presence: true, length: { maximum: 1000, too_long: "不能超过1000个字符" } + validates :analysis, length: { maximum: 1000, too_long: "不能超过1000个字符" } def validate! super 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 @@ -27,7 +27,7 @@ class ItemBanks::SaveItemForm attr_accessor :choice_text, :is_answer - validates :choice_text, presence: true, length: { maximum: 100 } + validates :choice_text, presence: true, length: { maximum: 500, too_long: "不能超过500个字符" } validates :is_answer, presence: true, inclusion: {in: 0..1}, numericality: { only_integer: true } end end \ No newline at end of file diff --git a/app/forms/validate/user.rb b/app/forms/validate/user.rb index 0f8f5e9ba..4387950dd 100644 --- a/app/forms/validate/user.rb +++ b/app/forms/validate/user.rb @@ -4,7 +4,7 @@ module Validate attr_accessor :nickname, :lastname - validates :nickname, presence: true, length: { maximum: 10 } + validates :nickname, presence: true, length: { maximum: 10, too_long: "不能超过10个字符" } validates :lastname, presence: true end end diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index cf9aec815..eaeb458a3 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -530,7 +530,7 @@ module ExercisesHelper exercise_cha_score = 0.0 answer_status = 0 # if game.status == 2 && game.final_score >= 0 - if game.final_score > 0 && game.end_time && game.end_time < exercise_end_time + if game.final_score > 0 && (game.end_time.nil? || game.end_time < exercise_end_time) exercise_cha_score = game.real_score(exercise_cha.question_score) # exercise_cha_score = exercise_cha.question_score #每一关卡的得分 answer_status = 1 diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index 8b61ca2b6..64ad114bd 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -851,7 +851,8 @@ module ExportHelper def make_zip_name(work, file_name="") Rails.logger.info("######################file_name: #{file_name}") # name = file_name === "" ? "" : (file_name[0, file_name.rindex('.')]+"_") - "#{work&.homework_common.course&.user_group_name(work.user_id)}_#{work&.user&.student_id}_#{work&.user&.real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" + course = work.is_a?(StudentWork) ? work&.homework_common&.course : work&.graduation_task&.course + "#{course&.user_group_name(work.user_id)}_#{work&.user&.student_id}_#{work&.user&.real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" end def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[]) diff --git a/app/helpers/subjects_helper.rb b/app/helpers/subjects_helper.rb index 75ae9f041..72154b0a8 100644 --- a/app/helpers/subjects_helper.rb +++ b/app/helpers/subjects_helper.rb @@ -1,10 +1,10 @@ module SubjectsHelper # 实训路径的发布状态 - def publish_status subject, is_manager, user, shixuns + def publish_status subject, is_manager, user status = -1 if is_manager - status = 0 if subject.status == 0 && shixuns.count > 0 + status = 0 if subject.status == 0 status = 1 if subject.status == 1 status = 2 if subject.status == 2 && user.admin? end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index ac051428f..3ff9a6a90 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -25,7 +25,7 @@ class Attachment < ApplicationRecord scope :search_by_container, -> (ids) {where(container_id: ids)} scope :unified_setting, -> {where("unified_setting = ? ", 1)} - validates_length_of :description, maximum: 100 + validates_length_of :description, maximum: 100, message: "不能超过100个字符" DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) diff --git a/app/models/challenge.rb b/app/models/challenge.rb index e9bef0c9d..9608b6e37 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -28,7 +28,7 @@ class Challenge < ApplicationRecord scope :fields_for_list, -> { select([:id, :subject, :st, :score, :position, :shixun_id]) } - validates :task_pass, length: { maximum: 10000 } + validates :task_pass, length: { maximum: 10000, too_long: "不能超过10000个字符" } after_commit :create_diff_record diff --git a/app/models/challenge_answer.rb b/app/models/challenge_answer.rb index d3fd69cd0..514f3471a 100644 --- a/app/models/challenge_answer.rb +++ b/app/models/challenge_answer.rb @@ -3,7 +3,7 @@ class ChallengeAnswer < ApplicationRecord belongs_to :challenge has_many :game_answers, :dependent => :destroy - validates :contents, length: { maximum: 5000 } + validates :contents, length: { maximum: 5000 , too_long: "不能超过5000个字符"} def view_answer_time(user_id) game_answers.where(user_id: user_id).last&.view_time diff --git a/app/models/challenge_choose.rb b/app/models/challenge_choose.rb index 2b8858f21..70997a925 100644 --- a/app/models/challenge_choose.rb +++ b/app/models/challenge_choose.rb @@ -4,6 +4,6 @@ class ChallengeChoose < ApplicationRecord has_many :challenge_tags, :dependent => :destroy has_many :challenge_questions, dependent: :destroy - validates :subject, length: { maximum: 1000 } + validates :subject, length: { maximum: 1000, too_long: "不能超过1000个字符" } end diff --git a/app/models/challenge_question.rb b/app/models/challenge_question.rb index 959b033f9..d5c26d90e 100644 --- a/app/models/challenge_question.rb +++ b/app/models/challenge_question.rb @@ -1,6 +1,6 @@ class ChallengeQuestion < ApplicationRecord belongs_to :challenge_choose - validates :option_name, length: { maximum: 500 } + validates :option_name, length: { maximum: 500, too_long: "不能超过500个字符" } end diff --git a/app/models/challenge_work_score.rb b/app/models/challenge_work_score.rb index 1e7c9f7fe..8d27b8107 100644 --- a/app/models/challenge_work_score.rb +++ b/app/models/challenge_work_score.rb @@ -4,6 +4,8 @@ class ChallengeWorkScore < ApplicationRecord belongs_to :challenge has_many :tidings, as: :container, dependent: :destroy + validates :comment, length: { maximum: 500, too_long: "不能超过500个字符" } + def create_tiding trigger_user_id tidings << Tiding.new(user_id: student_work.user_id, trigger_user_id: trigger_user_id, container_id: id, container_type: "ChallengeWorkScore", parent_container_id: student_work_id, diff --git a/app/models/chart_rule.rb b/app/models/chart_rule.rb index de8fceaf1..a4cca9a1c 100644 --- a/app/models/chart_rule.rb +++ b/app/models/chart_rule.rb @@ -2,5 +2,5 @@ class ChartRule < ApplicationRecord belongs_to :competition belongs_to :competition_stage, optional: true - validates :content, length: { maximum: 1000 } + validates :content, length: { maximum: 1000, too_long: "不能超过1000个字符" } end diff --git a/app/models/competition.rb b/app/models/competition.rb index 1d10e2032..55331c3c2 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -33,7 +33,7 @@ class Competition < ApplicationRecord has_many :competition_prizes, dependent: :destroy has_many :competition_prize_users, dependent: :destroy - validates :introduction, length: { maximum: 500 } + validates :introduction, length: { maximum: 500, too_long: "不能超过500个字符" } before_save :set_laboratory after_create :create_competition_modules diff --git a/app/models/competition_module_md_content.rb b/app/models/competition_module_md_content.rb index 936ded8ef..2d7ae5e36 100644 --- a/app/models/competition_module_md_content.rb +++ b/app/models/competition_module_md_content.rb @@ -5,6 +5,6 @@ class CompetitionModuleMdContent < ApplicationRecord # validates :name, presence: true validates :content, presence: true - validates :content, length: { maximum: 10000 } + validates :content, length: { maximum: 10000 , too_long: "不能超过10000个字符"} end \ No newline at end of file diff --git a/app/models/course.rb b/app/models/course.rb index 83d2bb56e..1d5175ed3 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -108,7 +108,7 @@ class Course < ApplicationRecord NORMAL = 6 # 普通用户 Anonymous = 7 # 普未登录 - validates :name, presence: true, length: { maximum: 60 } + validates :name, presence: true, length: { maximum: 60, too_long: "不能超过60个字符" } before_save :set_laboratory after_create :create_board_sync, :act_as_course_activity, :send_tiding diff --git a/app/models/course_group.rb b/app/models/course_group.rb index 9486c9043..5bd27804f 100644 --- a/app/models/course_group.rb +++ b/app/models/course_group.rb @@ -9,7 +9,7 @@ class CourseGroup < ApplicationRecord has_many :homework_group_settings, :dependent => :destroy scope :by_group_ids, lambda { |ids| where(id: ids)} - validates :name, length: { maximum: 60 } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } validates_uniqueness_of :name, scope: :course_id, message: "不能创建相同名称的分班" after_create :generate_invite_code diff --git a/app/models/course_module.rb b/app/models/course_module.rb index 641c70425..32a6a7794 100644 --- a/app/models/course_module.rb +++ b/app/models/course_module.rb @@ -5,7 +5,7 @@ class CourseModule < ApplicationRecord # 二级目录 has_many :course_second_categories - validates :module_name, length: { maximum: 20 } + validates :module_name, length: { maximum: 20, too_long: "不能超过20个字符" } scope :not_hidden, -> { where(hidden: 0) } scope :graduation_module, -> { where(module_type: "graduation") } diff --git a/app/models/course_second_category.rb b/app/models/course_second_category.rb index 630b74807..963367e0b 100644 --- a/app/models/course_second_category.rb +++ b/app/models/course_second_category.rb @@ -5,7 +5,7 @@ class CourseSecondCategory < ApplicationRecord belongs_to :course_module has_many :homework_commons - validates :name, length: { maximum: 60 } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } def category_type_str category_type == "graduation" && name == "毕设选题" ? "graduation_topics" : ( diff --git a/app/models/course_stage.rb b/app/models/course_stage.rb index f105e25f6..0fecfb434 100644 --- a/app/models/course_stage.rb +++ b/app/models/course_stage.rb @@ -4,6 +4,6 @@ class CourseStage < ApplicationRecord has_many :course_stage_shixuns, -> { order("course_stage_shixuns.position ASC") }, dependent: :destroy has_many :shixuns, :through => :course_stage_shixuns - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 300 } + validates :name, length: { maximum: 60 , too_long: "不能超过60个字符"} + validates :description, length: { maximum: 1000, too_long: "不能超过1000个字符" } end diff --git a/app/models/discuss.rb b/app/models/discuss.rb index f35ca4751..a4c833b55 100644 --- a/app/models/discuss.rb +++ b/app/models/discuss.rb @@ -13,7 +13,7 @@ class Discuss < ApplicationRecord belongs_to :challenge, optional: true validate :validate_sensitive_string - validates :content, length: { maximum: 1000 } + validates :content, length: { maximum: 2000, too_long: "不能超过2000个字符" } after_create :send_tiding 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/exercise.rb b/app/models/exercise.rb index 1fd84d1f7..bf752fb92 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -19,8 +19,8 @@ class Exercise < ApplicationRecord scope :exercise_search, lambda { |keywords| where("exercise_name LIKE ?", "%#{keywords}%") unless keywords.blank?} - validates :exercise_name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" } - validates :exercise_description, length: { maximum: 100 } + validates :exercise_name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :exercise_description, length: { maximum: 100, too_long: "不能超过100个字符" } after_create :create_exercise_list diff --git a/app/models/exercise_answer.rb b/app/models/exercise_answer.rb index 00c08dd77..60269366c 100644 --- a/app/models/exercise_answer.rb +++ b/app/models/exercise_answer.rb @@ -11,6 +11,6 @@ class ExerciseAnswer < ApplicationRecord scope :exercise_answer_is_right, -> {where("score > ?",0.0)} #判断答案是否正确,根据分数总和大于0 scope :score_reviewed, lambda {where("score >= ?",0.0)} #是否评分,用于判断主观题的 - validates :answer_text, length: { maximum: 5000 } + validates :answer_text, length: { maximum: 5000, too_long: "不能超过5000个字符" } end \ No newline at end of file diff --git a/app/models/exercise_answer_comment.rb b/app/models/exercise_answer_comment.rb index 110efc737..c769fd077 100644 --- a/app/models/exercise_answer_comment.rb +++ b/app/models/exercise_answer_comment.rb @@ -7,5 +7,5 @@ class ExerciseAnswerComment < ApplicationRecord scope :search_answer_comments, lambda {|name,ids| where("#{name}":ids)} - validates :comment, length: { maximum: 100 } + validates :comment, length: { maximum: 100, too_long: "不能超过100个字符" } end diff --git a/app/models/exercise_bank.rb b/app/models/exercise_bank.rb index 067d080b5..2d1931e01 100644 --- a/app/models/exercise_bank.rb +++ b/app/models/exercise_bank.rb @@ -18,7 +18,7 @@ class ExerciseBank < ApplicationRecord scope :exercise_bank_search, lambda { |keywords| where("name LIKE ?", "%#{keywords}%") unless keywords.blank?} - validates :name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" } - validates :description, length: { maximum: 100, too_long: "100 characters is the maximum allowed" } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :description, length: { maximum: 100, too_long: "不能超过100个字符" } end \ No newline at end of file diff --git a/app/models/exercise_bank_choice.rb b/app/models/exercise_bank_choice.rb index 8f1dc9028..4a4c46251 100644 --- a/app/models/exercise_bank_choice.rb +++ b/app/models/exercise_bank_choice.rb @@ -5,6 +5,6 @@ class ExerciseBankChoice < ApplicationRecord scope :find_choice_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题 scope :left_choice_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 - validates :choice_text, length: { maximum: 500 } + validates :choice_text, length: { maximum: 500, too_long: "不能超过500个字符" } end \ No newline at end of file diff --git a/app/models/exercise_bank_question.rb b/app/models/exercise_bank_question.rb index fbb6da88f..75d6bfedf 100644 --- a/app/models/exercise_bank_question.rb +++ b/app/models/exercise_bank_question.rb @@ -11,7 +11,7 @@ class ExerciseBankQuestion < ApplicationRecord scope :left_question_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 scope :find_objective_questions, -> {where("question_type != ?",4)} #查找全部客观题 - validates :question_title, length: { maximum: 1000 } + validates :question_title, length: { maximum: 1000, too_long: "不能超过1000个字符" } def question_type_name case self.question_type diff --git a/app/models/exercise_bank_standard_answer.rb b/app/models/exercise_bank_standard_answer.rb index 9bfbd67aa..c147c07c9 100644 --- a/app/models/exercise_bank_standard_answer.rb +++ b/app/models/exercise_bank_standard_answer.rb @@ -4,6 +4,6 @@ class ExerciseBankStandardAnswer < ApplicationRecord #attr_accessible :answer_text scope :standard_by_ids, lambda { |s| where(exercise_bank_choice_id: s) } - validates :answer_text, length: { maximum: 5000 } + validates :answer_text, length: { maximum: 5000, too_long: "不能超过5000个字符" } end \ No newline at end of file diff --git a/app/models/exercise_choice.rb b/app/models/exercise_choice.rb index 54b844ad9..3cfd7a17c 100644 --- a/app/models/exercise_choice.rb +++ b/app/models/exercise_choice.rb @@ -7,6 +7,6 @@ class ExerciseChoice < ApplicationRecord scope :find_choice_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题 scope :left_choice_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 - validates :choice_text, length: { maximum: 500 } + validates :choice_text, length: { maximum: 500, too_long: "不能超过500个字符" } end \ No newline at end of file diff --git a/app/models/exercise_question.rb b/app/models/exercise_question.rb index 3f1a49625..2b8d88c57 100644 --- a/app/models/exercise_question.rb +++ b/app/models/exercise_question.rb @@ -16,7 +16,7 @@ class ExerciseQuestion < ApplicationRecord scope :left_question_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 scope :find_objective_questions, -> {where("question_type != ?",4)} #查找全部客观题 - validates :question_title, length: { maximum: 1000 } + validates :question_title, length: { maximum: 1000, too_long: "不能超过1000个字符" } def question_type_name diff --git a/app/models/exercise_standard_answer.rb b/app/models/exercise_standard_answer.rb index ccf5c1203..cec6c6d46 100644 --- a/app/models/exercise_standard_answer.rb +++ b/app/models/exercise_standard_answer.rb @@ -6,5 +6,5 @@ class ExerciseStandardAnswer < ApplicationRecord scope :find_standard_answer_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题 scope :standard_by_ids, lambda { |s| where(exercise_choice_id: s) } - validates :answer_text, length: { maximum: 5000 } + validates :answer_text, length: { maximum: 5000, too_long: "不能超过5000个字符" } end diff --git a/app/models/graduation_task.rb b/app/models/graduation_task.rb index c9838954a..4b6465bde 100644 --- a/app/models/graduation_task.rb +++ b/app/models/graduation_task.rb @@ -29,8 +29,8 @@ class GraduationTask < ApplicationRecord belongs_to :gtask_bank, optional: true - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 5000 } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "不能超过5000个字符" } # 未提交 scope :unfinished, -> {where(status: 0)} diff --git a/app/models/graduation_topic.rb b/app/models/graduation_topic.rb index 294bfa785..2efef271a 100644 --- a/app/models/graduation_topic.rb +++ b/app/models/graduation_topic.rb @@ -19,10 +19,8 @@ class GraduationTopic < ApplicationRecord #after_create :act_as_course_activity # 课题名称和描述字段长度限制 - validates :name, length: { maximum: 60, - too_long: "60 characters is the maximum allowed" } - validates :description, length: { maximum: 5000, - too_long: "5000 characters is the maximum allowed" } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "不能超过5000个字符" } def status_name case self.status diff --git a/app/models/graduation_work.rb b/app/models/graduation_work.rb index 7fb0ecc24..76ecbb515 100644 --- a/app/models/graduation_work.rb +++ b/app/models/graduation_work.rb @@ -19,7 +19,7 @@ class GraduationWork < ApplicationRecord # has_many :formal_graduation_task_group_assignations, -> { formal }, class_name: "GraduationTaskGroupAssignation" # has_many :temporary_graduation_task_group_assignations, -> { temporary }, class_name: "GraduationTaskGroupAssignation" - validates :description, length: { maximum: 5000 } + validates :description, length: { maximum: 5000, too_long: "不能超过5000个字符" } scope :has_committed, lambda { where("work_status != 0") } diff --git a/app/models/graduation_work_score.rb b/app/models/graduation_work_score.rb index 853b996a1..78c2727fc 100644 --- a/app/models/graduation_work_score.rb +++ b/app/models/graduation_work_score.rb @@ -5,5 +5,5 @@ class GraduationWorkScore < ApplicationRecord belongs_to :graduation_task has_many :attachments, as: :container, dependent: :destroy - validates :comment, length: { maximum: 1000 } + validates :comment, length: { maximum: 2000, too_long: "不能超过2000个字符" } end diff --git a/app/models/gtask_bank.rb b/app/models/gtask_bank.rb index f9d38d33f..8b14d74b1 100644 --- a/app/models/gtask_bank.rb +++ b/app/models/gtask_bank.rb @@ -9,6 +9,6 @@ class GtaskBank < ApplicationRecord scope :myself, ->(user_id) { where(user_id: user_id)} scope :is_public, -> { where(:is_public => true) } - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 5000 } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "不能超过5000个字符" } end diff --git a/app/models/gtopic_bank.rb b/app/models/gtopic_bank.rb index fe9f184eb..1187fd9bc 100644 --- a/app/models/gtopic_bank.rb +++ b/app/models/gtopic_bank.rb @@ -10,8 +10,6 @@ class GtopicBank < ApplicationRecord # 课题名称和描述字段长度限制 - validates :name, length: { maximum: 60, - too_long: "60 characters is the maximum allowed" } - validates :description, length: { maximum: 5000, - too_long: "5000 characters is the maximum allowed" } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "不能超过5000个字符" } end diff --git a/app/models/hack.rb b/app/models/hack.rb index e89212cc3..0c5970af4 100644 --- a/app/models/hack.rb +++ b/app/models/hack.rb @@ -2,8 +2,8 @@ class Hack < ApplicationRecord # status: 0 未发布; 1已发布 # diffcult: 难度 1:简单;2:中等; 3:困难 # 编程题 - validates_length_of :name, maximum: 60 - validates_length_of :description, maximum: 5000 + validates_length_of :name, maximum: 60, message: "不能超过60个字符" + validates_length_of :description, maximum: 5000, message: "不能超过5000个字符" validates :description, presence: { message: "描述不能为空" } validates :name, presence: { message: "名称不能为空" } # 测试集 diff --git a/app/models/hack_set.rb b/app/models/hack_set.rb index 4dafd94a7..2c21c3c22 100644 --- a/app/models/hack_set.rb +++ b/app/models/hack_set.rb @@ -1,6 +1,6 @@ class HackSet < ApplicationRecord - validates_length_of :input, maximum: 500 - validates_length_of :output, maximum: 500 + validates_length_of :input, maximum: 1000, message: "不能超过1000个字符" + validates_length_of :output, maximum: 1000, message: "不能超过1000个字符" validates :input, presence: { message: "测试集输入不能为空" } validates :output, presence: { message: "测试集输出不能为空" } validates_uniqueness_of :input, scope: [:hack_id, :input], message: "多个测试集的输入不能相同" diff --git a/app/models/hack_user_lastest_code.rb b/app/models/hack_user_lastest_code.rb index 99582af41..afea69ed5 100644 --- a/app/models/hack_user_lastest_code.rb +++ b/app/models/hack_user_lastest_code.rb @@ -12,6 +12,6 @@ class HackUserLastestCode < ApplicationRecord scope :mine_hack, ->(author_id){ where(user_id: author_id) } scope :passed, -> {where(status: 1)} - validates_length_of :notes, maximum: 5000, message: "笔记不能超过5000个字" + validates_length_of :notes, maximum: 5000, message: "不能超过5000个字" end diff --git a/app/models/homework_bank.rb b/app/models/homework_bank.rb index d6db7bfab..7e13891d3 100644 --- a/app/models/homework_bank.rb +++ b/app/models/homework_bank.rb @@ -10,7 +10,7 @@ class HomeworkBank < ApplicationRecord scope :is_public, -> { where(is_public: true)} scope :myself, ->(user_id) { where(user_id: user_id)} - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 15000 } - validates :reference_answer, length: { maximum: 15000 } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :description, length: { maximum: 15000, too_long: "不能超过15000个字符" } + validates :reference_answer, length: { maximum: 15000, too_long: "不能超过15000个字符" } end diff --git a/app/models/homework_common.rb b/app/models/homework_common.rb index 58b52bdd2..8f084befd 100644 --- a/app/models/homework_common.rb +++ b/app/models/homework_common.rb @@ -35,10 +35,10 @@ class HomeworkCommon < ApplicationRecord # 学生的查重情况 has_many :homework_review_results, :dependent => :destroy - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 15000 } - validates :explanation, length: { maximum: 5000 } - validates :reference_answer, length: { maximum: 15000 } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :description, length: { maximum: 15000, too_long: "不能超过15000个字符" } + validates :explanation, length: { maximum: 5000, too_long: "不能超过5000个字符" } + validates :reference_answer, length: { maximum: 15000, too_long: "不能超过15000个字符" } # after_update :update_activity before_destroy :update_homework_bank_quotes diff --git a/app/models/inform.rb b/app/models/inform.rb index dc979ef32..689d52bae 100644 --- a/app/models/inform.rb +++ b/app/models/inform.rb @@ -1,8 +1,8 @@ class Inform < ApplicationRecord belongs_to :container, polymorphic: true, optional: true - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 5000 } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "不能超过5000个字符" } has_many :attachments, as: :container, dependent: :destroy diff --git a/app/models/item_analysis.rb b/app/models/item_analysis.rb index 8f6e71302..dc1453982 100644 --- a/app/models/item_analysis.rb +++ b/app/models/item_analysis.rb @@ -1,3 +1,3 @@ class ItemAnalysis < ApplicationRecord - belongs_to :item_bank + belongs_to :item_bank, touch: true 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/item_choice.rb b/app/models/item_choice.rb index ccc35698e..2b2b08c9d 100644 --- a/app/models/item_choice.rb +++ b/app/models/item_choice.rb @@ -1,3 +1,3 @@ class ItemChoice < ApplicationRecord - belongs_to :item_bank + belongs_to :item_bank, touch: true end diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index 66ab98c9b..3d0189c91 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -26,7 +26,7 @@ class JournalsForMessage < ApplicationRecord # "is_comprehensive_evaluation", # 1 教师评论、2 匿评、3 留言 # "hidden", 隐藏、 - validates :notes, length: { maximum: 1000 } + validates :notes, length: { maximum: 2000, too_long: "不能超过2000个字符" } after_create :send_tiding diff --git a/app/models/library.rb b/app/models/library.rb index 982db732b..baed383a9 100644 --- a/app/models/library.rb +++ b/app/models/library.rb @@ -13,7 +13,7 @@ class Library < ApplicationRecord has_one :praise_tread_cache, foreign_key: :object_id has_many :praise_treads, as: :praise_tread_object, dependent: :destroy - validates :content, length: { maximum: 5000 } + validates :content, length: { maximum: 5000, too_long: "不能超过5000个字符" } validates :uuid, presence: true, uniqueness: true diff --git a/app/models/memo.rb b/app/models/memo.rb index 9140fb5db..7be2cf080 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -27,7 +27,7 @@ class Memo < ApplicationRecord scope :hot, -> { order("all_replies_count desc, updated_at desc") } scope :posts, -> { where(root_id: nil, forum_id: [3, 5]) } - validates :content, length: { maximum: 10000 } + validates :content, length: { maximum: 10000, too_long: "不能超过10000个字符" } after_create :send_tiding diff --git a/app/models/message.rb b/app/models/message.rb index 7620ef11d..59dd84b5b 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -33,7 +33,7 @@ class Message < ApplicationRecord #转发表 # has_many :forwards, as: :from, dependent: :destroy - validates :subject, length: { maximum: 255 } + validates :subject, length: { maximum: 255, too_long: "不能超过255个字符" } def update_content(content) message_detail.update_attributes(content: content) diff --git a/app/models/message_detail.rb b/app/models/message_detail.rb index 0d7aaa1c1..d589ada3e 100644 --- a/app/models/message_detail.rb +++ b/app/models/message_detail.rb @@ -1,5 +1,5 @@ class MessageDetail < ApplicationRecord belongs_to :message, :touch => true - validates :content, length: { maximum: 5000 } + validates :content, length: { maximum: 10000, too_long: "内容不能超过10000个字符" } end diff --git a/app/models/poll.rb b/app/models/poll.rb index 1c38d2426..2ebf4c9ef 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -24,8 +24,8 @@ class Poll < ApplicationRecord scope :poll_search, lambda { |keywords| where("polls_name LIKE ?", "%#{keywords}%") unless keywords.blank?} - validates :polls_name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" } - validates :polls_description, length: { maximum: 100 } + validates :polls_name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :polls_description, length: { maximum: 100, too_long: "不能超过100个字符" } after_create :create_polls_list diff --git a/app/models/poll_answer.rb b/app/models/poll_answer.rb index c7fa7e75c..43588502f 100644 --- a/app/models/poll_answer.rb +++ b/app/models/poll_answer.rb @@ -8,6 +8,6 @@ class PollAnswer < ApplicationRecord scope :find_answer_by_custom, lambda {|k,v| where("#{k}":v)} #根据传入的参数查找问题 scope :left_answer_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 - validates :answer_text, length: { maximum: 500 } + validates :answer_text, length: { maximum: 500, too_long: "不能超过500个字符" } end \ No newline at end of file diff --git a/app/models/poll_question.rb b/app/models/poll_question.rb index dd7f3f95f..b38dc1f24 100644 --- a/app/models/poll_question.rb +++ b/app/models/poll_question.rb @@ -9,7 +9,7 @@ class PollQuestion < ApplicationRecord scope :ques_necessary, -> {where("is_necessary = ?",1)} scope :insert_question, lambda {|k| where("question_number > ?",k)} - validates :question_title, length: { maximum: 1000 } + validates :question_title, length: { maximum: 1000, too_long: "不能超过1000个字符" } def question_type_name case self.question_type diff --git a/app/models/poll_vote.rb b/app/models/poll_vote.rb index 2e70f1342..2f9715ebc 100644 --- a/app/models/poll_vote.rb +++ b/app/models/poll_vote.rb @@ -9,6 +9,6 @@ class PollVote < ApplicationRecord scope :find_current_vote,lambda {|k,v| where("#{k}": v)} scope :find_vote_text,-> {where("vote_text IS NOT NULL")} - validates :vote_text, length: { maximum: 5000 } + validates :vote_text, length: { maximum: 5000, too_long: "不能超过5000个字符" } end \ No newline at end of file diff --git a/app/models/program_bank.rb b/app/models/program_bank.rb new file mode 100644 index 000000000..c9be9af9f --- /dev/null +++ b/app/models/program_bank.rb @@ -0,0 +1,34 @@ +class ProgramBank < ApplicationRecord + + def oj_language + result = case language + when '1' + then 'C' + when '2' + then 'C++' + when '3' + then 'Python' + when '4' + then 'Java' + end + result + end + + def strip_description + strip_html description + end + + def oj_sub_discipline_id + result = case language + when '1' + then 3 + when '2' + then 4 + when '3' + then 5 + when '4' + then 2 + end + result + end +end diff --git a/app/models/program_bank_test.rb b/app/models/program_bank_test.rb new file mode 100644 index 000000000..ea336ae91 --- /dev/null +++ b/app/models/program_bank_test.rb @@ -0,0 +1,2 @@ +class ProgramBankTest < ApplicationRecord +end diff --git a/app/models/shixun_info.rb b/app/models/shixun_info.rb index e3a8d334b..c2498067f 100644 --- a/app/models/shixun_info.rb +++ b/app/models/shixun_info.rb @@ -1,10 +1,10 @@ class ShixunInfo < ApplicationRecord belongs_to :shixun validates_uniqueness_of :shixun_id - validates_length_of :fork_reason, maximum: 60 + validates_length_of :fork_reason, maximum: 60, message: "不能超过60个字符" after_commit :create_diff_record - validates :description, length: { maximum: 5000 } + validates :description, length: { maximum: 5000, too_long: "不能超过5000个字符" } private diff --git a/app/models/shixun_work_comment.rb b/app/models/shixun_work_comment.rb index 1d23718d3..b3b7cfdcd 100644 --- a/app/models/shixun_work_comment.rb +++ b/app/models/shixun_work_comment.rb @@ -2,6 +2,6 @@ class ShixunWorkComment < ApplicationRecord belongs_to :student_work belongs_to :user belongs_to :challenge, optional: true - validates :comment, length: { maximum: 500 } - validates :hidden_comment, length: { maximum: 500 } + validates :comment, length: { maximum: 500, too_long: "不能超过500个字符" } + validates :hidden_comment, length: { maximum: 500, too_long: "不能超过500个字符" } end diff --git a/app/models/stage.rb b/app/models/stage.rb index 84873b01f..061efcde3 100644 --- a/app/models/stage.rb +++ b/app/models/stage.rb @@ -6,6 +6,6 @@ class Stage < ApplicationRecord has_many :stage_shixuns, -> { order("stage_shixuns.position ASC") }, dependent: :destroy has_many :shixuns, :through => :stage_shixuns - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 1000 } + validates :name, length: { maximum: 60 , too_long: "不能超过60个字符" } + validates :description, length: { maximum: 1000, too_long: "不能超过1000个字符" } end diff --git a/app/models/student_work.rb b/app/models/student_work.rb index 473efa756..3aee0611b 100644 --- a/app/models/student_work.rb +++ b/app/models/student_work.rb @@ -19,7 +19,7 @@ class StudentWork < ApplicationRecord before_save :set_work_score - validates :description, length: { maximum: 5000 } + validates :description, length: { maximum: 5000, too_long: "不能超过5000个字符" } scope :has_committed, lambda { where("work_status != 0") } # 未提交 diff --git a/app/models/student_works_score.rb b/app/models/student_works_score.rb index f9f4f4220..a193d4e77 100644 --- a/app/models/student_works_score.rb +++ b/app/models/student_works_score.rb @@ -7,7 +7,7 @@ class StudentWorksScore < ApplicationRecord has_many :tidings, as: :container, dependent: :destroy has_many :attachments, as: :container, dependent: :destroy - validates :comment, length: { maximum: 1000 } + validates :comment, length: { maximum: 2000, too_long: "不能超过2000个字符" } scope :shixun_comment, lambda { where(is_ultimate: 0) } diff --git a/app/models/subject.rb b/app/models/subject.rb index df9271e5f..51ef88b3b 100644 --- a/app/models/subject.rb +++ b/app/models/subject.rb @@ -31,9 +31,9 @@ class Subject < ApplicationRecord has_many :subject_shixun_infos, dependent: :destroy has_many :subject_user_infos, dependent: :destroy - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 8000 } - validates :learning_notes, length: { maximum: 2000 } + validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } + validates :description, length: { maximum: 8000, too_long: "不能超过8000个字符" } + validates :learning_notes, length: { maximum: 2000, too_long: "不能超过2000个字符" } scope :visible, lambda{where(status: 2)} scope :published, lambda{where(status: 1)} diff --git a/app/models/tag_discipline_container.rb b/app/models/tag_discipline_container.rb index 585182bbf..44b28af1a 100644 --- a/app/models/tag_discipline_container.rb +++ b/app/models/tag_discipline_container.rb @@ -1,5 +1,5 @@ class TagDisciplineContainer < ApplicationRecord belongs_to :tag_discipline - belongs_to :container, polymorphic: true, optional: true + belongs_to :container, polymorphic: true, optional: true, touch: true end diff --git a/app/models/test_set.rb b/app/models/test_set.rb index 1fae89afa..01bc2b767 100644 --- a/app/models/test_set.rb +++ b/app/models/test_set.rb @@ -1,7 +1,7 @@ class TestSet < ApplicationRecord # match_rule: 匹配规则: full: 完全匹配, last: 末尾匹配 # - validates :input, length: { maximum: 5000 } - validates :input, length: { maximum: 5000 } + validates :input, length: { maximum: 5000, too_long: "不能超过5000个字符" } + validates :output, length: { maximum: 5000, too_long: "不能超过5000个字符" } end diff --git a/app/models/trustie_hack.rb b/app/models/trustie_hack.rb index 7c2f3264b..87d9d31d8 100644 --- a/app/models/trustie_hack.rb +++ b/app/models/trustie_hack.rb @@ -1,5 +1,5 @@ class TrustieHack < ApplicationRecord - validates_length_of :description, maximum: 500 + validates_length_of :description, maximum: 500, message: "不能超过500个字符" has_many :hack_users, :dependent => :destroy belongs_to :trustie_hackathon, counter_cache: true diff --git a/app/models/user.rb b/app/models/user.rb index 6022cc8eb..e74290c84 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -157,6 +157,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/git_service.rb b/app/services/git_service.rb index eedac2595..2bfc7423c 100644 --- a/app/services/git_service.rb +++ b/app/services/git_service.rb @@ -64,7 +64,7 @@ class GitService end def parse_return(body) - logger.info("--uri_exec: .....res is #{body}") + #logger.info("--uri_exec: .....res is #{body}") content = JSON.parse(body) if content["code"] != 0 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/services/subjects/shixun_used_info_service.rb b/app/services/subjects/shixun_used_info_service.rb index 32309fd59..dfd8485e0 100644 --- a/app/services/subjects/shixun_used_info_service.rb +++ b/app/services/subjects/shixun_used_info_service.rb @@ -2,23 +2,25 @@ class Subjects::ShixunUsedInfoService < ApplicationService attr_reader :subject, :stages def initialize(subject) @subject = subject - @stages = subject.stages.includes(shixuns: [myshixuns: :games, homework_commons_shixuns: [homework_common: :course]]) + @stages = subject.stages end def call shixun_infos = [] stages.each do |stage| position = stage.position - stage.shixuns.each_with_index do |shixun, index| + shixuns = stage.shixuns.includes(myshixuns: :games, homework_commons: :course) + shixuns.each_with_index do |shixun, index| stage = "#{position}-#{index+1}" name = shixun.name + myshixuns = shixun.myshixuns challenge_count = shixun.challenges_count course_count = shixun.homework_commons.map{|hc| hc.course_id}.uniq.size school_count = shixun.homework_commons.map{|hc| hc.course&.school_id}.uniq.size used_count = shixun.myshixuns_count - passed_count = shixun.myshixuns.select{|m| m.status == 1}.size - evaluate_count = shixun.myshixuns.map{|m| m.output_times }.sum - passed_ave_time = passed_count > 0 ? shixun.myshixuns.map{|m| m.total_cost_time}.sum : 0 + passed_count = myshixuns.select{|m| m.status == 1}.size + evaluate_count = myshixuns.map{|m| m.output_times }.sum + passed_ave_time = passed_count > 0 ? myshixuns.map{|m| m.total_cost_time}.sum : 0 shixun_infos << {stage: stage, name: name, challenge_count: challenge_count, course_count: course_count, school_count: school_count, used_count: used_count, passed_count: passed_count, evaluate_count: evaluate_count, passed_ave_time: passed_ave_time, shixun_id: shixun.id} 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/app/views/subjects/show.json.jbuilder b/app/views/subjects/show.json.jbuilder index 870d33d40..49ad55517 100644 --- a/app/views/subjects/show.json.jbuilder +++ b/app/views/subjects/show.json.jbuilder @@ -6,7 +6,7 @@ json.subject_score @subject.all_score json.member_count @subject.member_count json.allow_delete (@subject.status != 2 && @is_creator) || @user.admin? -json.publish_status publish_status(@subject, @is_manager, @user, @shixuns) +json.publish_status publish_status(@subject, @is_manager, @user) json.allow_statistics @is_manager json.allow_send @user.logged? json.allow_visit @subject.status > 1 || @is_manager diff --git a/app/views/subjects/statistics_info.json.jbuilder b/app/views/subjects/statistics_info.json.jbuilder new file mode 100644 index 000000000..b31e41b31 --- /dev/null +++ b/app/views/subjects/statistics_info.json.jbuilder @@ -0,0 +1,6 @@ +json.status 0 +json.message "success" +json.data do + json.subject_info @subject.subject_record + json.other_info @data +end \ No newline at end of file diff --git a/app/views/weapps/shared/_user.json.jbuilder b/app/views/weapps/shared/_user.json.jbuilder index be67384cc..53212ec15 100644 --- a/app/views/weapps/shared/_user.json.jbuilder +++ b/app/views/weapps/shared/_user.json.jbuilder @@ -7,6 +7,7 @@ json.admin user.admin? json.business user.business? json.is_teacher user.user_extension&.teacher? json.user_identity user.identity +json.identity user.user_extension&.identity json.tidding_count 0 json.user_phone_binded user.phone.present? json.phone user.phone diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index f11271ff5..33aaa1192 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -13,4 +13,157 @@ zh-CN: 'pending': '待审批' 'processed': '已审批' 'refused': '已拒绝' - 'agreed': '已同意' \ No newline at end of file + 'agreed': '已同意' + + activerecord: + attributes: + user: + login: '登录名' + lastname: '姓名' + nickname: '昵称' + discuss: + content: '内容' + journals_for_message: + notes: '内容' + subject: + name: '课程名称' + description: '课程简介' + learning_notes: '学习须知' + stage: + name: '章节名称' + description: '章节描述' + shixun_info: + description: '简介' + fork_reason: 'fork原因' + challenge: + task_pass: '过关任务' + test_set: + input: '输入' + output: '输出' + challenge_question: + option_name: '选项' + challenge_choose: + subject: '题干' + challenge_answer: + contents: '答案内容' + memo: + content: '帖子内容' + course: + name: '课堂名称' + course_group: + name: '分班名称' + course_module: + module_name: '目录名称' + course_second_category: + name: '目录名称' + inform: + name: '标题' + description: '内容' + course_stage: + name: '章节名称' + description: '章节描述' + attachment: + description: '资源描述' + message: + subject: '标题' + message_detail: + content: '内容' + homework_common: + name: '标题' + description: '内容' + explanation: '内容' + reference_answer: '参考答案' + student_work: + description: '内容' + student_works_score: + comment: '评语' + challenge_work_score: + comment: '评语' + shixun_work_comment: + comment: '评语' + hidden_comment: '隐藏评语' + graduation_topic: + name: '选题名称' + description: '选题简介' + graduation_task: + name: '任务标题' + description: '内容' + graduation_work: + description: '作品内容' + graduation_work_score: + comment: '评语' + poll: + polls_name: '问卷标题' + polls_description: '问卷须知' + poll_question: + question_title: '题干' + poll_answer: + answer_text: '选项' + poll_vote: + vote_text: '内容' + exercise: + exercise_name: '试卷标题' + exercise_description: '试卷须知' + exercise_question: + question_title: '题干' + exercise_choice: + choice_text: '选项' + exercise_answer: + answer_text: '答案' + exercise_standard_answer: + answer_text: '参考答案' + exercise_answer_comment: + comment: '评语' + homework_bank: + name: '标题' + description: '内容' + reference_answer: '参考答案' + gtask_bank: + name: '任务标题' + description: '内容' + gtopic_bank: + name: '选题名称' + description: '选题简介' + exercise_bank: + name: '试卷标题' + description: '试卷须知' + exercise_bank_question: + question_title: '题干' + exerise_bank_choice: + choice_text: '选项' + exercise_bank_standard_answer: + answer_text: '参考答案' + library: + title: '标题' + content: '内容' + author_name: '作者姓名' + author_school_name: '作者单位名称' + competition: + introduction: '简介' + competition_module_md_content: + content: '内容' + chart_rule: + content: '内容' + project_package: + title: '标题' + examination_bank: + name: '试卷名称' + item_bank: + name: '题干' + item_analysis: + analysis: '解析' + item_choice: + choice_text: '选项' + hack: + name: '任务名称' + description: '描述' + hack_set: + input: '测试集输入' + output: '测试集输出' + hack_user_lastest_code: + notes: '笔记' + trustie_hack: + description: '描述' + + + diff --git a/config/routes.rb b/config/routes.rb index 5a7b641f6..8546185da 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -80,6 +80,7 @@ Rails.application.routes.draw do resources :examination_banks do member do post :set_public + delete :revoke_item end end @@ -95,6 +96,18 @@ Rails.application.routes.draw do end end + resources :examination_intelligent_settings do + collection do + post :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 @@ -394,7 +407,7 @@ Rails.application.routes.draw do get 'cancel_publish' get 'cancel_has_publish' get 'statistics' - get 'statistics_new' + get 'statistics_info' get 'shixun_report' get 'school_report' post 'update_attr' 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/db/migrate/20200109062658_create_subject_records.rb b/db/migrate/20200109062658_create_subject_records.rb index 97741fd8c..b990b8bdc 100644 --- a/db/migrate/20200109062658_create_subject_records.rb +++ b/db/migrate/20200109062658_create_subject_records.rb @@ -1,7 +1,7 @@ class CreateSubjectRecords < ActiveRecord::Migration[5.2] def change create_table :subject_records do |t| - t.references :subject, unique: true + t.references :subject t.integer :study_count, default: 0 t.integer :course_study_count, default: 0 t.integer :initiative_study, default: 0 diff --git a/db/migrate/20200111024736_add_index_for_subject_records.rb b/db/migrate/20200111024736_add_index_for_subject_records.rb new file mode 100644 index 000000000..e196c407f --- /dev/null +++ b/db/migrate/20200111024736_add_index_for_subject_records.rb @@ -0,0 +1,6 @@ +class AddIndexForSubjectRecords < ActiveRecord::Migration[5.2] + def change + # remove_index :subject_records, :subject_id + add_index :subject_records, :subject_id, unique: true + end +end diff --git a/db/migrate/20200112030419_migrate_3176_exercise_score.rb b/db/migrate/20200112030419_migrate_3176_exercise_score.rb new file mode 100644 index 000000000..e96931f79 --- /dev/null +++ b/db/migrate/20200112030419_migrate_3176_exercise_score.rb @@ -0,0 +1,50 @@ +class Migrate3176ExerciseScore < ActiveRecord::Migration[5.2] + + def calculate_student_score(exercise,user) + score5 = 0.0 #实训题 + exercise_end_time = exercise.end_time + exercise_questions = exercise.exercise_questions.includes(:exercise_standard_answers,:exercise_shixun_challenges) + exercise_questions.each do |q| + if q.question_type == 5 + q.exercise_shixun_challenges.each do |exercise_cha| + game = Game.user_games(user.id,exercise_cha.challenge_id)&.first #当前用户的关卡 + if game.present? + exercise_cha_score = 0.0 + answer_status = 0 + # if game.status == 2 && game.final_score >= 0 + if game.final_score > 0 && (game.end_time.nil? || game.end_time < exercise_end_time) + exercise_cha_score = game.real_score(exercise_cha.question_score) + # exercise_cha_score = exercise_cha.question_score #每一关卡的得分 + answer_status = 1 + end + ex_shixun_answer_content = exercise_cha.exercise_shixun_answers.find_by(user_id:user.id,exercise_question_id:q.id) + if ex_shixun_answer_content.present? && !(ex_shixun_answer_content.score >0) #把关卡的答案存入试卷的实训里 + ex_shixun_answer_content.update_attributes!(score:exercise_cha_score.round(1),status:answer_status) + end + score5 += exercise_cha_score + else + score5 += 0.0 + end + end + end + end + score5 + end + + def change + exercise = Exercise.find_by(id: 3176) + if exercise + exercise_users = exercise.exercise_users.where("start_at is not null") + exercise_users.each do |exercise_user| + calculate_score = calculate_student_score(exercise, exercise_user.user) + subjective_score = exercise_user.subjective_score + total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score + total_score = calculate_score + total_score_subjective_score + if exercise_user.end_at.present? + exercise_user.update_attributes!(score:total_score,objective_score:calculate_score) + end + puts exercise_user.id + end + end + end +end diff --git a/db/migrate/20200112035304_migrate_3517_exercise_score.rb b/db/migrate/20200112035304_migrate_3517_exercise_score.rb new file mode 100644 index 000000000..821b2bbd8 --- /dev/null +++ b/db/migrate/20200112035304_migrate_3517_exercise_score.rb @@ -0,0 +1,49 @@ +class Migrate3517ExerciseScore < ActiveRecord::Migration[5.2] + def calculate_student_score(exercise,user) + score5 = 0.0 #实训题 + exercise_end_time = exercise.end_time + exercise_questions = exercise.exercise_questions.includes(:exercise_standard_answers,:exercise_shixun_challenges) + exercise_questions.each do |q| + if q.question_type == 5 + q.exercise_shixun_challenges.each do |exercise_cha| + game = Game.user_games(user.id,exercise_cha.challenge_id)&.first #当前用户的关卡 + if game.present? + exercise_cha_score = 0.0 + answer_status = 0 + # if game.status == 2 && game.final_score >= 0 + if game.final_score > 0 && (game.end_time.nil? || game.end_time < exercise_end_time) + exercise_cha_score = game.real_score(exercise_cha.question_score) + # exercise_cha_score = exercise_cha.question_score #每一关卡的得分 + answer_status = 1 + end + ex_shixun_answer_content = exercise_cha.exercise_shixun_answers.find_by(user_id:user.id,exercise_question_id:q.id) + if ex_shixun_answer_content.present? && !(ex_shixun_answer_content.score >0) #把关卡的答案存入试卷的实训里 + ex_shixun_answer_content.update_attributes!(score:exercise_cha_score.round(1),status:answer_status) + end + score5 += exercise_cha_score + else + score5 += 0.0 + end + end + end + end + score5 + end + + def change + exercise = Exercise.find_by(id: 3517) + if exercise + exercise_users = exercise.exercise_users.where("start_at is not null") + exercise_users.each do |exercise_user| + calculate_score = calculate_student_score(exercise, exercise_user.user) + subjective_score = exercise_user.subjective_score + total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score + total_score = calculate_score + total_score_subjective_score + if exercise_user.end_at.present? + exercise_user.update_attributes!(score:total_score,objective_score:calculate_score) + end + puts exercise_user.id + end + end + end +end diff --git a/lib/tasks/statistic_subject_info.rake b/lib/tasks/statistic_subject_info.rake index 6373d7170..0385e3b5a 100644 --- a/lib/tasks/statistic_subject_info.rake +++ b/lib/tasks/statistic_subject_info.rake @@ -5,26 +5,35 @@ namespace :subjects do puts("---------------------data_statistic_begin") Rails.logger.info("---------------------data_statistic_begin") subjects = Subject.where(status: 2) + str = "" + buffer_size = 0 + column_value = "subject_id, study_count, course_study_count, initiative_study, passed_count, course_used_count, " + + "school_used_count, created_at, updated_at" subjects.find_each do |subject| puts("---------------------data_statistic: #{subject.id}") Rails.logger.info("---------------------data_statistic: #{subject.id}") - sr = SubjectRecord.find_or_create_by!(subject_id: subject.id) data = Subjects::DataStatisticService.new(subject) study_count = data.study_count - # 总人数没有变化的话,不同课堂之类的变化了 - course_study_count = (study_count == sr.study_count ? sr.course_study_count : data.course_study_count) - passed_count = (study_count == sr.study_count ? sr.passed_count : data.passed_count) - course_used_count = (study_count == sr.study_count ? sr.course_used_count : data.course_used_count) - school_used_count = (study_count == sr.study_count ? sr.school_used_count : data.school_used_count) - update_params = { - study_count: study_count, - course_study_count: course_study_count, - initiative_study: (study_count - course_study_count), - passed_count: passed_count, - course_used_count: course_used_count, - school_used_count: school_used_count - } - sr.update_attributes!(update_params) + next if study_count == 0 + course_study_count = data.course_study_count + initiative_study = study_count - course_study_count + str += ", " unless str.empty? + str += ("(#{subject.id}, #{study_count}, #{course_study_count}, #{initiative_study}, " + + "#{data.passed_count}, #{data.course_used_count}, #{data.school_used_count}, " + + "'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')") + buffer_size += 1 + if buffer_size == 1000 + sql = "REPLACE INTO subject_records(#{column_value}) VALUES #{str}" + puts sql + ActiveRecord::Base.connection.execute sql + str = "" + buffer_size = 0 + end + end + if buffer_size > 0 + sql = "REPLACE INTO subject_records(#{column_value}) VALUES #{str}" + puts sql + ActiveRecord::Base.connection.execute sql end puts("---------------------data_statistic_end") Rails.logger.info("---------------------data_statistic_end") @@ -34,22 +43,35 @@ namespace :subjects do puts("---------------------course_info_statistic_begin") Rails.logger.info("---------------------course_info_statistic_begin") subjects = Subject.where(status: 2) + str = "" + buffer_size = 0 + column_value = "subject_id, school_id, school_name, course_count, student_count, choice_shixun_num, " + + "choice_shixun_frequency, created_at, updated_at" subjects.find_each do |subject| puts("---------------------course_info_statistic: #{subject.id}") Rails.logger.info("---------------------course_info_statistic: #{subject.id}") data = Subjects::CourseUsedInfoService.call(subject) data.each do |key| - scr = SubjectCourseRecord.find_or_create_by!(school_id: key[:school_id], subject_id: subject.id) - update_params = { - school_name: key[:school_name], - course_count: key[:course_count], - student_count: key[:student_count], - choice_shixun_num: key[:choice_shixun_num], - choice_shixun_frequency: key[:choice_shixun_frequency] - } - scr.update_attributes(update_params) + next if key[:school_id].nil? + str += ", " unless str.empty? + str += ("(#{subject.id}, #{key[:school_id]}, '#{key[:school_name]}', #{key[:course_count]}, " + + "#{key[:student_count]}, #{key[:choice_shixun_num]}, #{key[:choice_shixun_frequency]}, " + + "'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')") + buffer_size += 1 + if buffer_size == 1000 + sql = "REPLACE INTO subject_course_records(#{column_value}) VALUES #{str}" + puts sql + ActiveRecord::Base.connection.execute sql + str = "" + buffer_size = 0 + end end end + if buffer_size > 0 + sql = "REPLACE INTO subject_course_records(#{column_value}) VALUES #{str}" + puts sql + ActiveRecord::Base.connection.execute sql + end puts("---------------------course_info_statistic_end") Rails.logger.info("---------------------course_info_statistic_end") end @@ -58,26 +80,36 @@ namespace :subjects do puts("---------------------shixun_info_statistic_begin") Rails.logger.info("---------------------shixun_info_statistic_begin") subjects = Subject.where(status: 2) + str = "" + buffer_size = 0 + column_value = "subject_id, shixun_id, stage, shixun_name, challenge_count, course_count, " + + "school_count, used_count, passed_count, evaluate_count, passed_ave_time, created_at, updated_at" subjects.find_each(batch_size: 100) do |subject| puts("---------------------shixun_info_statistic: #{subject.id}") Rails.logger.info("---------------------shixun_info_statistic: #{subject.id}") data = Subjects::ShixunUsedInfoService.call(subject) data.each do |key| - ssi = SubjectShixunInfo.find_or_create_by!(shixun_id: key[:shixun_id], subject_id: subject.id) - update_params = { - stage: key[:stage], - shixun_name: key[:name], - challenge_count: key[:challenge_count], - course_count: key[:course_count], - school_count: key[:school_count], - used_count: key[:used_count], - passed_count: key[:passed_count], - evaluate_count: key[:evaluate_count], - passed_ave_time: key[:passed_ave_time] - } - ssi.update_attributes(update_params) + next if key[:shixun_id].nil? + str += ", " unless str.empty? + str += ("(#{subject.id}, #{key[:shixun_id]}, '#{key[:stage]}', '#{key[:name]}', #{key[:challenge_count]}, " + + "#{key[:course_count]}, #{key[:school_count]}, #{key[:used_count]}, #{key[:passed_count]}, " + + "#{key[:evaluate_count]}, #{key[:passed_ave_time]}, " + + "'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')") + buffer_size += 1 + if buffer_size == 1000 + sql = "REPLACE INTO subject_shixun_infos(#{column_value}) VALUES #{str}" + puts sql + ActiveRecord::Base.connection.execute sql + str = "" + buffer_size = 0 + end end end + if buffer_size > 0 + sql = "REPLACE INTO subject_shixun_infos(#{column_value}) VALUES #{str}" + puts sql + ActiveRecord::Base.connection.execute sql + end puts("---------------------shixun_info_statistic_end") Rails.logger.info("---------------------shixun_info_statistic_end") end @@ -86,22 +118,34 @@ namespace :subjects do puts("---------------------user_info_statistic_begin") Rails.logger.info("---------------------user_info_statistic_begin") subjects = Subject.where(status: 2) - subjects.find_each(batch_size: 100) do |subject| + str = "" + buffer_size = 0 + column_value = "user_id, subject_id, username, passed_myshixun_count, passed_games_count, " + + "code_line_count, evaluate_count, cost_time, created_at, updated_at" + subjects.find_each(batch_size: 50) do |subject| puts("---------------------user_info_statistic: #{subject.id}") data = Subjects::UserUsedInfoService.call(subject) data.each do |key| - sui = SubjectUserInfo.find_or_create_by!(user_id: key[:user_id], subject_id: subject.id) - update_params = { - username: key[:name], - passed_myshixun_count: key[:passed_myshixun_count], - passed_games_count: key[:passed_games_count], - code_line_count: key[:code_line_count], - evaluate_count: key[:evaluate_count], - cost_time: key[:cost_time] - } - sui.update_attributes(update_params) + next if key[:user_id].nil? + str += ", " unless str.empty? + str += ("(#{key[:user_id]}, #{subject.id}, '#{key[:name]}', '#{key[:passed_myshixun_count]}', " + + "#{key[:passed_games_count]}, #{key[:code_line_count]}, #{key[:evaluate_count]}, #{key[:cost_time]}, " + + "'#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')") + buffer_size += 1 + if buffer_size == 1000 + sql = "REPLACE INTO subject_user_infos(#{column_value}) VALUES #{str}" + puts sql + ActiveRecord::Base.connection.execute sql + str = "" + buffer_size = 0 + end end end + if buffer_size > 0 + sql = "REPLACE INTO subject_user_infos(#{column_value}) VALUES #{str}" + puts sql + ActiveRecord::Base.connection.execute sql + end puts("---------------------user_info_statistic_end") Rails.logger.info("---------------------user_info_statistic_end") end diff --git a/lib/tasks/sync_trustie_program_question.rake b/lib/tasks/sync_trustie_program_question.rake new file mode 100644 index 000000000..cd214e438 --- /dev/null +++ b/lib/tasks/sync_trustie_program_question.rake @@ -0,0 +1,70 @@ +desc "同步trustie的编程作业" + +namespace :sync_program do + DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) + task data: :environment do + ProgramBank.where(homework_type: 2).each do |program| + unless Hack.where(name: program.name).exists? + strip_des = strip_html(program.description, 5000) + description = strip_des.present? ? strip_des : program.name + hack_params = {name: program.name[0..59], description: description, difficult: 1, open_or_not: 1, score: 200, status:0, time_limit: 3, sub_discipline_id: program.oj_sub_discipline_id} + puts "language::::#{program.language}" + puts "program_bank::::#{program.id}" + hack = Hack.new(hack_params) + hack.user_id = 1 + hack.identifier = generate_identifier Hack, 8 + ActiveRecord::Base.transaction do + hack.save! + # 创建测试集与代码 + position = 1 + ProgramBankTest.where(homework_bank_id: program.id).each do |test_set| + if !test_set.input.blank? && !test_set.output.blank? && !hack.hack_sets.where(input: test_set.input).exists? && test_set.input.length <= 1000 && test_set.output.length <= 1000 + hack.hack_sets.create!(input: test_set.input, output: test_set.output, position: position) + position += 1 + end + end + # 新建知识点 + hack_code_params = {code: program.standard_code.blank? ? nil : Base64.encode64(program.standard_code), language: program.oj_language} + hack_codes = hack.hack_codes.new(hack_code_params) + hack_codes.modify_time = Time.now + hack_codes.save! + new_item_params = {name: program.name, sub_discipline_id: program.oj_sub_discipline_id, container: hack, item_type: 'PROGRAM', public: 0, difficulty: 1, user_id: 1} + ItemBank.create!(new_item_params) + end + puts hack.id + end + end + end + + # 随机生成字符 + def generate_identifier(container, num) + code = DCODES.sample(num).join + if container == User + while container.exists?(login: code) do + code = DCODES.sample(num).join + end + else + while container.exists?(identifier: code) do + code = DCODES.sample(num).join + end + end + code + end + + def strip_html(text, len=0, endss="...") + ss = "" + if !text.nil? && text.length>0 + ss=text.gsub(/<\/?.*?>/, '').strip + ss = ss.gsub(/ */, '') + ss = ss.gsub(/\r\n/,'') #新增 + ss = ss.gsub(/\n/,'') #新增 + if len > 0 && ss.length > len + ss = ss[0, len-4] + endss + elsif len > 0 && ss.length <= len + ss = ss + #ss = truncate(ss, :length => len) + end + end + ss + end +end \ No newline at end of file diff --git a/public/images/educoder/xcx/Professional.png b/public/images/educoder/xcx/Professional.png new file mode 100644 index 000000000..8273d9e79 Binary files /dev/null and b/public/images/educoder/xcx/Professional.png differ diff --git a/public/images/educoder/xcx/SMIDCard.png b/public/images/educoder/xcx/SMIDCard.png new file mode 100644 index 000000000..cea96596d Binary files /dev/null and b/public/images/educoder/xcx/SMIDCard.png differ diff --git a/public/images/educoder/xcx/Student.png b/public/images/educoder/xcx/Student.png new file mode 100644 index 000000000..f508bd000 Binary files /dev/null and b/public/images/educoder/xcx/Student.png differ diff --git a/public/images/educoder/xcx/Teacher.png b/public/images/educoder/xcx/Teacher.png new file mode 100644 index 000000000..a3385ffd4 Binary files /dev/null and b/public/images/educoder/xcx/Teacher.png differ diff --git a/public/images/educoder/xcx/ZYIDCard.png b/public/images/educoder/xcx/ZYIDCard.png new file mode 100644 index 000000000..7f2085fce Binary files /dev/null and b/public/images/educoder/xcx/ZYIDCard.png differ diff --git a/public/images/educoder/xcx/weixinhome.png b/public/images/educoder/xcx/weixinhome.png new file mode 100644 index 000000000..0ba56d1b6 Binary files /dev/null and b/public/images/educoder/xcx/weixinhome.png differ diff --git a/public/react/public/css/css_min_all.css b/public/react/public/css/css_min_all.css index 431a4da8e..93b1c7f96 100755 --- a/public/react/public/css/css_min_all.css +++ b/public/react/public/css/css_min_all.css @@ -1269,7 +1269,7 @@ input.knowledge_frame{height:28px;line-height:28px;border:none;background:#f3f5f .-relative { position: relative;} .-bg-white { background-color: #eee;} .split-panel.-handle .split-panel--second { padding-left: 2px;} -.split-panel--second { overflow: hidden;} +/* .split-panel--second { overflow: hidden;} */ .task-answer-view { position: absolute; top: 0; right: 0; bottom: 0;left: 0; display: flex; flex-direction: column; border-top: 1px solid #515151;} .-vertical { flex-direction: column;box-flex-direction: column;-webkit-flex-direction: column;} diff --git a/public/react/public/css/taskstyle.css b/public/react/public/css/taskstyle.css index 29358d6e0..85960fa8b 100755 --- a/public/react/public/css/taskstyle.css +++ b/public/react/public/css/taskstyle.css @@ -145,7 +145,7 @@ input.knowledge_frame{height:28px;line-height:28px;border:none;background:#f3f5f .-relative { position: relative;} .-bg-white { background-color: #eee;} .split-panel.-handle .split-panel--second { padding-left: 2px;} -.split-panel--second { overflow: hidden;} +/* .split-panel--second { overflow: hidden;} */ .task-answer-view { position: absolute; top: 0; right: 0; bottom: 0;left: 0; display: flex; flex-direction: column; border-top: 1px solid #515151;} .-vertical { flex-direction: column;box-flex-direction: column;-webkit-flex-direction: column;} diff --git a/public/react/src/App.js b/public/react/src/App.js index ee986824a..247e7939b 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -334,7 +334,11 @@ const Paperreview= Loadable({ loading: Loading }) - +//智能组卷 +const Integeneration= Loadable({ + loader: () => import('./modules/testpaper/Intecomponents'), + loading: Loading +}) // 学院统计 const College = Loadable({ @@ -754,6 +758,7 @@ class App extends Component { } } /> + () @@ -764,7 +769,14 @@ class App extends Component { render={ (props) => () } /> - + () + }/> + () + }/> () @@ -774,6 +786,7 @@ class App extends Component { render={ (props) => () }/> + () @@ -795,9 +808,10 @@ class App extends Component { render={ (props) => () }/> - () + (props) => () }/> - + 30 }> - {item.title} + {item.title} {item.filesize}

diff --git a/public/react/src/common/educoder.js b/public/react/src/common/educoder.js index 9a19c6ee2..ded33c43a 100644 --- a/public/react/src/common/educoder.js +++ b/public/react/src/common/educoder.js @@ -3,22 +3,23 @@ // export { default as OrderStateUtil } from '../routes/Order/components/OrderStateUtil'; export { getImageUrl as getImageUrl, getRandomNumber as getRandomNumber,getUrl as getUrl, publicSearchs as publicSearchs,getRandomcode as getRandomcode,getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl - , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth - , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode } from './UrlTool'; + , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth + , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode ,getupload_git_file as getupload_git_file} from './UrlTool'; + export {setmiyah as setmiyah} from './Component'; export { default as queryString } from './UrlTool2'; export { SnackbarHOC as SnackbarHOC } from './SnackbarHOC'; export { trigger as trigger, on as on, off as off - , broadcastChannelPostMessage, broadcastChannelOnmessage } from './EventUtil'; + , broadcastChannelPostMessage, broadcastChannelOnmessage } from './EventUtil'; export { updatePageParams as updatePageParams } from './RouterUtil'; export { bytesToSize as bytesToSize } from './UnitUtil'; export { markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension, - downloadFile, sortDirections } from './TextUtil' + downloadFile, sortDirections } from './TextUtil' export { handleDateString, getNextHalfHourOfMoment,formatDuring } from './DateUtil' export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil' @@ -30,7 +31,7 @@ export { toStore as toStore, fromStore as fromStore } from './Store' export { trace_collapse, trace, debug, info, warn, error, trace_c, debug_c, info_c, warn_c, error_c } from './LogUtil' export { EDU_ADMIN, EDU_BUSINESS, EDU_SHIXUN_MANAGER, EDU_SHIXUN_MEMBER, EDU_CERTIFICATION_TEACHER - , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL} from './Const' + , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL} from './Const' export { default as AttachmentList } from './components/attachment/AttachmentList' 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/common/quillForEditor/index.js b/public/react/src/common/quillForEditor/index.js index 525feba09..d993905a0 100644 --- a/public/react/src/common/quillForEditor/index.js +++ b/public/react/src/common/quillForEditor/index.js @@ -1,10 +1,10 @@ /* * @Description: quill 编辑器 * @Author: tangjiang - * @Github: + * @Github: * @Date: 2019-12-18 08:49:30 * @LastEditors : tangjiang - * @LastEditTime : 2020-01-10 15:05:27 + * @LastEditTime : 2020-01-11 13:43:31 */ import './index.scss'; import 'quill/dist/quill.core.css'; // 核心样式 @@ -18,7 +18,7 @@ import deepEqual from './deepEqual.js' import { fetchUploadImage } from '../../services/ojService.js'; import { getImageUrl } from 'educoder' import ImageBlot from './ImageBlot'; -import FillBlot from './FillBlot'; +// import FillBlot from './FillBlot'; const Size = Quill.import('attributors/style/size'); const Font = Quill.import('formats/font'); // const Color = Quill.import('attributes/style/color'); @@ -31,9 +31,9 @@ Quill.register(ImageBlot); Quill.register(Size); Quill.register(Font, true); // Quill.register({'modules/toolbar': Toolbar}); -Quill.register({ - 'formats/fill': FillBlot -}); +// Quill.register({ +// 'formats/fill': FillBlot +// }); // Quill.register(Color); @@ -57,7 +57,7 @@ function QuillForEditor ({ {size: ['12px', '14px', '16px', '18px', '20px']}, {align: []}, {list: 'ordered'}, {list: 'bullet'}, // 列表 {script: 'sub'}, {script: 'super'}, - { 'color': [] }, { 'background': [] }, + { 'color': [] }, { 'background': [] }, {header: [1,2,3,4,5,false]}, 'blockquote', 'code-block', 'link', 'image', 'video', @@ -67,7 +67,7 @@ function QuillForEditor ({ const editorRef = useRef(null); // quill 实例 - const [quill, setQuill] = useState(null); + const [quill, setQuill] = useState(null); const [selection, setSelection] = useState(null); const [fillCount, setFillCount] = useState(0); const [quillCtx, setQuillCtx] = useState({}); @@ -77,7 +77,7 @@ function QuillForEditor ({ // getQuillContent && getQuillContent(quill); onContentChange && onContentChange(content, quill); }; - + const renderOptions = options || defaultConfig; const bindings = { @@ -87,23 +87,17 @@ function QuillForEditor ({ console.log('调用了tab=====>>>>'); } }, - enter: { - key: 'Enter', - handler: function () { - console.log('enter====>>>>>>'); - } - }, backspace: { key: 'Backspace', /** - * @param {*} range + * @param {*} range * { index, // 删除元素的位置 * length // 删除元素的个数, 当删除一个时, length=0, 其它等于删除的元素的个数 - * } + * } * @param {*} context 上下文 */ handler: function (range, context) { - console.log('调用了删除按钮', range, context); + // console.log('调用了删除按钮', range, context); /** * 1. 根据range中的index及length值获取删除的起始位置 * length === 0 -> start = index - 1; @@ -112,13 +106,13 @@ function QuillForEditor ({ * ctx = this.quill.getText(start, length === 0 ? 1 : length); * 3. 判断当前删除的下划线是第几个 */ - const {index, length} = range; - const _start = length === 0 ? index - 1 : index; - const _length = length || 1; - let delCtx = this.quill.getText(_start, _length); + // const {index, length} = range; + // const _start = length === 0 ? index - 1 : index; + // const _length = length || 1; + // let delCtx = this.quill.getText(_start, _length); // aa - console.log(delCtx.match(/▁/g)); - console.log('删除的文本信息=====>>>>', delCtx); + // console.log(delCtx.match(/▁/g)); + // console.log('删除的文本信息=====>>>>', delCtx); // const r = window.confirm('确定要删除吗?') // if (r) { // // 调用传入的删除事件 @@ -126,7 +120,7 @@ function QuillForEditor ({ // } else { // return false; // } - return true; + return true; } } }; @@ -153,12 +147,6 @@ function QuillForEditor ({ editorRef.current.appendChild(quillNode); const _quill = new Quill(editorRef.current, quillOption); - // _quill.keyboard.addBinding({ - // key: 'tab' - // }, function (range, context) { - // console.log('点击了键盘的删除按钮: ', range, context); - // }); - setQuill(_quill); // 处理图片上传功能 _quill.getModule('toolbar').addHandler('image', (e) => { @@ -190,7 +178,7 @@ function QuillForEditor ({ onClick: showUploadImage, width, height - }); + }); } } }); @@ -208,19 +196,19 @@ function QuillForEditor ({ // 1. 获取编辑器内容 }); - // TODO + // TODO /** * 1.获取键盘删除事件 * 2.点击时获取删除的叶子节点 getLeaf(range.index) */ }, []); - - // 设置值 + + // 设置值 useEffect(() => { if (!quill) return const previous = quill.getContents() - + if (value && value.hasOwnProperty('ops')) { // console.log(value.ops); const ops = value.ops || []; @@ -234,7 +222,8 @@ function QuillForEditor ({ const current = value if (!deepEqual(previous, current)) { setSelection(quill.getSelection()) - if (typeof value === 'string') { + if (typeof value === 'string' && value) { + // debugger quill.clipboard.dangerouslyPasteHTML(value, 'api'); if (autoFocus) { quill.focus(); @@ -268,7 +257,7 @@ function QuillForEditor ({ if (typeof handleOnChange !== 'function') return; let handler; quill.on( - 'text-change', + 'text-change', (handler = (delta, oldDelta, source) => { const _ctx = quill.getContents(); setQuillCtx(_ctx); diff --git a/public/react/src/context/TPIContextProvider.js b/public/react/src/context/TPIContextProvider.js index ed7eb2210..bb1e0bef4 100644 --- a/public/react/src/context/TPIContextProvider.js +++ b/public/react/src/context/TPIContextProvider.js @@ -32,7 +32,7 @@ import _ from 'lodash' import TPIContext from './TPIContext' import { EDU_ADMIN, EDU_SHIXUN_MANAGER, EDU_SHIXUN_MEMBER, EDU_CERTIFICATION_TEACHER - , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL, EDU_BUSINESS, CNotificationHOC } from 'educoder' + , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL, EDU_BUSINESS, CNotificationHOC ,getRandomNumber} from 'educoder' import { MuiThemeProvider, createMuiTheme, withStyles } from 'material-ui/styles'; import MUIDialogStyleUtil from '../modules/page/component/MUIDialogStyleUtil' @@ -176,7 +176,7 @@ class TPIContextProvider extends Component { testPath = 'http://test-newweb.educoder.net' } // var url = `${testPath}/api/v1/games/${ game.identifier }/cost_time` - var url = `${testPath}/api/tasks/${ game.identifier }/cost_time` + var url = `${testPath}/api/tasks/${ game.identifier }/cost_time${getRandomNumber()}` window.$.ajax({ type: 'get', url: url, diff --git a/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentsChart.js b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentsChart.js index 420f83ff1..594eb3c5c 100644 --- a/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentsChart.js +++ b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentsChart.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import {Button,Layout,Tabs,Icon, Card, Avatar, Row, Col ,Table,Badge} from 'antd'; -import {markdownToHTML,getImageUrl} from 'educoder'; +import {markdownToHTML,getImageUrl,getRandomNumber} from 'educoder'; import axios from 'axios'; const { Content } = Layout; @@ -69,7 +69,7 @@ class CompetitionContents extends Component{ const operations = const columns = [ diff --git a/public/react/src/modules/courses/boards/TopicDetail.js b/public/react/src/modules/courses/boards/TopicDetail.js index e8767fb87..f4df177c7 100644 --- a/public/react/src/modules/courses/boards/TopicDetail.js +++ b/public/react/src/modules/courses/boards/TopicDetail.js @@ -682,6 +682,7 @@ class TopicDetail extends Component { {!isCourseEnd && } {/* onClick={ this.createNewComment } diff --git a/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js b/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js index 5c55f8894..ab3718b1d 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js @@ -1,10 +1,10 @@ import React, { Component } from 'react'; -import { SnackbarHOC } from 'educoder'; +import { getRandomNumber } from 'educoder'; import {Link} from 'react-router-dom'; import {BrowserRouter as Router,Route,Switch} from 'react-router-dom'; import Loadable from 'react-loadable'; import Loading from '../../../Loading'; -import { WordsBtn, MarkdownToHtml, trigger, queryString, downloadFile } from 'educoder'; +import { WordsBtn, MarkdownToHtml, trigger, queryString, getRandomcode } from 'educoder'; import axios from 'axios'; import CoursesListType from '../coursesPublic/CoursesListType'; import AccessoryModal from "../coursesPublic/AccessoryModal"; @@ -125,7 +125,7 @@ class CommonWorkDetailIndex extends Component{ }) } }else { - this.props.slowDownload(url) + this.props.slowDownload(getRandomcode(url)) // this.props.showNotification(`正在下载中`); // this.setState({ donwloading: true }) @@ -206,7 +206,7 @@ class CommonWorkDetailIndex extends Component{ } const isAdmin = this.props.isAdmin() - + let exportParams = {} const isListModule = childModuleName == '作品列表'; // 是列表页 @@ -221,10 +221,10 @@ class CommonWorkDetailIndex extends Component{ // console.log(params); let exportUrl = `/homework_commons/${workId}/works_list.zip?${queryString.stringify(params)}` let exportResultUrl = `/homework_commons/${workId}/works_list.xlsx?${queryString.stringify(params)}` - document.title=course_name === undefined ? "" : course_name; + document.title=course_name === undefined ? "" : course_name; return (
- @@ -234,8 +234,8 @@ class CommonWorkDetailIndex extends Component{ modalCancel={this.Downloadcal} modalsType={this.state.DownloadType} /> - +
@@ -266,7 +266,7 @@ class CommonWorkDetailIndex extends Component{ typelist={homework_status} typesylename={"mt12"} /> - + {category && 返回} @@ -293,24 +293,24 @@ class CommonWorkDetailIndex extends Component{ { noTab !== true &&
- this.setState({moduleName: '作品列表'})} className={`${isListModule ? 'active' : '' } `} to={`/courses/${courseId}/${moduleEngName}/${workId}/list`}>作品列表 - this.setState({moduleName: '作业描述'})} className={`${childModuleName == '作业描述' ? 'active' : '' } `} to={`/courses/${courseId}/${moduleEngName}/${workId}/question`}>作业描述 - {view_answer == true && this.setState({moduleName: '参考答案'})} - className={`${childModuleName == '参考答案' ? 'active' : '' } `} + className={`${childModuleName == '参考答案' ? 'active' : '' } `} to={`/courses/${courseId}/${moduleEngName}/${workId}/answer`}>参考答案} this.setState({moduleName: '设置'})} className={`${childModuleName == '设置' ? 'active' : '' } `} style={{paddingLeft:this.props.isAdmin()?'38px':'20px'}} to={`/courses/${courseId}/${moduleEngName}/${workId}/setting`}>{this.props.isAdmin()?"设置":"得分规则"} - + {/* { this.props.tabRightComponents } */} @@ -365,16 +365,16 @@ class CommonWorkDetailIndex extends Component{ {isAdmin && this.props.toEditPage(this.props.match.params, workId)}>编辑作业} { // - work_statuses && work_statuses.indexOf('关联项目') != -1 && + work_statuses && work_statuses.indexOf('关联项目') != -1 && this.openConnectionProject({ homework_id: workId })}>关联项目 this.props.toCreateProject()}>创建项目 } - + { // - work_statuses && work_statuses.indexOf('取消关联') != -1 && + work_statuses && work_statuses.indexOf('取消关联') != -1 && this.cancelConnectionProject( {homework_id: workId} )}>取消关联 } @@ -390,7 +390,7 @@ class CommonWorkDetailIndex extends Component{ {work_statuses && work_statuses.indexOf('修改作品') != -1 && { this.props.toWorkPostPage(this.props.match.params, null, true, work_id)}} >修改作品} - {work_statuses && work_statuses.indexOf('补交附件') != -1 && + {work_statuses && work_statuses.indexOf('补交附件') != -1 && 补交附件 - + } @@ -415,7 +415,7 @@ class CommonWorkDetailIndex extends Component{ {/* 内容区 */} - + {/* --------------------------------------------------------------------- */} {/* 作业设置 */} @@ -474,7 +474,7 @@ class CommonWorkDetailIndex extends Component{
- + ) } } diff --git a/public/react/src/modules/courses/busyWork/CommonWorkSetting.js b/public/react/src/modules/courses/busyWork/CommonWorkSetting.js index 30c418eef..8a8ee0ace 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkSetting.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkSetting.js @@ -978,10 +978,8 @@ class CommonWorkSetting extends Component{ let exportUrl = `/api/homework_commons/${workId}/works_list.zip` const exportResultUrl = `/api/homework_commons/${workId}/works_list.xlsx` const noAuth = !isAdmin || !startEditFlag; - return( - - + return( 启用匿评 - (作品数量≥2个,可以开启匿评) + {this.state.category&&this.state.category.category_name==="普通作业"?"(作品数量≥2个,可以开启匿评)":"(提交作品的分组数量≥2个,可以开启匿评)"}
{/* 开启时间 */}
diff --git a/public/react/src/modules/courses/busyWork/common/TabRightComponents.js b/public/react/src/modules/courses/busyWork/common/TabRightComponents.js index 41e03d176..ad26e8ca6 100644 --- a/public/react/src/modules/courses/busyWork/common/TabRightComponents.js +++ b/public/react/src/modules/courses/busyWork/common/TabRightComponents.js @@ -1,7 +1,7 @@ import React,{Component} from "react"; import { Form, Select, Input, Button,Checkbox,Icon,message,Modal, Table, Divider, Tag,DatePicker,Radio,Tooltip} from "antd"; import {Link} from 'react-router-dom'; -import { WordsBtn, MarkdownToHtml } from 'educoder'; +import { WordsBtn, getRandomcode } from 'educoder'; import axios from 'axios'; import PublishRightnow from '../PublishRightnow' import AccessoryModal from "../../coursesPublic/AccessoryModal"; @@ -44,7 +44,7 @@ class TabRightComponents extends Component{ } /// 确认是否下载 confirmysl(url){ - axios.get(url + '?export=true' ).then((response) => { + axios.get(url + '&export=true' ).then((response) => { if(response.data.status&&response.data.status===-1){ }else if(response.data.status&&response.data.status===-2){ @@ -63,7 +63,7 @@ class TabRightComponents extends Component{ }) } }else { - this.props.slowDownload(url); + this.props.slowDownload(getRandomcode(url)); // this.props.showNotification(`正在下载中`); // window.open("/api"+url, '_blank'); } @@ -108,9 +108,8 @@ class TabRightComponents extends Component{ const isAdmin = this.props.isAdmin() const isSuperAdmin = this.props.isSuperAdmin() - let exportUrl = `/api/homework_commons/${workId}/works_list.zip` - const exportResultUrl = `/api/homework_commons/${workId}/works_list.xlsx` - + let exportUrls = `/api/homework_commons/${workId}/works_list.zip` + const exportResultUrls = `/api/homework_commons/${workId}/works_list.xlsx` return( {isAdmin ? @@ -150,8 +149,8 @@ class TabRightComponents extends Component{ {this.props.isAdmin()?
  • 导出
  • :""} diff --git a/public/react/src/modules/courses/common/comments/CommonReply.js b/public/react/src/modules/courses/common/comments/CommonReply.js index 42ec3d65a..50f2b60cb 100644 --- a/public/react/src/modules/courses/common/comments/CommonReply.js +++ b/public/react/src/modules/courses/common/comments/CommonReply.js @@ -252,6 +252,7 @@ class CommonReply extends Component{ {/* bor-bottom-greyE */} diff --git a/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentsChart.js b/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentsChart.js index 420f83ff1..594eb3c5c 100644 --- a/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentsChart.js +++ b/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentsChart.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import {Button,Layout,Tabs,Icon, Card, Avatar, Row, Col ,Table,Badge} from 'antd'; -import {markdownToHTML,getImageUrl} from 'educoder'; +import {markdownToHTML,getImageUrl,getRandomNumber} from 'educoder'; import axios from 'axios'; const { Content } = Layout; @@ -69,7 +69,7 @@ class CompetitionContents extends Component{ const operations = const columns = [ diff --git a/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js b/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js index c37b45c84..ba8fe27b0 100644 --- a/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js +++ b/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js @@ -549,6 +549,10 @@ class Coursesleftnav extends Component{ window.location.href=`/courses/${coursesId}/boards/${result.data.category_id}`; } + if(positiontype!="course_groups"){ + this.updasaveNavmoda() + } + if(positiontype==="course_groups"){ window.location.href=`/courses/${coursesId}/course_groups/${result.data.group_id}`; } diff --git a/public/react/src/modules/courses/exercise/Testpapersettinghomepage.js b/public/react/src/modules/courses/exercise/Testpapersettinghomepage.js index 63bdbd170..ff60b553f 100644 --- a/public/react/src/modules/courses/exercise/Testpapersettinghomepage.js +++ b/public/react/src/modules/courses/exercise/Testpapersettinghomepage.js @@ -1,7 +1,7 @@ import React,{ Component } from "react"; import {Checkbox,Input,Table, Pagination,Menu,Spin} from "antd"; import {Link,NavLink} from 'react-router-dom'; -import { WordsBtn ,ActionBtn,queryString,getRandomcode} from 'educoder'; +import { WordsBtn ,getRandomNumber,queryString,getRandomcode} from 'educoder'; import CoursesListType from '../coursesPublic/CoursesListType'; import '../css/members.css'; import '../css/busyWork.css'; @@ -175,9 +175,9 @@ class Testpapersettinghomepage extends Component{ if(child!=undefined){ params =child._getRequestParams()!==undefined?child._getRequestParams():{}; } - console.log("170"); - console.log(params); - const urll=url+`?${queryString.stringify(params)}`; + + const urll=url+`?${queryString.stringify(params)}`; + axios.get(urll+ '&export=true').then((response) => { if(response===undefined){ return @@ -200,7 +200,7 @@ class Testpapersettinghomepage extends Component{ }) } }else { - this.props.slowDownload(urll) + this.props.slowDownload(getRandomcode(urll)) // this.setState({ donwloading: true }) // downloadFile({ // url: urll, 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/courses/gradinforms/Bullsubdirectory.js b/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js index 8c5561b02..78f56a0f7 100644 --- a/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js +++ b/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js @@ -32,8 +32,8 @@ class Bullsubdirectory extends Component{ } componentDidMount() { - console.log("获取到数据"); - console.log(this.props); + // console.log("获取到数据"); + // console.log(this.props); let{id,myname,mydescription,index,item} =this.props this.props.form.setFieldsValue({ id:id, diff --git a/public/react/src/modules/courses/gradinforms/Eduinforms.js b/public/react/src/modules/courses/gradinforms/Eduinforms.js index 5acfeb4fe..b41c65944 100644 --- a/public/react/src/modules/courses/gradinforms/Eduinforms.js +++ b/public/react/src/modules/courses/gradinforms/Eduinforms.js @@ -30,8 +30,8 @@ class Eduinforms extends Component{ } componentDidMount() { - console.log("Eduinformss"); - console.log("获取到数据"); + // console.log("Eduinformss"); + // console.log("获取到数据"); // console.log(this.props); const query = this.props.location.search; // const type = query.split('?chinaoocTimestamp='); diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js index 3a4890ece..3330f9389 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import {getRandomNumber,queryString} from 'educoder'; +import {getRandomNumber} from 'educoder'; import {Link} from 'react-router-dom'; import {Tooltip,Menu} from 'antd'; import Loadable from 'react-loadable'; @@ -313,15 +313,18 @@ class GraduationTaskDetail extends Component{ } CodeReview=()=>{ + let newgetRandomNumber=getRandomNumber(true); + console.log(newgetRandomNumber) this.props.showNotification("正在导出中..."); + if(newgetRandomNumber){ const task_Id = this.props.match.params.task_Id; window.open(`/api/graduation_tasks/${task_Id}/sonar? - ${this.state.taskdatas.teacher_comment===undefined||this.state.taskdatas.teacher_comment===null?"":"teacher_comment="+this.state.taskdatas.teacher_comment} - ${this.state.taskdatas.task_status===undefined||this.state.taskdatas.task_status===null?"":"&task_status="+this.state.taskdatas.task_status} - ${this.state.taskdatas.course_group===undefined||this.state.taskdatas.course_group===null?"":"&course_group="+this.state.taskdatas.course_group} - ${this.state.taskdatas.cross_comment===undefined||this.state.taskdatas.cross_comment===null?"":"&cross_comment="+this.state.taskdatas.cross_comment} - ${this.state.taskdatas.search===undefined||this.state.taskdatas.search===null?"":"&search="+this.state.taskdatas.search+"&"}${getRandomNumber(true)}`) - + ${this.state.taskdatas.teacher_comment===undefined||this.state.taskdatas.teacher_comment===null?"":"teacher_comment="+this.state.taskdatas.teacher_comment+"&"} + ${this.state.taskdatas.task_status===undefined||this.state.taskdatas.task_status===null?"":"task_status="+this.state.taskdatas.task_status+"&"} + ${this.state.taskdatas.course_group===undefined||this.state.taskdatas.course_group===null?"":"course_group="+this.state.taskdatas.course_group+"&"} + ${this.state.taskdatas.cross_comment===undefined||this.state.taskdatas.cross_comment===null?"":"cross_comment="+this.state.taskdatas.cross_comment+"&"} + ${this.state.taskdatas.search===undefined||this.state.taskdatas.search===null?"":"search="+this.state.taskdatas.search+"&"}${newgetRandomNumber}`) + } } getsonars=(teacher_comment,task_status,course_group,cross_comment,search)=>{ @@ -519,8 +522,8 @@ class GraduationTaskDetail extends Component{ {this.props.isAdmin()?
  • 导出
  • :""} {questionslist.work_status===undefined||questionslist.work_status===null||questionslist.work_status.length===0?"":questionslist.work_status.map((item,key)=>{ diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js index 5494ba05f..1415414e4 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js @@ -7,7 +7,7 @@ import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor'; import { getUrl, getUploadActionUrl } from 'educoder' const $ = window.$; -/* +/* */ class GraduationTasksappraiseMainEditor extends Component{ @@ -20,22 +20,32 @@ class GraduationTasksappraiseMainEditor extends Component{ score: undefined, same_score: false, errorMessage: '', - numberErrorMessage: '' + numberErrorMessage: '', + errorMessagetype:false } } onSubmit = () => { const { score, same_score } = this.state - let category_id= this.props.match.params.category_id; - const url = `/graduation_works/${category_id}/add_score.json` + let category_id= this.props.match.params.category_id; + const url = `/graduation_works/${category_id}/add_score.json` const attachment_ids = this.state.fileList.map(item => { return item.response ? item.response.id : item.id }) const comment = this.mdRef.current.getValue() - if ((!comment || comment.trim() == "") && !score) { + if ((!comment || comment.trim() == "") && !score &&this.props.isAdmin()===true) { this.setState( {errorMessage : '分数和评语不能同时为空' }) // this.props.showNotification('请先输入评阅说明') return; } + if (!score && this.props.isAdmin()===false) { + this.setState( { + errorMessage : '分数不能为空', + errorMessagetype:true + }) + // this.props.showNotification('请先输入评阅说明') + return; + } + if (comment.length > 2000) { this.setState( {errorMessage : '不能超过2000个字符' }) // this.props.showNotification('评阅说明文本长度不能超过2000') @@ -63,12 +73,12 @@ class GraduationTasksappraiseMainEditor extends Component{ this.clearInputs() this.props.addSuccess(); } - + }).catch((error)=>{ console.log(error) }) } - + } clearInputs = () => { this.setState({ @@ -79,7 +89,7 @@ class GraduationTasksappraiseMainEditor extends Component{ this.mdRef.current.setValue('') } onCancel = () => { - this.clearInputs() + this.clearInputs() } componentDidMount(){ } @@ -119,7 +129,7 @@ class GraduationTasksappraiseMainEditor extends Component{ const { status } = response.data; if (status == 0) { console.log('--- success') - + this.setState((state) => { const index = state[stateName].indexOf(file); const newFileList = state[stateName].slice(); @@ -136,6 +146,12 @@ class GraduationTasksappraiseMainEditor extends Component{ }); } onScoreChange = (val) => { + if(val){ + this.setState( { + errorMessage: '', + errorMessagetype:false + }) + } if (val > 100 ) { this.props.showNotification('不能大于100') this.setState({ score: 100 }) @@ -157,7 +173,7 @@ class GraduationTasksappraiseMainEditor extends Component{ this.setState({ same_score: e.target.checked }) //!this.state.same_score } render(){ - let { total_count, comments, pageCount, fileList, score, same_score, errorMessage, numberErrorMessage } = this.state + let { total_count, comments, errorMessagetype, fileList, score, same_score, errorMessage, numberErrorMessage } = this.state const { current_user, memo, showSameScore, placeholder } = this.props const isAdmin = this.props.isAdmin() const commentUploadProp = { @@ -209,7 +225,7 @@ class GraduationTasksappraiseMainEditor extends Component{ `} {this.props.title && {this.props.title}} + watch={false} height={160} className={errorMessage&&errorMessagetype!=true ? 'editorInputError' : ''} imageExpand={true}> { showSameScore == true &&
    整组同评 (选中,则本次评阅对象指小组全部成员,否则仅评阅此成员1人 ) @@ -235,7 +251,7 @@ class GraduationTasksappraiseMainEditor extends Component{ 提交 - 清空
    diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js index f90ca57f1..f87ea475e 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js @@ -2,7 +2,7 @@ import React,{Component} from "react"; import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal, Table, Divider, Tag,DatePicker,Radio,Tooltip} from "antd"; import {Link} from 'react-router-dom'; import locale from 'antd/lib/date-picker/locale/zh_CN'; -import { WordsBtn,getUrl ,handleDateString} from 'educoder'; +import { WordsBtn,getRandomcode ,handleDateString} from 'educoder'; import axios from 'axios'; import Modals from '../../../modals/Modals'; import DownloadMessageysl from "../../../modals/DownloadMessageysl"; @@ -870,9 +870,8 @@ class GraduationTaskssettingapp extends Component{ } /// 确认是否下载 - confirmysl(url){ - debugger; - console.log(3); + confirmysl(url,urls){ + axios.get(url + '?export=true' ).then((response) => { if(response === undefined){ return @@ -895,8 +894,10 @@ class GraduationTaskssettingapp extends Component{ }) } }else { - this.props.slowDownload(url) + // this.props.showNotification(`正在下载中`); + this.props.slowDownload(getRandomcode(url)) + // window.open(getRandomcode("/api" + url), '_blank'); // this.props.showNotification(`正在下载中`); // window.open("/api"+url, '_blank'); } diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingReply.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingReply.js index 4281d0ec6..ce0554488 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingReply.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingReply.js @@ -18,7 +18,7 @@ import { generateComments, generateChildComments, _findById, handleContentBefore const REPLY_PAGE_COUNT = 10 const $ = window.$; -/* +/* 相比较GraduateTopicReply 改动的地方 列表接口名 /graduation_tasks/${graduation_topic_id}/show_comment.json?parent_id=${parent.id}&limit=500 回复类型名 jour_type: 'GraduationTask', @@ -34,7 +34,7 @@ class GraduationTaskssettingReply extends Component{ componentDidMount(){ this.fetchReplies() - + } _getUser() { const { current_user } = this.props; @@ -58,7 +58,7 @@ class GraduationTaskssettingReply extends Component{ // m_parent_id reply_id: memo.user_id } - } + } ).then((response) => { if (response.data.status === -1) { console.error('服务端异常') @@ -66,18 +66,18 @@ class GraduationTaskssettingReply extends Component{ } // this.props.showNotification('帖子发表成功') - if (response.data && response.data.id) { + if (response.data && response.data.id) { const _id = response.data.id; // md editor.setValue && editor.setValue('') - + const user = this._getUser(); this.setState({ comments: addNewComment(this.state.comments, _id, content, user, this.props.isSuperAdmin(), this), total_count: this.state.total_count + 1 }) this.refs.editor.showEditor(); - + } }).catch((error) => { console.log(error) @@ -95,13 +95,13 @@ class GraduationTaskssettingReply extends Component{ return; } const url = `/users/reply_message.json`; - + const { comments } = this.state; const user = this._getUser(); const graduation_topic_id = this.props.memo.id const commentIndex = this._findById(id, comments); let comment = comments[commentIndex]; - + commentContent = handleContentBeforeCreateSecondLevelComment(commentContent) axios.post(url, { journals_for_message: { @@ -113,9 +113,9 @@ class GraduationTaskssettingReply extends Component{ } }, { - } + } ).then((response) => { - if (response.data.id) { + if (response.data.id) { let newId = response.data.id; this.setState({ @@ -128,7 +128,7 @@ class GraduationTaskssettingReply extends Component{ memo: newMemo2 }) } - + }).catch((error) => { console.log(error) }) @@ -142,7 +142,7 @@ class GraduationTaskssettingReply extends Component{ }) .then((response) => { const { comments } = response.data - + // const memo = Object.assign({}, this.state.memo) // memo.sum_replies_count = sum_replies_count; @@ -160,7 +160,7 @@ class GraduationTaskssettingReply extends Component{ this.fetchReplies() }) } - + fetchReplies = () => { const graduation_topic_id = this.props.memo.id const course_id = this.props.course_id @@ -170,7 +170,7 @@ class GraduationTaskssettingReply extends Component{ }) .then((response) => { const { comments, messages_count } = response.data - + this.setState({ comments: generateComments(comments, this.transformReply), // : this.state.comments.concat(comments), @@ -180,7 +180,7 @@ class GraduationTaskssettingReply extends Component{ console.log(error) }) } - + transformReply = (reply, children = []) => { const isAdmin = this.props.isAdmin() const isSuperAdmin = this.props.isSuperAdmin() @@ -189,7 +189,7 @@ class GraduationTaskssettingReply extends Component{ isSuperAdmin: isSuperAdmin, permission: true, // children: children, - hidden: reply.hidden, + hidden: reply.hidden, id: reply.id, image_url: reply.author.image_url, reward: null, // @@ -235,7 +235,7 @@ class GraduationTaskssettingReply extends Component{ -
    - - - {/* { true ? : + + + {/* { true ? :
    写评论
    } */}
    - - { total_count > REPLY_PAGE_COUNT && + + { total_count > REPLY_PAGE_COUNT &&
    写评论
    diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js index c9ef0ec0d..e0ebdf245 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js @@ -1,7 +1,7 @@ import React,{Component} from "react"; import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal,Pagination, Table, Divider, Tag,Tooltip} from "antd"; import {Link} from 'react-router-dom'; -import {getImageUrl, NoneData, sortDirections} from 'educoder'; +import {getImageUrl, NoneData, sortDirections,getRandomcode} from 'educoder'; import axios from 'axios'; import moment from 'moment'; import HomeworkModal from "../../coursesPublic/HomeworkModal"; @@ -759,7 +759,7 @@ class GraduationTaskssettinglist extends Component{ }) } }else { - this.props.slowDownload(url) + this.props.slowDownload(getRandomcode(url)) // this.props.showNotification(`正在下载中`); // window.open("/api"+url, '_blank'); diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingquestions.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingquestions.js index b15b6fb2f..8d430b93c 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingquestions.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingquestions.js @@ -1,7 +1,7 @@ import React,{Component} from "react"; import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal, Table, Divider, Tag} from "antd"; import {Link} from 'react-router-dom'; -import { WordsBtn,markdownToHTML,AttachmentList} from 'educoder'; +import { getRandomcode,markdownToHTML,AttachmentList} from 'educoder'; import axios from 'axios'; import Modals from '../../../modals/Modals'; import DownloadMessageysl from "../../../modals/DownloadMessageysl"; @@ -214,9 +214,8 @@ class GraduationTasksquestions extends Component{ } /// 确认是否下载 - confirmysl(url){ - debugger; - console.log(2); + confirmysl(url,urls){ + axios.get(url + '?export=true').then((response) => { if(response === undefined){ return @@ -239,8 +238,10 @@ class GraduationTasksquestions extends Component{ }) } }else { - this.props.slowDownload(url) - + // this.props.slowDownload(urls) + //this.props.showNotification(`正在下载中`); + this.props.slowDownload(getRandomcode(url)) + // window.open(getRandomcode("/api" + url), '_blank'); // this.props.showNotification(`正在下载中`); // window.open("/api"+url, '_blank'); } diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js index df6152c04..f08938b4e 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js @@ -226,7 +226,7 @@ class GraduateTopicReply extends Component{ return( -
    { const checkBoxValues = this.state.checkBoxValues.slice(0); const index = checkBoxValues.indexOf(item.id); @@ -198,7 +198,7 @@ class Boards extends Component{ }) } cancelOperateTopic=()=>{ - this.setState({ + this.setState({ modalsType:false, modalsTopval:"", modalsBottomval:"", @@ -257,7 +257,7 @@ onDelete=(index)=>{ console.log(error) }) } - + }else{ this.setState({ // delType:true, @@ -319,7 +319,7 @@ sureDelTopic=()=>{ }).catch((error)=>{ console.log(error); }) - } + } }else{ this.setState({ delType:false, @@ -335,7 +335,7 @@ onBoardsNew=()=>{ } /// 确认是否下载 confirmysl(url){ - axios.get(url + '?export=true').then((response) => { + axios.get(url + '&export=true').then((response) => { if(response.data.status&&response.data.status===-1){ }else if(response.data.status&&response.data.status===-2){ @@ -376,12 +376,12 @@ onBoardsNew=()=>{ this.fetchAll(searchValue,page,status); } render(){ - let { - searchValue, - topicList, + let { + searchValue, + topicList, data, course_public, - checkBoxValues, + checkBoxValues, checkAllValue, page, totalCount, @@ -507,9 +507,9 @@ onBoardsNew=()=>{ :
    } - -
    -
    + +
    +
    ) } diff --git a/public/react/src/modules/courses/groupjobbank/GroupPackage.js b/public/react/src/modules/courses/groupjobbank/GroupPackage.js index e0b220202..1cd0564a2 100644 --- a/public/react/src/modules/courses/groupjobbank/GroupPackage.js +++ b/public/react/src/modules/courses/groupjobbank/GroupPackage.js @@ -1,6 +1,6 @@ import React, {Component} from "react"; -import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder'; +import { WordsBtn,on, off, trigger,markdownToHTML,getRandomNumber} from 'educoder'; import { Button, Checkbox, @@ -23,7 +23,8 @@ class GroupPackage extends Component { } } DownloadOpenPdf=(type,url)=>{ - type===true?window.open(url):window.location.href=url; + let newurl=url+getRandomNumber(); + type===true?window.open(newurl):window.location.href=newurl; } componentDidMount() { console.log("Groupjobquesanswer"); diff --git a/public/react/src/modules/courses/members/CourseGroupList.js b/public/react/src/modules/courses/members/CourseGroupList.js index 0db0ae37e..afec12fa9 100644 --- a/public/react/src/modules/courses/members/CourseGroupList.js +++ b/public/react/src/modules/courses/members/CourseGroupList.js @@ -14,7 +14,7 @@ import CourseLayoutcomponent from '../common/CourseLayoutComponent' import Titlesearchsection from '../common/titleSearch/TitleSearchSection' import ColorCountText from '../common/titleSearch/ColorCountText' -import { WordsBtn, trigger, on, off, getUrl, downloadFile , sortDirections, NoneData } from 'educoder' +import { WordsBtn, trigger, on, off, getUrl, downloadFile , getRandomcode, NoneData } from 'educoder' import Modals from "../../modals/Modals"; import DownloadMessageysl from "../../modals/DownloadMessageysl"; @@ -23,7 +23,7 @@ import ChangeRolePop from './ChangeRolePop' import CourseGroupListTable from './CourseGroupListTable' import './studentsList.css' -/** +/** 角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生 */ function CourseGroupList(props) { @@ -36,7 +36,7 @@ function CourseGroupList(props) { const [listRes, setListRes] = useState({}) const createGroupModalEl = useRef(null); - const courseId = props.match.params.coursesId + const courseId = props.match.params.coursesId useEffect(() => { fetchAll() @@ -63,7 +63,7 @@ function CourseGroupList(props) { } const onConfirm = async () => { } - + function createGroupImportSuccess() { } @@ -83,7 +83,7 @@ function CourseGroupList(props) { } const confirmysl = (url) => { - axios.get(url + 'export=true').then((response) => { + axios.get(url + '&export=true').then((response) => { if(response === undefined){ return } @@ -100,13 +100,13 @@ function CourseGroupList(props) { setDownloadMessageval(500) } }else { - props.slowDownload(url) + props.slowDownload(getRandomcode(url)) } }).catch((error) => { console.log(error) }); } - + const isAdmin = props.isAdmin(); const isSuperAdmin = props.isSuperAdmin(); const isParent = true; @@ -121,9 +121,9 @@ function CourseGroupList(props) { const course_groups = listRes.course_groups const current_group_id = listRes.current_group_id - let exportUrl = `/courses/${courseId}/export_member_scores_excel.xlsx?`; //总成绩 - let exportUrltwo = `/courses/${courseId}/export_couser_info.xlsx?`; //课堂信息 - let exportUrlthree = `/courses/${courseId}/export_member_act_score.xlsx?`; //活跃度 + let exportUrl = `/courses/${courseId}/export_member_scores_excel.xlsx`; //总成绩 + let exportUrltwo = `/courses/${courseId}/export_couser_info.xlsx`; //课堂信息 + let exportUrlthree = `/courses/${courseId}/export_member_act_score.xlsx`; //活跃度 return ( = 10} searchPlaceholder={ '请输入分班名称进行搜索' } firstRowRight={ - - { // pageType !== TYPE_STUDENTS && + + { // pageType !== TYPE_STUDENTS && isSuperAdmin && {/* ref="createGroupByImportModal" */} {createGroupModalEl.current.setVisible(true)}}>导入创建分班 } - { - // pageType !== TYPE_STUDENTS && + { + // pageType !== TYPE_STUDENTS && !isCourseEnd && isAdmin && addDir()}>新建分班 } - {/* { + {/* { isAdmin && !isParent && course_group_id != 0 && deleteDir()}>删除分班 } */} - {/* { + {/* { isAdmin && !isParent && course_group_id != 0 && this.renameDir()}>分班重命名 } */}
    网址克隆
    @@ -354,11 +381,15 @@ class VNCContainer extends Component { > - - {/* */} + {/* {this.state.vnc_reseting ? : } 重置桌面系统 + */} + + {this.state.vnc_reseting ? + : } + 重置实训 {/* diff --git a/public/react/src/modules/page/VNCDisplay.js b/public/react/src/modules/page/VNCDisplay.js index b9ec77988..17dbff309 100644 --- a/public/react/src/modules/page/VNCDisplay.js +++ b/public/react/src/modules/page/VNCDisplay.js @@ -166,7 +166,8 @@ class VNCDisplay extends Component { `}
    Loading
    -
    Send CtrlAltDel
    + {/*
    Send CtrlAltDel
    */} +
    diff --git a/public/react/src/modules/page/header.scss b/public/react/src/modules/page/header.scss new file mode 100644 index 000000000..b8320638f --- /dev/null +++ b/public/react/src/modules/page/header.scss @@ -0,0 +1,6 @@ +.headerRight .exit_btn{ + color: rgba(237,237,237,1); + &:hover{ + // color: #fff; + } +} \ No newline at end of file diff --git a/public/react/src/modules/page/layers/TaskResultLayer.js b/public/react/src/modules/page/layers/TaskResultLayer.js index 9e096b7b3..f4ccea8f7 100644 --- a/public/react/src/modules/page/layers/TaskResultLayer.js +++ b/public/react/src/modules/page/layers/TaskResultLayer.js @@ -14,6 +14,7 @@ import passpartImg from '../../../images/tpi/passpart.png' import empiricgreenImg from '../../../images/tpi/empiricgreen.png' import { trigger } from 'educoder'; +import SecondTab from "../../paths/SchoolStatistics/SecondTab"; class TaskResultLayer extends Component { @@ -29,7 +30,7 @@ class TaskResultLayer extends Component { } componentWillReceiveProps(newProps, newContext) { - if (newProps.currentGamePassed && (!this.props.currentGamePassed + if (newProps.currentGamePassed && (!this.props.currentGamePassed || (newProps.currentGamePassed !== this.props.currentGamePassed ))) { // this.fakeRanking = this._fakeRanking() const $ = window.$; @@ -51,10 +52,10 @@ class TaskResultLayer extends Component { } } } - + onStarChange(challenge, index, value) { this.props.onStarChange(challenge, index, value); - + this.setState({ stared: value ? true : false, }) @@ -87,11 +88,11 @@ class TaskResultLayer extends Component { // this.context.router.push('/sample'); if (goNext === true) { if (next_game) { // https://www.trustie.net/issues/18573 - this.goNext = true; + this.goNext = true; } // 隐藏掉效果查看页面 window.$('#picture_display').hide() - } + } this.props.onGamePassed(); this.setState({ stared: false @@ -110,9 +111,9 @@ class TaskResultLayer extends Component { // return; // } // const { showLanguagePictrue } = this.props.challenge; - // if ( prevProps.challenge.showLanguagePictrue != showLanguagePictrue && + // if ( prevProps.challenge.showLanguagePictrue != showLanguagePictrue && // showLanguagePictrue == true ) { - + // } // } initEffectDisplayServerTimer = () => { @@ -128,7 +129,7 @@ class TaskResultLayer extends Component { this.setState({ timeRemain }) }, 1000) }) - + } componentWillUnmount() { this.intervalHandler && clearInterval(this.intervalHandler); @@ -162,7 +163,7 @@ class TaskResultLayer extends Component { // const fakeRanking = this.fakeRanking; return (
    - {currentGamePassed ? + {currentGamePassed ?
    @@ -174,52 +175,60 @@ class TaskResultLayer extends Component {

    {currentPassedGameGainExperience >= 0 ? `+${currentPassedGameGainExperience}` : '+0'} -

    +

    - +
    - { !game.star ? + { !game.star ?

    您的评价决定老师的江湖地位~

    this.onStarChange(this.props.game, this.props.challenge.position, value)} - /> + />
    : ''} -

    +

    {/*下一关*/} this.onFinish(true)}>{ next_game ? '下一关' : '完成'} - { challenge.showLanguagePictrue && + { challenge.showLanguagePictrue && this.onFinish()}> { `查看效果` } {/* ${ moment(this.state.timeRemain * 1000).format('mm:ss') } */} - + } - {/* - - (this.state.timeRemain ? + {/* + + (this.state.timeRemain ? - - + + : {}} style={{ backgroundColor: 'gray'}}> { `查看效果` } - + ) */} - {/* + {/* 注意:效果查看服务只会保留5分钟 效果查看服务已被终止运行,需要重新评测后才能查看 */} diff --git a/public/react/src/modules/page/tpiPage.css b/public/react/src/modules/page/tpiPage.css index 0c4faee83..015a66b98 100644 --- a/public/react/src/modules/page/tpiPage.css +++ b/public/react/src/modules/page/tpiPage.css @@ -120,8 +120,10 @@ button.buttonHoverColor:hover a { #myshixun_top { - display: flex; - height: 54px; + display: flex; + position: fixed; + height: 54px; + z-index: 1 !important; } .headerLeft { flex: 0 0 400px; diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js new file mode 100644 index 000000000..232ba9d72 --- /dev/null +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -0,0 +1,970 @@ +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, + Drawer, + Input, + Tooltip +} from "antd"; +import {parabola} from './animation/parabola' +import Headplugselections from "./component/Headplugselections"; +import QuestionModal from "./component/QuestionModal"; +import QuestionModals from "./component/QuestionModals"; +import Contentpart from "./component/Contentpart"; +import {TPMIndexHOC} from "../tpm/TPMIndexHOC"; +import NoneData from './component/NoneData'; +import './questioncss/questioncom.css'; +import Bottomsubmit from "../modals/Bottomsubmit"; + +//exam_id 试卷的id +class NewMyShixunModel extends Component { + constructor(props) { + super(props); + this.state = { + count: 50, + defaultActiveKey:"1", + Headertop: "", + Footerdown: "", + visible: false, + placement: 'right', + modalsType: false, + modalsTypes:false, + titilesm: "在平台审核后,所有成员均可使用试题", + titiless: "是否设置为公开?", + titilesms:"单选题", + titbool: false, + Contentdata: [], + difficulty: null, + visiblemys: false, + visiblemyss: false, + item_type: null, + keyword: null, + timuid: null, + items_count: 0, + basket_list: [], + completion_questions_count: 0, + judgement_questions_count: 0, + multiple_questions_count: 0, + practical_questions_count: 0, + program_questions_count: 0, + single_questions_count: 0, + subjective_questions_count: 0, + page:1, + per_page:10, + disciplinesdata:[], + discipline_id:null, + sub_discipline_id:null, + tag_discipline_id:null, + booljupyterurls:false, + disciplinesdatakc:0, + disciplinesdatazsd:0, + selectallquestionsonthispages:false, + oj_status:null, + isVisible: false, + selectionbools:false, + } + + } + setdiscipline_id=(discipline_id)=>{ + this.setState({ + discipline_id:discipline_id, + sub_discipline_id:null, + tag_discipline_id:null, + keywords:"", + page:1, + per_page:10, + oj_status:null + }) + var data = { + discipline_id:discipline_id, + sub_discipline_id:null, + tag_discipline_id:null, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: null, + page: this.state.page, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + this.getdata(data); + + } + + setsub_discipline_id=(discipline_id,sub_discipline_id)=>{ + this.setState({ + sub_discipline_id:sub_discipline_id, + tag_discipline_id:null, + keywords:"", + page:1, + per_page:10, + oj_status:null + }) + var data = { + discipline_id:discipline_id, + sub_discipline_id:sub_discipline_id, + tag_discipline_id:null, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords:null, + page: 1, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + this.getdata(data); + } + + settag_discipline_id=(tag_discipline_id)=>{ + this.setState({ + tag_discipline_id:tag_discipline_id, + keywords:"", + page:1, + per_page:10, + oj_status:null + }) + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: null, + page: 1, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + this.getdata(data); + } + + //初始化 + componentDidMount() { + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.props; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ + defaultActiveKeys="1" + } + this.callback(defaultActiveKeys); + let url = `/users/get_navigation_info.json`; + axios.get(url, {}).then((response) => { + // //////console.log("开始请求/get_navigation_info.json"); + // //////console.log(response); + if (response != undefined) { + if (response.status === 200) { + this.setState({ + Headertop: response.data.top, + Footerdown: response.data.down + }) + } + } + }); + + this.getbasket_listdata(); + + //获取题库筛选资料 + let urls = `/disciplines.json`; + axios.get(urls, {params: { + source:"question" + }}).then((response) => { + //console.log("Questiondisciplines"); + //console.log(response.data); + if (response) { + this.setState({ + disciplinesdata: response.data.disciplines, + }) + } + }); + } + + componentDidUpdate(prevProps) { + if(prevProps.current_user !== this.props.current_user) { + debugger + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.props; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ + defaultActiveKeys="1" + } + this.callback(defaultActiveKeys); + } + } + + //公共和我的 + callback = (key) => { + this.setState({ + defaultActiveKey: key, + selectallquestionsonthispages:false, + difficulty:null, + page:1, + oj_status:null + }) + 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: key, + item_type: this.state.item_type, + difficulty: null, + page: 1, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + this.getdata(data); + + } + + //刷新加载 + getdata = (data) => { + const url = `/item_banks.json`; + this.setState({ + booljupyterurls:true, + selectionbools:false, + }) + axios.get((url), {params: data}).then((response) => { + setTimeout(()=>{ + this.setState({ + booljupyterurls:false, + }) + },1000); + if (response === null || response === undefined) { + + return + } + if (response.data.status === 403 || response.data.status === 401 || response.data.status === 500) { + + } else { + + } + //////console.log("item_banks"); + //////console.log(response); + this.setState({ + Contentdata: response.data, + items_count: response.data.items_count, + }) + this.getdataslen(response.data.items); + }).catch((error) => { + //////console.log(error) + this.setState({ + booljupyterurls:false, + }) + }); + } + + //不刷新加载 + getdatasy = (data) => { + const url = `/item_banks.json`; + this.setState({ + selectionbools:false, + }) + axios.get((url), {params: data}).then((response) => { + setTimeout(()=>{ + + },1000); + if (response === null || response === undefined) { + + return + } + if (response.data.status === 403 || response.data.status === 401 || response.data.status === 500) { + + } else { + + } + //////console.log("item_banks"); + //////console.log(response); + this.setState({ + Contentdata: response.data, + items_count: response.data.items_count, + + }) + + this.getdataslen(response.data.items); + }).catch((error) => { + + }); + } + + //计算 + getdataslen=(arr)=>{ + var contes=0; + for(let data of arr) { + if(data.item_type==="PROGRAM"){ + //编程题 + if(data.choosed===true){ + + }else{ + //未选用 + if(data.program_attr.status===1){ + //已发布 + contes=contes+1; + } + + } + + }else{ + //不是编程题 + if(data.choosed===true){ + + }else{ + //未选用 + contes=contes+1; + } + } + + } + + if(contes>0){ + this.setState({ + selectionbools:false, + selectallquestionsonthispages:false, + }) + }else { + this.setState({ + selectionbools:true, + selectallquestionsonthispages:true, + }) + } + } + + paginationonChange = (pageNumber) => { + this.setState({ + page: pageNumber, + }) + 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: pageNumber, + per_page:10, + oj_status:this.state.oj_status, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + + }; + this.getdata(data); + } + showDrawer = () => { + if(this.state.visible===true){ + this.setState({ + visible: false, + }); + }else{ + this.setState({ + visible: true, + }); + this.getbasket_listdata(); + } + + + + }; + + onClose = () => { + this.setState({ + visible: false, + }); + }; + + onChange = e => { + this.setState({ + placement: e.target.value, + }); + }; + + getContainer = () => { + return this.container; + }; + saveContainer = container => { + this.container = container; + }; + + showmodels = (id) => { + + this.setState({ + modalsType: true, + titilesm: "在平台审核后,所有成员均可使用试题", + titiless: "是否设置为公开?", + titbool: true, + timuid: id + }) + }; + showmodelysl = (id) => { + this.setState({ + modalsType: true, + titilesm: "确认删除后,无法撤销", + titiless: "是否确认删除?", + titbool: false, + timuid: id + }) + }; + + + modalCancel = () => { + this.setState({ + modalsType: false + }) + } + modalCancels=()=>{ + this.setState({ + modalsTypes: false + }) + } + showQuestionModals =(item_type)=>{ + this.setState({ + modalsTypes: true, + titilesms:item_type, + }) + + } + setDownloads=(item_type)=>{ + this.Deletebigquestiontype(item_type); + this.setState({ + modalsTypes: false + }) + } + setDownload = () => { + //确认 + if (this.state.titbool === true) { + //公开 + this.publicopentimu(this.state.timuid); + } else { + // 删除 + this.deletetimu(this.state.timuid); + } + this.setState({ + modalsType: false + }) + } + + setdifficulty = (difficulty) => { + this.setState({ + difficulty: difficulty, + visiblemys: false, + page: 1, + per_page:10, + keywords:"", + oj_status:null + }) + + 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: difficulty, + item_type: this.state.item_type, + keywords:null, + page:1, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + + this.getdata(data); + + } + setitem_types = (item_type) => { + this.setState({ + item_type: item_type, + visiblemyss: false, + page: 1, + per_page:10, + keywords:"", + oj_status:null + }) + + 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: item_type, + page: 1, + per_page:10, + keywords:null, + oj_status:null, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + + this.getdata(data); + } + + handleVisibleChange = (boll) => { + if (this.state.visiblemyss === true) { + this.setState({ + visiblemys: boll, + visiblemyss: false, + }) + } else { + this.setState({ + visiblemys: boll, + }) + } + + } + + handleVisibleChanges = (boll) => { + if (this.state.visiblemys === true) { + this.setState({ + visiblemyss: boll, + visiblemys: false, + }) + } else { + this.setState({ + visiblemyss: boll, + }) + } + + } + + setdatafunsval = (e) => { + this.setState({ + keywords: e.target.value + }) + } + + setdatafuns = (value) => { + this.setState({ + keywords: value, + }) + 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: value, + page: this.state.page, + per_page:10, + oj_status:this.state.oj_status, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + + this.getdata(data); + } + + deletetimu = (id) => { + + const url = `/item_banks/${id}.json`; + axios.delete(url) + .then((response) => { + if (response.data.status == 0) { + // this.props.showNotification('删除试题成功') + // props.history.push(response.data.right_url) + 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.getdata(data); + } + }) + .catch(function (error) { + ////console.log(error); + }); + } + publicopentimu = (id) => { + + const url = `/item_banks/${id}/set_public.json`; + axios.post(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.getdata(data); + } + }).catch((error) => { + ////console.log(error); + }) + } + + getbasket_listdata = () => { + // 获取试题篮展开的数据 + // const url = "/item_baskets/basket_list.json"; + // axios.get(url) + // .then((result) => { + // // ////console.log("getbasket_listdata"); + // // ////console.log(result.data); + // this.setState({ + // completion_questions_count: result.data.completion_questions_count, + // judgement_questions_count: result.data.judgement_questions_count, + // multiple_questions_count: result.data.multiple_questions_count, + // practical_questions_count: result.data.practical_questions_count, + // program_questions_count: result.data.program_questions_count, + // single_questions_count: result.data.single_questions_count, + // subjective_questions_count: result.data.subjective_questions_count, + // }) + // + // }).catch((error) => { + // // ////console.log(error); + // this.setState({ + // completion_questions_count: 0, + // judgement_questions_count: 0, + // multiple_questions_count: 0, + // practical_questions_count: 0, + // program_questions_count: 0, + // single_questions_count: 0, + // subjective_questions_count: 0, + // }) + // }) + + } + + + //选用 + getitem_baskets=(data)=>{ + //选用题型可以上传单个 或者多个题型 + let url=""; + if(this.props.exam_id===undefined){ + url="/item_baskets.json"; + }else{ + url="/examination_items.json"; + } + + + axios.post(url, data) + .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(); + // this.setState({ + // visible:true + // }) + } + }).catch((error) => { + ////console.log(error); + }) + } + // 撤销 + getitem_basketss=(id)=>{ + 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/${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); + }) + } + + + } + //全选试题库 + selectallquestionsonthispage=()=>{ + var item_idsdata=[]; + + var arr= this.state.Contentdata.items; + for(let data of arr) { + if(data.item_type==="PROGRAM"){ + //编程题 + if(data.choosed===true){ + + }else{ + //未选用 + if(data.program_attr.status===1){ + //已发布 + item_idsdata.push(data.id); + } + + } + + }else{ + //不是编程题 + if(data.choosed===true){ + + }else{ + //未选用 + item_idsdata.push(data.id); + } + } + + } + const data={ + item_ids:item_idsdata, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + } + this.getitem_baskets(data); + this.setState({ + selectallquestionsonthispages:true, + }) + } + + //全选的状态 + + //删除大题型 + Deletebigquestiontype =(item_type)=>{ + const url=`/item_baskets/delete_item_type.json`; + axios.delete((url), { data: { + item_type:item_type + }}) + .then((response) => { + if (response.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.getdata(data); + this.getbasket_listdata(); + } + }) + .catch(function (error) { + ////console.log(error); + }); + + } + + + //跳转 + gotopaperreview=()=>{ + + this.props.history.replace("/paperreview"); + + } + + setoj_status=(oj_status)=>{ + //编程题发布未发布 + this.setState({ + selectallquestionsonthispages:false, + difficulty:null, + oj_status:oj_status + }) + 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, + oj_status:oj_status, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + this.getdata(data); + } + + + render() { + let { + page, per_page, items_count, Headertop, visible, placement, modalsType, modalsTypes,basket_list, + completion_questions_count, judgement_questions_count, multiple_questions_count, practical_questions_count, + program_questions_count, single_questions_count, subjective_questions_count,selectionbools + } = this.state; + + const Datacount = completion_questions_count + judgement_questions_count + + multiple_questions_count + practical_questions_count + + program_questions_count + + single_questions_count + + subjective_questions_count; + + return ( +

    + + + { + visible===true? + + :"" + } + { + visible===true? +
    + :""} + { + modalsTypes===true? + this.modalCancels()} + setDownloads={(e) => this.setDownloads(e)}> + :"" + } + { + modalsType===true? + this.modalCancel()} + setDownload={() => this.setDownload()}> + :"" + } + + {/*顶部*/} + + this.setdifficulty(e)} + setitem_types={(e) => this.setitem_types(e)} + setdiscipline_id={(e)=>this.setdiscipline_id(e)} + setsub_discipline_id={(e)=>this.setsub_discipline_id(e)} + settag_discipline_id={(e)=>this.settag_discipline_id(e)} + /> + {/*头部*/} + this.getitem_basketss(id)} + selectallquestionsonthispage={()=>this.selectallquestionsonthispage()} + getitem_baskets={(e)=>this.getitem_baskets(e)} + setdatafuns={(e) => this.setdatafuns(e)} + setdatafunsval={(e) => this.setdatafunsval(e)} + handleVisibleChanges={(e) => this.handleVisibleChanges(e)} + handleVisibleChange={(e) => this.handleVisibleChange(e)} + showmodels={(e) => this.showmodels(e)} + showmodelysl={(e) => this.showmodelysl(e)} + callback={(e) => this.callback(e)} + setoj_status={(e)=>this.setoj_status(e)}> + + { + items_count&&items_count>10? +
    + +
    + :
    + +
    + } + + + this.props.setnewmyshixunmodelbool(false)} + onSubmits={() => this.props.setnewmyshixunmodelbool(false)} url={'/paperlibrary'}> +
    + ) + + } + +} + +export default NewMyShixunModel; diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index 47593ea2d..2adc77c03 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -24,6 +24,8 @@ import JudquestionEditor from "./component/JudquestionEditor"; import Paperreview_item from "./Paperreview_item" import Bottomsubmit from "../../modules/modals/Bottomsubmit"; import Comthetestpaperst from "./comthetestpaper/Comthetestpaperst"; +import NewMyShixunModel from "../question/NewMyShixunModel"; +import IntelligentModel from "../question/component/IntelligentModel" //人工组卷预览 class Paperreview extends Component { constructor(props) { @@ -49,7 +51,9 @@ class Paperreview extends Component { difficulty:null, name:null, duration:null, - + newmyshixunmodelbool:false, + artificialtype:"artificial", + Intelligentformation:false, } // single_questions:null, 单选题 @@ -63,10 +67,13 @@ class Paperreview extends Component { //初始化 componentDidMount() { - - - var data = {} - this.getdata(data); + //console.log("Paperreview.js"); + //console.log(this.props.match.params); + this.setState({ + artificialtype:this.props.match.params.type + }) + var data = {}; + this.getdata(data); let urls = `/disciplines.json`; axios.get(urls, { params: { @@ -129,6 +136,18 @@ class Paperreview extends Component { getdata = (data) => { + + if(this.props.match.params.type==="artificial"){ + //人工组卷 + + + }else{ + //智能组卷 + // + data = { + exam_setting_id:this.props.match.params.id + } + } const url = `/item_baskets.json`; this.setState({ booljupyterurls: true, @@ -166,7 +185,7 @@ class Paperreview extends Component { } }).catch((error) => { - ////console.log(error) + //////console.log(error) this.setState({ booljupyterurls: false, }) @@ -192,43 +211,51 @@ class Paperreview extends Component { } preservation = () => { //保存试卷 - if(this.state.Cohetepaperbool===true){ - if (this.contentMdRef.Getdatas().length === 0) { - this.scrollToAnchor("Itembankstopid"); - return; - } - var myrbkc=[]; - var Getdatasdatas=this.contentMdRef.Getdatas()[2].rbzsd; - for(let myda of Getdatasdatas) { - myrbkc.push(myda.id); - } - const url = `/examination_banks.json`; - var data={ - difficulty:this.contentMdRef.Getdatas()[0].rbnd, - name:this.contentMdRef.Getdatas()[4].classroom, - duration:this.contentMdRef.Getdatas()[5].kssc, - discipline_id: this.contentMdRef.Getdatas()[3].rbkc[0], - sub_discipline_id: this.contentMdRef.Getdatas()[3].rbkc[1], - tag_discipline_id: myrbkc, + if(this.state.artificialtype==="artificial"){ + if(this.state.Cohetepaperbool===true){ + if (this.contentMdRef.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return; + } + var myrbkc=[]; + var Getdatasdatas=this.contentMdRef.Getdatas()[2].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url = `/examination_banks.json`; + var data={ + difficulty:this.contentMdRef.Getdatas()[0].rbnd, + name:this.contentMdRef.Getdatas()[4].classroom, + duration:this.contentMdRef.Getdatas()[5].kssc, + discipline_id: this.contentMdRef.Getdatas()[3].rbkc[0], + sub_discipline_id: this.contentMdRef.Getdatas()[3].rbkc[1], + tag_discipline_id: myrbkc, + } + axios.post(url, data) + .then((result) => { + if (result.data.status === 0) { + // this.props.showNotification(`组卷成功`); + this.props.history.replace('/paperlibrary'); + } + }).catch((error) => { + //console.log(error); + }) + + }else{ + this.setCohetepaperbool(true); + } - axios.post(url, data) - .then((result) => { - if (result.data.status === 0) { - this.props.showNotification(`组卷成功`); - this.props.history.replace('/paperlibrary'); - } - }).catch((error) => { - console.log(error); - }) }else{ - this.setCohetepaperbool(true); + //智能组卷 + this.setIntelligentformation(true); } + } @@ -245,14 +272,123 @@ class Paperreview extends Component { getcontentMdRef = (Ref) => { this.contentMdRef = Ref; } + + setnewmyshixunmodelbool=(bool)=>{ + //人工组卷 + if(bool===true){ + let scrollToTop = window.setInterval(function() { + let pos = window.pageYOffset; + if ( pos > 0 ) { + window.scrollTo( 0, pos - 20 ); // how far to scroll on each step + } else { + window.clearInterval( scrollToTop ); + } + }, 2); + } + this.setState({ + newmyshixunmodelbool:bool + }) + var data = {} + this.getdata(data); + + + + + } + + //换题型 + Replacementtype=(value)=>{ + var item_types=""; + if(value==="单选题"){ + item_types="SINGLE"; + } + else if(value==="多选题"){ + item_types="MULTIPLE"; + + } + else if(value==="判断题"){ + item_types="JUDGMENT"; + + } + else if(value==="编程题"){ + item_types="PROGRAM"; + + } + const url=`/examination_intelligent_settings/${this.props.match.params.id}/exchange_items.json`; + let data={ + item_type:item_types, + } + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + //console.log(result); + var data = {} + this.getdata(data); + } + }).catch((error) => { + //console.log(error); + }) + } + //换题 + Changingtopics=(id)=>{ + const url=`/examination_intelligent_settings/${this.props.match.params.id}/exchange_one_item.json`; + let data={ + item_id:id, + } + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + //console.log(result); + var data = {} + this.getdata(data); + } + }).catch((error) => { + //console.log(error); + }) + } + + setIntelligentformation=(bool)=>{ + this.setState({ + Intelligentformation:bool + }) + } + Confirmationofvolumeformations=()=>{ + this.setState({ + Intelligentformation:false + }) + + } render() { - let {page, limit, count, Headertop, visible, placement, modalsType, item_type,Cohetepaperbool} = this.state; + let {page, limit, count, Headertop, visible, placement, modalsType, item_type,artificialtype,Cohetepaperbool,newmyshixunmodelbool,Intelligentformation} = this.state; const params = this.props && this.props.match && this.props.match.params; - // //console.log(params); + // ////console.log(params); return (
    + { + Intelligentformation===true? + this.getdata(data)} {...this.state} {...this.props} exam_id={this.props.match.params.id} Confirmationofvolumeformations={()=>this.Confirmationofvolumeformations()}> + :"" + } + { + newmyshixunmodelbool===true? + + :"" + } + + { + newmyshixunmodelbool===true? +
    + this.setnewmyshixunmodelbool(e)}> +
    + : + "" + } {/*顶部*/}
    @@ -99,9 +141,39 @@ class Paperreview_single extends Component { ` } -
    -
    + { + objectsingle.item_type==="PROGRAM"? +
    +
    + ({objectsingle.score}分) +
    +
    + +
    +
    + : +
    +
    + ({objectsingle.score}分) +
    +
    + + +
    +
    + } +
    {/*内容*/}
    @@ -114,7 +186,7 @@ class Paperreview_single extends Component { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { return (

    - + {object.choice_text}

    @@ -126,19 +198,48 @@ class Paperreview_single extends Component { objectsingle.item_type === "PROGRAM" ?

    -

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

    + +

    + : + ""}

    :

    { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { + var string="" + try { + string=JSON.parse(object.choice_text); + }catch (e) { + string=object.choice_text; + } + 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 51d50932e..f1f139257 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -11,6 +11,7 @@ import { Input, Tooltip } from "antd"; +import {parabola} from './animation/parabola' import Headplugselections from "./component/Headplugselections"; import QuestionModal from "./component/QuestionModal"; import QuestionModals from "./component/QuestionModals"; @@ -25,14 +26,14 @@ class Question extends Component { super(props); this.state = { count: 50, - defaultActiveKey:"0", + defaultActiveKey:"1", Headertop: "", Footerdown: "", visible: false, placement: 'right', modalsType: false, modalsTypes:false, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titilesms:"单选题", titbool: false, @@ -63,9 +64,29 @@ class Question extends Component { disciplinesdatazsd:0, selectallquestionsonthispages:false, oj_status:null, + isVisible: false, + selectionbools:false, + chakanjiexiboolindex:"无", } } + + chakanjiexibool=(index)=>{ + 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, @@ -92,7 +113,7 @@ class Question extends Component { } - setsub_discipline_id=(sub_discipline_id)=>{ + setsub_discipline_id=(discipline_id,sub_discipline_id)=>{ this.setState({ sub_discipline_id:sub_discipline_id, tag_discipline_id:null, @@ -102,7 +123,7 @@ class Question extends Component { oj_status:null }) var data = { - discipline_id:this.state.discipline_id, + discipline_id:discipline_id, sub_discipline_id:sub_discipline_id, tag_discipline_id:null, public: this.state.defaultActiveKey, @@ -141,21 +162,8 @@ class Question extends Component { //初始化 componentDidMount() { - let {defaultActiveKey} = this.state; - 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: defaultActiveKey, - page:1, - per_page:10, - }; - this.getdata(data); - let url = `/users/get_navigation_info.json`; axios.get(url, {}).then((response) => { - // ////console.log("开始请求/get_navigation_info.json"); - // ////console.log(response); if (response != undefined) { if (response.status === 200) { this.setState({ @@ -165,16 +173,14 @@ class Question extends Component { } } }); - this.getbasket_listdata(); - //获取题库筛选资料 let urls = `/disciplines.json`; axios.get(urls, {params: { source:"question" }}).then((response) => { - console.log("Questiondisciplines"); - console.log(response.data); + //console.log("Questiondisciplines"); + //console.log(response.data); if (response) { this.setState({ disciplinesdata: response.data.disciplines, @@ -206,10 +212,12 @@ class Question extends Component { } + //刷新加载 getdata = (data) => { const url = `/item_banks.json`; this.setState({ booljupyterurls:true, + selectionbools:false, }) axios.get((url), {params: data}).then((response) => { setTimeout(()=>{ @@ -226,20 +234,96 @@ class Question extends Component { } else { } - ////console.log("item_banks"); - ////console.log(response); + //////console.log("item_banks"); + //////console.log(response); this.setState({ Contentdata: response.data, items_count: response.data.items_count, }) + this.getdataslen(response.data.items); }).catch((error) => { - ////console.log(error) + //////console.log(error) this.setState({ booljupyterurls:false, }) }); } + //不刷新加载 + getdatasy = (data) => { + const url = `/item_banks.json`; + this.setState({ + selectionbools:false, + }) + axios.get((url), {params: data}).then((response) => { + setTimeout(()=>{ + + },1000); + if (response === null || response === undefined) { + + return + } + if (response.data.status === 403 || response.data.status === 401 || response.data.status === 500) { + + } else { + + } + //////console.log("item_banks"); + //////console.log(response); + this.setState({ + Contentdata: response.data, + items_count: response.data.items_count, + + }) + + this.getdataslen(response.data.items); + }).catch((error) => { + + }); + } + + //计算 + getdataslen=(arr)=>{ + var contes=0; + for(let data of arr) { + if(data.item_type==="PROGRAM"){ + //编程题 + if(data.choosed===true){ + + }else{ + //未选用 + if(data.program_attr.status===1){ + //已发布 + contes=contes+1; + } + + } + + }else{ + //不是编程题 + if(data.choosed===true){ + + }else{ + //未选用 + contes=contes+1; + } + } + + } + + if(contes>0){ + this.setState({ + selectionbools:false, + selectallquestionsonthispages:false, + }) + }else { + this.setState({ + selectionbools:true, + selectallquestionsonthispages:true, + }) + } + } + paginationonChange = (pageNumber) => { this.setState({ page: pageNumber, @@ -257,6 +341,8 @@ class Question extends Component { oj_status:this.state.oj_status }; this.getdata(data); + this.setmychakanjiexibool("无") + } showDrawer = () => { if(this.state.visible===true){ @@ -297,7 +383,7 @@ class Question extends Component { this.setState({ modalsType: true, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titbool: true, timuid: id @@ -435,19 +521,6 @@ class Question extends Component { this.setState({ keywords: e.target.value }) - // 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: e.target.value, - // page: this.state.page, - // per_page:10, - // }; - // - // this.getdata(data); } setdatafuns = (value) => { @@ -476,7 +549,7 @@ class Question extends Component { axios.delete(url) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('删除试题成功') + // this.props.showNotification('删除试题成功') // props.history.push(response.data.right_url) var data = { discipline_id:this.state.discipline_id, @@ -493,7 +566,7 @@ class Question extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); } publicopentimu = (id) => { @@ -502,7 +575,7 @@ class Question extends Component { axios.post(url) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`公开题目成功`); + // this.props.showNotification(`公开题目成功`); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -517,7 +590,7 @@ class Question extends Component { this.getdata(data); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -526,8 +599,8 @@ class Question extends Component { const url = "/item_baskets/basket_list.json"; axios.get(url) .then((result) => { - // //console.log("getbasket_listdata"); - // //console.log(result.data); + // ////console.log("getbasket_listdata"); + // ////console.log(result.data); this.setState({ completion_questions_count: result.data.completion_questions_count, judgement_questions_count: result.data.judgement_questions_count, @@ -539,7 +612,7 @@ class Question extends Component { }) }).catch((error) => { - // //console.log(error); + // ////console.log(error); this.setState({ completion_questions_count: 0, judgement_questions_count: 0, @@ -562,7 +635,7 @@ class Question extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`选用成功`); + // this.props.showNotification(`选用成功`); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -574,14 +647,14 @@ class Question extends Component { page: this.state.page, per_page:10, }; - this.getdata(data); + this.getdatasy(data); this.getbasket_listdata(); - this.setState({ - visible:true - }) + // this.setState({ + // visible:true + // }) } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } // 撤销 @@ -592,7 +665,7 @@ class Question extends Component { axios.delete(url) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`撤销成功`); + // this.props.showNotification(`撤销成功`); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -604,11 +677,11 @@ class Question extends Component { page: this.state.page, per_page:10, }; - this.getdata(data); + this.getdatasy(data); this.getbasket_listdata(); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } //全选试题库 @@ -617,7 +690,29 @@ class Question extends Component { var arr= this.state.Contentdata.items; for(let data of arr) { - item_idsdata.push(data.id); + if(data.item_type==="PROGRAM"){ + //编程题 + if(data.choosed===true){ + + }else{ + //未选用 + if(data.program_attr.status===1){ + //已发布 + item_idsdata.push(data.id); + } + + } + + }else{ + //不是编程题 + if(data.choosed===true){ + + }else{ + //未选用 + item_idsdata.push(data.id); + } + } + } const data={ item_ids:item_idsdata @@ -638,7 +733,7 @@ class Question extends Component { }}) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('删除成功'); + // this.props.showNotification('删除成功'); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -655,7 +750,7 @@ class Question extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); } @@ -664,7 +759,7 @@ class Question extends Component { //跳转 gotopaperreview=()=>{ - this.props.history.replace("/paperreview"); + this.props.history.replace("/paperreview/artificial"); } @@ -689,11 +784,15 @@ class Question extends Component { }; this.getdata(data); } + + + + render() { let { page, per_page, items_count, Headertop, visible, placement, modalsType, modalsTypes,basket_list, completion_questions_count, judgement_questions_count, multiple_questions_count, practical_questions_count, - program_questions_count, single_questions_count, subjective_questions_count + program_questions_count, single_questions_count, subjective_questions_count,selectionbools } = this.state; const Datacount = completion_questions_count + judgement_questions_count @@ -701,8 +800,13 @@ class Question extends Component { + program_questions_count + single_questions_count + subjective_questions_count; + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + + return ( -
    +
    { visible===true? - this.showDrawer()} - Headertop={Headertop}/> + { + isysladmins===true? + this.showDrawer()} + Headertop={Headertop} + + /> + : + is_teacher===true&&professional_certification===true? + this.showDrawer()} + Headertop={Headertop} + + /> + : + + "" + } + {/*顶部*/} this.setdifficulty(e)} setitem_types={(e) => this.setitem_types(e)} setdiscipline_id={(e)=>this.setdiscipline_id(e)} - setsub_discipline_id={(e)=>this.setsub_discipline_id(e)} + setsub_discipline_id={(e,id)=>this.setsub_discipline_id(e,id)} settag_discipline_id={(e)=>this.settag_discipline_id(e)} /> {/*头部*/} this.chakanjiexibool(e)} getitem_basketss={(id)=>this.getitem_basketss(id)} selectallquestionsonthispage={()=>this.selectallquestionsonthispage()} getitem_baskets={(e)=>this.getitem_baskets(e)} @@ -957,12 +1086,3 @@ class Question extends Component { } export default SnackbarHOC()(TPMIndexHOC(Question)); -{/* this.onClose()}*/} -{/* visible={visible}*/} -{/* mask={false}*/} -{/* closable={true}*/} -{/*>*/} diff --git a/public/react/src/modules/question/Questionitem_banks.js b/public/react/src/modules/question/Questionitem_banks.js index 097528656..549bcc5ae 100644 --- a/public/react/src/modules/question/Questionitem_banks.js +++ b/public/react/src/modules/question/Questionitem_banks.js @@ -52,8 +52,8 @@ class Questionitem_banks extends Component { // axios.get(url, { // // }).then((response) => { - // // //////console.log("开始请求/get_navigation_info.json"); - // // //////console.log(response); + // // ////////console.log("开始请求/get_navigation_info.json"); + // // ////////console.log(response); // if(response!=undefined){ // if(response.status===200){ // this.setState({ @@ -80,15 +80,15 @@ class Questionitem_banks extends Component { } else { } - //////console.log("item_banks"); - //console.log("Questionitem_banks"); - //console.log(response.data); + ////////console.log("item_banks"); + ////console.log("Questionitem_banks"); + ////console.log(response.data); this.setState({ item_banksedit: response.data, }) }).catch((error) => { - //////console.log(error) + ////////console.log(error) }); @@ -173,10 +173,10 @@ class Questionitem_banks extends Component { // }else{ // // } - // //////console.log("item_banks"); - // //////console.log(response); + // ////////console.log("item_banks"); + // ////////console.log(response); // }).catch((error) => { - // //////console.log(error) + // ////////console.log(error) // // }); } @@ -239,7 +239,7 @@ class Questionitem_banks extends Component { if (this.state.item_type === "SINGLE") { if (this.answerMdRef != null) { //单选题 - // //console.log(this.answerMdRef.onSave()); + // ////console.log(this.answerMdRef.onSave()); if (this.answerMdRef.onSave().length === 0) { return; @@ -282,24 +282,24 @@ class Questionitem_banks extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`新增单选题成功`); + // this.props.showNotification(`新增单选题成功`); this.props.history.replace('/question'); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } else { axios.put(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`编辑单选题成功`); + // this.props.showNotification(`编辑单选题成功`); this.props.history.replace('/question'); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -311,7 +311,7 @@ class Questionitem_banks extends Component { if (this.state.item_type === "MULTIPLE") { if (this.Choques != null) { //多选题 - // //console.log(this.Choques.onSave()); + // ////console.log(this.Choques.onSave()); if (this.Choques.onSave().length === 0) { return; } @@ -319,8 +319,8 @@ class Questionitem_banks extends Component { const choices = []; // 1: [3] // 2: (4) ["1", "2", "3", "4"] - //console.log("MULTIPLE"); - //console.log(anserdata); + ////console.log("MULTIPLE"); + ////console.log(anserdata); for (var k = 0; k < anserdata[2].length; k++) { var bool = false @@ -360,26 +360,26 @@ class Questionitem_banks extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`新增多选题成功`); + // this.props.showNotification(`新增多选题成功`); this.props.history.replace('/question'); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } else { axios.put(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`编辑多选题成功`); + // this.props.showNotification(`编辑多选题成功`); this.props.history.replace('/question'); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -390,7 +390,7 @@ class Questionitem_banks extends Component { if (this.state.item_type === "JUDGMENT") { if (this.Judquestio != null) { //判断题 - // //console.log(this.Judquestio.onSave()); + // ////console.log(this.Judquestio.onSave()); if (this.Judquestio.onSave().length === 0) { return; } @@ -427,24 +427,24 @@ class Questionitem_banks extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`新增判断题成功`); + // this.props.showNotification(`新增判断题成功`); this.props.history.replace('/question'); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } else { axios.put(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`编辑判断题成功`); + // this.props.showNotification(`编辑判断题成功`); this.props.history.replace('/question'); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -476,13 +476,13 @@ class Questionitem_banks extends Component { this.setState({ item_type: item_type }) - + this.scrollToAnchor("Itembankstopid"); } render() { let {page, limit, count, Headertop, visible, placement, modalsType, item_type} = this.state; const params = this.props && this.props.match && this.props.match.params; - // //console.log(params); + // ////console.log(params); return (
    +
    { item_type && item_type === "SINGLE" ? @@ -555,9 +556,8 @@ class Questionitem_banks extends Component { : item_type && item_type === "PROGRAM" ? "" : "" - } - - + } +
    diff --git a/public/react/src/modules/question/animation/parabola.js b/public/react/src/modules/question/animation/parabola.js new file mode 100644 index 000000000..439babd9d --- /dev/null +++ b/public/react/src/modules/question/animation/parabola.js @@ -0,0 +1,51 @@ +/** + * 抛物线动画函数 + * @param ballWrapper 小球的父容器 + * @param origin 动画起点DOM + * @param target 动画目标DOM + * @param time 持续时间 + * @param a 抛物线参数 + * @param offset 动画尺寸 + * @param callback 回调 + */ + +export function parabola(config) { + const { + ballWrapper, + origin, + target, + time = 1000, + a = 0.004, + callback, + finish, + offset = 0 + } = + config || {}; + const ballWrapperDimension = ballWrapper.getBoundingClientRect(); + const originDimension = origin.getBoundingClientRect(); + const targetDimension = target.getBoundingClientRect(); + const x1 = originDimension.left + 0.5 * originDimension.width; + const y1 = originDimension.top + 0.5 * originDimension.height; + const x2 = targetDimension.left + 0.5 * targetDimension.width; + const y2 = targetDimension.top + 0.5 * targetDimension.height; + const diffx = x2 - x1; + const diffy = y2 - y1; + const speedx = diffx / time; + const b = (diffy - a * diffx * diffx) / diffx; + + const refPoint_x = x1 - ballWrapperDimension.left - 0.5 * offset; + const refPoint_y = y1 - ballWrapperDimension.top - 0.5 * offset; + + const start = Date.now(); + const timer = setInterval(() => { + if (Date.now() - start > time) { + finish(); + clearInterval(timer); + return; + } + + const x = speedx * (Date.now() - start); + const y = a * x * x + b * x; + callback && callback(refPoint_x + x, refPoint_y + y); + }, 15); +} diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index 28ef8e8a5..3637fad3e 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,18 +71,21 @@ 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 = () => { const { question_choices, standard_answers } = this.state; - // ////console.log("addOption"); - // ////console.log(question_choices); - // ////console.log(standard_answers); + // //////console.log("addOption"); + // //////console.log(question_choices); + // //////console.log(standard_answers); question_choices.push('') @@ -91,8 +95,8 @@ class ChoquesEditor extends Component{ deleteOption = (index) => { let {question_choices}=this.state; - // ////console.log("deleteOption"); - // ////console.log(question_choices); + // //////console.log("deleteOption"); + // //////console.log(question_choices); if(question_choices[index]===""){ // repeat code @@ -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, }) @@ -198,15 +199,17 @@ class ChoquesEditor extends Component{ } } componentDidUpdate(prevProps) { - //console.log("componentDidUpdate"); - // //console.log(prevProps); - // //console.log(this.props.item_banksedit); + ////console.log("componentDidUpdate"); + // ////console.log(prevProps); + // ////console.log(this.props.item_banksedit); 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, @@ -260,9 +333,9 @@ class ChoquesEditor extends Component{ // [true, false, true] -> [0, 2] const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1); - // ////console.log("xuanzheshijuan"); - // ////console.log(answerTagArray); - // ////console.log(!exerciseIsPublish); + // //////console.log("xuanzheshijuan"); + // //////console.log(answerTagArray); + // //////console.log(!exerciseIsPublish); return(
    @@ -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,25 +364,30 @@ 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 */} {/* */} - this.onOptionClick(index)} style={{flex: '0 0 38px'}}>
    {tagArray[index]}
    @@ -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 9b576af24..96ac64153 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,21 +34,74 @@ class Contentpart extends Component { } chakanjiexibool=(index)=>{ - debugger - if(this.state.chakanjiexiboolindex===index){ - this.setState({ - chakanjiexiboolindex:"无", - }) - return + this.props.chakanjiexibool(index); + } + componentDidUpdate(prevProps) { + if(prevProps.current_user !== this.props.current_user) { + debugger + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.props; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ + defaultActiveKeys="1" + } + this.props.callback(defaultActiveKeys); } - this.setState({ - chakanjiexiboolindex: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}=this.props; + let {defaultActiveKey,item_type,booljupyterurls}=this.props; + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + + const content = (

    this.props.setoj_status(null)}>全部

    @@ -82,11 +134,12 @@ class Contentpart extends Component {
    ); - const buttonWidth = 70; - //console.log("Contentpart"); - //console.log(this.props); + + //console.log("Contentpart.js"); + //console.log(this.props.defaultActiveKey); + return ( -
    +
    - this.props.callback(e)}> - - - - - + + + { + isysladmins===true||(is_teacher===true&&professional_certification===true)? + this.props.callback(e)}> + + + + + + : + this.props.callback(e)}> + + + + } +
    { defaultActiveKey===0||defaultActiveKey==="0"? - -
    -

    新增

    -
    -
    + isysladmins===true||(is_teacher===true&&professional_certification===true)? + this.props.Isitapopup&&this.props.Isitapopup==="true"? + "" + : + this.xinzenw(e)}> +
    +

    新增

    +
    +
    + :"" :"" } - { + {item_type==="PROGRAM"? defaultActiveKey===0||defaultActiveKey==="0"? trigger.parentNode} placement="bottom" trigger="hover" content={contents} onVisibleChange={()=>this.props.handleVisibleChange(true)}>
    @@ -169,26 +238,25 @@ class Contentpart extends Component {
    : - "" + "":"" } - - - - {/* trigger.parentNode} placement="bottom" trigger="hover" content={content} onVisibleChange={()=>this.props.handleVisibleChanges(true)}>*/} - {/*
    */} - {/*
    */} - {/* 题型*/} - {/*
    */} - {/* */} - {/*
    */} - {/*
    */} - { defaultActiveKey===0||defaultActiveKey==="0"? + this.props.Isitapopup&&this.props.Isitapopup==="true"? + this.props.setdatafunsval(e)} + onSearch={ (value)=>this.props.setdatafuns(value)} /> + : this.props.setdatafuns(value)} /> : { - defaultActiveKey===1||defaultActiveKey==="1"? + defaultActiveKey===1||defaultActiveKey==="1"? this.props.selectallquestionsonthispage()} > :"" } @@ -241,6 +309,8 @@ 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/Contentquestionbank.js b/public/react/src/modules/question/component/Contentquestionbank.js index 4f7441956..79e8bbb88 100644 --- a/public/react/src/modules/question/component/Contentquestionbank.js +++ b/public/react/src/modules/question/component/Contentquestionbank.js @@ -20,9 +20,9 @@ class Contentquestionbank extends Component { } //初始化 componentDidMount(){ - ////console.log("componentDidMount"); - ////console.log(this.state); - ////console.log(this.props); + //////console.log("componentDidMount"); + //////console.log(this.state); + //////console.log(this.props); // let homeworkid = this.props.match.params.homeworkid; // let url = "/homework_commons/" + homeworkid + "/end_groups.json"; // axios.get(url).then((response) => { @@ -30,16 +30,17 @@ class Contentquestionbank extends Component { // this.setState({}) // } // }).catch((error) => { - // ////console.log(error) + // //////console.log(error) // }); } onChange=(e)=> { - ////console.log(`checked = ${e.target.checked}`); + //////console.log(`checked = ${e.target.checked}`); } render() { let {page}=this.state; + let {selectionbools}=this.props; return ( @@ -47,7 +48,13 @@ class Contentquestionbank extends Component {
    - this.props.selectallquestionsonthispage()}> + { + selectionbools===true? + this.props.selectallquestionsonthispage()} disabled> + : + this.props.selectallquestionsonthispage()}> + + }

    选用本页全部试题

    diff --git a/public/react/src/modules/question/component/Headplugselection.js b/public/react/src/modules/question/component/Headplugselection.js index 142a316cb..26495fdf8 100644 --- a/public/react/src/modules/question/component/Headplugselection.js +++ b/public/react/src/modules/question/component/Headplugselection.js @@ -77,8 +77,8 @@ class Headplugselection extends Component { } render() { let {page,titlestting,titlesttings,titlesttingss}=this.state; - // console.log("Headplugselection"); - // console.log(this.props.disciplinesdata); + // //console.log("Headplugselection"); + // //console.log(this.props.disciplinesdata); // disciplinesdatakc:kc, // disciplinesdatazsd:zsd, var kc=0; diff --git a/public/react/src/modules/question/component/Headplugselections.js b/public/react/src/modules/question/component/Headplugselections.js index 3cff40cc2..643729ec1 100644 --- a/public/react/src/modules/question/component/Headplugselections.js +++ b/public/react/src/modules/question/component/Headplugselections.js @@ -48,10 +48,7 @@ class Headplugselections extends Component { componentDidMount(){ } -// -// setdiscipline_id={(e)=>this.setdiscipline_id(e)} -// setsub_discipline_id={(e)=>this.setsub_discipline_id(e)} -// settag_discipline_id={(e)=>this.settag_discipline_id(e)} + settitlestting=(name,id)=>{ //如果全部其他的选项重置 this.setState({ @@ -87,8 +84,8 @@ class Headplugselections extends Component { //获取方向 shixunsearchAll = (id) => { - console.log("获取方向"); - console.log(id); + //console.log("获取方向"); + //console.log(id); if(id!=undefined){ this.setState({ shixunsearchAllvalue:id, @@ -130,16 +127,16 @@ class Headplugselections extends Component { } getshixunchildValue = (id,ids) => { - console.log("getshixunchildValue"); - console.log(id); - debugger + // //console.log("getshixunchildValue"); + // //console.log(id); + // debugger if(id!=undefined ||ids!=undefined){ this.setState({ shixunsearchAllvalue:ids }) try { - this.props.setsub_discipline_id(id); + this.props.setsub_discipline_id(ids,id); }catch (e) { } @@ -153,7 +150,7 @@ class Headplugselections extends Component { { item&&item.map((list,k)=>{ return( - + diff --git a/public/react/src/modules/question/component/IntelligentModel.js b/public/react/src/modules/question/component/IntelligentModel.js new file mode 100644 index 000000000..016c00d2c --- /dev/null +++ b/public/react/src/modules/question/component/IntelligentModel.js @@ -0,0 +1,221 @@ +import React, { Component } from 'react'; +import {getImageUrl} from 'educoder'; +import { Modal} from 'antd'; +import axios from 'axios'; +import { + notification, + Spin, + Table, + Pagination, + Radio, + Checkbox, + Form, + Input, + Select, + Cascader, + Col, Row, InputNumber, DatePicker, AutoComplete, Button, Tag,Icon +} from "antd"; +import './../questioncss/questioncom.css'; +const InputGroup = Input.Group; +const {Option} = Select; +//智能组卷化弹框 +class IntelligentModel extends Component { + + constructor(props) { + super(props); + this.state={ + iconLoading:false, + } + } + + handleSubmit=()=>{ + + } + + handleSearch=(value)=>{ + + + if(value!=""){ + this.props.form.setFieldsValue({ + classroom:value, + // course:value + }); + // this.Searchvalue(value) + } + + }; + + Confirmationofvolumeformation=()=>{ + + this.props.form.validateFields((err, values) => { + if (!err) { + this.setState({ + iconLoading:true + }) + const url=`/examination_intelligent_settings/${this.props.exam_id}/save_exam.json`; + let data={ + name:values.classroom, + duration:values.kssc + } + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + //console.log(result); + this.props.history.push(`/paperlibrary`); + + } + setTimeout(() => { + this.setState({ + iconLoading:false + }) + }, 1500) + + }).catch((error) => { + setTimeout(() => { + this.setState({ + iconLoading:false + }) + }, 1500) + }) + + + + } + + }); + + } + + + render() { + let {iconLoading}=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('classroom', { + rules: [{required: true, message: "不能为空"}], + })( + + + + + )} +
    +
    +
    + +
    + +
    + + + {getFieldDecorator('kssc')()} + 分钟 + +
    + + +
    +
    提示:组卷完成后,在试卷库—我的试卷库查看!
    + +
    + +
    + this.props.Confirmationofvolumeformations()}>取消 + + +
    +
    + ) + } +} + +const IntelligentModels = Form.create({name: 'IntelligentModel'})(IntelligentModel); +export default IntelligentModels; diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 8ff1307b8..b7143f6a1 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -13,12 +13,14 @@ import { Input, Select, Cascader, - Col, Row, InputNumber, DatePicker, AutoComplete, Button, Tag + Col, Row, InputNumber, DatePicker, AutoComplete, Button, Tag,Tooltip } from "antd"; 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,41 @@ class Itembankstop extends Component { knowledgepoints: [], knowledgepoints2:[], options: [], - NewknTypedel:false + NewknTypedel:false, + boolred:false, + boolnews:false, + } } + setboolred=(bool)=>{ + this.setState({ + boolred:bool + }) + + } + //初始化 componentDidMount() { + + const params = this.props && this.props.match && this.props.match.params; + if (JSON.stringify(params) === "{}") { + // "新增" + this.setState({ + boolnews:false, + }) + } else { + if(params){ + if( params.id){ + this.setState({ + boolnews:true, + }) + } + } + } + + + try { this.props.getcontentMdRef(this); } catch (e) { @@ -68,7 +99,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 +156,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 +188,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) { } } @@ -119,12 +218,13 @@ class Itembankstop extends Component { this.handleFormtixing(this.props.item_banksedit.item_type); } if (this.props.item_banksedit.difficulty) { - this.handleFormLayoutChange(this.props.item_banksedit.difficulty); + this.handleFormLayoutChangeysl(this.props.item_banksedit.difficulty); } if (this.props.item_banksedit.tag_disciplines) { 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 +275,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] @@ -216,8 +351,8 @@ class Itembankstop extends Component { this.props.form.validateFields((err, values) => { data = [] if (!err) { - // ////console.log("获取的form 数据"); - // ////console.log(values); + // //////console.log("获取的form 数据"); + // //////console.log(values); data.push({ rbnd: parseInt(values.rbnd) }) @@ -241,31 +376,42 @@ class Itembankstop extends Component { e.preventDefault(); this.props.form.validateFields((err, values) => { if (!err) { - ////console.log("获取的form 数据"); - ////console.log(values); + //////console.log("获取的form 数据"); + //////console.log(values); } }); } - - handleFormLayoutChange = (value) => { + handleFormLayoutChangeysl = (value) => { //难度塞选 - ////console.log("难度塞选"); - ////console.log(value); + //////console.log("难度塞选"); + //////console.log(value); this.props.form.setFieldsValue({ - rbnd: value + "", + rbnd: value+ "", }); this.setState({ rbnd: value + "", }) + } + handleFormLayoutChange = (e) => { + //难度塞选 + //////console.log("难度塞选"); + //////console.log(value); + this.props.form.setFieldsValue({ + rbnd: e.target.value + "", + }); + this.setState({ + rbnd: e.target.value + "", + }) + } handleFormkechen = (value) => { //课程 - ////console.log("课程"); - ////console.log(value); + //////console.log("课程"); + //////console.log(value); if(this.state.Knowpoints.length>4){ this.props.showNotification(`知识点最多选择5个`); return @@ -286,8 +432,8 @@ class Itembankstop extends Component { const _result =[]; this.state.knowledgepoints.filter(item => { if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { - console.log("guonue"); - console.log(item); + // //console.log("guonue"); + // //console.log(item); _result.push(item); } }); @@ -302,8 +448,8 @@ class Itembankstop extends Component { } handleFormzhishidian = (value) => { - console.log("handleFormzhishidian 课程"); - console.log(value); + //console.log("handleFormzhishidian 课程"); + //console.log(value); //课程 this.props.form.setFieldsValue({ @@ -312,8 +458,8 @@ class Itembankstop extends Component { this.setState({ rbkc:value, }) - // console.log("handleFormzhishidian"); - // console.log(this.props.disciplinesdata); + // //console.log("handleFormzhishidian"); + // //console.log(this.props.disciplinesdata); const didata = this.props.disciplinesdata; const knowledgepointsdata = []; @@ -357,8 +503,8 @@ class Itembankstop extends Component { handleFormtixing = (value) => { //题型 - //console.log("题型"); - //console.log(value); + ////console.log("题型"); + ////console.log(value); this.setState({ rbtx: value + "", }) @@ -369,7 +515,7 @@ class Itembankstop extends Component { } preventDefault = (e) => { e.preventDefault(); - ////console.log('Clicked! But prevent default.'); + //////console.log('Clicked! But prevent default.'); } deletesobject = (item, index) => { @@ -413,6 +559,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 +570,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] @@ -443,27 +606,45 @@ class Itembankstop extends Component { axios.post(url,data) .then((result) => { if (result.data.status === 0) { - this.props.showNotification(`新增知识点成功!`); + // this.props.showNotification(`新增知识点成功!`); var leydata={ 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); + ////console.log(error); }) this.setState({ @@ -476,6 +657,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 (
    @@ -495,7 +681,7 @@ class Itembankstop extends Component { height: 33px !important; } .ant-input-group{ - width:258px !important; + width:270px !important; } .ant-input { height: 33px !important; @@ -512,6 +698,8 @@ class Itembankstop extends Component { { NewknTypedel? this.setboolred(bool)} NewknTypedeldel={(bool)=>this.NewknTypedeldel(bool)} NewknTypedeltyoedel={(value)=>this.NewknTypedeltyoedel(value)} > @@ -519,32 +707,29 @@ class Itembankstop extends Component { }
    - +
    {getFieldDecorator("rbkc", - { + {initialValue: this.state.rbkc, rules: [{required: true, message: '请选择课程'}], } )( -
    - - - -
    )}
    +
    {getFieldDecorator("rbzsd" )(
    - - - - this.NewknTypedeldel(true)}/> + this.NewknTypedeldel(true)}/> -
    + )} + + { + this.state.Knowpoints===undefined||this.state.Knowpoints===null?"": + this.state.Knowpoints.length>0? +
    - {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { return ( -

    {object.name}

    - this.deletesobject(object, index)} src={getImageUrl("/images/educoder/bzucha.png")}/> + this.deletesobject(object, index)} src={getImageUrl("images/educoder/bzucha.png")}/>
    ) })} +
    + : + "" + } -
    -
    - )} -
    - {getFieldDecorator("rbtx", - { + {initialValue: this.state.rbtx, rules: [{required: true, message: '请选择题型'}], } )( - - - )} - - 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 3c24c6a6b..92a5a9e3a 100644 --- a/public/react/src/modules/question/component/Listjihe.js +++ b/public/react/src/modules/question/component/Listjihe.js @@ -1,71 +1,123 @@ 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.', 'S.', 'T.', 'U.', 'V.', 'W.', 'X.', 'Y.', 'Z.' ] +const tagArrays = [ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + '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={ - item_ids:[id] - } - this.props.getitem_baskets(data); + 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), + } + } + + 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; + + // 编程答案 + 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 (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]; + } - render() { - 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.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{ + 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; + } + } } } } @@ -74,194 +126,335 @@ class Listjihe extends Component { } } + var itemssname=""; + try { + itemssname= JSON.parse(items.name); + }catch (e) { + } + if(itemssname===undefined){ + itemssname=items.name + } + + + var itemsnamesy=""; + try { + itemsnamesy= JSON.parse(items&&items.program_attr&&items.program_attr.description); + + }catch (e) { + itemsnamesy=items&&items.program_attr&&items.program_attr.description; + } + + var analysisnames=""; + try { + analysisnames= JSON.parse(items&&items.analysis); + }catch (e) { + analysisnames=items&&items.analysis; + } return ( -
    +
    {/*顶部*/} +
    { this.props.listjihe - } -
    -
    - . -
    -
    + }.
    + { + 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 === undefined ||items === null? "" : items.choices.map((object, index) => { - return ( -

    - - {object.choice_text} - -

    - ) - }) - } -

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

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

    + + {object.choice_text} + +

    + ) + }) + } +

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

    -

    -

    +

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

    + +

    + :"" + } + + + +

    +

    + : +

    + { + items === undefined || items === null ? "" : items.choices.map((object, index) => { + var string="" + try { + string=JSON.parse(object.choice_text); + }catch (e) { + string=object.choice_text; + } + return ( +

    +

    {tagArray[index]}

    +

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

    +

    + ) + }) + }

    - : -

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

    - {tagArray[index]} -

    -

    - ) - }) - } -

    }
    -

    难度:{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}

    +

    更新时间:{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.program_attr.language}

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

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

    + : "" + } + { + 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" ? + this.props.Isitapopup&&this.props.Isitapopup==="true"? + "" + : -

    +

    编辑

    : + this.props.Isitapopup&&this.props.Isitapopup==="true"? + "" + : -

    +

    编辑

    } { - 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)}> + items.apply===false? +

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

    + : + "" + :items.apply===false? +

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

    : -

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

    + "" : - "" + "" }
    - :"" + : "" } { - 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&&items.analysis? - "" - :"" - } -
    -

    +

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

    -
    :"" +
    : "" } @@ -271,4 +464,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..36dd88e10 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/NoneData.js b/public/react/src/modules/question/component/NoneData.js index 123b7524e..f993190d5 100644 --- a/public/react/src/modules/question/component/NoneData.js +++ b/public/react/src/modules/question/component/NoneData.js @@ -21,7 +21,7 @@ class NoneData extends Component{ margin: 40px auto 20px; } .zenwuxgsj{ - font-size:17px; + font-size:14px; font-family:MicrosoftYaHei; color:rgba(136,136,136,1); } diff --git a/public/react/src/modules/question/component/Paperreview_itemModel.js b/public/react/src/modules/question/component/Paperreview_itemModel.js index 0759bb677..b4ceacc02 100644 --- a/public/react/src/modules/question/component/Paperreview_itemModel.js +++ b/public/react/src/modules/question/component/Paperreview_itemModel.js @@ -13,8 +13,8 @@ class Paperreview_itemModel extends Component { } onChange=(value)=>{ - console.log("设置批量得分"); - console.log(value); + //console.log("设置批量得分"); + //console.log(value); this.setState({ value:value, }) diff --git a/public/react/src/modules/question/component/Paperreview_itemModels.js b/public/react/src/modules/question/component/Paperreview_itemModels.js index 167769313..ba7978aff 100644 --- a/public/react/src/modules/question/component/Paperreview_itemModels.js +++ b/public/react/src/modules/question/component/Paperreview_itemModels.js @@ -14,8 +14,8 @@ class Paperreview_itemModels extends Component { } onChange=(value)=>{ - console.log("Paperreview_itemModels"); - console.log(value); + //console.log("Paperreview_itemModels"); + //console.log(value); this.setState({ value:value, }) diff --git a/public/react/src/modules/question/component/SiderBars.js b/public/react/src/modules/question/component/SiderBars.js index 2717985fb..78674068c 100644 --- a/public/react/src/modules/question/component/SiderBars.js +++ b/public/react/src/modules/question/component/SiderBars.js @@ -25,7 +25,7 @@ $(window).scroll(function(){ function rightSlider(){ var poi=parseInt((parseInt($(window).width())- 1200 )/2)-81; - // console.log(parseInt($(window).width())+" "+poi); + // //console.log(parseInt($(window).width())+" "+poi); if(poi>0){ $(".-task-sidebar").css("right",poi); }else{ @@ -82,28 +82,38 @@ class SiderBars extends Component { } componentDidMount() { - _initSider() + // _initSider() } render() { - // console.log("SiderBar"); - // console.log(this.props); + // //console.log("SiderBar"); + // //console.log(this.props); var mypath= this.props&&this.props.match&&this.props.match.path; - let{myvisible}=this.props; + let{myvisible,Datacount,animateStyle}=this.props; return ( -
    +
    0?"-task-sidebar mystask-sidebars":"-task-sidebar mystask-sidebarss"} > {this.props.mygetHelmetapi&&this.props.mygetHelmetapi.main_site===true?
    { mypath&&mypath==="/question"? -
    this.props.showDrawer()} > + +
    this.props.showDrawer()} > + + { + Datacount&&Datacount>0? +
    + {Datacount} +
    + :"" + } + diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index c111aa41b..dffbf620c 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -52,8 +52,8 @@ class SingleEditor extends Component{ if(this.props.item_banksedit.choices){ this.props.item_banksedit.choices.forEach((item, index) => { - //console.log("SingleEditor"); - //console.log(item); + ////console.log("SingleEditor"); + ////console.log(item); choicescomy.push({ choice_text:item.choice_text, standard_boolean:item.is_answer, @@ -75,19 +75,21 @@ 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:[], } } addOption = () => { const { question_choices, standard_answers } = this.state; - // ////console.log("addOption"); - // ////console.log(question_choices); - // ////console.log(standard_answers); + // //////console.log("addOption"); + // //////console.log(question_choices); + // //////console.log(standard_answers); question_choices.push('') @@ -97,8 +99,8 @@ class SingleEditor extends Component{ deleteOption = (index) => { let {question_choices}=this.state; - // ////console.log("deleteOption"); - // ////console.log(question_choices); + // //////console.log("deleteOption"); + // //////console.log(question_choices); if(question_choices[index]===""){ // repeat code @@ -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, }) @@ -194,18 +207,19 @@ class SingleEditor extends Component{ }catch (e) { } - } componentDidUpdate(prevProps) { - //console.log("componentDidUpdate"); - // //console.log(prevProps); - // //console.log(this.props.item_banksedit); + ////console.log("componentDidUpdate"); + // ////console.log(prevProps); + // ////console.log(this.props.item_banksedit); 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, }) @@ -214,10 +228,10 @@ class SingleEditor extends Component{ onOptionClick = (index) => { let standard_answers = this.state.standard_answers.slice(0); - // ////console.log("onOptionClick"); - // ////console.log(standard_answers); - // ////console.log(standard_answers[index]); - // ////console.log(!standard_answers[index]); + // //////console.log("onOptionClick"); + // //////console.log(standard_answers); + // //////console.log(standard_answers[index]); + // //////console.log(!standard_answers[index]); for (var i=0;i { + 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 +285,69 @@ class SingleEditor extends Component{ } - onContentChange=(e)=>{ - console.log(e); + onContentChange=(value,quill)=>{ + var _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 + }) + try { + //console.log("onContentChange"); + //console.log(quill.getText().length); + }catch (e) { + + } + } } + 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, @@ -276,18 +365,18 @@ class SingleEditor extends Component{ // [true, false, true] -> [0, 2] const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1); - // ////console.log("xuanzheshijuan"); - // ////console.log(answerTagArray); - // ////console.log(!exerciseIsPublish); - + // //////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 4f6099202..000000000 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpapers.js +++ /dev/null @@ -1,640 +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 53f073656..bc1e8cd00 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 { @@ -125,7 +131,9 @@ class Comthetestpaperst extends Component { // this.handleFormtixing(this.props.item_banksedit.item_type); // } if (this.props.item_banksedit.difficulty) { - this.handleFormLayoutChange(this.props.item_banksedit.difficulty); + // this.handleFormLayoutChange(this.props.item_banksedit.difficulty); + this.handleFormLayoutChangeysl(this.props.item_banksedit.difficulty); + } if (this.props.item_banksedit.tag_disciplines) { this.handletag_disciplinesChange(this.props.item_banksedit.tag_disciplines); @@ -231,7 +239,7 @@ class Comthetestpaperst extends Component { }; handleChange=(e)=>{ - console.log(e); + //console.log(e); this.props.form.setFieldsValue({ // course:value, classroom:e.target.value, @@ -316,19 +324,19 @@ class Comthetestpaperst extends Component { e.preventDefault(); this.props.form.validateFields((err, values) => { if (!err) { - ////console.log("获取的form 数据"); - ////console.log(values); + //////console.log("获取的form 数据"); + //////console.log(values); } }); } - - handleFormLayoutChange = (value) => { + handleFormLayoutChangeysl = (value) => { //难度塞选 - ////console.log("难度塞选"); - ////console.log(value); + //////console.log("难度塞选"); + //////console.log(value); + this.props.form.setFieldsValue({ rbnd: value + "", }); @@ -336,11 +344,24 @@ class Comthetestpaperst extends Component { rbnd: value + "", }) + } + handleFormLayoutChange = (e) => { + //难度塞选 + //////console.log("难度塞选"); + //////console.log(value); + + this.props.form.setFieldsValue({ + rbnd: e.target.value + "", + }); + this.setState({ + rbnd: e.target.value + "", + }) + } handleFormkechen = (value) => { //课程 - ////console.log("课程"); - ////console.log(value); + //////console.log("课程"); + //////console.log(value); if(this.state.Knowpoints.length>4){ this.props.showNotification(`知识点最多选择5个`); return @@ -361,8 +382,8 @@ class Comthetestpaperst extends Component { const _result =[]; this.state.knowledgepoints.filter(item => { if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { - console.log("guonue"); - console.log(item); + //console.log("guonue"); + //console.log(item); _result.push(item); } }); @@ -377,8 +398,8 @@ class Comthetestpaperst extends Component { } handleFormzhishidian = (value) => { - console.log("handleFormzhishidian 课程"); - console.log(value); + //console.log("handleFormzhishidian 课程"); + //console.log(value); //课程 this.props.form.setFieldsValue({ @@ -387,8 +408,8 @@ class Comthetestpaperst extends Component { this.setState({ rbkc:value, }) - // console.log("handleFormzhishidian"); - // console.log(this.props.disciplinesdata); + // //console.log("handleFormzhishidian"); + // //console.log(this.props.disciplinesdata); const didata = this.props.disciplinesdata; const knowledgepointsdata = []; @@ -432,8 +453,8 @@ class Comthetestpaperst extends Component { handleFormtixing = (value) => { //题型 - //console.log("题型"); - //console.log(value); + ////console.log("题型"); + ////console.log(value); this.setState({ rbtx: value + "", }) @@ -444,7 +465,7 @@ class Comthetestpaperst extends Component { } preventDefault = (e) => { e.preventDefault(); - ////console.log('Clicked! But prevent default.'); + //////console.log('Clicked! But prevent default.'); } deletesobject = (item, index) => { debugger @@ -488,6 +509,10 @@ class Comthetestpaperst extends Component { } NewknTypedeldel=(bool)=>{ + if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ + this.props.showNotification(`请选择课程方向`); + return; + } this.setState({ NewknTypedel:bool }) @@ -495,21 +520,30 @@ 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(`请选择课程方向`); - return; - } + var data={ name:value, sub_discipline_id:this.state.rbkc[1] @@ -518,27 +552,44 @@ class Comthetestpaperst extends Component { axios.post(url,data) .then((result) => { if (result.data.status === 0) { - this.props.showNotification(`新增知识点成功!`); + // this.props.showNotification(`新增知识点成功!`); var leydata={ 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); + ////console.log(error); }) this.setState({ @@ -575,7 +626,23 @@ class Comthetestpaperst extends Component { .ant-select-selection{ height: 33px !important; } - .ant-input-group{ + .kechen .ant-input-group{ + width:258px !important; + } + + .zsdd .ant-input-group{ + width:258px !important; + } + + .sjmc .ant-input-group{ + width:258px !important; + } + + .kssc .ant-input-group{ + width:258px !important; + } + + .rbndclass .ant-input-group{ width:258px !important; } .ant-input { @@ -593,6 +660,8 @@ class Comthetestpaperst extends Component { { NewknTypedel? this.setboolred(bool)} NewknTypedeldel={(bool)=>this.NewknTypedeldel(bool)} NewknTypedeltyoedel={(value)=>this.NewknTypedeltyoedel(value)} > @@ -600,24 +669,24 @@ class Comthetestpaperst extends Component { }
    - +
    +
    - {getFieldDecorator("rbkc", - { + {getFieldDecorator("rbkc" + , + {initialValue: this.state.rbkc, rules: [{required: true, message: '请选择课程'}], } )( -
    - - - - -
    )}
    +
    +
    +
    @@ -637,36 +706,37 @@ class Comthetestpaperst extends Component { - this.NewknTypedeldel(true)}/> + this.NewknTypedeldel(true)}/> -
    + )} + +
    + { + this.state.Knowpoints===undefined||this.state.Knowpoints===null?"": + this.state.Knowpoints.length>0? +
    - {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { return ( -

    {object.name}

    - this.deletesobject(object, index)} src={getImageUrl("/images/educoder/bzucha.png")}/> + this.deletesobject(object, index)} src={getImageUrl("images/educoder/bzucha.png")}/>
    ) })} - - - -
    -
    - )} - - + : + "" + }
    - {getFieldDecorator('rbnd', - { + {getFieldDecorator('rbnd' + , + {initialValue: this.state.rbnd, rules: [{required: true, message: '请选择难度'}], } )( - + 简单 适中 困难 diff --git a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js new file mode 100644 index 000000000..64d57e452 --- /dev/null +++ b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js @@ -0,0 +1,831 @@ +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, + Col, Row, InputNumber, DatePicker, AutoComplete, Button, Tag,Icon +} from "antd"; +import './../questioncss/questioncom.css'; +import Newknledpots from '../component/Newknledpots'; +import Ldanxuan from './lntlligentpone'; +const InputGroup = Input.Group; +const {Option} = Select; +//Itembankstop Comthetestpaperst 题库的 +class Intelligentcomponents extends Component { + constructor(props) { + super(props); + this.contentMdRef = React.createRef() + this.state = { + page: 1, + Knowpoints: [], + rbtx: undefined, + rbkc: undefined, + knowledgepoints: [], + knowledgepoints2:[], + options: [], + NewknTypedel:false, + boolred:false, + rbly:"1" + } + } + setboolred=(bool)=>{ + this.setState({ + boolred:bool + }) + + } + //初始化 + componentDidMount() { + try { + this.props.getJudquestio(this); + } catch (e) { + + } + this.setState({ + options: this.props.disciplmy, + + }) + + } + + componentDidUpdate(prevProps) { + //编辑的时候 + if (prevProps.disciplmy !== this.props.disciplmy) { + this.setState({ + options: this.props.disciplmy + }) + } + + } + + + + handdisciplinesChange =(name,title)=>{ + this.setState({ + rbkc:[name.id,title.id] + }) + this.props.form.setFieldsValue({ + rbkc: [name.id,title.id], + }); + + + + } + handleSearch=(value)=>{ + + + if(value!=""){ + this.props.form.setFieldsValue({ + classroom:value, + // course:value + }); + // this.Searchvalue(value) + } + + }; + handleChange=(e)=>{ + //console.log(e); + + 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 + }) + + } + + }; + + handletag_disciplinesChange = (data) => { + //是否选中的知识点 + try { + var sju=data[data.length-1].name; + this.setState({ + Knowpoints:data, + }) + this.props.form.setFieldsValue({ + rbzsd: sju, + }); + }catch (e) { + + } + + + } + onChange = (e) => { + + } + Getdatas = () => { + return this.handleSubmits(); + } + handleSubmits = () => { + var dxt=0; + var dxtx=0; + var pdt=0; + var bct=0; + try { + dxt=this.$dxt.mygetinputnumber(); + }catch (e) { + dxt=0; + } + + try { + dxtx=this.$ddxt.mygetinputnumber(); + }catch (e) { + dxtx=0; + } + + try { + pdt=this.$pdt.mygetinputnumber(); + }catch (e) { + pdt=0; + } + + try { + bct=this.$bct.mygetinputnumber(); + }catch (e) { + bct=0; + } + + + + + var data = []; + this.props.form.validateFields((err, values) => { + data = []; + if (!err) { + data.push({ + rbnd: parseInt(values.rbnd) + }) + data.push({ + rbzsd: this.state.Knowpoints + }) + data.push({ + rbkc: values.rbkc + }) + data.push({ + rbdxt: dxt + }) + data.push({ + rbdxtx: dxtx + }) + data.push({ + rbpdt: pdt + }) + data.push({ + rbbct: bct + }) + data.push({ + rbly: parseInt(values.rbly) + }) + } + }); + return data; + } + handleSubmit = (e) => { + e.preventDefault(); + this.props.form.validateFields((err, values) => { + if (!err) { + //////console.log("获取的form 数据"); + //////console.log(values); + + } + + + }); + } + handleFormLayoutChanges = (e) => { + // //console.log("handleFormLayoutChanges"); + // //console.log(value); + // debugger + //来源 + this.props.form.setFieldsValue({ + rbly: e.target.value + "", + }); + this.setState({ + rbly: e.target.value + "", + }) + + try { + this.props.getdatassssy(e.target.value); + }catch (e) { + + } + + } + handleFormLayoutChange = (e) => { + // //console.log("handleFormLayoutChange"); + // //console.log(value); + // debugger + //难度塞选 + this.props.form.setFieldsValue({ + rbnd: e.target.value + "", + }); + this.setState({ + rbnd: e.target.value + "", + }); + try { + this.props.getdatass(parseInt(e.target.value)); + }catch (e) { + + } + } + handleFormkechen = (value) => { + //课程 + if(this.state.Knowpoints.length>4){ + this.props.showNotification(`知识点最多选择5个`); + return + } + 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; + } + } + + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + + + this.setState({ + rbzsd: valuename, + Knowpoints: this.state.Knowpoints, + knowledgepoints2: _result, + }) + + try { + this.props.getdatassss(this.state.Knowpoints); + }catch (e) { + + } + + } + + 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, + knowledgepoints2:knowledgepointsdata, + }) + + this.props.form.setFieldsValue({ + rbzsd: undefined, + }); + this.setState({ + rbzsd: undefined, + }) + + try { + this.props.getdatasss(parseInt(value[1])); + }catch (e) { + + } + } + + 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 tmp = this.state.Knowpoints; + for (var i = 0; i < tmp.length; i++) { + if (i ===index) { + tmp.splice(i,1); + } + } + + this.props.form.setFieldsValue({ + rbzsd: this.state.Knowpoints, + }); + + 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, + knowledgepoints2:_result, + }) + 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) { + + } + + } + //删除知识点 + try { + this.props.getdatassss(this.state.Knowpoints); + }catch (e) { + + } + + } + + NewknTypedeldel=(bool)=>{ + if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ + this.props.showNotification(`请选择课程方向`); + return; + } + this.setState({ + NewknTypedel:bool + }) + + } + + 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 + } + + + var data={ + name:value, + sub_discipline_id:this.state.rbkc[1] + } + const url="/tag_disciplines.json"; + axios.post(url,data) + .then((result) => { + if (result.data.status === 0) { + // this.props.showNotification(`新增知识点成功!`); + var leydata={ + id: result.data.tag_discipline_id, + name:value, + } + + 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); + }) + //新增知识点 + try { + this.getdatassss(this.state.Knowpoints); + }catch (e) { + + } + this.setState({ + NewknTypedel:false + }) + } + + + + render() { + let {page, options,NewknTypedel,knowledgepoints,knowledgepoints2,Knowpoints} = this.state; + const {getFieldDecorator} = this.props.form; + const optionss = this.state.searchlist && this.state.searchlist.map(d => ); + + + return ( + +
    + +
    + { + NewknTypedel? + this.setboolred(bool)} + NewknTypedeldel={(bool)=>this.NewknTypedeldel(bool)} + NewknTypedeltyoedel={(value)=>this.NewknTypedeltyoedel(value)} + > + :"" + } + + +
    +
    + + {getFieldDecorator("rbkc" + , + {initialValue: this.state.rbkc, + rules: [{required: true, message: '请选择课程'}], + } + )( + + )} + +
    +
    +
    + + {getFieldDecorator("rbzsd" + )( +
    + + + + + + + this.NewknTypedeldel(true)}/> + + + +
    + )} +
    +
    + { + this.state.Knowpoints===undefined||this.state.Knowpoints===null?"": + this.state.Knowpoints.length>0? +
    + {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { + return ( +
    +

    {object.name}

    + + this.deletesobject(object, index)} src={getImageUrl("images/educoder/bzucha.png")}/> + +
    + ) + })} +
    + : + "" + } + + +
    + + {getFieldDecorator('rbly' + , + {initialValue: this.state.rbly, + } + )( + + 公共 + 我的 + , + )} + +
    + +

    条件设置

    +
    + + + +
    + + {getFieldDecorator('rbnd' + , + {initialValue: this.state.rbnd, + rules: [{required: true, message: '请选择难度'}], + } + )( + + 简单 + 适中 + 困难 + , + )} + +
    + + + + { + this.props.single_question_count===0&&this.props.multiple_question_count===0&&this.props.judgement_question_count===0&& + this.props.program_question_count===0? + "" + : +
    +

    题型及数量

    +
    + this.props.getdatas()} ref={dom => { + this.$dxt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$ddxt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$pdt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$bct = dom; + }}> +
    + + } + + +
    +
    + ) + + } + + +} + +const Intelligentcomponentss = Form.create({name: 'Intelligentcomponents'})(Intelligentcomponents); +export default Intelligentcomponentss; diff --git a/public/react/src/modules/question/comthetestpaper/lntlligentpone.js b/public/react/src/modules/question/comthetestpaper/lntlligentpone.js new file mode 100644 index 000000000..d9c6527c1 --- /dev/null +++ b/public/react/src/modules/question/comthetestpaper/lntlligentpone.js @@ -0,0 +1,169 @@ +import React, {Component} from "react"; +import {Link, NavLink} from 'react-router-dom'; +import {WordsBtn, ActionBtn, getImageUrl, markdownToHTML} from 'educoder'; +import axios from 'axios'; +import { + notification, + Spin, + Table, + Pagination, + Drawer, + Input, + Button, + Breadcrumb, + Icon, + InputNumber, + Tooltip +} from "antd"; +import '../questioncss/questioncom.css'; + +//判断题 +class lntlligentpone extends Component { + constructor(props) { + super(props); + + this.state = { + count: 0, + countbool: false, + } + + } + + //初始化 + componentDidMount() { + + + } + + increase = () => { + + const datasbool=this.props.getdatas(); + // if(datasbool===undefined || datasbool===null){ + // if(this.props.mycount===0){ + // this.props.showNotification(`题数为0无法增加题目`); + // return + // } + // + // } + + const count = this.state.count + 1; + if(count<=this.props.mycount){ + this.setState({count: count, countbool: false}); + } + + + }; + + decline = () => { + const datasbool=this.props.getdatas(); + // if(datasbool===undefined || datasbool===null){ + // if(this.props.mycount===0){ + // this.props.showNotification(`题数为0无法减少题目`); + // return + // } + // } + + let count = this.state.count - 1; + if (count < 0) { + count = 0; + } + this.setState({count: count, countbool: false}); + }; + inputsnumber = (value) => { + const datasbool=this.props.getdatas(); + // if(datasbool===undefined || datasbool===null){ + // if(this.props.mycount===0){ + // this.setState({count: 0, countbool: false}); + // this.props.showNotification(`题数为0无法输入`); + // return + // } + // } + + if(this.props.mycount===0){ + this.setState({count: 0, countbool: false}); + }else { + this.setState({count: value, countbool: false}); + } + + + } + + //返回数据 + mygetinputnumber=()=>{ + return this.state.count; + } + isNumber=(val)=>{ + var regPos = /^\d+(\.\d+)?$/; //非负浮点数 + var regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; //负浮点数 + if(regPos.test(val) && regNeg.test(val)){ + return true; + }else{ + return false; + } + } + + render() { + let {questions, totalscore, total, items} = this.state; + return ( +
    +

    {this.props.dxtx}

    + { + this.props.mycount===0? +
    + + + +
    + + + + + +
    + + + + +

    共{this.props.mycount}道

    +
    + : + +
    + +
    + +
    + +

    共{this.props.mycount}道

    +
    + + } + +
    + ) + + } + + +} + +export default lntlligentpone + + diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index f61cfb8fd..dcfdff84d 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -323,7 +323,8 @@ .listjihetixingstitsy { color: #333333; font-size: 14px; - line-height: 25px; + line-height: 20px !important; + height: 25px !important; } .listjihetixingstits{ @@ -332,6 +333,12 @@ line-height:19px; margin-top: 19px; } +.listjihetixingstitsp{ + color: #333333; + font-size: 14px; + line-height:19px; + margin-top: 10px; +} .listjihetixingstitssy{ color: #333333; font-size: 14px; @@ -372,7 +379,7 @@ .selectionss{ width:88px; height:30px; - background:#eeeeee; + background:#CCCCCC; border-radius:4px; text-align: center; line-height: 30px; @@ -399,7 +406,7 @@ padding-bottom: 20px; } .icontianjiadaohangcolor{ - color: #FFFFFF; + color: #ffffff; } .icontianjiadaohangcolors{ @@ -518,11 +525,18 @@ margin-top: 19px; } .mytags{ - width:106px; + min-width:106px !important; height:32px; border-radius:2px; border:1px solid #DDDDDD; - margin-left: 20px; + margin-right: 20px; +} +.mytagss{ + min-width:106px !important; + height:32px; + border-radius:2px; + border:1px solid #DDDDDD; + margin-right: 20px; } .lh32{ line-height: 32px; @@ -747,6 +761,17 @@ font-size:12px; } +.szdfds{ + width:100px; + height:40px; + background:#FC7E30; + border-radius:4px 4px 0px 0px; + text-align: center; + color: #ffffff; + line-height: 40px; + margin-right: 27px; + font-size:12px; +} .pd20{ padding: 20px; @@ -779,6 +804,9 @@ line-height: 20px; background-color: #fff; } +.lh20s{ + line-height: 20px; +} .backgroudwhites{ background-color: #fff; @@ -882,3 +910,159 @@ border-radius: 4px; top: -50%; } +.shitikussmys{ + width:29px !important; + height:20px!important; + background:#FF6601 !important; + border-radius:10px !important; + position: absolute !important; + font-size:11px !important; + color:#ffffff !important; + line-height:20px !important; + top: -14px !important; + right: -14px !important; +} + + +.maxnamewidth30{ + max-width: 30px; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; + cursor: default; +} +.ball { + width: 8px; + height: 8px; + background: #FF6601; + position: absolute; + left: 0; + top: 0; + border-radius: 50%; + opacity: 0; + z-index: 1; +} + +.mt25{ + margin-top: 25px; +} + +.mr15{ + margin-right: 15px; +} +.fangdatwo{ + background: #fefefe; + background-color: #fefefe; + height: 100%; + overflow-y: scroll !important; + width: 100%; + position: fixed; + top:0px; + bottom: 0px; + left: 0px; + z-index: 999999; + right: 0px; +} + +.searchwidth{ + width: 347px !important; +} +.lh26{ + line-height: 26px !important; +} +.tites{ + color: #888888 !important; +} +.ant-popover-inner-content{ + padding: 0px !important; +} + +.huanhan{ + flex-wrap: wrap; +} +.mb20{ + margin-bottom: 20px; +} + +.inpustred .ant-input{ + border: 1px solid #f30707; + border-radius: 5px; +} + +.mt15{ + margin-top: 15px; +} +.conditionsetting{ + width:64px; + height:21px; + font-size:16px; + color:#333333; + line-height:21px; +} +.hengxians{ + width:1021px; + height:1px; + background: #EEEEEE; +} +.mt13{ + margin-top: 13px; +} +.inpustredss .ant-input-number{ + border: 1px solid #f30707; + border-radius: 5px; +} + +.inpustredssdiv button { + border-radius: 50%; + width: 38px; + height: 38px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.inpustredssdiv .ant-input-number-input{ + text-align: center; +} +.lh32{ + line-height: 32px; +} +.ml23{ + margin-left: 23px; +} +.ml12{ + margin-left: 12px; +} +.mr12{ + margin-right: 12px; +} +.tishiyuyan{ + color: #888888 !important; + font-size:14px; +} +.tishiyuyans{ + color: #4CACFF !important; + font-size:14px; +} +.tikutask-btn{ + width:80px; + height:34px; + background:rgba(204,204,204,1); + border-radius:4px; +} +.tikutask-btns{ + width:80px; + height:34px; + background:rgba(76,172,255,1); + border-radius:4px; +} +.w100{ + width: 100px !important; +} +.h34{ + height: 34px !important; +} +.lh34{ + line-height: 34px !important; +} diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js new file mode 100644 index 000000000..8776b6a9e --- /dev/null +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -0,0 +1,418 @@ +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, + Drawer, + Input, + Button, + Breadcrumb +} from "antd"; +import {TPMIndexHOC} from "../tpm/TPMIndexHOC"; +import './testioncss/testioncss.css'; +import '../tpm/newshixuns/css/Newshixuns.css'; +import Bottomsubmit from "../../modules/modals/Bottomsubmit"; +import Intelligentcomponents from "../question/comthetestpaper/Intelligentcomponents"; + +//试卷编辑 +class Intecomponents extends Component { + constructor(props) { + super(props); + this.Judquestio = React.createRef(); + this.state = { + paperlibrartdata: [], + disciplinesdata: [], + knowledgepoints: [], + disciplmy: [], + item_banksedit: [], + newmyshixunmodelbool:false, + single_question_count:0, + multiple_question_count:0, + judgement_question_count:0, + program_question_count:0, + } + + + } + + getJudquestio = (Ref) => { + //console.log("子组件对象"); + //console.log(Ref); + this.Judquestio = Ref; + } + + //初始化 + componentDidMount() { + let urls = `/disciplines.json`; + axios.get(urls, { + params: { + source: "question" + } + }).then((response) => { + if (response) { + this.setState({ + disciplinesdata: response.data.disciplines, + }) + if (response.data) { + if (response.data.disciplines) { + + const didata = response.data.disciplines; + + for (var i = 0; i < didata.length; i++) { + const childern = []; + //方向 + const fxdidata = didata[i].sub_disciplines; + + + for (var j = 0; j < fxdidata.length; j++) { + //课程 + const zsddata = fxdidata[j].tag_disciplines; + childern.push( + { + value: fxdidata[j].id, + label: fxdidata[j].name, + } + ) + for (var k = 0; k < zsddata.length; k++) { + //知识点 + this.state.knowledgepoints.push(zsddata[k]); + + + } + } + + const datakec = { + value: didata[i].id, + label: didata[i].name, + children: childern, + } + this.state.disciplmy.push(datakec); + } + + this.setState({ + knowledgepoints: this.state.knowledgepoints, + disciplmy: this.state.disciplmy, + }) + + + } + + } + + } + }); + + + + + } + //难度 + getdatas=()=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + //console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + + this.getwangluodata(url,data); + + } + //课程 + getdatasss=(kech)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + //console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:kech, + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + + this.getwangluodata(url,data); + + } + //知识点 + getdatassss=(zhishidian)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + //console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=zhishidian; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + this.getwangluodata(url,data); + } + + //来源 + getdatassssy=(rbly)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + //console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + this.getwangluodata(url,data); + } + + + getwangluodata=(url,data)=>{ + axios.post(url,data).then((response) => { + if (response) { + //console.log("智能组卷"); + //console.log(response); + if(response.data){ + this.setState({ + single_question_count:response.data.single_question_count, + multiple_question_count:response.data.multiple_question_count, + judgement_question_count:response.data.judgement_question_count, + program_question_count:response.data.program_question_count, + }) + + } + + } + }); + } + //难度 + getdatass=(nandu)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + //console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:nandu, + } + + axios.post(url,data).then((response) => { + if (response) { + //console.log("智能组卷"); + //console.log(response); + if(response.data){ + this.setState({ + single_question_count:response.data.single_question_count, + multiple_question_count:response.data.multiple_question_count, + judgement_question_count:response.data.judgement_question_count, + program_question_count:response.data.program_question_count, + }) + + } + + } + }); + + } + + + componentDidUpdate(prevProps) { + + } + + + + //跳转道描点的地方 + scrollToAnchor = (anchorName) => { + try { + if (anchorName) { + // 找到锚点 + let anchorElement = document.getElementById(anchorName); + // 如果对应id的锚点存在,就跳转到锚点 + if (anchorElement) { + anchorElement.scrollIntoView(); + } + } + } catch (e) { + + } + + } + preservation = () => { + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return; + } + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + // //console.log(myrbkc); + // //console.log("preservation"); + // //console.log(this.Judquestio.Getdatas()); + + + var question_settings =[ + { + "item_type": "SINGLE", + "count": this.Judquestio.Getdatas()[3].rbdxt + }, + { + "item_type": "MULTIPLE", + "count": this.Judquestio.Getdatas()[4].rbdxtx + }, + { + "item_type": "JUDGMENT", + "count": this.Judquestio.Getdatas()[5].rbpdt + }, + { + "item_type": "PROGRAM", + "count": this.Judquestio.Getdatas()[6].rbbct + } + ] + + + const url="/examination_intelligent_settings.json" + var data = { + discipline_id: this.Judquestio.Getdatas()[2].rbkc[0], + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + question_settings:question_settings, + } + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + //console.log("组卷成功"); + this.props.history.push(`/Integeneration/Intelligence/${result.data.exam_setting_id}`); + } + }).catch((error) => { + //console.log(error); + }) + + } + + + setitem_type = (item_type) => { + + + } + + setCohetepaperbool = (bool) => { + + } + getcontentMdRef = (Ref) => { + this.contentMdRef = Ref; + } + + setnewmyshixunmodelbool=()=>{ + + } + + render() { + let {paperlibrartdata,newmyshixunmodelbool,single_question_count,multiple_question_count,judgement_question_count,program_question_count} = this.state; + const params = this.props && this.props.match && this.props.match.params; + return ( +
    +
    + +
    +
    + + 试题库 + 智能组卷 + +
    + this.getdatas()} + getdatass={(nd)=>this.getdatass(nd)} + getJudquestio={(ref) => this.getJudquestio(ref)} + getdatasss={(e)=>this.getdatasss(e)} + getdatassss={(e)=>this.getdatassss(e)} + getdatassssy={(e)=>this.getdatassssy(e)} + > + + + + +
    + + +
    + { + newmyshixunmodelbool === true ? "" : + this.setCohetepaperbool(bool)} + onSubmits={() => this.preservation()} url={'/paperlibrary'}> + } +
    + ) + + } + + +} + +export default SnackbarHOC()(TPMIndexHOC(Intecomponents)); + + diff --git a/public/react/src/modules/testpaper/Paperlibraryeditid.js b/public/react/src/modules/testpaper/Paperlibraryeditid.js index ba8cb6926..c65191e96 100644 --- a/public/react/src/modules/testpaper/Paperlibraryeditid.js +++ b/public/react/src/modules/testpaper/Paperlibraryeditid.js @@ -22,8 +22,10 @@ import Paperlibraryseeid_item from './component/Paperlibraryseeid_item'; import Comthetestpaperst from '../question/comthetestpaper/Comthetestpaperst'; import Paperlibraryseeid_itemss from './component/Paperlibraryseeid_itemss'; import JudquestionEditor from "../question/component/JudquestionEditor"; +import NewMyShixunModel from "../question/NewMyShixunModel"; -//人工组卷预览 + +//试卷编辑 class Paperlibraryeditid extends Component { constructor(props) { super(props); @@ -33,15 +35,16 @@ class Paperlibraryeditid extends Component { disciplinesdata: [], knowledgepoints: [], disciplmy: [], - item_banksedit: [] + item_banksedit: [], + newmyshixunmodelbool:false, } } getJudquestio = (Ref) => { - console.log("子组件对象"); - console.log(Ref); + //console.log("子组件对象"); + //console.log(Ref); this.Judquestio = Ref; } @@ -163,11 +166,11 @@ class Paperlibraryeditid extends Component { axios.put(url, data) .then((result) => { if (result.data.status === 0) { - this.props.showNotification(`试卷更新成功`); + // this.props.showNotification(`试卷更新成功`); this.props.history.push('/paperlibrary'); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -185,14 +188,50 @@ class Paperlibraryeditid extends Component { this.contentMdRef = Ref; } + setnewmyshixunmodelbool=(bool)=>{ + if(bool===true){ + let scrollToTop = window.setInterval(function() { + let pos = window.pageYOffset; + if ( pos > 0 ) { + window.scrollTo( 0, pos - 20 ); // how far to scroll on each step + } else { + window.clearInterval( scrollToTop ); + } + }, 2); + } + this.setState({ + newmyshixunmodelbool:bool + }) + this.getdata(); + } + render() { - let {paperlibrartdata} = this.state; + let {paperlibrartdata,newmyshixunmodelbool} = this.state; const params = this.props && this.props.match && this.props.match.params; - // //console.log(params); + // //console.log("newmyshixunmodelbool"); + // //console.log(newmyshixunmodelbool); return (
    + { + newmyshixunmodelbool===true? + + :"" + } + + { + newmyshixunmodelbool===true? +
    + this.setnewmyshixunmodelbool(e)}> +
    + : + "" + } +
    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} > - - - +
    - - this.setCohetepaperbool(bool)} - onSubmits={() => this.preservation()} url={'/paperlibrary'}> + { + newmyshixunmodelbool === true ? "" : + this.setCohetepaperbool(bool)} + onSubmits={() => this.preservation()} url={'/paperlibrary'}> + }
    ) diff --git a/public/react/src/modules/testpaper/Paperlibraryseeid.js b/public/react/src/modules/testpaper/Paperlibraryseeid.js index 67d095250..aa9263e67 100644 --- a/public/react/src/modules/testpaper/Paperlibraryseeid.js +++ b/public/react/src/modules/testpaper/Paperlibraryseeid.js @@ -35,7 +35,7 @@ class Paperlibraryseeid extends Component { //初始化 componentDidMount() { - console.log("Paperlibraryseeid"); + ////console.log("Paperlibraryseeid"); this.getdata(); @@ -94,7 +94,7 @@ class Paperlibraryseeid extends Component { render() { let {paperlibrartdata} = this.state; const params = this.props && this.props.match && this.props.match.params; - // //console.log(params); + // ////console.log(params); return (
    { - // ////console.log("开始请求/get_navigation_info.json"); - // ////console.log(response); + // //////console.log("开始请求/get_navigation_info.json"); + // //////console.log(response); if (response != undefined) { if (response.status === 200) { this.setState({ @@ -64,7 +64,6 @@ class Testpaperlibrary extends Component { } } }); - //获取题库筛选资料 let urls = `/disciplines.json`; axios.get(urls, {params: { @@ -76,18 +75,6 @@ class Testpaperlibrary extends Component { }) } }); - 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, - keywords: this.state.keywords, - page: 1, - per_page:10, - } - this.getdata(data); - } paginationonChange=(pages)=>{ @@ -171,14 +158,14 @@ class Testpaperlibrary extends Component { } else { } - ////console.log("item_banks"); - ////console.log(response); + //////console.log("item_banks"); + //////console.log(response); this.setState({ Contentdata: response.data, items_count: response.data.exam_count, }) }).catch((error) => { - ////console.log(error) + //////console.log(error) this.setState({ booljupyterurls:false, }) @@ -207,7 +194,7 @@ class Testpaperlibrary extends Component { this.getdata(data); } - setsub_discipline_id=(sub_discipline_id)=>{ + setsub_discipline_id=(discipline_id,sub_discipline_id)=>{ this.setState({ sub_discipline_id:sub_discipline_id, tag_discipline_id:null, @@ -216,7 +203,7 @@ class Testpaperlibrary extends Component { per_page:10, }) var data = { - discipline_id:this.state.discipline_id, + discipline_id:discipline_id, sub_discipline_id:sub_discipline_id, tag_discipline_id:null, public: this.state.defaultActiveKey, @@ -290,7 +277,7 @@ class Testpaperlibrary extends Component { axios.post(url) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`公开试卷成功`); + // this.props.showNotification(`公开试卷成功`); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -304,7 +291,7 @@ class Testpaperlibrary extends Component { this.getdata(data); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -315,7 +302,7 @@ class Testpaperlibrary extends Component { axios.delete(url) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('删除试卷成功') + // this.props.showNotification('删除试卷成功'); // props.history.push(response.data.right_url) var data = { discipline_id:this.state.discipline_id, @@ -331,7 +318,7 @@ class Testpaperlibrary extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); } @@ -417,6 +404,12 @@ class Testpaperlibrary extends Component { render() { let{Headertop,items_count,page,per_page,modalsTypes,modalsType}=this.state; + + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + + return (
    { @@ -441,7 +434,7 @@ class Testpaperlibrary extends Component { this.setdiscipline_id(e)} - setsub_discipline_id={(e)=>this.setsub_discipline_id(e)} + setsub_discipline_id={(e,id)=>this.setsub_discipline_id(e,id)} settag_discipline_id={(e)=>this.settag_discipline_id(e)} setitem_types={(e) => this.setitem_types(e)} setdifficulty={(e) => this.setdifficulty(e)} @@ -450,6 +443,7 @@ class Testpaperlibrary extends Component { this.Testpapereditor(e)} setdifficulty={(e)=>this.setdifficulty(e)} showmodels={(e)=>this.showmodels(e)} diff --git a/public/react/src/modules/testpaper/component/Contentpart.js b/public/react/src/modules/testpaper/component/Contentpart.js index 9841ff8a9..7df1997cd 100644 --- a/public/react/src/modules/testpaper/component/Contentpart.js +++ b/public/react/src/modules/testpaper/component/Contentpart.js @@ -38,9 +38,31 @@ class Contentpart extends Component { } + componentDidUpdate(prevProps) { + if(prevProps.current_user !== this.props.current_user) { + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.props; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ + defaultActiveKeys="1" + } + this.props.callback(defaultActiveKeys); + } + } + render() { let {page}=this.state; let {defaultActiveKey}=this.props; + + + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + const contents = (

    ); + + return ( -
    +
    - this.props.callback(e)}> - - - - - + { + isysladmins===true||(is_teacher===true&&professional_certification===true)? + this.props.callback(e)}> + + + + + + : + this.props.callback(e)}> + + + + }
    -
    +
    - - @@ -189,6 +221,7 @@ class Contentpart extends Component { Testpapereditor={(e)=>this.props.Testpapereditor(e)} showmodels={(e)=>this.props.showmodels(e)} showmodelysl={(e)=>this.props.showmodelysl(e)} + Isitapopup={this.props.Isitapopup} > diff --git a/public/react/src/modules/testpaper/component/Contentquestionbank.js b/public/react/src/modules/testpaper/component/Contentquestionbank.js index 1e036f858..2ed246023 100644 --- a/public/react/src/modules/testpaper/component/Contentquestionbank.js +++ b/public/react/src/modules/testpaper/component/Contentquestionbank.js @@ -20,9 +20,9 @@ class Contentquestionbank extends Component { } //初始化 componentDidMount(){ - ////console.log("componentDidMount"); - ////console.log(this.state); - ////console.log(this.props); + //////console.log("componentDidMount"); + //////console.log(this.state); + //////console.log(this.props); // let homeworkid = this.props.match.params.homeworkid; // let url = "/homework_commons/" + homeworkid + "/end_groups.json"; // axios.get(url).then((response) => { @@ -30,12 +30,12 @@ class Contentquestionbank extends Component { // this.setState({}) // } // }).catch((error) => { - // ////console.log(error) + // //////console.log(error) // }); } onChange=(e)=> { - ////console.log(`checked = ${e.target.checked}`); + //////console.log(`checked = ${e.target.checked}`); } render() { diff --git a/public/react/src/modules/testpaper/component/Listjihe.js b/public/react/src/modules/testpaper/component/Listjihe.js index 83b656628..53fc7181a 100644 --- a/public/react/src/modules/testpaper/component/Listjihe.js +++ b/public/react/src/modules/testpaper/component/Listjihe.js @@ -76,8 +76,8 @@ class Listjihe extends Component { return (
    -
    - +
    +

    this.gotoseesj(items.id)}>{names}

    @@ -114,12 +114,18 @@ class Listjihe extends Component { 删除

    - -

    this.props.Testpapereditor(items.id)}> - - 编辑 -

    -
    + { + this.props.Isitapopup&&this.props.Isitapopup==="true"? + "" + : + +

    this.props.Testpapereditor(items.id)}> + + 编辑 +

    +
    + } + { items.public === false ?

    this.props.showmodels(items.id)}> diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js index e4615caa1..06298299f 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js @@ -69,8 +69,8 @@ class Paperreview_item extends Component { } onDragEnd = (result) => { - console.log("单选题"); - console.log(result); + //console.log("单选题"); + //console.log(result); const ids = this.props.single_questions.questions[result.source.index].id; const positions = this.props.single_questions.questions[result.destination.index].position; @@ -81,17 +81,17 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata(); } }).catch((error) => { - console.log(error); + //console.log(error); }) } onDragEnds = (result) => { - console.log("多选题"); - console.log(result); + //console.log("多选题"); + //console.log(result); const ids = this.props.multiple_questions.questions[result.source.index].id; const positions = this.props.multiple_questions.questions[result.destination.index].position; const url = `/examination_items/${ids}/adjust_position.json`; @@ -101,11 +101,11 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata(); } }).catch((error) => { - console.log(error); + //console.log(error); }) @@ -113,8 +113,8 @@ class Paperreview_item extends Component { onDragEndss = (result) => { - console.log("判断题"); - console.log(result); + //console.log("判断题"); + //console.log(result); const ids = this.props.judgement_questions.questions[result.source.index].id; const positions = this.props.judgement_questions.questions[result.destination.index].position; const url = `/examination_items/${ids}/adjust_position.json`; @@ -125,18 +125,18 @@ class Paperreview_item extends Component { .then((result) => { debugger if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata(); } }).catch((error) => { - console.log(error); + //console.log(error); }) } onDragEndsss = (result) => { - console.log("编程题"); - console.log(result); + //console.log("编程题"); + //console.log(result); const ids = this.props.program_questions.questions[result.source.index].id; const positions = this.props.program_questions.questions[result.destination.index].position; @@ -147,11 +147,11 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata(); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -181,12 +181,12 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazine("", false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -198,12 +198,12 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazines(false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -225,7 +225,7 @@ class Paperreview_item extends Component { } hideparagraph = (name) => { - console.log("hideparagraph"); + //console.log("hideparagraph"); } @@ -238,7 +238,7 @@ class Paperreview_item extends Component { }) } showparagraph = (name) => { - console.log("showparagraph"); + //console.log("showparagraph"); if (name === "SINGLE") { this.setState({ singlebool: true, @@ -290,8 +290,8 @@ class Paperreview_item extends Component { } showparagraphs = (e,name) => { - // console.log("showparagraphs"); - // console.log(e); + // //console.log("showparagraphs"); + // //console.log(e); this.setState({ paperreviewsingleindex: e, paperreviewsinglename:name, diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js index 1ab987ba0..7d66a19c4 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js @@ -15,6 +15,7 @@ import { } from "antd"; import '../testioncss/testioncss.css'; import '../../tpm/newshixuns/css/Newshixuns.css'; +import QuillForEditor from "../../../common/quillForEditor"; const tagArray = [ 'A.', 'B.', 'C.', 'D.', 'E.', 'F.', 'G.', 'H.', 'I.', @@ -67,15 +68,52 @@ class Paperlibraryseeid_items extends Component { render() { let {questions, totalscore, total, items} = this.state; let {objectsingle, indexx, paperreviewsingleindex, indexxy,name} = this.props; - // console.log("objectsingle"); - // console.log(objectsingle); + + + var itemssname=""; + try { + itemssname= JSON.parse(objectsingle.name); + }catch (e) { + } + if(itemssname===undefined){ + itemssname=objectsingle.name + } + + var itemsnamesy=""; + try { + itemsnamesy= JSON.parse(objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description); + + }catch (e) { + itemsnamesy=objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description; + } return (

    - + {/*顶部*/}
    @@ -100,29 +138,49 @@ 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,19 +192,47 @@ class Paperlibraryseeid_items extends Component { objectsingle.item_type === "PROGRAM" ?

    -

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

    + +

    + : + ""}

    :

    { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { + var string="" + try { + string=JSON.parse(object.choice_text); + }catch (e) { + string=object.choice_text; + } return ( -

    +

    {tagArray[index]} -

    +

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

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

    } -
    diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js index 25f588977..b725b4e5e 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js @@ -89,11 +89,11 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -108,11 +108,11 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) @@ -129,11 +129,11 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -149,11 +149,11 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -184,12 +184,12 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazine("", false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -201,12 +201,12 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazines(false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -247,7 +247,7 @@ class Paperlibraryseeid_itemss extends Component { }) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('大题删除成功'); + // this.props.showNotification('大题删除成功'); this.props.getdata({}); this.setState({ titilesms: "" @@ -255,7 +255,7 @@ class Paperlibraryseeid_itemss extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); @@ -275,7 +275,7 @@ class Paperlibraryseeid_itemss extends Component { axios.delete((url)) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('试题删除成功'); + // this.props.showNotification('试题删除成功'); this.props.getdata({}); } }) @@ -299,7 +299,7 @@ class Paperlibraryseeid_itemss extends Component { } hideparagraph = (name) => { - console.log("hideparagraph"); + //console.log("hideparagraph"); } @@ -312,7 +312,7 @@ class Paperlibraryseeid_itemss extends Component { }) } showparagraph = (name) => { - console.log("showparagraph"); + //console.log("showparagraph"); if (name === "SINGLE") { this.setState({ singlebool: true, @@ -364,8 +364,8 @@ class Paperlibraryseeid_itemss extends Component { } showparagraphs = (e,name) => { - // console.log("showparagraphs"); - // console.log(e); + // //console.log("showparagraphs"); + // //console.log(e); this.setState({ paperreviewsingleindex: e, paperreviewsinglename:name, diff --git a/public/react/src/modules/testpaper/component/Seeoagertits.js b/public/react/src/modules/testpaper/component/Seeoagertits.js index 1c2b596bf..a983bd67e 100644 --- a/public/react/src/modules/testpaper/component/Seeoagertits.js +++ b/public/react/src/modules/testpaper/component/Seeoagertits.js @@ -48,7 +48,7 @@ class Seeoagertit extends Component {
    -
    this.jixuxuantioncli()}> +
    this.props.setnewmyshixunmodelbool(true)}> 继续选题
    diff --git a/public/react/src/modules/testpaper/testioncss/testioncss.css b/public/react/src/modules/testpaper/testioncss/testioncss.css index fa87531b0..2025779ab 100644 --- a/public/react/src/modules/testpaper/testioncss/testioncss.css +++ b/public/react/src/modules/testpaper/testioncss/testioncss.css @@ -366,7 +366,7 @@ .selectionss{ width:88px; height:30px; - background:#eeeeee; + background:#CCCCCC; border-radius:4px; text-align: center; line-height: 30px; @@ -548,7 +548,7 @@ height:32px; border-radius:2px; border:1px solid #DDDDDD; - margin-left: 20px; + margin-right: 20px; } .lh32{ line-height: 32px; @@ -884,3 +884,46 @@ text-align: center; line-height: 20px; } +.mt25{ + margin-top: 25px; +} + +.imgtp{ + width: 39px; + height: 44px; +} +.tites{ + color: #888888 !important; +} +.conditionsetting{ + width:64px; + height:21px; + font-size:16px; + color:#333333; + line-height:21px; +} + +.conditionsettings{ + width:80px; + height:21px; + font-size:16px; + font-family:MicrosoftYaHei; + color:rgba(51,51,51,1); + line-height:21px; +} +.hengxians{ + width:1021px; + height:1px; + background: #EEEEEE; +} +.mt13{ + margin-top: 13px; +} +.dxuantitie{ + width:57px; + height:19px; + font-size:14px; + font-family:MicrosoftYaHei; + color:rgba(51,51,51,1); + line-height:19px; +} diff --git a/public/react/src/modules/tpm/NewHeader.js b/public/react/src/modules/tpm/NewHeader.js index 3be22a05f..5ca8e986b 100644 --- a/public/react/src/modules/tpm/NewHeader.js +++ b/public/react/src/modules/tpm/NewHeader.js @@ -949,6 +949,13 @@ submittojoinclass=(value)=>{ return (
    + {isRender===true?this.Modifyloginvalue()} diff --git a/public/react/src/modules/tpm/TPMIndex.css b/public/react/src/modules/tpm/TPMIndex.css index d5b8ef5c2..4f19260aa 100644 --- a/public/react/src/modules/tpm/TPMIndex.css +++ b/public/react/src/modules/tpm/TPMIndex.css @@ -268,8 +268,32 @@ body>.-task-title { background: #EEEEEE; } .mystask-sidebar{ - right: 210px !important; + right: 220px !important; } .mystask-sidebars{ - right: 10px !important; + right: 20px !important; +} +.shitikussmys{ + width:29px !important; + height:20px!important; + background:#FF6601 !important; + border-radius:10px !important; + position: absolute !important; + font-size:11px !important; + color:#ffffff !important; + line-height:20px !important; + top: -13px !important; + right: -10px !important; +} + + +.maxnamewidth30{ + max-width: 30px; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; + cursor: default; +} +.mystask-sidebarss{ + right: 5px !important; } diff --git a/public/react/src/modules/tpm/TPMIndexHOC.js b/public/react/src/modules/tpm/TPMIndexHOC.js index 363acdba1..7d37ea073 100644 --- a/public/react/src/modules/tpm/TPMIndexHOC.js +++ b/public/react/src/modules/tpm/TPMIndexHOC.js @@ -396,7 +396,7 @@ export function TPMIndexHOC(WrappedComponent) { }); } - + fetchUser = () => { let url = `/users/get_user_info.json` let courseId; @@ -590,6 +590,17 @@ export function TPMIndexHOC(WrappedComponent) { checkIfProfileCompleted = () => { return this.state.current_user && this.state.current_user.profile_completed } + + showaccountprofileDialog = () => { + this.dialogObj = { + content: '您需要去完成您的个人资料,才能使用此功能', + okText: '立即完成', + okHref: '/account/profile' + } + this.setState({ + AccountProfiletype: true, + }) + } showProfessionalCertificationDialog = () => { this.dialogObj = { content: '您需要去完成您的职业认证,才能使用此功能', @@ -713,6 +724,7 @@ export function TPMIndexHOC(WrappedComponent) { showProfileCompleteDialog: this.showProfileCompleteDialog, showhideAccountPhoneemailDialog:this.showhideAccountPhoneemailDialog, checkIfProfileCompleted: this.checkIfProfileCompleted, + showaccountprofileDialog:this.showaccountprofileDialog, checkIfProfessionalCertification: this.checkIfProfessionalCertification, showProfessionalCertificationDialog: this.showProfessionalCertificationDialog, diff --git a/public/react/src/modules/tpm/component/TPMRightSection.js b/public/react/src/modules/tpm/component/TPMRightSection.js index 2cfe0047a..6b25635c8 100644 --- a/public/react/src/modules/tpm/component/TPMRightSection.js +++ b/public/react/src/modules/tpm/component/TPMRightSection.js @@ -115,7 +115,7 @@ class TPMRightSection extends Component {
    学习统计 - 已完成 {TPMRightSectionData&&TPMRightSectionData.complete_count===null?0:TPMRightSectionData&&TPMRightSectionData.complete_count} 个 / 共 {TPMRightSectionData&&TPMRightSectionData.challenge_count} 关 + 已完成 {TPMRightSectionData&&TPMRightSectionData.complete_count===null?0:TPMRightSectionData&&TPMRightSectionData.complete_count} 关 / 共 {TPMRightSectionData&&TPMRightSectionData.challenge_count} 关
    diff --git a/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js b/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js index 86a2e287d..9e50e44d5 100644 --- a/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js +++ b/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js @@ -77,20 +77,20 @@ class Challengesjupyter extends Component { }else{ if(boxoffsetHeigh>=300){ - if(this.props&&this.props.is_jupyter===true&&this.props&&this.props.user.user_identity==="学生"){ - this.setState({ - opentitletype:false, - isopentitletype:"greater", - boxoffsetHeigh:boxoffsetHeigh - }) - }else{ - this.setState({ - opentitletype:true, - isopentitletype:"greater", - boxoffsetHeigh:boxoffsetHeigh - }) - } - + // if(this.state.enlarge===false){ + // this.setState({ + // opentitletype:false, + // isopentitletype:"greater", + // boxoffsetHeigh:boxoffsetHeigh + // }) + // }else{ + // + // } + this.setState({ + opentitletype:false, + isopentitletype:"greater", + boxoffsetHeigh:boxoffsetHeigh + }) }else{ this.setState({ isopentitletype:"Less", @@ -284,7 +284,7 @@ class Challengesjupyter extends Component { .then((result) => { if (result.data.status === 0) { // this.props.showNotification(`应用成功`); - console.log("应用成功了"); + // console.log("应用成功了"); this.props.showNotification('保存成功!'); setTimeout(() => { this.setState({ @@ -645,12 +645,14 @@ class Challengesjupyter extends Component { ` } + {/*this.state.enlarge===false?"":*/} + {/*{this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}>*/} + {/* 阅读全文 */} + {/*:this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}>*/} + {/* 收起全文 */} + {/*}*/} + - {this.props&&this.props.is_jupyter===true&&this.props&&this.props.user.user_identity==="学生"?"":this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> - 阅读全文 - :this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> - 收起全文 - }

    @@ -725,10 +727,11 @@ class Challengesjupyter extends Component {
    - :"" + : "" : ( admin===true||business===true||mysidentity===true? +
    diff --git a/public/react/src/modules/tpm/shixuns/ShixunCardList.js b/public/react/src/modules/tpm/shixuns/ShixunCardList.js index 948bbed48..46abc5bf0 100644 --- a/public/react/src/modules/tpm/shixuns/ShixunCardList.js +++ b/public/react/src/modules/tpm/shixuns/ShixunCardList.js @@ -75,17 +75,18 @@ class ShixunCardList extends Component { type="new"; } + if(typekeyid===key){ if(upcircle===true){ this.setState({ upcircle:false, }) - this.props.Shixunsupcircles("desc") + // this.props.Shixunsupcircles("desc") }else if(upcircle===false){ this.setState({ upcircle:true, }) - this.props.Shixunsupcircles("asc") + // this.props.Shixunsupcircles("desc") } }else{ this.setState({ @@ -93,8 +94,8 @@ class ShixunCardList extends Component { }) } - //allevent - this.props.ShixunsState(false,type); + + this.props.ShixunsState(false,type,"desc"); } diff --git a/public/react/src/modules/tpm/shixuns/ShixunsIndex.js b/public/react/src/modules/tpm/shixuns/ShixunsIndex.js index f14afb0ac..82fa6a3f9 100644 --- a/public/react/src/modules/tpm/shixuns/ShixunsIndex.js +++ b/public/react/src/modules/tpm/shixuns/ShixunsIndex.js @@ -296,21 +296,23 @@ class ShixunsIndex extends Component { console.log(error) }); } - ShixunsState=(val,type)=>{ + ShixunsState=(val,type,sorts)=>{ // sort, let {tag_level, tag_id, page, limit, keyword, status, diff,sort} = this.state; - let newsort=sort; + let newsort=sorts?sorts:sort; this.setState({ order_by:type, typepvisible:true, pages:1, - // sort:sort + sort:sorts?sorts:sort }) let params // let vals=false if(newsort===undefined){ newsort="desc" + }else{ + newsort=sorts?sorts:sort } params= { order_by:type, diff --git a/public/react/src/modules/user/LoginRegisterComponent.js b/public/react/src/modules/user/LoginRegisterComponent.js index d00d54371..e4faebd0a 100644 --- a/public/react/src/modules/user/LoginRegisterComponent.js +++ b/public/react/src/modules/user/LoginRegisterComponent.js @@ -608,7 +608,7 @@ class LoginRegisterComponent extends Component { }; //短信验证 SMSverification = () => { - let logins=this.state.login; + let logins=this.state.logins; var url = `/accounts/get_verification_code.json`; axios.get((url), { params: { 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 diff --git a/spec/models/program_bank_spec.rb b/spec/models/program_bank_spec.rb new file mode 100644 index 000000000..d8a764494 --- /dev/null +++ b/spec/models/program_bank_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ProgramBank, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/program_bank_test_spec.rb b/spec/models/program_bank_test_spec.rb new file mode 100644 index 000000000..22720f254 --- /dev/null +++ b/spec/models/program_bank_test_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ProgramBankTest, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end