Merge branch 'dev_aliyun' into educoder

dev_aliyun
daiao 5 years ago
commit 5734c1a0ab

@ -18,7 +18,16 @@ class CompetitionTeamsController < ApplicationController
def shixun_detail def shixun_detail
return render_404 if @competition.identifier != 'gcc-course-2019' return render_404 if @competition.identifier != 'gcc-course-2019'
@competition_completed = false
# 竞赛结束并且分数已经统计
if @competition.end_time < Time.current && CompetitionCourseRecord.exists?(competition_id: @competition.id)
@competition_completed = true
@records = CompetitionCourseRecord.where(type: 'CompetitionCourseShixunRecord', competition_team_id: @team.id)
return
end
# 竞赛正在进行,分数动态计算
@team_user_ids = @team.team_members.pluck(:user_id) @team_user_ids = @team.team_members.pluck(:user_id)
shixuns = Shixun.where(user_id: @team_user_ids, status: 2) shixuns = Shixun.where(user_id: @team_user_ids, status: 2)
@ -48,6 +57,14 @@ class CompetitionTeamsController < ApplicationController
def course_detail def course_detail
return render_404 if @competition.identifier != 'gcc-course-2019' return render_404 if @competition.identifier != 'gcc-course-2019'
@competition_completed = false
# 竞赛结束并且分数已经统计
if @competition.end_time < Time.current && CompetitionCourseRecord.exists?(competition_id: @competition.id)
@competition_completed = true
@records = CompetitionCourseRecord.where(type: 'CompetitionCourseCourseRecord', competition_team_id: @team.id)
return
end
@team_user_ids = @team.team_members.pluck(:user_id) @team_user_ids = @team.team_members.pluck(:user_id)

@ -0,0 +1,3 @@
class CompetitionCourseCourseRecord < CompetitionCourseRecord
end

@ -0,0 +1,6 @@
class CompetitionCourseRecord < ActiveRecord::Base
belongs_to :competition
belongs_to :competition_team
serialize :snapshot, JSON
end

@ -0,0 +1,2 @@
class CompetitionCourseShixunRecord < CompetitionCourseRecord
end

@ -15,8 +15,43 @@
<% <%
total_members_count = 0 total_members_count = 0
total_shixun_homework_count = 0 total_shixun_homework_count = 0
total_valid_homework_count = 0
total_course_score = 0 total_course_score = 0
%> %>
<% if @competition_completed %>
<% @records.each do |record| %>
<%
course = record.snapshot['course']
total_members_count += record.snapshot['members_count'].to_i
total_shixun_homework_count += record.snapshot['shixun_homework_count'].to_i
total_valid_homework_count += record.snapshot['valid_myshixun_count'].to_i
total_course_score += record.score.to_i
%>
<tr>
<td width="10%"><%= course.teachers.where(user_id: @team_user_ids).first.user.show_real_name %></td>
<td width="40%" class="edu-txt-left">
<%= link_to course_path(course), target: '_blank' do %>
<span class="task-hide fl" style="max-width: 480px;"><%= course.name %></span>
<% end %>
</td>
<td width="10%"><%= record.snapshot['members_count'].to_i %></td>
<td width="15%"><%= record.snapshot['shixun_homework_count'].to_i || '--' %></td>
<td width="10%"><%= record.snapshot['valid_myshixun_count'].to_i %></td>
<td width="15%"><%= record.score.to_i.zero? ? '--' : record.score.to_i %></td>
</tr>
<% end %>
</tbody>
<tfoot class="tfootLastPart">
<tr class="color-orange font-16">
<th width="10%" class="color-grey-6">合计</th>
<th width="40%" class="edu-txt-left"><%= @records.size %></th>
<th width="10%"><%= total_members_count %></th>
<th width="15%"><%= total_shixun_homework_count %></th>
<th width="10%"><%= total_valid_homework_count %></th>
<th width="15%"><%= total_course_score %></th>
</tr>
</tfoot>
<% else %>
<% @courses.each do |course| %> <% @courses.each do |course| %>
<% <%
total_members_count += course.members_count.to_i total_members_count += course.members_count.to_i
@ -49,4 +84,5 @@
<th width="15%"><%= total_course_score %></th> <th width="15%"><%= total_course_score %></th>
</tr> </tr>
</tfoot> </tfoot>
<% end %>
</table> </table>

@ -14,8 +14,46 @@
<% <%
total_myshixun_count = 0 total_myshixun_count = 0
total_forked_myshixun_count = 0 total_forked_myshixun_count = 0
total_valid_myshixun_count = 0
total_shixun_score = 0 total_shixun_score = 0
%> %>
<% if @competition_completed %>
<% @records.each do |record| %>
<%
shixun = record.snapshot['shixun']
total_myshixun_count += record.snapshot['myshixuns_count'].to_i
total_forked_myshixun_count += record.snapshot['forked_myshixun_count'].to_i
total_valid_myshixun_count += record.snapshot['valid_myshixun_count'].to_i
total_shixun_score += record.score.to_i
%>
<tr>
<td width="10%"><%= record.username %></td>
<td width="40%" class="edu-txt-left">
<%= link_to shixun_path(shixun['identifier']), target: '_blank' do %>
<span class="task-hide fl" style="max-width: 410px;"><%= shixun['name'] %></span>
<% end %>
<% if shixun['fork_from'].blank? %>
<span class="connectTag ml10">原创</span>
<% end %>
</td>
<td width="10%"><%= record.snapshot['myshixuns_count'].to_i.zero? ? '--' : record.snapshot['myshixuns_count'].to_i %></td>
<td width="15%"><%= record.snapshot['forked_myshixun_count'].to_i.zero? ? '--' : record.snapshot['forked_myshixun_count'].to_i %></td>
<td width="10%"><%= record.snapshot['valid_myshixun_count'].to_i.zero? ? '--' : record.snapshot['valid_myshixun_count'].to_i %></td>
<td width="15%"><%= record.score.zero? ? '--' : record.score %></td>
</tr>
<% end %>
</tbody>
<tfoot class="tfootLastPart">
<tr class="color-orange font-16">
<th width="10%" class="color-grey-6">合计</th>
<th width="40%" class="edu-txt-left"><%= @records.size %></th>
<th width="10%"><%= total_myshixun_count %></th>
<th width="15%"><%= total_forked_myshixun_count %></th>
<th width="10%"><%= total_valid_myshixun_count %></th>
<th width="15%"><%= total_shixun_score %></th>
</tr>
</tfoot>
<% else %>
<% @shixuns.each do |shixun| %> <% @shixuns.each do |shixun| %>
<% <%
total_myshixun_count += shixun.myshixuns_count total_myshixun_count += shixun.myshixuns_count
@ -65,4 +103,5 @@
<th width="15%"><%= total_shixun_score %></th> <th width="15%"><%= total_shixun_score %></th>
</tr> </tr>
</tfoot> </tfoot>
<% end %>
</table> </table>

@ -71,7 +71,7 @@
<td>#<%= issue.id %></td> <td>#<%= issue.id %></td>
<td><a href="<%= issue_path(issue) %>" class="new_roadmap_info_title color-grey3" title="<%= issue.subject %>" target="_blank"><%= issue.subject %></a> </td> <td><a href="<%= issue_path(issue) %>" class="new_roadmap_info_title color-grey3" title="<%= issue.subject %>" target="_blank"><%= issue.subject %></a> </td>
<td> <%= issue.tracker %> </td> <td> <%= issue.tracker %> </td>
<td><a href="<%= issue.assigned_to_id.nil? ? "" : user_path(issue.assigned_to) %>" style="max-width: 200px" title="<%= User.find(issue.try(:assigned_to_id)).nil? ? "" : User.find(issue.try(:assigned_to_id)).show_name %>" class="new_roadmap_info_name" target="_blank"> <td><a href="<%= issue.assigned_to_id.nil? ? "" : user_path(issue.assigned_to) %>" style="max-width: 200px" data-tip-down="<%= User.find(issue.try(:assigned_to_id)).nil? ? "" : User.find(issue.try(:assigned_to_id)).show_name %>" class="new_roadmap_info_name" target="_blank">
<%= User.find(issue.try(:assigned_to_id)).nil? ? "" : User.find(issue.try(:assigned_to_id)).show_name %></a> <%= User.find(issue.try(:assigned_to_id)).nil? ? "" : User.find(issue.try(:assigned_to_id)).show_name %></a>
</td> </td>
<td><%= format_time issue.updated_on %></td> <td><%= format_time issue.updated_on %></td>

@ -0,0 +1,15 @@
class CreateCompetitionCourseRecords < ActiveRecord::Migration
def change
create_table :competition_course_records do |t|
t.references :competition
t.references :competition_team
t.string :type
t.integer :user_id
t.string :username
t.integer :score
t.text :snapshot
end
end
end

@ -0,0 +1,164 @@
namespace :competition do
desc "statistic gcc_course competition score"
task :gcc_course_statistic, [:competition_id] => :environment do |_, args|
competition = Competition.find args[:competition_id]
custom_logger("Start Statistic Competition Score: #{competition.id}|#{competition.identifier}|#{competition.name} ~")
custom_logger("Clear Old Competition Scores ~")
CompetitionScore.where(competition_id: competition.id).delete_all
CompetitionCourseRecord.where(competition_id: competition.id).delete_all
custom_logger("Clear Old Competition Scores Completed!")
competition.competition_teams.each do |team|
custom_logger("Start Statistic Competition Team: #{team.id}|#{team.name} ~")
team_user_ids = team.team_members.pluck(:user_id)
total_score = 0
# =========== Shixun ===========
shixuns = Shixun.where(user_id: team_user_ids, status: 2)
.where('shixuns.created_at > ? && shixuns.created_at <= ?', Time.parse('2018-06-01'), competition.end_time)
shixuns = shixuns.joins('left join shixuns forked_shixuns on forked_shixuns.fork_from = shixuns.id and forked_shixuns.status = 2')
shixuns = shixuns.select('shixuns.id, shixuns.identifier, shixuns.user_id, shixuns.myshixuns_count, shixuns.name, shixuns.fork_from, sum(forked_shixuns.myshixuns_count) forked_myshixun_count')
shixuns = shixuns.group('shixuns.id').order('shixuns.myshixuns_count desc').includes(:creator)
shixun_ids = shixuns.map(&:id)
myshixun_count_map = get_valid_myshixun_count(shixun_ids)
original_myshixun_count_map = myshixun_count_map.clone
# forked shixun valid myshixun count
forked_shixun_map = Shixun.where(status: 2, fork_from: shixun_ids).select('id, fork_from')
forked_shixun_map = forked_shixun_map.each_with_object({}) { |sx, obj| obj[sx.id] = sx.fork_from }
forked_myshixun_count_map = get_valid_myshixun_count(forked_shixun_map.keys)
forked_myshixun_count_map.each { |k, v| myshixun_count_map[forked_shixun_map[k]] += v }
course_count_map = get_valid_course_count(shixun_ids)
forked_map = get_valid_course_count(forked_shixun_map.keys)
forked_course_count_map = {}
forked_map.each do |forked_id, course_count|
forked_course_count_map[forked_shixun_map[forked_id]] ||= 0
forked_course_count_map[forked_shixun_map[forked_id]] += course_count
end
custom_logger("Start Shixun Score ~")
shixuns.each do |shixun|
valid_course_count = course_count_map.fetch(shixun.id, 0)
valid_student_count = original_myshixun_count_map.fetch(shixun.id, 0)
score =
if shixun.fork_from.blank?
500 + 50 * valid_course_count + 10 * valid_student_count
else
100 + 10 * valid_course_count + 5 * valid_student_count
end
forked_shixun_map.each do |shixun_id, fork_from_id|
next if fork_from_id != shixun.id
score += 100 + 10 * forked_map.fetch(shixun_id, 0) + 5 * forked_myshixun_count_map.fetch(shixun_id, 0)
end
total_score += score
attr = {
competition_id: competition.id,
competition_team_id: team.id,
user_id: shixun.creator.id,
username: shixun.creator.show_real_name,
score: score,
snapshot: {
shixun: shixun.as_json(only: [:id, :name, :identifier, :fork_from])['shixun'],
myshixuns_count: shixun.myshixuns_count.to_i,
forked_myshixun_count: shixun['forked_myshixun_count'].to_i,
valid_myshixun_count: myshixun_count_map.fetch(shixun.id, 0),
}
}
CompetitionCourseShixunRecord.create(attr)
end
custom_logger("Shixun Score Completed!")
# =========== Course ===========
student_count_subquery = CourseMember.where('course_id = courses.id AND role = 4').select('count(*)').to_sql
subquery = StudentWork.where('homework_common_id = hcs.id')
.select('sum(compelete_status !=0 ) as finish, count(*) as total')
.having('total != 0 and finish >= (total / 2)').to_sql
course_ids = Course.where('courses.created_at > ?', Time.parse('2018-06-01'))
.where('courses.created_at <= ?', competition.end_time)
.where("(#{student_count_subquery}) >= 3")
.where("exists(select 1 from homework_commons hcs where hcs.course_id = courses.id and hcs.publish_time is not null and hcs.publish_time < NOW() and hcs.homework_type = 4 and exists(#{subquery}))")
.joins('join course_members on course_members.course_id = courses.id and course_members.role in (1,2,3)')
.where(course_members: { user_id: team_user_ids }).pluck(:id)
courses = Course.where(id: course_ids).joins(:shixun_homework_commons).where('homework_commons.publish_time < now()')
courses = courses.select('courses.id, courses.name, courses.members_count, count(*) shixun_homework_count')
.group('courses.id').order('shixun_homework_count desc').having('shixun_homework_count > 0')
course_ids = courses.map(&:id)
course_myshixun_map = Myshixun.joins(student_works: :homework_common)
.where(homework_commons: { course_id: course_ids })
.where('exists(select 1 from games where games.myshixun_id = myshixuns.id and games.status = 2)')
.group('homework_commons.course_id').count
course_shixun_count_map = get_valid_shixun_count(course_ids)
custom_logger("Start Course Score ~")
courses.each do |course|
user = course.teachers.where(user_id: team_user_ids).first.user
score = 500 + 5 * course_shixun_count_map.fetch(course.id, 0) * course_myshixun_map.fetch(course.id, 0)
total_score += score
attr = {
competition_id: competition.id,
competition_team_id: team.id,
user_id: user.id,
username: user.show_real_name,
score: score,
snapshot: {
course: course.as_json(only: [:id, :name]),
members_count: course.members_count.to_i,
shixun_homework_count: course['shixun_homework_count'].to_i,
valid_myshixun_count: course_myshixun_map.fetch(course.id, 0),
}
}
CompetitionCourseCourseRecord.create(attr)
end
custom_logger("Course Score Completed!")
custom_logger('Create Competition Score ~')
CompetitionScore.create(user_id: team.user_id, competition_team_id: team.id, competition_id: competition.id, score: total_score)
custom_logger("Statistic Competition Team: #{team.id}|#{team.name} Completed!")
end
end
def custom_logger(msg)
Rails.logger.info(msg)
p msg
end
def get_valid_myshixun_count(ids)
Myshixun.where(shixun_id: ids)
.where('exists(select 1 from games where games.myshixun_id = myshixuns.id and games.status = 2)')
.group('shixun_id').count
end
def get_valid_course_count(ids)
percentage_sql = StudentWork.where('homework_common_id = homework_commons.id and homework_commons.publish_time is not null and homework_commons.publish_time < NOW()')
.select('sum(compelete_status !=0 ) as finish, count(*) as total')
.having('total != 0 and finish >= (total / 2)').to_sql
Course.joins(shixun_homework_commons: :homework_commons_shixuns)
.where('shixun_id in (?)', ids)
.where("exists (#{percentage_sql})")
.group('shixun_id').count
end
def get_valid_shixun_count(ids)
percentage_sql = StudentWork.where('homework_common_id = homework_commons.id and homework_commons.publish_time is not null and homework_commons.publish_time < NOW()')
.select('sum(compelete_status !=0 ) as finish, count(*) as total')
.having('total != 0 and finish >= (total / 2)').to_sql
Shixun.joins(homework_commons_shixuns: :homework_common)
.where(homework_commons: { homework_type: 4 })
.where('course_id in (?)', ids)
.where("exists (#{percentage_sql})")
.group('course_id').count
end
end
Loading…
Cancel
Save