diff --git a/app/controllers/admins/school_base_statistics_controller.rb b/app/controllers/admins/school_base_statistics_controller.rb new file mode 100644 index 000000000..026fd9492 --- /dev/null +++ b/app/controllers/admins/school_base_statistics_controller.rb @@ -0,0 +1,17 @@ +class Admins::SchoolBaseStatisticsController < Admins::BaseController + + def index + params[:sort_by] = params[:sort_by].presence || :teacher_count + params[:sort_direction] = params[:sort_direction].presence || :desc + + total_count, statistics = Admins::SchoolBaseStatisticService.call(params) + + @statistics = paginate statistics, total_count: total_count + @params_page = params[:page] || 1 + + respond_to do |format| + format.html + format.js + end + end +end diff --git a/app/services/admins/school_base_statistic_service.rb b/app/services/admins/school_base_statistic_service.rb new file mode 100644 index 000000000..cbad5d45a --- /dev/null +++ b/app/services/admins/school_base_statistic_service.rb @@ -0,0 +1,138 @@ +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 \ No newline at end of file diff --git a/app/views/admins/school_base_statistics/_list.html.erb b/app/views/admins/school_base_statistics/_list.html.erb new file mode 100644 index 000000000..aab91f5c7 --- /dev/null +++ b/app/views/admins/school_base_statistics/_list.html.erb @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + <% if statistics.present? %> + <% statistics.each_with_index do |statistic, index| %> + + + + + + + + + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
序号单位名称<%= sort_tag('注册教师', name: 'teacher_count', path: admins_school_base_statistics_path) %><%= sort_tag('注册学生', name: 'student_count', path: admins_school_base_statistics_path) %><%= sort_tag('教学课堂', name: 'course_count', path: admins_school_base_statistics_path) %><%= sort_tag('管理分班', name: 'course_group_count', path: admins_school_base_statistics_path) %><%= sort_tag('课件资源', name: 'attachment_count', path: admins_school_base_statistics_path) %><%= sort_tag('教学视频', name: 'video_count', path: admins_school_base_statistics_path) %><%= sort_tag('普通作业', name: 'normal_work_count', path: admins_school_base_statistics_path) %><%= sort_tag('实训作业', name: 'shixun_work_count', path: admins_school_base_statistics_path) %><%= sort_tag('作业文件', name: 'student_work_count', path: admins_school_base_statistics_path) %><%= sort_tag('评测次数', name: 'evaluate_count', path: admins_school_base_statistics_path) %><%= sort_tag('在线试卷', name: 'exercise_count', path: admins_school_base_statistics_path) %>
<%= list_index_no(@params_page.to_i, index) %> + <%= link_to statistic[:name], "/colleges/#{statistic[:id]}/statistics", + target: '_blank', data: { toggle: 'tooltip', title: '点击查看学校统计概况' } %> + <%= statistic[:teacher_count].to_i %><%= statistic[:student_count].to_i %><%= statistic[:course_count].to_i %><%= statistic[:course_group_count].to_i %><%= statistic[:attachment_count].to_i %><%= statistic[:video_count].to_i %><%= statistic[:normal_work_count].to_i %><%= statistic[:shixun_work_count].to_i %><%= statistic[:student_work_count].to_i %><%= statistic[:evaluate_count].to_i %><%= statistic[:exercise_count].to_i %>
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: statistics } %> \ No newline at end of file diff --git a/app/views/admins/school_base_statistics/index.html.erb b/app/views/admins/school_base_statistics/index.html.erb new file mode 100644 index 000000000..a519f245f --- /dev/null +++ b/app/views/admins/school_base_statistics/index.html.erb @@ -0,0 +1,14 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('数据项列表', admins_school_base_statistics_path) %> +<% end %> + +
+ <%= form_tag(admins_school_base_statistics_path, method: :get, class: 'form-inline search-form', remote: true) do %> + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '学校名称搜索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + <% end %> +
+ +
+ <%= render partial: 'admins/school_base_statistics/list', locals: { statistics: @statistics } %> +
\ No newline at end of file diff --git a/app/views/admins/school_base_statistics/index.js.erb b/app/views/admins/school_base_statistics/index.js.erb new file mode 100644 index 000000000..64df1e490 --- /dev/null +++ b/app/views/admins/school_base_statistics/index.js.erb @@ -0,0 +1 @@ +$(".school-base-statistic-list-container").html("<%= j(render partial: 'admins/school_base_statistics/list', locals: { statistics: @statistics }) %>") \ No newline at end of file diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index c7c487dcf..d77e4ed4e 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -17,7 +17,8 @@
  • <%= sidebar_item_group('#school-submenu', '学校统计', icon: 'area-chart') do %>
  • <%= sidebar_item(admins_daily_school_statistics_path, '统计总表', icon: 'bar-chart', controller: 'admins-daily_school_statistics') %>
  • -
  • <%= sidebar_item(admins_school_statistics_path, '数据变化报表', icon: 'line-chart', controller: 'admins-schools') %>
  • +
  • <%= sidebar_item(admins_school_statistics_path, '数据变化报表', icon: 'line-chart', controller: 'admins-school_statistics') %>
  • +
  • <%= sidebar_item(admins_school_base_statistics_path, '数据项列表', icon: 'eyedropper', controller: 'admins-school_base_statistics') %>
  • <% end %> diff --git a/config/routes.rb b/config/routes.rb index f858056a7..9a471fb7f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1173,6 +1173,8 @@ Rails.application.routes.draw do get :contrast, on: :collection end + resources :school_base_statistics, only: [:index] + resources :users, only: [:index, :edit, :update, :destroy] do member do post :reward_grade