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/dashboards/index.html.erb b/app/views/admins/dashboards/index.html.erb index b463e5571..2cd7a583f 100644 --- a/app/views/admins/dashboards/index.html.erb +++ b/app/views/admins/dashboards/index.html.erb @@ -2,6 +2,9 @@ <% add_admin_breadcrumb('概览', admins_path) %> <% end %> +<% content_for(:head) do %> + +<% 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 %> | + +
{coursedata.teacher_school}
+{coursedata.teacher_school}
-
{coursedata.teacher_applies_count===undefined?"":coursedata.teacher_applies_count>0?
- 您有{coursedata.teacher_applies_count}条新的加入申请
- this.setHistoryFun("/classrooms/"+this.props.match.params.coursesId+"/teachers?tab=2")}>
+ 新收到{coursedata.teacher_applies_count}条加入课堂的申请
+ this.setHistoryFun("/classrooms/"+this.props.match.params.coursesId+"/teachers?tab=2")}>
- 待审批
+ 去审批
:""}
}>
this.setHistoryFun("/classrooms/"+this.props.match.params.coursesId+"/teachers")}>
教师
diff --git a/public/react/src/modules/courses/exercise/Studentshavecompletedthelist.js b/public/react/src/modules/courses/exercise/Studentshavecompletedthelist.js
index b8880c6f2..b3f126e9f 100644
--- a/public/react/src/modules/courses/exercise/Studentshavecompletedthelist.js
+++ b/public/react/src/modules/courses/exercise/Studentshavecompletedthelist.js
@@ -23,14 +23,18 @@ import './yslexercisetable.css';
import {getImageUrl, toPath, sortDirections} from 'educoder';
import NoneData from '../../../modules/courses/coursesPublic/NoneData';
import ModulationModal_exercise from "../coursesPublic/ModulationModal_exercise";
+
const Search = Input.Search;
const RadioGroup = Radio.Group;
const CheckboxGroup = Checkbox.Group;
const {Option} = Select;
//学生老师页面
-let columnsystwo=[];
+let columnsystwo = [];
+let myssubjective = 0; //是否显示主观题
+let mysubjective_score = 0;//主观题得分
+let myobjective_score = 0;//客观题得分
+
class Studentshavecompletedthelist extends Component {
- // http://localhost:3007/courses/1309/exercises/722/exercises/student_exercise_list?debug=s
constructor(props) {
super(props);
this.state = {
@@ -47,7 +51,7 @@ class Studentshavecompletedthelist extends Component {
teacherlist: undefined,
searchtext: "",
Teacherliststudentlist: undefined,
- mylistansum:0,
+ mylistansum: 0,
review: null,
course_groupysls: undefined,
nocomment: false,
@@ -72,13 +76,13 @@ class Studentshavecompletedthelist extends Component {
key: 'number',
align: 'center',
className: "edu-txt-center font-14",
- width:'100px',
+ width: '100px',
render: (text, record) => (
{record.number === "--" ?
- {record.number}
+ {record.number}
:
- {record.number}
+ {record.number}
}
@@ -90,15 +94,16 @@ class Studentshavecompletedthelist extends Component {
key: 'name',
align: 'center',
className: "edu-txt-center font-14 maxnamewidth110",
- width:'100px',
+ width: '100px',
render: (text, record) => (
{record.name === "--" ?
- {record.name}
+ {record.name}
:
- {record.name}
+ {record.name}
}
@@ -110,30 +115,30 @@ class Studentshavecompletedthelist extends Component {
key: 'stduynumber',
align: 'center',
className: "edu-txt-center font-14 maxnamewidth175",
- width:'175px',
+ width: '175px',
sorter: true,
sortDirections: sortDirections,
render: (text, record) => (
{record.stduynumber === null ?
-- :
record.stduynumber ===
"" ?
-- :
{record.stduynumber}
}
@@ -146,26 +151,26 @@ class Studentshavecompletedthelist extends Component {
dataIndex: 'classroom',
align: 'center',
className: "edu-txt-center font-14 maxnamewidth255",
- width:'255px',
+ width: '255px',
render: (text, record) => (
-
+
{record.classroom === null ?
-- :
record.classroom ===
"" ?
-- :
{record.classroom}
}
@@ -178,19 +183,19 @@ class Studentshavecompletedthelist extends Component {
key: 'submitstate',
align: 'center',
className: "edu-txt-center font-14",
- width:'98px',
+ width: '98px',
render: (text, record) => (
{record.submitstate}
)
@@ -202,18 +207,18 @@ class Studentshavecompletedthelist extends Component {
key: 'updatetime',
align: 'center',
className: "edu-txt-center font-14",
- width:'175px',
+ width: '175px',
sorter: true,
defaultSortOrder: 'descend',
sortDirections: sortDirections,
render: (text, record) => (
{record.updatetime === "--" ?
- {record.updatetime}
+ {record.updatetime}
:
- {record.updatetime}
+ {record.updatetime}
}
),
@@ -224,14 +229,14 @@ class Studentshavecompletedthelist extends Component {
key: 'completion',
align: 'center',
className: "edu-txt-center font-14",
- width:'98px',
+ width: '98px',
render: (text, record) => (
{
record.completion === "--" ?
{record.completion}
@@ -239,20 +244,20 @@ class Studentshavecompletedthelist extends Component {
90 ? {
color: '#DD1717',
textAlign: "center",
- width:'98px',
- } : parseInt(record.completion) <= 90 ? {
+ width: '98px',
+ } : parseInt(record.completion) <= 90 &&parseInt(record.completion)>60? {
color: '#FF6800',
textAlign: "center",
- width:'98px',
+ width: '98px',
} : parseInt(record.completion) <= 60 ? {
color: '#747A7F',
textAlign: "center",
- width:'98px',
+ width: '98px',
} :
{
color: '#747A7F',
textAlign: "center",
- width:'98px',
+ width: '98px',
}}>{record.completion}
}
@@ -265,14 +270,14 @@ class Studentshavecompletedthelist extends Component {
key: 'levelscore',
align: 'center',
className: "edu-txt-center font-14",
- width:'99px',
+ width: '99px',
render: (text, record) => (
{record.levelscore === "--" ?
{record.levelscore}
@@ -280,22 +285,36 @@ class Studentshavecompletedthelist extends Component {
90 ? {
color: '#DD1717',
textAlign: "center",
- width:'99px',
- } : parseInt(record.levelscore) <= 90 ? {
+ width: '99px',
+ } : parseInt(record.levelscore) <= 90 &&parseInt(record.levelscore) >60? {
color: '#FF6800',
textAlign: "center",
- width:'99px',
+ width: '99px',
} : parseInt(record.levelscore) <= 60 ? {
color: '#747A7F',
textAlign: "center",
- width:'99px',
- } : {color: '#747A7F', textAlign: "center",width:'99px'}}>{record.levelscore}
+ width: '99px',
+ } : {color: '#747A7F', textAlign: "center", width: '99px'}}>{record.levelscore}
+ {
+ //主观题老师没有评分是
+ parseInt(record.levelscore) === 0 && myssubjective === 1 && mysubjective_score > 0 ?
+
+ (待批阅)
+ :
+ ""
+
+ }
+
}
)
},
{
- title:最终成绩