diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 8eefe5ff5..075777891 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -1349,6 +1349,7 @@ class CoursesController < ApplicationController def search_slim courses = current_user.manage_courses.not_deleted.processing + courses = courses.where(id: current_laboratory.all_courses) keyword = params[:keyword].to_s.strip if keyword.present? diff --git a/app/controllers/item_baskets_controller.rb b/app/controllers/item_baskets_controller.rb index dc5367378..03355189d 100644 --- a/app/controllers/item_baskets_controller.rb +++ b/app/controllers/item_baskets_controller.rb @@ -12,13 +12,7 @@ class ItemBasketsController < ApplicationController end def basket_list - @single_questions_count = current_user.item_baskets.where(item_type: "SINGLE").count - @multiple_questions_count = current_user.item_baskets.where(item_type: "MULTIPLE").count - @judgement_questions_count = current_user.item_baskets.where(item_type: "JUDGMENT").count - @completion_questions_count = current_user.item_baskets.where(item_type: "COMPLETION").count - @subjective_questions_count = current_user.item_baskets.where(item_type: "SUBJECTIVE").count - @practical_questions_count = current_user.item_baskets.where(item_type: "PRACTICAL").count - @program_questions_count = current_user.item_baskets.where(item_type: "PROGRAM").count + @basket_count = current_user.item_baskets.group(:item_type).count end def create diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 30de10b73..d197b6f9d 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -291,13 +291,13 @@ class ShixunsController < ApplicationController new_challenge.attributes = challenge.attributes.dup.except("id","shixun_id","user_id", "challenge_tags_count") new_challenge.user_id = User.current.id new_challenge.shixun_id = @new_shixun.id - new_challenge.save! + new_challenge.save!(validate: false) # 同步参考答案 challenge.challenge_answers.each do |answer| new_answer = ChallengeAnswer.new new_answer.attributes = answer.attributes.dup.except("id","challenge_id") new_answer.challenge_id = new_challenge.id - new_answer.save! + new_answer.save!(validate: false) end if challenge.st == 0 # 评测题 # 同步测试集 @@ -306,7 +306,7 @@ class ShixunsController < ApplicationController new_test_set = TestSet.new new_test_set.attributes = test_set.attributes.dup.except("id","challenge_id") new_test_set.challenge_id = new_challenge.id - new_test_set.save! + new_test_set.save!(validate: false) end end # 同步关卡标签 @@ -1187,7 +1187,10 @@ private end def validate_wachat_support - tip_exception(-2, "..") if (params[:wechat].present? && !@shixun.is_wechat_support?) + + if (params[:wechat].present? && !@shixun.is_wechat_support?) + tip_exception(-5, "..") + end end end diff --git a/app/controllers/weapps/code_sessions_controller.rb b/app/controllers/weapps/code_sessions_controller.rb index 350fa4978..984e008a5 100644 --- a/app/controllers/weapps/code_sessions_controller.rb +++ b/app/controllers/weapps/code_sessions_controller.rb @@ -21,6 +21,8 @@ class Weapps::CodeSessionsController < Weapps::BaseController Rails.logger.info("[Weapp] code: #{params[:code]}") user_info = Wechat::Weapp.decrypt(result['session_key'], params[:encrypted_data], params[:iv]) + # user_info.delete(:nickName) + # 老用户,已绑定 open_user = OpenUsers::Wechat.find_by(uid: user_info['unionId']) if open_user.present? && open_user.user @@ -29,7 +31,7 @@ class Weapps::CodeSessionsController < Weapps::BaseController end set_session_unionid(user_info['unionId']) - user_info['nickname'] = user_info['nickName'] + # user_info['nickname'] = user_info['nickName'] session[:wechat_user_extra] = user_info end diff --git a/app/controllers/weapps/homes_controller.rb b/app/controllers/weapps/homes_controller.rb index 00b955f1b..e53923fa8 100644 --- a/app/controllers/weapps/homes_controller.rb +++ b/app/controllers/weapps/homes_controller.rb @@ -16,6 +16,7 @@ class Weapps::HomesController < Weapps::BaseController current_user.manage_courses end @courses = @courses.not_deleted.not_excellent + @courses = @courses.where(id: current_laboratory.all_courses) @course_count = @courses.count order_str = "course_members.sticky=1 desc, course_members.sticky_time desc, courses.created_at desc" @courses = paginate(@courses.order(order_str).includes(:teacher, :school)) diff --git a/app/controllers/weapps/sessions_controller.rb b/app/controllers/weapps/sessions_controller.rb index 8c7c57a7f..732d0a686 100644 --- a/app/controllers/weapps/sessions_controller.rb +++ b/app/controllers/weapps/sessions_controller.rb @@ -15,8 +15,9 @@ class Weapps::SessionsController < Weapps::BaseController return end + # session[:wechat_user_extra].delete(:nickName) # 绑定微信号 - OpenUsers::Wechat.create!(user: user, uid: session_unionid, extra: session[:wechat_user_extra]) if user.wechat_open_user.blank? + OpenUsers::Wechat.create!(user: user, uid: session_unionid) if user.wechat_open_user.blank? successful_authentication(user) end diff --git a/app/models/item_bank.rb b/app/models/item_bank.rb index 840f488d8..242b7de92 100644 --- a/app/models/item_bank.rb +++ b/app/models/item_bank.rb @@ -19,38 +19,26 @@ class ItemBank < ApplicationRecord end def apply? - !public && ApplyAction.where(container_type: "ItemBank", container_id: id, status: 0).exists? + !public && ApplyAction.exists?(container_type: "ItemBank", container_id: id, status: 0) end def type_string - result = case item_type - when "SINGLE" - "单选题" - when "MULTIPLE" - "多选题" - when "JUDGMENT" - "判断题" - when "COMPLETION" - "填空题" - when "SUBJECTIVE" - "简答题" - when "PRACTICAL" - "实训题" - when "PROGRAM" - "编程题" - end - result + case item_type + when "SINGLE" then "单选题" + when "MULTIPLE" then "多选题" + when "JUDGMENT" then "判断题" + when "COMPLETION" then "填空题" + when "SUBJECTIVE" then "简答题" + when "PRACTICAL" then "实训题" + when "PROGRAM" then "编程题" + end end def difficulty_string - result = case difficulty - when 1 - "简单" - when 2 - "适中" - when 3 - "困难" - end - result + case difficulty + when 1 then "简单" + when 2 then "适中" + when 3 then "困难" + end end end diff --git a/app/models/student_work.rb b/app/models/student_work.rb index 3aee0611b..f8f3bee99 100644 --- a/app/models/student_work.rb +++ b/app/models/student_work.rb @@ -223,7 +223,7 @@ class StudentWork < ApplicationRecord game_score = adjust_score.score elsif game.present? setting = homework_common.homework_group_setting game.user_id - if game.status == 2 && ((game.end_time && game.end_time < setting.end_time) || (homework_common.allow_late && game.end_time && game.end_time < homework_common.late_time)) + if game.status == 2 && ((game.end_time && setting.end_time && game.end_time < setting.end_time) || (homework_common.allow_late && homework_common.late_time && game.end_time && game.end_time < homework_common.late_time)) answer_open_evaluation = homework_common.homework_detail_manual.answer_open_evaluation game_score = answer_open_evaluation ? score : (game.final_score > 0 ? game.real_score(score) : 0) end diff --git a/app/queries/admins/shixun_settings_query.rb b/app/queries/admins/shixun_settings_query.rb index 1e45952bf..30a402d1c 100644 --- a/app/queries/admins/shixun_settings_query.rb +++ b/app/queries/admins/shixun_settings_query.rb @@ -51,6 +51,7 @@ class Admins::ShixunSettingsQuery < ApplicationQuery all_shixuns = all_shixuns.where(task_pass: params[:task_pass]) if params[:task_pass] all_shixuns = all_shixuns.where(code_hidden: params[:code_hidden]) if params[:code_hidden] all_shixuns = all_shixuns.where(vip: params[:vip]) if params[:vip] + all_shixuns = all_shixuns.where(is_wechat_support: params[:is_wechat_support]) if params[:is_wechat_support] custom_sort(all_shixuns, params[:sort_by], params[:sort_direction]) end diff --git a/app/services/git_service.rb b/app/services/git_service.rb index 2bfc7423c..3f7a42c97 100644 --- a/app/services/git_service.rb +++ b/app/services/git_service.rb @@ -68,8 +68,8 @@ class GitService content = JSON.parse(body) if content["code"] != 0 - raise("版本库异常") logger.error("repository error: #{content['msg']}") + raise("版本库异常") end #raise content["msg"] if content["code"] != 0 diff --git a/app/views/admins/shixun_settings/index.html.erb b/app/views/admins/shixun_settings/index.html.erb index 16a02ab96..82d7fa3a1 100644 --- a/app/views/admins/shixun_settings/index.html.erb +++ b/app/views/admins/shixun_settings/index.html.erb @@ -71,6 +71,13 @@ 只看vip +
+ +
+ <% end %> diff --git a/app/views/item_baskets/basket_list.json.jbuilder b/app/views/item_baskets/basket_list.json.jbuilder index 11db844ab..4cb0d5592 100644 --- a/app/views/item_baskets/basket_list.json.jbuilder +++ b/app/views/item_baskets/basket_list.json.jbuilder @@ -1,7 +1,7 @@ -json.single_questions_count @single_questions_count -json.multiple_questions_count @multiple_questions_count -json.judgement_questions_count @judgement_questions_count -json.completion_questions_count @completion_questions_count -json.subjective_questions_count @subjective_questions_count -json.practical_questions_count @practical_questions_count -json.program_questions_count @program_questions_count +json.single_questions_count @basket_count&.fetch("SINGLE", 0) +json.multiple_questions_count @basket_count&.fetch("MULTIPLE", 0) +json.judgement_questions_count @basket_count&.fetch("JUDGMENT", 0) +json.completion_questions_count @basket_count&.fetch("COMPLETION", 0) +json.subjective_questions_count @basket_count&.fetch("SUBJECTIVE", 0) +json.practical_questions_count @basket_count&.fetch("PRACTICAL", 0) +json.program_questions_count @basket_count&.fetch("PROGRAM", 0) \ No newline at end of file diff --git a/db/migrate/20200117095750_modify_1_wechat_support_for_shixuns.rb b/db/migrate/20200117095750_modify_1_wechat_support_for_shixuns.rb new file mode 100644 index 000000000..1e973b014 --- /dev/null +++ b/db/migrate/20200117095750_modify_1_wechat_support_for_shixuns.rb @@ -0,0 +1,13 @@ +class Modify1WechatSupportForShixuns < ActiveRecord::Migration[5.2] + def change + shixuns = Shixun.joins(:challenges).where(is_wechat_support: true, status: 2) + .select("shixuns.*, challenges.path path") + shixuns.each do |shixun| + if shixun.path && shixun.path.split(";").count > 1 + shixun.update_attribute(:is_wechat_support, false) + end + end + Shixun.joins(:challenges).where(challenges: {st: 1}).update_all(is_wechat_support: false) + + end +end diff --git a/lib/tasks/statistic_subject_info.rake b/lib/tasks/statistic_subject_info.rake index 259824174..c510c60fb 100644 --- a/lib/tasks/statistic_subject_info.rake +++ b/lib/tasks/statistic_subject_info.rake @@ -9,8 +9,8 @@ namespace :subjects do 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_in_batches(batch_size: 50) do |s| - Parallel.each(s, in_processes: 4) do |subject| + subjects.find_in_batches(batch_size: 50) do |s, index| + Parallel.each_with_index(s, in_processes: 4) do |subject| puts("---------------------data_statistic: #{subject.id}") Rails.logger.info("---------------------data_statistic: #{subject.id}") data = Subjects::DataStatisticService.new(subject) @@ -23,7 +23,7 @@ namespace :subjects do "#{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 + if buffer_size == 1000 || subjects.count == (index+1) sql = "REPLACE INTO subject_records(#{column_value}) VALUES #{str}" puts sql ActiveRecord::Base.connection.execute sql @@ -55,14 +55,14 @@ namespace :subjects do puts("---------------------course_info_statistic: #{subject.id}") Rails.logger.info("---------------------course_info_statistic: #{subject.id}") data = Subjects::CourseUsedInfoService.call(subject) - Parallel.map(data) do |key| + Parallel.map_with_index(data) do |key, index| 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 + if buffer_size == 1000 || (index + 1) == data.size sql = "REPLACE INTO subject_course_records(#{column_value}) VALUES #{str}" puts sql ActiveRecord::Base.connection.execute sql @@ -90,11 +90,11 @@ namespace :subjects do 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_in_batches(batch_size: 50) do |s| - Parallel.each(s, in_processes: 4) do |subject| + Parallel.each_with_index(s, in_processes: 4) 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| + data.each_with_index do |key, index| next if key[:shixun_id].nil? str += ", " unless str.empty? str += ("(#{subject.id}, #{key[:shixun_id]}, '#{key[:stage]}', '#{key[:name]}', #{key[:challenge_count]}, " + @@ -102,7 +102,7 @@ namespace :subjects do "#{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 + if buffer_size == 1000 || (index+1) == data.size sql = "REPLACE INTO subject_shixun_infos(#{column_value}) VALUES #{str}" puts sql ActiveRecord::Base.connection.execute sql @@ -131,7 +131,7 @@ namespace :subjects do "code_line_count, evaluate_count, cost_time, created_at, updated_at" subjects.find_in_batches(batch_size: 50) do |s| - Parallel.each(s, in_processes: 4) do |subject| + Parallel.each_with_index(s, in_processes: 4) do |subject, index| puts("---------------------user_info_statistic: #{subject.id}") data = Subjects::UserUsedInfoService.call(subject) data.each do |key| @@ -141,7 +141,7 @@ namespace :subjects do "#{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 + if buffer_size == 1000 || (index+1 == data.size) sql = "REPLACE INTO subject_user_infos(#{column_value}) VALUES #{str}" ActiveRecord::Base.connection.execute sql str = "" diff --git a/lib/tasks/zip_pack.rake b/lib/tasks/zip_pack.rake index 393f7ab3c..9cfb36a8e 100644 --- a/lib/tasks/zip_pack.rake +++ b/lib/tasks/zip_pack.rake @@ -1,51 +1,85 @@ -# 执行示例 bundle exec rake zip_pack:shixun_pack args=123,2323 +# 执行示例 bundle exec rake zip_pack:shixun_pack class=Course ids=123,2323 parallel_size=4 +# 执行示例 bundle exec rake zip_pack:shixun_pack class=HomeworkCommon ids=123,2323 namespace :zip_pack do desc "手工打包作品" OUTPUT_FOLDER = "#{Rails.root}/files/archiveZip" task :shixun_pack => :environment do - if ENV['args'] - homework_ids = ENV['args'].split(",").map(&:to_i) - homeworks = HomeworkCommon.where(id: homework_ids) - homeworks.includes(:score_student_works).each do |homework| - out_file_name = "#{Time.now.strftime("%Y%m%d%H%M%S").to_s}-#{homework.course_id}-#{homework.name}.zip" - out_file_name.gsub!(" ", "-") - out_file_name.gsub!("/", "_") + if ENV['class'] && ENV['ids'] + parallel_size = ENV['parallel_size'] || 2 + parallel_size = parallel_size.to_i + env_ids = ENV['ids'].split(",").map(&:to_i) + folders = [] + if ENV['class'] == "Course" + courses = Course.where(id: env_ids) + courses.each do |course| + homeworks = course.practice_homeworks.homework_published + new_dir_name = "#{course.name.to_s.strip}_#{Time.now.strftime("%Y%m%d%H%M%S").to_s}" + new_dir_name.gsub!(" ", "-") + new_dir_name.gsub!("/", "_") + new_folder = "#{OUTPUT_FOLDER}/#{new_dir_name}" + zip_homework_pdf homeworks, new_folder, parallel_size + folders << new_folder + end + else + homeworks = HomeworkCommon.where(id: env_ids) + new_dir_name = "#{homeworks.first&.course&.name.to_s.strip}_#{Time.now.strftime("%Y%m%d%H%M%S").to_s}" + new_dir_name.gsub!(" ", "-") + new_dir_name.gsub!("/", "_") + new_folder = "#{OUTPUT_FOLDER}/#{new_dir_name}" + zip_homework_pdf homeworks, new_folder, parallel_size + folders << new_folder + end - zipfile_name = "#{OUTPUT_FOLDER}/#{out_file_name}" - Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name)) + puts "下载路径: #{folders.join(",")}" + end + end - student_works = homework.score_student_works + def zip_homework_pdf homeworks, folder, parallel_size + Dir.mkdir(folder) unless File.directory?(folder) - if student_works.size > 0 - pdfs = [] - Zip::File.open(zipfile_name, Zip::File::CREATE) do |zip| - student_works.find_each.map do |student_work| - export = ExportShixunReportService.new(homework, student_work) - pdf = export.to_pdf - pdfs << pdf - begin - zip.add(export.filename, pdf.path) - puts "out: #{export.filename}_#{pdf.path}" - rescue => ex - Rails.logger.error(ex.message) + homeworks.includes(:score_student_works).each do |homework| + out_file_name = "#{Time.now.strftime("%Y%m%d%H%M%S").to_s}-#{homework.course_id}-#{homework.name}.zip" + out_file_name.gsub!(" ", "-") + out_file_name.gsub!("/", "_") - zip.get_output_stream('FILE_NOTICE.txt'){|os| os.write("文件重复:#{export.filename}") } - next - end - end + zipfile_name = "#{folder}/#{out_file_name}" + + student_works = homework.score_student_works + + if student_works.size > 0 + pdfs = [] + file_paths = [] + student_works.find_in_batches(batch_size: 500) do |sw| + Parallel.each(sw, in_threads: parallel_size) do |student_work| + export = ExportShixunReportService.new(homework, student_work) + pdf = export.to_pdf + pdfs << pdf + file_paths << {filename: export.filename, path: pdf.path} + puts "out: #{export.filename}_#{pdf.path}" end - zipfile = zipfile_name - else - zipfile = {:message => "no file"} end - puts "out: #{zipfile}" + Zip::File.open(zipfile_name, Zip::File::CREATE) do |zip| + file_paths.each do |pdf| + begin + zip.add(pdf[:filename], pdf[:path]) + rescue => ex + Rails.logger.error(ex.message) + + zip.get_output_stream('FILE_NOTICE.txt'){|os| os.write("文件重复:#{export.filename}") } + next + end + end + end + else + zipfile = {:message => "no file"} end end end + # 执行示例 bundle exec rake zip_pack:homework_attach_pack args=123 task :homework_attach_pack => :environment do include ExportHelper if ENV['args'] @@ -61,7 +95,4 @@ namespace :zip_pack do end end - def filename_for_content_disposition(name) - request.env['HTTP_USER_AGENT'] =~ %r{MSIE|Trident|Edge} ? ERB::Util.url_encode(name) : name - end end \ No newline at end of file diff --git a/public/react/package.json b/public/react/package.json index 25aa1d87f..a30780480 100644 --- a/public/react/package.json +++ b/public/react/package.json @@ -75,6 +75,7 @@ "react-codemirror": "^1.0.0", "react-codemirror2": "^6.0.0", "react-content-loader": "^3.1.1", + "react-cookies": "^0.1.1", "react-dev-utils": "^5.0.0", "react-dom": "^16.9.0", "react-hot-loader": "^4.0.0", diff --git a/public/react/public/css/demo_index.html b/public/react/public/css/demo_index.html index e0b7e8b5c..49a560afc 100644 --- a/public/react/public/css/demo_index.html +++ b/public/react/public/css/demo_index.html @@ -1134,6 +1134,12 @@
&#xe7f9;
+
  • + +
    过滤器
    +
    &#xe71b;
    +
  • +
  • 20从属连接
    @@ -3572,6 +3578,15 @@
  • +
  • + +
    + 过滤器 +
    +
    .icon-guolvqi +
    +
  • +
  • @@ -6171,6 +6186,14 @@
    #icon-gengduo1
  • +
  • + +
    过滤器
    +
    #icon-guolvqi
    +
  • +
  • +
    +
    + +
    +
    +
    + + + 初始化 + + + + 测试集 + +
    + {/* */} + +
    +
    + {/* 测试集 */} +
    +
    +
    + 共{testCase.length}个测试用例 + 关闭 +
    +
    + + {test_sets_count - sets_error_count}/{test_sets_count} + {resultTxt} +
    +
      + { + testCase.map((item, i) => { + const {input, output, actual_output, is_public, result} = item; + const _classes = isActive === i ? 'case-item-desc active' : 'case-item-desc'; + const iconclasses = isActive === i ? 'iconfont icon-sanjiaoxing-down icon active' : 'iconfont icon-triangle icon'; + const headerClasses = is_public ? 'item-header-desc active' : 'item-header-desc'; + // console.log(_classes); + return ( +
    • +
      handleCloseItem(i, is_public)}> +

      + + 测试集{i + 1} +

      + { + is_public && last_compile_output + ? (result + ? + : ) + : ( + 隐藏测试集,暂不支持解锁和查看 + {/* {result + ? + : + } */} + ) + } +
      + +
      + 测试输入 + {input || '-'} + 预期输出 + {/* */} + */} + 实际输出 +