dev_home
parent
160ea730fc
commit
8dbd024051
@ -0,0 +1,6 @@
|
||||
class CompetitionCourseRecord < ApplicationRecord
|
||||
belongs_to :competition
|
||||
belongs_to :competition_team
|
||||
|
||||
serialize :snapshot, JSON
|
||||
end
|
@ -0,0 +1,194 @@
|
||||
|
||||
namespace :competition do
|
||||
desc "statistic gcc_course competition score"
|
||||
task :extra_course_statistic, [:end_time] => :environment do |_, args|
|
||||
end_time = Time.parse(args[:end_time])
|
||||
start_time = Time.parse('2018-06-01')
|
||||
|
||||
old_competition = Competition.find 3
|
||||
competition = Competition.find 10
|
||||
|
||||
old_competition_user_ids = old_competition.team_members.pluck(:user_id)
|
||||
|
||||
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
|
||||
shixun_user_ids = Shixun.where.not(user_id: old_competition_user_ids).where(status: 2).where('shixuns.created_at > ? && shixuns.created_at <= ?', start_time, end_time).pluck(:user_id).uniq
|
||||
course_user_ids = Course.where.not(tea_id: old_competition_user_ids).where('courses.created_at > ?', start_time)
|
||||
.where('courses.created_at <= ?', 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 < ? and hcs.homework_type = 4 and exists(#{subquery}))", end_time)
|
||||
.joins('join course_members on course_members.course_id = courses.id and course_members.role in (1,2,3)').pluck(:tea_id)
|
||||
|
||||
user_ids = shixun_user_ids + course_user_ids
|
||||
|
||||
user_ids.uniq.each do |user_id|
|
||||
user = User.find user_id
|
||||
if user
|
||||
team = CompetitionTeam.create!(competition_id: competition.id, user_id: user_id, name: user.real_name)
|
||||
TeamMember.create!(competition_team_id: team.id, user_id: user_id, role: 1, competition_id: competition.id)
|
||||
end
|
||||
end
|
||||
|
||||
custom_logger("Start Statistic Competition Score ~")
|
||||
|
||||
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!")
|
||||
|
||||
CompetitionTeam.where(competition_id: competition.id).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 <= ?', start_time, 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(:user)
|
||||
|
||||
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, end_time)
|
||||
forked_map = get_valid_course_count(forked_shixun_map.keys, end_time)
|
||||
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.user.id,
|
||||
username: shixun.user.show_real_name,
|
||||
score: score,
|
||||
type: 'CompetitionCourseCourseRecord',
|
||||
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),
|
||||
}
|
||||
}
|
||||
CompetitionCourseRecord.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 > ?', start_time)
|
||||
.where('courses.created_at <= ?', 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 < ? and hcs.homework_type = 4 and exists(#{subquery}))", end_time)
|
||||
.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 < ?', end_time)
|
||||
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, end_time)
|
||||
|
||||
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,
|
||||
type: 'CompetitionCourseShixunRecord',
|
||||
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),
|
||||
}
|
||||
}
|
||||
CompetitionCourseRecord.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, end_time)
|
||||
percentage_sql = StudentWork.where('homework_common_id = homework_commons.id and homework_commons.publish_time is not null and homework_commons.publish_time < ?', end_time)
|
||||
.select('sum(compelete_status !=0 ) as finish, count(*) as total')
|
||||
.having('total != 0 and finish >= (total / 2)').to_sql
|
||||
|
||||
Course.joins(practice_homeworks: :homework_commons_shixun)
|
||||
.where('shixun_id in (?)', ids)
|
||||
.where("exists (#{percentage_sql})")
|
||||
.group('shixun_id').count
|
||||
end
|
||||
|
||||
def get_valid_shixun_count(ids, end_time)
|
||||
percentage_sql = StudentWork.where('homework_common_id = homework_commons.id and homework_commons.publish_time is not null and homework_commons.publish_time < ?', end_time)
|
||||
.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
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -0,0 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe CompetitionCourseRecord, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
Loading…
Reference in new issue