From 372db525bd2d5ee1ba86e6352175ba3d6869778d Mon Sep 17 00:00:00 2001
From: winse
Date: Wed, 24 Apr 2019 16:18:03 +0800
Subject: [PATCH] management school report feature
---
.gitignore | 1 +
.../managements/base_controller.rb | 5 ++
.../managements/schools_controller.rb | 20 +++++++
app/helpers/application_helper.rb | 26 +++++++++
app/libs/custom_sortable.rb | 45 ++++++++++++++
.../management/school_report_service.rb | 58 +++++++++++++++++++
app/views/layouts/base_management.html.erb | 5 ++
.../schools/_statistics_list.html.erb | 43 ++++++++++++++
.../managements/schools/statistics.html.erb | 19 ++++++
.../managements/schools/statistics.js.erb | 1 +
config/routes.rb | 1 +
.../javascripts/educoder/edu_application.js | 3 +-
12 files changed, 226 insertions(+), 1 deletion(-)
create mode 100644 app/controllers/managements/base_controller.rb
create mode 100644 app/controllers/managements/schools_controller.rb
create mode 100644 app/libs/custom_sortable.rb
create mode 100644 app/services/management/school_report_service.rb
create mode 100644 app/views/managements/schools/_statistics_list.html.erb
create mode 100644 app/views/managements/schools/statistics.html.erb
create mode 100644 app/views/managements/schools/statistics.js.erb
diff --git a/.gitignore b/.gitignore
index a6e5b74a..0966e944 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@
.DS_Store
public/api_doc/
/.metadata
+.byebug_history
vendor/cache
/files
/public/images/avatars
diff --git a/app/controllers/managements/base_controller.rb b/app/controllers/managements/base_controller.rb
new file mode 100644
index 00000000..cbb61c33
--- /dev/null
+++ b/app/controllers/managements/base_controller.rb
@@ -0,0 +1,5 @@
+class Managements::BaseController < ApplicationController
+ layout 'base_management'
+
+ before_filter :require_admin
+end
\ No newline at end of file
diff --git a/app/controllers/managements/schools_controller.rb b/app/controllers/managements/schools_controller.rb
new file mode 100644
index 00000000..6684db66
--- /dev/null
+++ b/app/controllers/managements/schools_controller.rb
@@ -0,0 +1,20 @@
+class Managements::SchoolsController < Managements::BaseController
+ before_filter :set_navigation_bar
+ before_filter :set_default_sort_params, only: :statistics
+
+ def statistics
+ @sub_type = 1
+ schools = Management::SchoolReportService.new(params).call
+ @schools = paginateHelper schools
+ end
+
+ private
+ def set_navigation_bar
+ @menu_type = 1
+ end
+
+ def set_default_sort_params
+ params[:sort_by] ||= :teacher_count
+ params[:sort_direction] ||= :desc
+ end
+end
\ No newline at end of file
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 707ff571..6bc8f9f6 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -668,6 +668,11 @@ module ApplicationHelper
def managements_navigation_bar_show menu_type, sub_type, grandchild_type={}
case menu_type
+ when 1
+ case sub_type
+ when 1 then "统计总表"
+ when 2 then "变化报表"
+ end
when 2
sub_type == 1 ? "课程列表" : (sub_type == 2? "课堂列表" : (sub_type == 3? "实训作业" : "项目列表"))
when 3
@@ -5509,6 +5514,27 @@ challengeProgramNames=(CHALLENGEPROGRAMNAMES)"
return sort_projects
end
end
+
+ def sort_tag(content, **opts)
+ options = {}
+ options[:sort_by] = opts.delete(:name)
+ is_current_sort = params[:sort_by].to_s == options[:sort_by]
+ options[:sort_direction] = is_current_sort && params[:sort_direction].to_s == 'desc' ? 'asc' : 'desc'
+
+ path = opts.delete(:path) + "?" + params.merge(options).to_query
+ arrow_class = case params[:sort_direction].to_s
+ when 'desc' then 'fa-long-arrow-down'
+ when 'asc' then 'fa-long-arrow-up'
+ else ''
+ end
+
+ content_tag(:span, opts) do
+ link_to path, remote: true do
+ content += content_tag(:i, '', class: "fa color-light-green ml5 #{arrow_class}") if is_current_sort
+ raw content
+ end
+ end
+ end
end
def user_url_in_org(user_id)
diff --git a/app/libs/custom_sortable.rb b/app/libs/custom_sortable.rb
new file mode 100644
index 00000000..a127c9bd
--- /dev/null
+++ b/app/libs/custom_sortable.rb
@@ -0,0 +1,45 @@
+module CustomSortable
+ extend ActiveSupport::Concern
+
+ included do |base|
+ base.instance_variable_set("@_sort_options", {})
+ base.instance_variable_set("@_sort_columns", [])
+ base.instance_variable_set("@_sort_directions", %w(asc desc))
+ end
+
+ def custom_sort(relations, sort_by, sort_direction)
+ sort_by ||= self.class.sort_options[:default_by]
+ sort_direction ||= self.class.sort_options[:default_direction]
+
+ return relations unless self.class.check_sort_parameter_validate(sort_by, sort_direction)
+
+ order_method = self.class.sort_options[:reorder] ? :reorder : :order
+ relations.send(order_method, "#{sort_by} #{sort_direction}")
+ end
+
+ def multiple_custom_sort(relations, **opts)
+ opts.each do |sort_by, sort_direction|
+ relations = custom_sort(relations, sort_by, sort_direction)
+ end
+ relations
+ end
+
+ module ClassMethods
+ def sort_columns(*columns)
+ opts = columns.extract_options!
+ @_sort_options[:default_by] = opts[:default_by].to_s
+ @_sort_options[:default_direction] = opts[:default_direction].to_s
+ @_sort_options[:reorder] = opts[:reorder]
+
+ @_sort_columns = columns.map(&:to_s)
+ end
+
+ def check_sort_parameter_validate(sort_by, sort_direction)
+ (sort_by.blank? || @_sort_columns.include?(sort_by)) && @_sort_directions.include?(sort_direction)
+ end
+
+ def sort_options
+ @_sort_options
+ end
+ end
+end
diff --git a/app/services/management/school_report_service.rb b/app/services/management/school_report_service.rb
new file mode 100644
index 00000000..f47230ac
--- /dev/null
+++ b/app/services/management/school_report_service.rb
@@ -0,0 +1,58 @@
+class Management::SchoolReportService
+ include CustomSortable
+
+ attr_reader :params
+
+ sort_columns :student_count, :teacher_count, :homework_count, :other_homework_count,
+ :course_count, :active_course_count, :nearly_course_time,
+ default_by: :teacher_count, default_direction: :desc
+
+ def initialize(params)
+ @params = params
+ end
+
+ def call
+ schools = School.select(select_columns_sql)
+
+ keyword = params[:keyword]&.to_s&.strip
+ if keyword.present?
+ schools = schools.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%")
+ end
+
+ schools = custom_sort(schools, params[:sort_by], params[:sort_direction])
+
+ schools
+ end
+
+ private
+ def select_columns_sql
+ <<-SQL
+ schools.id, schools.name,
+ (
+ SELECT COUNT(*) FROM users u
+ LEFT JOIN user_extensions ue ON ue.user_id = u.id
+ LEFT JOIN ec_school_users esu ON esu.user_id = u.id
+ WHERE esu.school_id = schools.id AND ue.identity = #{User::STUDENT}
+ ) student_count,
+ (
+ SELECT COUNT(*) FROM users u
+ LEFT JOIN user_extensions ue ON ue.user_id = u.id
+ LEFT JOIN ec_school_users esu ON esu.user_id = u.id
+ WHERE esu.school_id = schools.id AND ue.identity = #{User::TEACHER}
+ ) teacher_count,
+ (
+ SELECT COUNT(*) FROM homework_commons hc
+ LEFT JOIN courses ON courses.id = hc.course_id
+ WHERE courses.school_id = schools.id
+ ) homework_count,
+ (
+ SELECT COUNT(*) FROM homework_commons hc
+ LEFT JOIN courses ON courses.id = hc.course_id
+ WHERE courses.school_id = schools.id AND hc.homework_type IN (1,3)
+ ) other_homework_count,
+ (SELECT COUNT(*) FROM courses cs WHERE cs.school_id = schools.id) course_count ,
+ (SELECT MAX(cs.updated_at) FROM courses cs WHERE cs.school_id = schools.id) nearly_course_time ,
+ (SELECT COUNT(*) FROM courses acs WHERE acs.school_id = schools.id AND acs.is_end = false) active_course_count
+ SQL
+ end
+end
diff --git a/app/views/layouts/base_management.html.erb b/app/views/layouts/base_management.html.erb
index 86cdbe60..c38bf3eb 100644
--- a/app/views/layouts/base_management.html.erb
+++ b/app/views/layouts/base_management.html.erb
@@ -32,6 +32,11 @@