diff --git a/app/controllers/admins/competition_stages_controller.rb b/app/controllers/admins/competition_stages_controller.rb index 1e68b3f50..4961192cd 100644 --- a/app/controllers/admins/competition_stages_controller.rb +++ b/app/controllers/admins/competition_stages_controller.rb @@ -16,87 +16,64 @@ class Admins::CompetitionStagesController < Admins::BaseController def calculate_stage_score if current_stage.max_end_time && current_stage.max_end_time < Time.now - current_stage.competition_scores.destroy_all - if current_stage.competition_stage_sections.size > 0 - # 是否只有老师参赛 - only_teacher = current_competition.member_staff.blank? - stage_sections = current_stage.competition_stage_sections.includes(:competition_entries) - shixuns = Shixun.where(identifier: current_stage.competition_entries.pluck(:shixun_identifier).reject(&:blank?)) - - - # 计算每个战队的成绩 - current_competition.competition_teams.each do |team| - totoal_score = 0 - total_time = 0 - user_ids = only_teacher ? team.team_members.pluck(:user_id) : team.team_members.where(is_teacher: 0).pluck(:user_id) - - stage_sections.each do |section| - shixun_identifiers = section.competition_entries.pluck(:shixun_identifier).reject(&:blank?) - shixun_ids = shixuns.select{ |shixun| shixun_identifiers.include?(shixun.identifier) }.map(&:id) + ActiveRecord::Base.transaction do + begin + current_stage.competition_scores.destroy_all + + if current_stage.competition_stage_sections.size > 0 + # 是否只有老师参赛 + only_teacher = current_competition.member_staff.blank? + stage_sections = current_stage.competition_stage_sections.includes(:competition_entries) + shixuns = Shixun.where(identifier: current_stage.competition_entries.pluck(:shixun_identifier).reject(&:blank?)) + challenges = Challenge.where(shixun_id: shixuns.pluck(:id)) + + # 计算每个战队的成绩 + current_competition.competition_teams.each do |team| + totoal_score = 0 + total_time = 0 + # 只有老师参赛则计算所有参赛队员的成绩,否则只计算学生的成绩 + user_ids = only_teacher ? team.team_members.pluck(:user_id) : team.team_members.where(is_teacher: 0).pluck(:user_id) + + stage_sections.each do |section| + shixun_identifiers = section.competition_entries.pluck(:shixun_identifier).reject(&:blank?) + shixun_ids = shixuns.select{ |shixun| shixun_identifiers.include?(shixun.identifier) }.map(&:id) + section_challenges = challenges.select{ |challenge| shixun_ids.include?(challenge.shixun_id) } + if section.score_source == 0 + result1 = chart_stage_score user_ids, section.start_time, section.end_time, section_challenges, section_challenges.length/shixun_ids.length + else + result1 = chart_stage_rate user_ids, section.start_time, section.end_time, section_challenges, section_challenges.length/shixun_ids.length + end + score = result1[0] + time = result1[1] + + totoal_score += score + total_time += time + end + + # 比赛已截止且未有分数纪录 则创建 + unless team.competition_scores.exists?(competition_id: current_competition.id, competition_stage_id: current_stage.id) + CompetitionScore.create!(user_id: team.user_id, competition_team_id: team.id, competition_id: current_competition.id, + competition_stage_id: current_stage.id, score: totoal_score, cost_time: total_time) + end + end + + # 如果计算的是最后一个阶段,则同时计算总成绩(只有一个阶段则不需计算) + if current_stage.max_end_time == current_competition.max_stage_end_time && current_competition.competition_stages.size != 0 + calculate_total_score current_competition + end end - end - end - if @type == "预赛" - # 'nyog9r7c','yugrij4n','48flws5g','bfgau7s6','mfv6zrj7','f398leqr','qwaffs2p','ose7482b','y5wh2ofx' - # 预赛的实训id 第一阶段:1185,1197,1195 第二阶段:1202, 1210, 1207 第三阶段:1254,1255,1243 - shixun1_id = [2303] - shixun2_id = [2994, 3012, 3024] - shixun3_id = [2944, 2938, 2943] - elsif @type == "决赛" - # '92b7vt8x','a7fxenvc','wt2xfzny','xa4m9cng','tng6heyf','am5o73er','9fla2zry','fzp3iu4w','qlsy6xb4' - # 预赛的实训id 第一阶段:1289,1373,1256 第二阶段:1488, 1453, 1487 第三阶段:1470, 1473, 1408 - shixun1_id = Shixun.where(:identifier => ['ftlc4x38']).pluck(:id) - shixun2_id = Shixun.where(:identifier => ['y9npgih2','ucqt7fw3','2p7ouzwk']).pluck(:id) - shixun3_id = Shixun.where(:identifier => ['fj49r7xv','gf2cvxfh','cmoxhtbs']).pluck(:id) - end - - if @competition.competition_scores.where(:competition_stage_id => @stage.id).count == 0 - # 三个阶段的开始时间和结束时间 - s1_time = @stage.competition_stage_sections[0].start_time - e1_time = @stage.competition_stage_sections[0].end_time - s2_time = @stage.competition_stage_sections[1].start_time - e2_time = @stage.competition_stage_sections[1].end_time - s3_time = @stage.competition_stage_sections[2].start_time - e3_time = @stage.competition_stage_sections[2].end_time - - @records = @competition.competition_teams.includes(:user => [:user_extensions => [:school]]) - @records.each do |team| - user_ids = team.team_members.where(:is_teacher => 0).pluck(:user_id) - # 第一阶段的得分和耗时 - challenges_1 = Challenge.where(:shixun_id => shixun1_id) - challenge_rate1 = 1.0 - result1 = chart_exp_score_pre user_ids, s1_time, e1_time, challenges_1, challenge_rate1, 2 - score1 = result1[0] - time1 = result1[1] - - # 第二阶段的得分和耗时 - challenge_rate2 = 1.0 - challenges_2 = Challenge.where(:shixun_id => shixun2_id) - result2 = chart_exp_score_pre user_ids, s2_time, e2_time, challenges_2, challenge_rate2, 2 - score2 = result2[0] - time2 = result2[1] - - - # 第三阶段的得分和耗时 - challenges_3 = Challenge.where(:shixun_id => shixun3_id) - result3 = chart_exp_score_third user_ids, s3_time, e3_time, challenges_3 - score3 = result3[0] - time3 = result3[1] - - team[:s_score] = (score1 + score2 + score3).try(:round, 2) - team[:s_spend_time] = time1 + time2 + time3 - - # 比赛已截止且未有分数纪录 则创建 - if Time.now > e3_time && team.competition_scores.where(:competition_id => @competition.id, :competition_stage_id => @stage.id).count == 0 - CompetitionScore.create(:user_id => team.user_id, :competition_team_id => team.id, :competition_id => @competition.id, :competition_stage_id => @stage.id, :score => team[:s_score], :cost_time => team[:s_spend_time]) - end + rescue Exception => e + uid_logger_error(e.message) + @message = "#{e.message}" end end + + @message = "计算成功" else - render_error("#{current_stage.name}还未结束") + @message = "#{current_stage.name}还未结束" end end @@ -139,16 +116,16 @@ class Admins::CompetitionStagesController < Admins::BaseController # rate 关卡经验值与分数的比值 # challenge_count 每个实训的关卡数 # 对三个实训的所有关卡循环: 找到在比赛时间内通关的最低耗时 - def chart_stage_score user_ids, s_time, e_time, challenges, s_rate, challenge_count + def chart_stage_score user_ids, s_time, e_time, challenges, challenge_count total_score = 0 total_time = 0 length = challenge_count #每个实训的关卡数 for i in 1..length score = 0 time = 0 - challenges.where(:position => i).each do |challenge| + challenges.select{|challenge| challenge.position == i}.each do |challenge| Game.where(:challenge_id => challenge.id, :user_id => user_ids, :status => 2).select{|game| game.open_time >= s_time && game.end_time <= e_time }.each do |game| - game_score = challenge.score * s_rate + game_score = challenge.score cost_time = (game.end_time.to_i - s_time.to_i) > 0 ? (game.end_time.to_i - s_time.to_i) : 0 if score < game_score score = game_score @@ -164,27 +141,50 @@ class Admins::CompetitionStagesController < Admins::BaseController return [total_score, total_time] end - def chart_stage_rate user_ids, s_time, e_time, challenges + def chart_stage_rate user_ids, s_time, e_time, challenges, challenge_count # 第三阶段的得分和耗时 - score3 = 0 - time3 = 0 - - challenges.each do |challenge| - Game.where(:challenge_id => challenge.id, :user_id => user_ids, :status => 2).select{|game| game.open_time >= s_time && game.end_time <= e_time }.each do |game| - outputs = game.outputs.select{|output| !output.text_scor.nil? && output.created_at <= e_time } - if outputs.present? - outputs = outputs.sort { |a, b| b[:text_scor].to_f <=> a[:text_scor].to_f } - myshixun_score = outputs.first.text_scor.to_f - myshixun_time = outputs.first.created_at.to_i - s_time.to_i - if score3 < myshixun_score - score3 = myshixun_score - time3 = myshixun_time - elsif score3 == myshixun_score - time3 = myshixun_time > time3 ? time3 : myshixun_time + total_score = 0 + total_time = 0 + length = challenge_count #每个实训的关卡数 + for i in 1..length + score3 = 0 + time3 = 0 + + challenges.select{|challenge| challenge.position == i}.each do |challenge| + Game.where(:challenge_id => challenge.id, :user_id => user_ids, :status => 2).select{|game| game.open_time >= s_time && game.end_time <= e_time }.each do |game| + outputs = game.outputs.select{|output| !output.text_scor.nil? && output.created_at <= e_time } + if outputs.present? + outputs = outputs.sort { |a, b| b[:text_scor].to_f <=> a[:text_scor].to_f } + myshixun_score = outputs.first.text_scor.to_f + myshixun_time = outputs.first.created_at.to_i - s_time.to_i + if score3 < myshixun_score + score3 = myshixun_score + time3 = myshixun_time + elsif score3 == myshixun_score + time3 = myshixun_time > time3 ? time3 : myshixun_time + end end end end + + total_score += score3 + total_time += time3 + end + return [total_score, total_time] + end + + def calculate_total_score competition + competition.competition_teams.each do |team| + total_score = 0 + total_time = 0 + + competition.competition_stages.where("score_rate > 0").each do |stage| + stage_score = team.competition_scores.where(competition_stage_id: stage.id).take + total_score += stage_score.try(:score).to_f * stage.score_rate + total_time += stage_score.try(:cost_time).to_i + end + CompetitionScore.create!(user_id: team.user_id, competition_team_id: team.id, competition_id: competition.id, + competition_stage_id: 0, score: total_score, cost_time: total_time) end - return [score3, time3] end end \ No newline at end of file diff --git a/app/controllers/competitions/competitions_controller.rb b/app/controllers/competitions/competitions_controller.rb index 85e463d9e..e02ccb4a5 100644 --- a/app/controllers/competitions/competitions_controller.rb +++ b/app/controllers/competitions/competitions_controller.rb @@ -118,6 +118,7 @@ class Competitions::CompetitionsController < Competitions::BaseController current_team_ids = @competition.team_members.where(user_id: current_user.id).pluck(:competition_team_id).uniq @user_ranks = @records.select{|com_team| current_team_ids.include?(com_team.id)} @records = @records.where("score > 0") + @record_ids = @records.pluck(:id) if params[:format] == "xlsx" @records = @records.includes(user: [user_extension: :school], team_members: :user) respond_to do |format| diff --git a/app/models/competition.rb b/app/models/competition.rb index 47be8f9d9..eb1d2a5fa 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -122,6 +122,10 @@ class Competition < ApplicationRecord %w[home enroll inform chart resource] end + def max_stage_end_time + competition_stages.map(&:max_end_time).max + end + # def awards_count # competition_awards.pluck(:num)&.sum > 0 ? competition_awards.pluck(:num)&.sum : 20 # end diff --git a/app/views/admins/competition_settings/index.html.erb b/app/views/admins/competition_settings/index.html.erb index 392d539ab..9f9b15b6c 100644 --- a/app/views/admins/competition_settings/index.html.erb +++ b/app/views/admins/competition_settings/index.html.erb @@ -351,10 +351,10 @@ <%= agree_link '发送短信提醒', send_message_admins_competition_competition_stage_path(@competition, stage, element: ".send-message-#{stage.id}"), class: 'btn btn-outline-primary ml20', 'data-confirm': '确认执行发送短信操作?' %> <% end %> - <% if stage.max_end_time < Time.now %> + <% if stage.max_end_time && stage.max_end_time < Time.now && Time.now < Time.at(stage.max_end_time.to_i + 30*24*3600) %> <%= agree_link '计算成绩', calculate_stage_score_admins_competition_competition_stage_path(@competition, stage, element: ".calculate-score-#{stage.id}"), class: 'btn btn-outline-primary ml20', 'data-confirm': '确认执行计算成绩操作?' %> - <% end %> + <% end %> <%= delete_link '删除', admins_competition_competition_stage_path(competition_id: @competition.id, id: stage.id), class: 'btn btn-default delete-stage ml20' %> 保存 diff --git a/app/views/admins/competition_stages/calculate_stage_score.js.erb b/app/views/admins/competition_stages/calculate_stage_score.js.erb new file mode 100644 index 000000000..cb7a93c09 --- /dev/null +++ b/app/views/admins/competition_stages/calculate_stage_score.js.erb @@ -0,0 +1 @@ +alert("<%= @message %>"); \ No newline at end of file diff --git a/app/views/competitions/competitions/charts.json.jbuilder b/app/views/competitions/competitions/charts.json.jbuilder index e0d501fbd..e1952b5f3 100644 --- a/app/views/competitions/competitions/charts.json.jbuilder +++ b/app/views/competitions/competitions/charts.json.jbuilder @@ -1,5 +1,5 @@ json.user_ranks @user_ranks.each do |user_rank| - rank = @records.map(&:id).index(user_rank.id) + rank = @record_ids.index(user_rank.id) rank = rank.present? ? (rank+1) : 0 json.rank rank == 0 ? "--" : rank json.team_name user_rank.name diff --git a/public/react/src/modules/competitions/Competitioncommon/CompetitionCommon.css b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommon.css index ff20efb97..264642b7d 100644 --- a/public/react/src/modules/competitions/Competitioncommon/CompetitionCommon.css +++ b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommon.css @@ -394,6 +394,7 @@ .userranksclass{ text-align: left; - width: 15%; - padding-left: 31px; + width: 18%; + padding-left: 12px; + margin-right: 28px; } \ No newline at end of file diff --git a/public/react/src/modules/competitions/Competitioncommon/CompetitionContentsChart.js b/public/react/src/modules/competitions/Competitioncommon/CompetitionContentsChart.js index fcd0657ee..f287b66a5 100644 --- a/public/react/src/modules/competitions/Competitioncommon/CompetitionContentsChart.js +++ b/public/react/src/modules/competitions/Competitioncommon/CompetitionContentsChart.js @@ -33,12 +33,12 @@ class CompetitionContents extends Component{ } derivefun=(url)=>{ - axios.get(url).then((response) => { + axios.get(url).then((response)=>{ if(response === undefined){ return } if(response.data.status&&response.data.status===-1){ - + this.props.showNotification(response.data.message); }else if(response.data.status&&response.data.status===-2){ // if(response.data.message === "100"){ // // 已超出文件导出的上限数量(100 ),建议: @@ -54,6 +54,7 @@ class CompetitionContents extends Component{ // DownloadMessageval:500 // }) // } + this.props.showNotification(response.data.message); }else { // this.props.showNotification(`正在下载中`); // window.open("/api"+url, '_blank'); @@ -133,7 +134,7 @@ class CompetitionContents extends Component{ // - // console.log(this.props.chartdata&&this.props.chartdata.user_ranks) + //console.log(chartdata&&chartdata.teams) return (
{chart_rules===undefined?"":this.props.Competitioncallback(e)} activeKey={this.props.tabkey} tabBarExtraContent={this.props.current_user&&this.props.current_user.admin===true||this.props.current_user&&this.props.current_user.business===true?this.props.Competitionedittype===false?this.props.has_url===false?operations:"":"":""}> @@ -166,7 +167,7 @@ class CompetitionContents extends Component{ {chartdata===undefined?"":chartdata.teams.length===0?"":chartdata.teams.map((item,key)=>{ - if(key===3){ + if(key===2){ return( { - if(key===1){ + if(key===0){ return( { - if(key===2){ + if(key===1){ return( } - - {chartdata===undefined?"":chartdata.teams.length===0||chartdata.teams.length<3?"":} + + {chartdata===undefined?"":chartdata.teams.length===0||chartdata.teams.length<4?"":
}