diff --git a/Gemfile b/Gemfile index 31af87f14..b8b174a6f 100644 --- a/Gemfile +++ b/Gemfile @@ -39,6 +39,8 @@ gem 'pdfkit' gem 'wkhtmltopdf-binary' #gem 'iconv' +# markdown 转html +gem 'redcarpet', '~> 3.4' gem 'rqrcode', '~> 0.10.1' gem 'rqrcode_png' diff --git a/Gemfile.lock b/Gemfile.lock index 83bd79628..86f524bc2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -193,6 +193,7 @@ GEM rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) rchardet (1.8.0) + redcarpet (3.4.0) redis (4.1.0) redis-actionpack (5.0.2) actionpack (>= 4.0, < 6) @@ -328,6 +329,7 @@ DEPENDENCIES rails (~> 5.2.0) rails-i18n (~> 5.1) rchardet (~> 1.8) + redcarpet (~> 3.4) redis-rails roo-xls rqrcode (~> 0.10.1) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index afe2129a9..cbd2962b6 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -427,6 +427,24 @@ class ApplicationController < ActionController::Base container.to_json end + # 实训中间层pod配置 + def shixun_container_limit shixun + container = [] + shixun.shixun_service_configs.each do |config| + mirror = config.mirror_repository + if mirror.name.present? + container << {:image => mirror.name, + :cpuLimit => config.cpu_limit, + :cpuRequest => config.lower_cpu_limit, + :memoryLimit => "#{config.memory_limit}M", + :memoryRequest => "#{config.request_limit}M", + :resourceLimit => "#{config.resource_limit}K", + :type => mirror.try(:main_type) == "1" ? "main" : "sub"} + end + end + container.to_json + end + # 毕设任务列表的赛选 def course_work(task, **option) logger.info("#############{option}") diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb index 2ba76c60a..856afeb01 100644 --- a/app/controllers/challenges_controller.rb +++ b/app/controllers/challenges_controller.rb @@ -138,7 +138,7 @@ class ChallengesController < ApplicationController # tab 0,nil 过关任务, 1 评测设置, 2 参考答案 def edit @tab = params[:tab].to_i - @power = current_user.manager_of_shixun?(@shixun) && @shixun.status == 0 + @power = @shixun.status == 0 challenge_num = Challenge.where(:shixun_id => @shixun).count @position = @challenge.position @chooses = @challenge.challenge_chooses @@ -151,17 +151,17 @@ class ChallengesController < ApplicationController def index uid_logger("identifier: #{params}") # 通过调试发现 这里includes(:games)性能会慢10倍 + current_myshixun = @shixun.current_myshixun(current_user.id) + @challenges = @shixun.challenges.includes(:games).where("games.user_id" => (current_myshixun ? current_user.id : nil)) - @challenges = @shixun.challenges.fields_for_list.includes(:games).where("games.user_id" => current_user.id) - - @editable = current_user.manager_of_shixun?(@shixun) && @shixun.status == 0 + @editable = @shixun.status == 0 # before_action:有判断权限,如果没发布,则肯定是管理人员 @user = current_user end def show @tab = params[:tab].nil? ? 1 : params[:tab].to_i - challenge_num = Challenge.where(shixun_id: @shixun).count - @power = current_user.manager_of_shixun?(@shixun) && @shixun.status == 0 + challenge_num = @shixun.challenges_count + @power = @shixun.status == 0 # 之前验证走过了是不是管理员,因此这里只用判断是否发布 @position = @challenge.position if @position < challenge_num @next_challenge = Challenge.where(:shixun_id => @shixun, :position => @position + 1).first @@ -279,9 +279,6 @@ class ChallengesController < ApplicationController def find_shixun @shixun = Shixun.find_by_identifier(params[:shixun_identifier]) - if !current_user.shixun_permission(@shixun) - tip_exception(403, "..") - end end # 通用接口 @@ -293,7 +290,7 @@ class ChallengesController < ApplicationController def challenge_params params.require(:challenge).permit(:subject, :task_pass, :difficulty, :score, :st, :modify_time, :test_set_average, :path, :exec_path, :show_type, :original_picture_path, :test_set_score, - :expect_picture_path, :picture_path, :web_route, :answer) + :expect_picture_path, :picture_path, :web_route, :answer, :exec_time) end def chooce_params diff --git a/app/controllers/concerns/git_common.rb b/app/controllers/concerns/git_common.rb index 2f977245c..452204419 100644 --- a/app/controllers/concerns/git_common.rb +++ b/app/controllers/concerns/git_common.rb @@ -28,7 +28,6 @@ module GitCommon end def file_content - logger.info("#################{@repo_path}, #{@path}") @content = git_fle_content @repo_path, @path end diff --git a/app/controllers/concerns/git_helper.rb b/app/controllers/concerns/git_helper.rb index 445d67087..8d769a244 100644 --- a/app/controllers/concerns/git_helper.rb +++ b/app/controllers/concerns/git_helper.rb @@ -9,9 +9,10 @@ module GitHelper # 版本库文件内容,带转码 def git_fle_content(repo_path, path) begin + logger.info("git file content: repo_path is #{repo_path}, path is #{path}") content = GitService.file_content(repo_path: repo_path, path: path) - logger.info("@@@@@@@@@@@@@@@@@@#{content}") + logger.info("git file content: content is #{content}") decode_content = nil if content.present? content = content["content"] #6.24 -hs 这个为新增,因为当实训题里含有选择题时,这里会报错,undefined method `[]' for nil:NilClass @@ -31,7 +32,7 @@ module GitHelper decode_content rescue Exception => e - uid_logger_error(e.message) + Rails.logger.error(e.message) raise Educoder::TipException.new("文档内容获取异常") end end diff --git a/app/controllers/exercise_questions_controller.rb b/app/controllers/exercise_questions_controller.rb index dd0247f70..b231d6af7 100644 --- a/app/controllers/exercise_questions_controller.rb +++ b/app/controllers/exercise_questions_controller.rb @@ -616,7 +616,7 @@ class ExerciseQuestionsController < ApplicationController elsif params[:question_type].to_i == 2 && (params[:standard_answers].count > 1 || params[:question_choices].blank? || params[:question_choices].include?("")) #判断题的标准答案不能大于1个,选项不能为空 normal_status(-1,"判断题选项不能为空/标准答案不能大于1个!") elsif params[:question_type].to_i <= 1 && (params[:question_choices].blank? || params[:question_choices].include?("") || params[:question_choices].count < 2) #选择题选项不能为空,且不能小于2 - normal_status(-1,"选择题选项内容不能为空,且不能少于3个!") + normal_status(-1,"选择题选项内容不能为空,且不能少于2个!") elsif params[:question_type].to_i == 3 && (params[:standard_answers].blank? || params[:standard_answers].count > 5 ) #填空题选项最多为5个,且如果为1个的话,不允许修改is_ordered normal_status(-1,"填空题标准答案不能为空/不能超过5个!") elsif params[:question_type].to_i == 4 && params[:standard_answers].count > 2 #简单题参考答案最多为1个 @@ -640,7 +640,7 @@ class ExerciseQuestionsController < ApplicationController if @exercise.exercise_status != 1 question_score = @exercise_question.question_score #原来的分数 update_question_score = params[:question_score].to_f.round(1) #传入的分数 - choices_count = @exercise_question.exercise_choices.count #原来的选项个数 + choices_count = @exercise_question.exercise_choices.size #原来的选项个数 exercise_choice_ids = @exercise_question.exercise_standard_answers.pluck(:exercise_choice_id).uniq standard_answers_text = @exercise_question.exercise_standard_answers.pluck(:answer_text).uniq update_choices_count = params[:question_choices].present? ? params[:question_choices].count : choices_count #传入的选项个数 diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 421c5177a..2377f411b 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -101,7 +101,7 @@ class ExercisesController < ApplicationController @page = params[:page] || 1 @limit = params[:limit] || 15 @exercises = @exercises.page(@page).per(@limit) - @exercises = @exercises.includes(:exercise_users,:exercise_questions,:exercise_group_settings) + @exercises = @exercises&.includes(:exercise_users,:exercise_questions,:exercise_group_settings) else @exercises = [] end @@ -188,7 +188,7 @@ class ExercisesController < ApplicationController else @is_teacher_or = 0 #为学生 end - @exercise_questions = @exercise.exercise_questions.order("question_number ASC") + @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("试卷创建失败!") @@ -1334,6 +1334,7 @@ class ExercisesController < ApplicationController #导出空白试卷 def export_exercise @exercise_questions = @exercise.exercise_questions.includes(:exercise_choices).order("question_number ASC") + @request_url = request.base_url filename = "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.current.strftime('%Y%m%d%H%M%S')}.pdf" stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css" render pdf: 'exercise_export/blank_exercise', filename: filename, stylesheets: stylesheets @@ -1418,7 +1419,7 @@ class ExercisesController < ApplicationController :best_counts => best_counts, } - @exercise_questions = @exercise.exercise_questions + @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices,:exercise_answers,:exercise_standard_answers,:exercise_shixun_challenges,:exercise_shixun_answers) @paging_type = "percent" # 按题型排序 diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 7e150c44c..c8fd042ea 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -16,26 +16,27 @@ class FilesController < ApplicationController sort = params[:sort] || 0 # 0: 降序;1: 升序 sort_type = params[:sort_type] || 'created_on' # created_on:时间排序, downloads:下载次数排序; quotes: 引用次数排序 course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id - @user = current_user || nil - @attachments = @course.attachments.by_keywords(params[:search]) + @user = current_user + @attachments = @course.attachments.by_course_second_category_id(course_second_category_id) .includes(attachment_group_settings: :course_group, author: [:user_extension, :course_members]) - .by_course_second_category_id(course_second_category_id) .ordered(sort: sort.to_i, sort_type: sort_type.strip) - get_category(@course, course_second_category_id) - - case @user.course_identity(@course) - when 5 - # 课程学生 - @attachments = @attachments.published - when 6 || 7 - # 非课堂成员 - @attachments = @attachments.publiced.published - end + get_category(@course, course_second_category_id) @total_count = @attachments.size @public_count = @attachments.publiced.size @private_count = @total_count - @public_count + @attachments = @attachments.by_keywords(params[:search]) + @attachments = + case @user.course_identity(@course) + when 5 + @attachments.published + when 6, 7 + @attachments.publiced.published + else + @attachments + end + @attachments = @attachments.page(@page).per(@page_size) end diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb index 9e645c35a..7e7b6e082 100644 --- a/app/controllers/games_controller.rb +++ b/app/controllers/games_controller.rb @@ -33,7 +33,7 @@ class GamesController < ApplicationController is_teacher = @user.is_teacher? # 实训超时设置 - time_limit = @shixun.exec_time + time_limit = game_challenge.exec_time # 上一关、下一关 prev_game = @game.prev_of_current_game(@shixun.id, @game.myshixun_id, game_challenge.position) @@ -52,7 +52,7 @@ class GamesController < ApplicationController record_onsume_time = EvaluateRecord.where(game_id: @game.id).first.try(:consume_time) # myshixun_manager判断用户是否有权限查看隐藏测试集(TPM管理员;平台认证的老师;花费金币查看者) - myshixun_manager = @identity < USER::EDU_GAME_MANAGER + myshixun_manager = @identity < User::EDU_GAME_MANAGER # 选择题和编程题公共部分 @base_date = {st: @st, discusses_count: discusses_count, game_count: game_count, myshixun: @myshixun, @@ -66,7 +66,7 @@ class GamesController < ApplicationController shixun_tomcat = edu_setting('cloud_bridge') service_host = edu_setting('vnc_url') uri = "#{shixun_tomcat}/bridge/vnc/getvnc" - params = {tpiID: @myshixun.id, :containers => "#{Base64.urlsafe_encode64(container_limit(@shixun.mirror_repositories))}"} + params = {tpiID: @myshixun.id, :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(@shixun))}"} res = uri_post uri, params if res && res['code'].to_i != 0 raise("实训云平台繁忙(繁忙等级:99)") @@ -426,12 +426,12 @@ class GamesController < ApplicationController game_code = GameCode.where(:game_id => @game.try(:id), :path => path).first if game_code.present? content = game_code.try(:new_code) - @content = if @myshixun.mirror_name.select{|a| a.include?("MachineLearning") || a.include?("Python")}.present? && content.present? - content.gsub(/\t/, ' ') - else - content - end - update_file_content(@content, @myshixun.repo_path, path, current_user.mail, current_user.full_name, "game passed reset") + # @content = if @myshixun.mirror_name.select{|a| a.include?("MachineLearning") || a.include?("Python")}.present? && content.present? + # content.gsub(/\t/, ' ') + # else + # content + # end + update_file_content(content, @myshixun.repo_path, path, current_user.mail, current_user.full_name, "game passed reset") else tip_exception("代码重置失败,代码为空") end @@ -461,6 +461,7 @@ class GamesController < ApplicationController git_fle_content(@myshixun.shixun.repo_path, path) rescue Exception => e uid_logger_error("#{e.message}") + # 如果已发布的TPM实训也不能获取到内容,那么肯定是版本库异常了 if @myshixun.shixun.try(:status) < 2 tip_exception("代码获取异常,请检查实训模板的评测设置是否正确") else @@ -546,7 +547,7 @@ class GamesController < ApplicationController br_params = {:tpiID => "#{@myshixun.id}", :tpiGitURL => "#{gitUrl}", :buildID => "#{@game.id}", :instanceChallenge => "#{step}", :testCases => "#{testCases}", :resubmit => "#{resubmit}", :times => params[:first].to_i, :podType => @shixun.webssh, :content_modified => content_modified, - :containers => "#{Base64.urlsafe_encode64(container_limit(@shixun.mirror_repositories))}", + :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(@shixun))}", :persistenceName => @shixun.identifier, :tpmScript => "#{tpmScript}", :timeLimit => "#{@shixun.exec_time}", :isPublished => (@shixun.status < 2 ? 0 : 1) } diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index 8ce99cb79..f242f3438 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -1285,7 +1285,7 @@ class HomeworkCommonsController < ApplicationController # 代码查重届结果 def code_review_results # 如果有未获取结果的查重操作 则先读取结果 - #get_new_code_reviews_result @homework + get_new_code_reviews_result @homework @current_user = current_user # 列表数据 diff --git a/app/controllers/myshixuns_controller.rb b/app/controllers/myshixuns_controller.rb index 035b43955..909533301 100644 --- a/app/controllers/myshixuns_controller.rb +++ b/app/controllers/myshixuns_controller.rb @@ -217,7 +217,7 @@ class MyshixunsController < ApplicationController shixun_tomcat = edu_setting('tomcat_webssh') uri = "#{shixun_tomcat}/bridge/webssh/getConnectInfo" params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh), - containers:(Base64.urlsafe_encode64(container_limit @myshixun.shixun.mirror_repositories))} + containers:(Base64.urlsafe_encode64(shixun_container_limit @myshixun.shixun))} res = uri_post uri, params if res && res['code'].to_i != 0 tip_exception("实训云平台繁忙(繁忙等级:92)") @@ -243,55 +243,55 @@ class MyshixunsController < ApplicationController # -----Repository # TODO: 之类需要一个resubmit参数,但是是关于games. def update_file - @hide_code = Shixun.where(id: @myshixun.shixun_id).pluck(:hide_code).first - tip_exception("技术平台为空!") if @myshixun.mirror_name.blank? - path = params[:path].strip unless params[:path].blank? - game_id = params[:game_id] - game = Game.find(game_id) - @content_modified = 0 - # params[:evaluate] 实训评测时更新必须给的参数,需要依据该参数做性能统计,其它类型的更新可以跳过 - # 自动保存的时候evaluate为0;点评测的时候为1 - if params[:evaluate] == 1 - record = EvaluateRecord.create!(:user_id => current_user.id, :shixun_id => @myshixun.shixun_id, :game_id => game_id) - uid_logger("-- game is #{game_id}, record id is #{record.id}, time is **** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") - student_work_time = format("%.3f", (Time.now.to_f - record.created_at.to_f)).to_f - record.update_attributes!(:student_work => student_work_time) - end - unless @hide_code - # 远程版本库文件内容 - last_content = GitService.file_content(repo_path: @repo_path, path: path)["content"] + begin + @hide_code = Shixun.where(id: @myshixun.shixun_id).pluck(:hide_code).first + tip_exception("技术平台为空!") if @myshixun.mirror_name.blank? + path = params[:path].strip unless params[:path].blank? + game_id = params[:game_id] + game = Game.find(game_id) + @content_modified = 0 - content = if @myshixun.mirror_name.select{|a| a.include?("MachineLearning") || a.include?("Python")}.present? && params[:content].present? - params[:content].gsub(/\t/, ' ') - else - params[:content] - end - if content != last_content - @content_modified = 1 + # params[:evaluate] 实训评测时更新必须给的参数,需要依据该参数做性能统计,其它类型的更新可以跳过 + # 自动保存的时候evaluate为0;点评测的时候为1 + if params[:evaluate] == 1 + @sec_key = generate_identifier(EvaluateRecord, 12) + record = EvaluateRecord.create!(:user_id => current_user.id, :shixun_id => @myshixun.shixun_id, :game_id => game_id, + :identifier => @sec_key) + uid_logger("-- game build: file update #{@sec_key}, record id is #{record.id}, time is **** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") + end + unless @hide_code + # 远程版本库文件内容 + last_content = GitService.file_content(repo_path: @repo_path, path: path)["content"] + content = params[:content] - author_name = current_user.full_name - author_email = current_user.mail - message = params[:evaluate] == 0 ? "auto commit" : "task commit" - @content = GitService.update_file(repo_path: @repo_path, - file_path: path, - message: message, - content: content, - author_name: author_name, - author_email: author_email) + if content != last_content + @content_modified = 1 - uid_logger("-- file update #{@content}") + author_name = current_user.full_name + author_email = current_user.mail + message = params[:evaluate] == 0 ? "System automatically submitted" : "User submitted" + @content = GitService.update_file(repo_path: @repo_path, + file_path: path, + message: message, + content: content, + author_name: author_name, + author_email: author_email) + end end - end - if game.status == 2 - @resubmit = Time.now.to_i - end + if game.status == 2 + @resubmit = Time.now.to_i + end - # 评测时间记录 - if record.present? - consume_time = format("%.3f", (Time.now.to_f - record.created_at.to_f)).to_f - record.update_attributes!(:file_update => consume_time) + # 评测时间记录 + if record.present? + consume_time = format("%.3f", (Time.now.to_f - record.created_at.to_f)).to_f + record.update_attributes!(:file_update => consume_time) + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception("文件内容更新异常,请稍后重试") end end diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 6fbba1c3d..cd9679972 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -90,7 +90,7 @@ class PollsController < ApplicationController @limit = params[:limit] || 15 @polls = @polls.page(@page).per(@limit) - @polls = @polls.includes(:poll_users,:poll_questions,:poll_group_settings) + @polls = @polls&.includes(:poll_users,:poll_questions,:poll_group_settings) else @polls = [] @@ -183,7 +183,7 @@ class PollsController < ApplicationController else @is_teacher_or = 0 end - @poll_questions = @poll.poll_questions.order("question_number ASC") + @poll_questions = @poll.poll_questions&.includes(:poll_answers).order("question_number ASC") rescue Exception => e uid_logger_error(e.message) tip_exception("没有权限") @@ -1148,7 +1148,7 @@ class PollsController < ApplicationController end def get_questions_count - @poll_questions = @poll.poll_questions.order("question_number ASC") + @poll_questions = @poll.poll_questions&.includes(:poll_answers,:poll_votes).order("question_number ASC") @poll_questions_count = @poll_questions.count # 全部的题目数 @poll_question_singles = @poll_questions.ques_count(1).all.count # 单选题 @poll_question_doubles = @poll_questions.ques_count(2).all.count # 多选题 diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 73029706f..f079aed1e 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -315,9 +315,13 @@ class ShixunsController < ApplicationController # 镜像-实训关联表 ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i) if main_type.present? + # 实训主镜像服务配置 + ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i) if sub_type.present? sub_type.each do |mirror| ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror) + # 实训子镜像服务配置 + ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror) end end @@ -395,6 +399,18 @@ class ShixunsController < ApplicationController use_scope = 0 end @shixun.update_attributes!(:use_scope => use_scope) + # 超级管理员和运营人员才能保存 中间层服务器pod信息的配置 + if current_user.admin? || current_user.business? + @shixun.shixun_service_configs.destroy_all + params[:mirror_id].each_with_index do |mirror_id, index| + ShixunServiceConfig.create!(:shixun_id => @shixun.id, + :cpu_limit => params[:cpu_limit][index], + :lower_cpu_limit => params[:lower_cpu_limit][index], + :memory_limit => params[:memory_limit][index], + :request_limit => params[:request_limit][index], + :mirror_repository_id => mirror_id) + end + end rescue Exception => e uid_logger_error(e.message) tip_exception("实训保存失败") @@ -553,11 +569,6 @@ class ShixunsController < ApplicationController end end - # REDO:开启实训时更新关联作品的状态 - # TODO:这个可以异步。或者放到课程里面取,不要在开启实训这边做 - # HomeworksService.new.update_myshixun_work_status myshixun - UpdateMyshixunWorkStatusJob.perform_later(myshixun.id) - @current_task = myshixun.current_task(myshixun.games) uid_logger("## shixun exec: myshixun id is #{myshixun.id}") rescue Exception => e diff --git a/app/controllers/zips_controller.rb b/app/controllers/zips_controller.rb index a8750fc3d..77a41d065 100644 --- a/app/controllers/zips_controller.rb +++ b/app/controllers/zips_controller.rb @@ -17,7 +17,7 @@ class ZipsController < ApplicationController end def export_exercises - exercises = ExportExercisesService.new(@exercise,@ex_users) + exercises = ExportExercisesService.new(@exercise,@ex_users,@request_url) file_name = filename_for_content_disposition(exercises.filename) send_file exercises.ex_zip, filename: file_name, type: 'application/zip' @@ -41,6 +41,7 @@ class ZipsController < ApplicationController ActiveRecord::Base.transaction do begin @exercise = Exercise.includes(:exercise_users,:exercise_questions).find_by(id:params[:exercise_id]) + @request_url = request.base_url group_id = params[:exercise_group_id] if @exercise.blank? normal_status(-1,"试卷不存在") @@ -48,19 +49,20 @@ class ZipsController < ApplicationController @course = @exercise.course default_ex_users = @exercise.all_exercise_users(current_user.id).exercise_user_committed - default_ex_users_size = default_ex_users.size @ex_users = default_ex_users #仅导出已提交的,截止后则是全部为提交的。 #可以分班选择 if group_id.present? - exercise_students = @course.students.course_find_by_ids("course_group_id",group_id) # 试卷所分班的全部人数 - user_ids = exercise_students.pluck(:user_id).reject(&:blank?) - @ex_users = @ex_users.exercise_commit_users(user_ids) + exercise_students = @course.students.where(course_group_id: group_id) # 试卷所分班的全部人数 + user_ids = exercise_students.pluck(:user_id).reject(&:blank?).uniq + @ex_users = @ex_users.where(user_id: user_ids) end - # @ex_users = @ex_users.first(200) + + default_ex_users_size = @ex_users.size + if default_ex_users_size == 0 normal_status(-1,"导出失败,暂时没有已提交的学生") - elsif default_ex_users_size > 200 - normal_status(-1,"导出数量超过200,请分班导出或联系网站管理员导出") + elsif default_ex_users_size > 100 + normal_status(-1,"导出数量超过100,请分班导出或联系网站管理员导出") end end rescue Exception => e diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 32c4438a6..055731168 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,6 +1,7 @@ # 所有的方法请按首字母的顺序依次列出 module ApplicationHelper include Educoder::I18n + include GitHelper ONE_MINUTE = 60 * 1000 ONE_HOUR = 60 * ONE_MINUTE @@ -332,6 +333,23 @@ module ApplicationHelper raw arr.join('') end + + def to_markdown(text) + return nil if text.blank? + options = { + :autolink => true, + :no_intra_emphasis => true, + :fenced_code_blocks => true, + :lax_html_blocks => true, + :strikethrough => true, + :superscript => true, + :tables => true + } + + markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,options) + markdown.render(text).html_safe + end + end diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index a2a80c311..1442e1da3 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -1,5 +1,6 @@ module ExercisesHelper + # include GitHelper #获取每个学生对每个题的答案状态 def get_each_student_exercise(exercise_id,exercise_questions,user_id) @@ -166,10 +167,13 @@ module ExercisesHelper ex_score = ex&.question_score full_scores = effictive_users.search_exercise_answer("score",ex_score).count #满分人数 no_full_scores = effictive_users.exercise_no_full_scores(ex_score).count #部分分数人数 - all_zero_scores = effictive_users.search_exercise_answer("score",0.0).count #包含为0分的,及未评阅的 - review_scores = ex.exercise_answer_comments.count #主观题的评阅数量 - un_review_scores = effictive_users_count - review_scores #未评阅数 - zero_scores = all_zero_scores - un_review_scores #已评阅,且答案未0分的人数 + zero_scores = effictive_users.search_exercise_answer("score",0.0).count #包含为0分的,及未评阅的 + # review_scores = ex.exercise_answer_comments.count #主观题的评阅数量 + un_review_scores = effictive_users_count - full_scores - no_full_scores - zero_scores #未评阅数 + if un_review_scores < 0 + un_review_scores = 0 + end + # zero_scores = all_zero_scores - un_review_scores #已评阅,且答案未0分的人数 main_scores_array = [full_scores,no_full_scores,zero_scores,un_review_scores] main_scores_array.each_with_index do |s,index| if index == 0 @@ -428,15 +432,19 @@ module ExercisesHelper answer_status = 1 end ex_shixun_answer_content = answers_content&.where(exercise_shixun_challenge_id: exercise_cha.id) - if ex_shixun_answer_content.blank? #把关卡的答案存入试卷的实训里 + code = nil + if exercise_cha.challenge&.path.present? cha_path = challenge_path(exercise_cha.challenge&.path) game_challenge = game.game_codes.search_challenge_path(cha_path)&.first if game_challenge.present? game_code = game_challenge code = game_code.try(:new_code) else - code = git_fle_content(exercise_cha.shixun&.repo_path,cha_path) + code = git_fle_content(game.myshixun.repo_path,cha_path) end + end + if ex_shixun_answer_content.blank? #把关卡的答案存入试卷的实训里 + ### Todo 实训题的_shixun_details里的代码是不是直接从这里取出就可以了?涉及到code的多个版本库的修改 sx_option = { :exercise_question_id => q.id, :exercise_shixun_challenge_id => exercise_cha.id, @@ -447,7 +455,7 @@ module ExercisesHelper } ExerciseShixunAnswer.create(sx_option) else - ex_shixun_answer_content.first.update_column('score',exercise_cha_score) + ex_shixun_answer_content.first.update_attributes(score:exercise_cha_score.round(1),answer_text:code) end score5 += exercise_cha_score else @@ -637,7 +645,11 @@ module ExercisesHelper end if student_status == 2 #当前为老师,或为学生且已提交 user_score_pre = exercise_answers.score_reviewed - user_score = user_score_pre.present? ? user_score_pre.pluck(:score).sum : nil + if ques_type == 4 && user_score_pre.blank? #主观题时,且没有大于0的分数时,为空 + user_score = nil + else + user_score = user_score_pre.present? ? user_score_pre.pluck(:score).sum : 0.0 + end end if user_score.present? && (user_score > q.question_score) diff --git a/app/helpers/polls_helper.rb b/app/helpers/polls_helper.rb index b5ba79dcc..d9b6ccee7 100644 --- a/app/helpers/polls_helper.rb +++ b/app/helpers/polls_helper.rb @@ -110,7 +110,7 @@ module PollsHelper poll_user_name = user.nickname end course_member = course_members.find_by(user_id:user.id) - course_group_id = course_members.present? ? course_member.course_group_id : nil + course_group_id = course_member.present? ? course_member.course_group_id : nil if course_group_id == 0 course_group_name = "未分班" else diff --git a/app/models/challenge.rb b/app/models/challenge.rb index 07a49196d..18b177e1c 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -20,7 +20,7 @@ class Challenge < ApplicationRecord # acts_as_attachable scope :base_attrs, -> { select([:id, :subject, :position, :shixun_id, :st, :score, :path, :task_pass, :modify_time, - :web_route, :answer]) } + :web_route, :answer, :exec_time]) } scope :choose_type, -> { where(st: 1) } scope :practice_type, -> { where(st: 0) } diff --git a/app/models/shixun.rb b/app/models/shixun.rb index 556a4400f..18d5c5fae 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -30,6 +30,8 @@ class Shixun < ApplicationRecord has_one :shixun_info, dependent: :destroy belongs_to :user + # 实训服务配置 + has_many :shixun_service_configs, :dependent => :destroy scope :search_by_name, ->(keyword) { where("name like ? or description like ? ", diff --git a/app/models/shixun_service_config.rb b/app/models/shixun_service_config.rb new file mode 100644 index 000000000..6d106fc07 --- /dev/null +++ b/app/models/shixun_service_config.rb @@ -0,0 +1,4 @@ +class ShixunServiceConfig < ApplicationRecord + belongs_to :shixun + belongs_to :mirror_repository +end diff --git a/app/services/exercise_user_pdf_service.rb b/app/services/exercise_user_pdf_service.rb index 22804092e..9b96cd70c 100644 --- a/app/services/exercise_user_pdf_service.rb +++ b/app/services/exercise_user_pdf_service.rb @@ -5,9 +5,10 @@ class ExerciseUserPdfService attr_reader :exercise, :ex_user - def initialize(exercise, ex_user) + def initialize(exercise, ex_user,request_url) @exercise = exercise @ex_user = ex_user + @request_url = request_url @ex_user_user = @ex_user.user @course = @exercise.course end @@ -37,10 +38,10 @@ class ExerciseUserPdfService kit = PDFKit.new(html) base_css = %w(app/templates/exercise_export/exercise_export.css) base_css.each { |css| kit.stylesheets << Rails.root.join(css) } - #-----正式需删掉 + # #-----正式需删掉 # aa = File.open(Rails.root.join("public/123.html"),"w+") # aa.syswrite(kit.source) - #正式需删掉------- + # #正式需删掉------- file = Tempfile.new(filename) kit.to_pdf(file.path) file diff --git a/app/services/export_exercises_service.rb b/app/services/export_exercises_service.rb index 12b5501f9..48bfc9519 100644 --- a/app/services/export_exercises_service.rb +++ b/app/services/export_exercises_service.rb @@ -3,9 +3,10 @@ class ExportExercisesService include StudentWorksHelper attr_reader :exercise, :ex_users - def initialize(exercise, ex_users) + def initialize(exercise, ex_users,request_url) @exercise = exercise @ex_users = ex_users + @request_url = request_url end def filename @@ -18,7 +19,7 @@ class ExportExercisesService pdfs = [] Zip::File.open(zip_file.path, Zip::File::CREATE) do |zip| ex_users.each do |ex_user| - export = ExerciseUserPdfService.new(exercise, ex_user) + export = ExerciseUserPdfService.new(exercise, ex_user,@request_url) pdf = export.ex_pdf pdfs << pdf begin diff --git a/app/templates/exercise_export/blank_exercise.html.erb b/app/templates/exercise_export/blank_exercise.html.erb index 2745f8cbe..bdb86d9d9 100644 --- a/app/templates/exercise_export/blank_exercise.html.erb +++ b/app/templates/exercise_export/blank_exercise.html.erb @@ -68,13 +68,17 @@ (<%= q&.question_score %>分)