You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
4.7 KiB
137 lines
4.7 KiB
5 years ago
|
class Admins::UserStatisticQuery < ApplicationQuery
|
||
|
include CustomSortable
|
||
|
|
||
|
attr_reader :params
|
||
|
|
||
|
sort_columns :study_challenge_count, :finish_challenge_count, :study_shixun_count, :finish_shixun_count,
|
||
|
default_by: :finish_shixun_count, default_direction: :desc
|
||
|
|
||
|
def initialize(params)
|
||
|
@params = params
|
||
|
end
|
||
|
|
||
|
def call
|
||
|
users = User.where(type: 'User').group(:id)
|
||
|
|
||
|
users = users.joins(:user_extension).where(user_extensions: { school_id: params[:school_id] }) if params[:school_id].present?
|
||
|
|
||
|
total = users.count.count
|
||
|
|
||
|
# 根据排序字段进行查询
|
||
|
users = query_by_sort_column(users, params[:sort_by])
|
||
|
users = custom_sort(users, params[:sort_by], params[:sort_direction])
|
||
|
|
||
|
users = users.includes(user_extension: [:school, :department])
|
||
|
users = users.limit(page_size).offset(offset).to_a
|
||
|
# 查询并组装其它数据
|
||
|
users = package_other_data(users)
|
||
|
|
||
|
[total, users]
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def package_other_data(users)
|
||
|
ids = users.map(&:id)
|
||
|
|
||
|
study_myshixun = Myshixun.where(user_id: ids)
|
||
|
finish_myshixun = Myshixun.where(user_id: ids, status: 1)
|
||
|
study_challenge = Game.joins(:myshixun).where(myshixuns: { user_id: ids }).where(status: [0, 1, 2])
|
||
|
finish_challenge = Game.joins(:myshixun).where(myshixuns: { user_id: ids }).where(status: 2)
|
||
|
|
||
|
if time_range.present?
|
||
|
study_myshixun = study_myshixun.where(updated_at: time_range)
|
||
|
finish_myshixun = finish_myshixun.where(updated_at: time_range)
|
||
|
study_challenge = study_challenge.where(updated_at: time_range)
|
||
|
finish_challenge = finish_challenge.where(updated_at: time_range)
|
||
|
end
|
||
|
|
||
|
study_myshixun_map = study_myshixun.group(:user_id).count
|
||
|
finish_myshixun_map = finish_myshixun.group(:user_id).count
|
||
|
study_challenge_map = study_challenge.group(:user_id).count
|
||
|
finish_challenge_map = finish_challenge.group(:user_id).count
|
||
|
|
||
|
users.each do |user|
|
||
|
user._extra_data = {
|
||
|
study_shixun_count: study_myshixun_map.fetch(user.id, 0),
|
||
|
finish_shixun_count: finish_myshixun_map.fetch(user.id, 0),
|
||
|
study_challenge_count: study_challenge_map.fetch(user.id, 0),
|
||
|
finish_challenge_count: finish_challenge_map.fetch(user.id, 0),
|
||
|
}
|
||
|
end
|
||
|
|
||
|
users
|
||
|
end
|
||
|
|
||
|
def query_by_sort_column(users, sort_by_column)
|
||
|
base_query_column = 'users.*'
|
||
|
|
||
|
case sort_by_column.to_s
|
||
|
when 'study_shixun_count' then
|
||
|
users =
|
||
|
if time_range.present?
|
||
|
users.joins("LEFT JOIN myshixuns ON myshixuns.user_id = users.id "\
|
||
|
"AND myshixuns.updated_at BETWEEN '#{time_range.min}' AND '#{time_range.max}'")
|
||
|
else
|
||
|
users.left_joins(:myshixuns)
|
||
|
end
|
||
|
|
||
|
users.select("#{base_query_column}, COUNT(*) study_shixun_count")
|
||
|
when 'finish_shixun_count' then
|
||
|
users =
|
||
|
if time_range.present?
|
||
|
users.joins("LEFT JOIN myshixuns ON myshixuns.user_id = users.id AND myshixuns.status = 1 AND "\
|
||
|
"myshixuns.updated_at BETWEEN '#{time_range.min}' AND '#{time_range.max}'")
|
||
|
else
|
||
|
users.left_joins(:myshixuns).where(myshixuns: { status: 1 })
|
||
|
end
|
||
|
|
||
|
users.select("#{base_query_column}, COUNT(*) finish_shixun_count")
|
||
|
when 'study_challenge_count' then
|
||
|
users =
|
||
|
if time_range.present?
|
||
|
users.joins('LEFT JOIN myshixuns ON myshixuns.user_id = users.id')
|
||
|
.joins("LEFT JOIN games ON games.myshixun_id = myshixuns.id "\
|
||
|
"AND games.status IN (0,1,2) AND games.updated_at BETWEEN '#{time_range.min}' AND '#{time_range.max}'")
|
||
|
else
|
||
|
users.left_joins(myshixuns: :games).where(games: { status: [0, 1, 2] })
|
||
|
end
|
||
|
|
||
|
users.select("#{base_query_column}, COUNT(*) study_challenge_count")
|
||
|
when 'finish_challenge_count' then
|
||
|
users =
|
||
|
if time_range.present?
|
||
|
users.joins('LEFT JOIN myshixuns ON myshixuns.user_id = users.id')
|
||
|
.joins("LEFT JOIN games ON games.myshixun_id = myshixuns.id "\
|
||
|
"AND games.status = 2 AND games.updated_at BETWEEN '#{time_range.min}' AND '#{time_range.max}'")
|
||
|
else
|
||
|
users.left_joins(myshixuns: :games).where(games: { status: 2 })
|
||
|
end
|
||
|
|
||
|
users.select("#{base_query_column}, COUNT(*) finish_challenge_count")
|
||
|
else
|
||
|
users
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def time_range
|
||
|
@_time_range ||= begin
|
||
|
case params[:date]
|
||
|
when 'weekly' then 1.weeks.ago..Time.now
|
||
|
when 'monthly' then 1.months.ago..Time.now
|
||
|
when 'quarterly' then 3.months.ago..Time.now
|
||
|
when 'yearly' then 1.years.ago..Time.now
|
||
|
else ''
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def page_size
|
||
|
params[:per_page].to_i.zero? ? 20 : params[:per_page].to_i
|
||
|
end
|
||
|
|
||
|
def offset
|
||
|
(params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * page_size
|
||
|
end
|
||
|
end
|