modify school statistic service to decrease response time

dev_partners
p31729568 6 years ago
parent face0cc8de
commit 1298e748f2

@ -4,11 +4,12 @@ class Managements::SchoolsController < Managements::BaseController
def statistics def statistics
@sub_type = 1 @sub_type = 1
params[:sort_by] ||= :teacher_count params[:sort_by] = :teacher_count if params[:sort_by].blank?
params[:sort_direction] ||= :desc params[:sort_direction] = :desc if params[:sort_direction].blank?
schools = Management::SchoolReportService.new(params).call service = Management::SchoolReportService.new(params)
@schools = paginateHelper schools @obj_count, @schools = service.call
@obj_pages = Paginator.new(@obj_count, 20, params[:page])
respond_to do |format| respond_to do |format|
format.html { load_statistic_total } format.html { load_statistic_total }
@ -19,20 +20,20 @@ class Managements::SchoolsController < Managements::BaseController
def data_grow def data_grow
@sub_type = 2 @sub_type = 2
params[:data_type] ||= 'grow' params[:data_type] ||= 'grow'
params[:sort_by] ||= :teacher_increase_count params[:sort_by] = :teacher_increase_count if params[:sort_by].blank?
params[:sort_direction] ||= :desc params[:sort_direction] = :desc if params[:sort_direction].blank?
service = Management::SchoolDataGrowService.new(params) service = Management::SchoolDataGrowService.new(params)
@grow_summary = service.grow_summary @grow_summary = service.grow_summary
@obj_count, @reports = service.call @obj_count, @reports = service.call
@obj_pages = Paginator.new(@obj_count, Management::SchoolDataGrowService::PAGE_SIZE, params[:page]) @obj_pages = Paginator.new(@obj_count, 20, params[:page])
end end
def data_contrast def data_contrast
params[:contrast_column] = :teacher_increase_count if params[:contrast_column].blank? params[:contrast_column] = :teacher_increase_count if params[:contrast_column].blank?
params[:sort_direction] ||= :desc params[:sort_direction] ||= :desc
params[:sort_by] ||= :percentage params[:sort_by] = :percentage
# 无对比日期时直接返回无数据页面 # 无对比日期时直接返回无数据页面
if useless_contrast_date_parameter? if useless_contrast_date_parameter?
@ -41,16 +42,17 @@ class Managements::SchoolsController < Managements::BaseController
end end
@obj_count, @reports = Management::SchoolDataContrastService.new(params).call @obj_count, @reports = Management::SchoolDataContrastService.new(params).call
@obj_pages = Paginator.new(@obj_count, Management::SchoolDataContrastService::PAGE_SIZE, params[:page]) @obj_pages = Paginator.new(@obj_count, 20, params[:page])
rescue Management::SchoolDataContrastService::ParameterError rescue Management::SchoolDataContrastService::ParameterError
raise '参数错误' raise '参数错误'
end end
def statistics_xlsx def statistics_xlsx
@schools = Management::SchoolReportService.new(params).call params[:per_page] = 10000
_count, @schools = Management::SchoolReportService.new(params).call
filename = ["学校统计总表", params[:keyword], Time.zone.now.strftime('%Y%m%d%H%M%S')].join('-') << ".xlsx" filename = ['学校统计总表', params[:keyword], Time.zone.now.strftime('%Y%m%d%H%M%S')].join('-') << '.xlsx'
render xlsx: "statistics_xlsx", filename: filename render xlsx: 'statistics_xlsx', filename: filename
end end
private private

@ -56,6 +56,8 @@ class Course < ActiveRecord::Base
has_many :course_homework_categories, :dependent => :destroy, :order => "CONVERT(name USING gbk) COLLATE gbk_chinese_ci ASC" has_many :course_homework_categories, :dependent => :destroy, :order => "CONVERT(name USING gbk) COLLATE gbk_chinese_ci ASC"
has_many :homework_commons, :dependent => :destroy has_many :homework_commons, :dependent => :destroy
has_many :shixun_homework_commons, class_name: 'HomeworkCommon', conditions: 'homework_type = 4'
has_many :other_homework_commons, class_name: 'HomeworkCommon', conditions: 'homework_type IN (1, 3)'
has_many :homework_group_settings, :dependent => :destroy has_many :homework_group_settings, :dependent => :destroy
has_many :student_works, :through => :homework_commons, :dependent => :destroy has_many :student_works, :through => :homework_commons, :dependent => :destroy

@ -6,6 +6,7 @@ class School < ActiveRecord::Base
:identifier, :is_online, :video_desc, :video_name,:course_link, :identifier, :is_online, :video_desc, :video_name,:course_link,
:course_name, :partner_id, :customer_id :course_name, :partner_id, :customer_id
has_many :courses has_many :courses
has_many :active_courses, class_name: 'Course', conditions: 'is_end = false'
has_many :departments, :dependent => :destroy has_many :departments, :dependent => :destroy
has_many :shixun_schools, :dependent => :destroy has_many :shixun_schools, :dependent => :destroy
has_many :shixuns, :through => :shixun_schools has_many :shixuns, :through => :shixun_schools
@ -25,6 +26,9 @@ class School < ActiveRecord::Base
# 报表信息 # 报表信息
has_many :school_daily_reports has_many :school_daily_reports
has_many :teacher_extensions, conditions: "identity = #{User::TEACHER}", class_name: 'UserExtensions'
has_many :student_extensions, conditions: "identity = #{User::STUDENT}", class_name: 'UserExtensions'
# 视频附件 # 视频附件
acts_as_attachable acts_as_attachable

@ -12,30 +12,85 @@ class Management::SchoolReportService
end end
def call def call
schools = School.select(select_columns_sql) schools = School.group('schools.id')
keyword = params[:keyword].try(:to_s).try(:strip) keyword = params[:keyword].try(:to_s).try(:strip)
if keyword.present? if keyword.present?
schools = schools.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%") schools = schools.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%")
end end
count = schools.count.count
# 根据排序字段进行查询
schools = query_by_sort_column(schools, params[:sort_by])
schools = custom_sort(schools, params[:sort_by], params[:sort_direction]) schools = custom_sort(schools, params[:sort_by], params[:sort_direction])
schools schools = schools.limit(page_size).offset(offset)
# 查询并组装其它数据
schools = package_other_data(schools)
[count, schools]
end
def package_other_data(schools)
ids = schools.map(&:id)
student_map = UserExtensions.where(school_id: ids, identity: User::STUDENT).group(:school_id).count
teacher_map = UserExtensions.where(school_id: ids, identity: User::TEACHER).group(:school_id).count
homeworks = HomeworkCommon.joins(:course)
shixun_homework_map = homeworks.where(homework_type: 4, courses: { school_id: ids }).group('school_id').count
other_homework_map = homeworks.where(homework_type: [1, 3], courses: { school_id: ids }).group('school_id').count
courses = Course.where(school_id: ids).group('school_id')
course_map = courses.count
nearly_course_time_map = courses.joins(:course_activities).maximum('course_activities.updated_at')
active_course_map = courses.where(is_end: false).count
schools.map do |school|
{
id: school.id,
name: school.name,
teacher_count: teacher_map[school.id],
student_count: student_map[school.id],
homework_count: shixun_homework_map[school.id],
other_homework_count: other_homework_map[school.id],
course_count: course_map[school.id],
nearly_course_time: nearly_course_time_map[school.id],
active_course_count: active_course_map[school.id],
}
end
end end
private private
def select_columns_sql def query_by_sort_column(schools, sort_by_column)
"schools.id, schools.name,"\ base_query_column = 'schools.id, schools.name'
"(SELECT COUNT(*) FROM user_extensions ue WHERE ue.school_id = schools.id AND ue.identity = #{User::STUDENT}) student_count,"\
"(SELECT COUNT(*) FROM user_extensions ue WHERE ue.school_id = schools.id AND ue.identity = #{User::TEACHER}) teacher_count,"\ case sort_by_column.to_s
"(SELECT COUNT(*) FROM homework_commons hc LEFT JOIN courses ON courses.id = hc.course_id "\ when 'teacher_count' then
"WHERE courses.school_id = schools.id AND hc.homework_type = 4) homework_count,"\ schools.joins(:teacher_extensions).select("#{base_query_column}, COUNT(*) teacher_count")
"(SELECT COUNT(*) FROM homework_commons hc LEFT JOIN courses ON courses.id = hc.course_id "\ when 'student_count' then
"WHERE courses.school_id = schools.id AND hc.homework_type IN (1,3)) other_homework_count,"\ schools.joins(:student_extensions).select("#{base_query_column}, COUNT(*) student_count")
"(SELECT COUNT(*) FROM courses cs WHERE cs.school_id = schools.id) course_count ,"\ when 'homework_count' then
"(SELECT MAX(ca.updated_at) FROM course_activities ca LEFT JOIN courses cs ON cs.id = ca.course_id "\ schools.joins(courses: :shixun_homework_commons).select("#{base_query_column}, COUNT(*) homework_count")
"WHERE cs.school_id = schools.id) nearly_course_time ,"\ when 'other_homework_count' then
"(SELECT COUNT(*) FROM courses acs WHERE acs.school_id = schools.id AND acs.is_end = false) active_course_count" schools.joins(courses: :other_homework_commons).select("#{base_query_column}, COUNT(*) other_homework_count")
when 'course_count' then
schools.joins(:courses).select("#{base_query_column}, COUNT(*) course_count")
when 'nearly_course_time' then
schools.joins(courses: :course_activities).select("#{base_query_column}, MAX(course_activities.updated_at) nearly_course_time")
when 'active_course_count' then
schools.joins(:active_courses).select("#{base_query_column}, COUNT(*) active_course_count")
else
schools.joins(:teacher_extensions).select("#{base_query_column}, COUNT(*) teacher_count")
end
end
def page_size
params[:per_page] || 20
end
def offset
(params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * page_size
end end
end end

@ -18,15 +18,15 @@
<% @schools.each_with_index do |school, index| %> <% @schools.each_with_index do |school, index| %>
<tr> <tr>
<td><%= (@obj_pages.page - 1) * @obj_pages.per_page + index + 1 %></td> <td><%= (@obj_pages.page - 1) * @obj_pages.per_page + index + 1 %></td>
<td><%= school['id'] %></td> <td><%= school[:id] %></td>
<td class="edu-txt-left"><%= school['name'] %></td> <td class="edu-txt-left"><%= school[:name] %></td>
<td><%= school['teacher_count'] %></td> <td><%= school[:teacher_count].to_i %></td>
<td><%= school['student_count'] %></td> <td><%= school[:student_count].to_i %></td>
<td><%= school['course_count'] %></td> <td><%= school[:course_count].to_i %></td>
<td><%= school['active_course_count'] %></td> <td><%= school[:active_course_count].to_i %></td>
<td><%= school['homework_count'] %></td> <td><%= school[:homework_count].to_i %></td>
<td><%= school['other_homework_count'] %></td> <td><%= school[:other_homework_count].to_i %></td>
<td><%= format_time school['nearly_course_time'] %></td> <td><%= format_time school[:nearly_course_time] %></td>
</tr> </tr>
<% end %> <% end %>
</tbody> </tbody>

@ -1,20 +1,12 @@
wb = xlsx_package.workbook wb = xlsx_package.workbook
wb.add_worksheet(name: "统计总表") do |sheet| wb.add_worksheet(name: '统计总表') do |sheet|
sheet.add_row %w(ID 单位名称 教师总人数 学生总人数 课堂总数 正在进行课堂数 实训作业总数 其它作业总数 动态时间) sheet.add_row %w(ID 单位名称 教师总人数 学生总人数 课堂总数 正在进行课堂数 实训作业总数 其它作业总数 动态时间)
total = @schools.count @schools.each do |school|
buffer_size = 500
times = total % 500 > 0 ? total / 500 + 1 : total / 500
times.times do |index|
schools = @schools.limit(buffer_size).offset(index * buffer_size)
schools.each do |school|
sheet.add_row([ sheet.add_row([
school['id'].to_s, school['name'].to_s, school['teacher_count'].to_s, school['student_count'].to_s, school['id'].to_s, school['name'].to_s, (school['teacher_count'] || 0).to_s, (school['student_count'] || 0).to_s,
school['course_count'].to_s, school['active_course_count'].to_s, school['homework_count'].to_s, (school['course_count'] || 0).to_s, (school['active_course_count'] || 0).to_s, (school['homework_count'] || 0).to_s,
school['other_homework_count'].to_s, format_time(school['nearly_course_time']) (school['other_homework_count'] || 0).to_s, format_time(school['nearly_course_time'])
]) ])
end end
end
end end
Loading…
Cancel
Save