class Admins::SchoolBaseStatisticService < ApplicationService include CustomSortable attr_reader :params sort_columns :student_count, :teacher_count, :course_count, :course_group_count, :attachment_count, :video_count, :normal_work_count, :shixun_work_count, :evaluate_count, :student_work_count, :exercise_count, default_direction: :desc def initialize(params) @params = params end def call schools = School.group('schools.id') keyword = params[:keyword].try(:to_s).try(:strip) if keyword.present? schools = schools.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%") end count = schools.count.count # 根据排序字段进行查询 schools = query_by_sort_column(schools, params[:sort_by]) schools.reorder("#{ params[:sort_by] != 0} desc") schools = custom_sort(schools, params[:sort_by], params[:sort_direction]) 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_count = CourseMember.course_students.joins(course: :school).group(:school_id).where("role= 'STUDENT' AND courses.is_delete = false AND schools.id in (?)", ids).count("distinct user_id") teachers = UserExtension.where(school_id: ids, identity: :teacher).group(:school_id) teacher_count = teachers.count courses = Course.where(is_delete: 0, school_id: ids).group(:school_id) course_count= courses.count course_group_count = courses.joins(:course_groups).count attachment_count = courses.joins(:attachments).count video_count = teachers.joins(user: :videos).where("videos.delete_state IS NOT NULL").count homeworks = HomeworkCommon.joins(:course).where(courses: { school_id: ids }).where("courses.is_delete = false") shixun_work_count = homeworks.where(homework_type: 4).group(:school_id).count normal_work_count = homeworks.where(homework_type: 1).group(:school_id).count student_work_count = homeworks.joins(:student_works).group(:school_id).count evaluate_count = EvaluateRecord.unscoped.joins('JOIN homework_commons_shixuns hcs ON hcs.shixun_id = evaluate_records.shixun_id JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4 JOIN course_members ON course_members.user_id = evaluate_records.user_id JOIN courses ON course_members.course_id = courses.id AND hc.course_id = courses.id') .where(courses: { school_id: ids }) .group(:school_id).count exercise_count = Exercise.joins(:course).where(courses: { school_id: ids }).group(:school_id).count schools.map do |school| { id: school.id, name: school.name, teacher_count: teacher_count[school.id], student_count: student_count[school.id], course_count: course_count[school.id], course_group_count: course_group_count[school.id], attachment_count: attachment_count[school.id], video_count: video_count[school.id], normal_work_count: normal_work_count[school.id], shixun_work_count: shixun_work_count[school.id], student_work_count: student_work_count[school.id], evaluate_count: evaluate_count[school.id], exercise_count: exercise_count[school.id] } end end private def query_by_sort_column(schools, sort_by_column) base_query_column = 'schools.id, schools.name' case sort_by_column.to_s when 'teacher_count' then schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0') .select("#{base_query_column}, COUNT(*) teacher_count") when 'student_count' then schools.joins("LEFT JOIN courses ue ON ue.school_id = schools.id AND ue.is_delete = FALSE LEFT JOIN course_members ON course_members.course_id = ue.id AND course_members.role = 'STUDENT'") .select("#{base_query_column}, COUNT(distinct user_id) student_count") when 'course_count' then schools.joins('LEFT JOIN courses ON courses.school_id = schools.id AND courses.is_delete = false') .select("#{base_query_column}, COUNT(*) course_count") when 'course_group_count' then schools.joins("LEFT JOIN courses ON courses.school_id = schools.id AND courses.is_delete = false LEFT JOIN course_groups ON course_groups.course_id = courses.id") .select("#{base_query_column}, COUNT(*) course_group_count") when 'attachment_count' then schools.joins("LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0 LEFT JOIN attachments ON attachments.container_type ='Course' AND attachments.container_id = cs.id") .select("#{base_query_column}, COUNT(*) attachment_count") when 'video_count' then schools.joins("LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0 LEFT JOIN videos ON videos.user_id = ue.user_id AND videos.delete_state IS NOT NULL") .select("#{base_query_column}, COUNT(*) video_count") when 'normal_work_count' then schools.joins("LEFT JOIN courses ON courses.school_id = schools.id LEFT JOIN homework_commons ON homework_commons.course_id = courses.id AND homework_commons.homework_type = 0") .select("#{base_query_column}, COUNT(*) normal_work_count") when 'shixun_work_count' then schools.joins("LEFT JOIN courses ON courses.school_id = schools.id LEFT JOIN homework_commons ON homework_commons.course_id = courses.id AND homework_commons.homework_type = 4") .select("#{base_query_column}, COUNT(*) shixun_work_count") when 'student_work_count' then schools.joins("LEFT JOIN courses ON courses.school_id = schools.id LEFT JOIN homework_commons ON homework_commons.course_id = courses.id LEFT JOIN student_works ON student_works.homework_common_id = homework_commons.id") .select("#{base_query_column}, COUNT(*) student_work_count") when 'evaluate_count' then schools.joins(' LEFT JOIN courses ON courses.school_id = schools.id AND courses.is_delete = false LEFT JOIN course_members ON course_members.course_id = courses.id LEFT JOIN evaluate_records ON course_members.user_id = evaluate_records.user_id LEFT JOIN homework_commons_shixuns hcs ON hcs.shixun_id = evaluate_records.shixun_id LEFT JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4') .select("#{base_query_column}, COUNT(*) evaluate_count") when 'exercise_count' then schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0 LEFT JOIN exercises ON exercises.course_id = cs.id') .select("#{base_query_column}, COUNT(*) exercise_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