diff --git a/app/assets/javascripts/admins/modals/admin-merge-course-list-modal.js b/app/assets/javascripts/admins/modals/admin-merge-course-list-modal.js new file mode 100644 index 000000000..e08277024 --- /dev/null +++ b/app/assets/javascripts/admins/modals/admin-merge-course-list-modal.js @@ -0,0 +1,60 @@ +$(document).on('turbolinks:load', function() { + var $modal = $('.modal.admin-merge-course-list-modal'); + if ($modal.length > 0) { + var $form = $modal.find('form.admin-merge-course-list-form'); + var $originCourseListIdInput = $form.find('input[name="origin_course_list_id"]'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + course_list_name: { + required: true + } + }, + messages: { + course_list_name: { + required: '请输入课程名称' + } + } + }); + + // modal ready fire + $modal.on('show.bs.modal', function (event) { + var $link = $(event.relatedTarget); + + var couresListId = $link.data('courseListId'); + var url = $link.data('url'); + + $originCourseListIdInput.val(couresListId); + $form.data('url', url); + }); + + $modal.on('click', '.submit-btn', function(){ + $form.find('.error').html(''); + + if ($form.valid()) { + var url = $form.data('url'); + + $.ajax({ + method: 'POST', + dataType: 'json', + url: url, + data: $form.serialize(), + success: function(){ + $.notify({ message: '操作成功' }); + $modal.modal('hide'); + + setTimeout(function(){ + window.location.reload(); + }, 500); + }, + error: function(res){ + var data = res.responseJSON; + $form.find('.error').html(data.message); + } + }); + } + }); + } +}); \ No newline at end of file diff --git a/app/controllers/admins/course_lists_controller.rb b/app/controllers/admins/course_lists_controller.rb new file mode 100644 index 000000000..83ac92c61 --- /dev/null +++ b/app/controllers/admins/course_lists_controller.rb @@ -0,0 +1,35 @@ +class Admins::CourseListsController < Admins::BaseController + + def index + course_lists = Admins::CourseListQuery.call(params) + @course_lists = paginate course_lists.preload(:courses, :user) + @params_page = params[:page] || 1 + respond_to do |format| + format.js + format.html + end + end + + def destroy + CourseList.find(params[:id]).destroy! + + render_delete_success + end + + def merge + origin_course_list = CourseList.find_by!(id: params[:origin_course_list_id]) + o_courselist = CourseList.find_by(name: params[:course_list_name]) + if o_courselist + origin_course_list.courses.each do |course| + course.update!(name: course.name.sub(origin_course_list.name, params[:course_list_name]), course_list_id: o_courselist.id) + end + origin_course_list.destroy + else + origin_course_list.courses.each do |course| + course.update!(name: course.name.sub(origin_course_list.name, params[:course_list_name])) + end + origin_course_list.update!(name: params[:course_list_name]) + end + render_ok + end +end \ No newline at end of file diff --git a/app/controllers/admins/courses_controller.rb b/app/controllers/admins/courses_controller.rb index e69de29bb..c7275b0f8 100644 --- a/app/controllers/admins/courses_controller.rb +++ b/app/controllers/admins/courses_controller.rb @@ -0,0 +1,26 @@ +class Admins::CoursesController < Admins::BaseController + before_action :find_course, except: [:index] + + def index + default_sort('created_at', 'desc') + + courses = Admins::CourseQuery.call(params) + @ended_courses = courses.where(is_end: 1).size + @processed_courses = courses.where(is_end: 0).size + @courses = paginate courses.includes(:school, :students, :attachments, :homework_commons, teacher: :user_extension) + end + + def destroy + if @course.is_delete == 0 + @course.delete! + Tiding.create!(user_id: current_user.id, trigger_user_id: current_user.id, container_id: @course.id, + container_type: 'DeleteCourse', tiding_type: 'System', belong_container: @course, extra: @course.name) + end + end + + private + + def find_course + @course = Course.find_by!(id: params[:id]) + end +end \ No newline at end of file diff --git a/app/models/course.rb b/app/models/course.rb index 0a9b63458..f0b70b2f3 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -31,6 +31,7 @@ class Course < ApplicationRecord has_many :graduation_groups, dependent: :destroy has_many :course_members, dependent: :destroy + has_many :students, -> { course_students }, class_name: 'CourseMember' has_many :teacher_course_members, -> { teachers_and_admin }, class_name: 'CourseMember' has_many :teacher_users, through: :teacher_course_members, source: :user has_many :course_messages, dependent: :destroy @@ -238,11 +239,6 @@ class Course < ApplicationRecord course_members.where(role: %i[CREATOR PROFESSOR]) end - # 课堂学生 - def students - course_members.where(role: %i[STUDENT]) - end - # 更新课程的访问人数 def update_visits(new_visits) update_attributes(visits: new_visits) @@ -371,6 +367,19 @@ class Course < ApplicationRecord count = course_challeng_count == 0 ? 0 : ((my_challenge_count.to_f / course_challeng_count).round(2) * 100).to_i end + # 课堂实训作业的评测次数 + def evaluate_count + course_user_ids = students.pluck(:user_id) + shixun_ids = homework_commons.joins(:homework_commons_shixun).where(homework_type: 4).pluck(:shixun_id) + return 0 if shixun_ids.blank? + Game.joins(:challenge).where(challenges: {shixun_id: shixun_ids}, games: {user_id: course_user_ids}).sum(:evaluate_count) + end + + # 课堂作业数 + def course_homework_count type + homework_commons.select{|homework| homework.homework_type == type}.size + end + private #创建课程后,给该用户发送消息 diff --git a/app/models/course_list.rb b/app/models/course_list.rb index 080c05ae2..cd622f20a 100644 --- a/app/models/course_list.rb +++ b/app/models/course_list.rb @@ -5,4 +5,5 @@ class CourseList < ApplicationRecord has_many :exercise_banks has_many :gtask_banks has_many :gtopic_banks + belongs_to :user end diff --git a/app/queries/admins/course_list_query.rb b/app/queries/admins/course_list_query.rb new file mode 100644 index 000000000..24eedaf1b --- /dev/null +++ b/app/queries/admins/course_list_query.rb @@ -0,0 +1,30 @@ +class Admins::CourseListQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :created_at, default_by: :created_at, default_direction: :desc + + def initialize(params) + @params = params + end + + def call + course_lists = CourseList.all + + # 关键字模糊查询 + keyword = params[:keyword].to_s.strip + if keyword.present? + search_type = params[:search_type] || "0" + case search_type + when "0" + course_lists = course_lists.joins(:user) + .where('CONCAT(lastname, firstname) like :keyword', keyword: "%#{keyword}%") + when "1" + course_lists = course_lists.where('name like :keyword', keyword: "%#{keyword}%") + end + end + + custom_sort(course_lists, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/queries/admins/course_query.rb b/app/queries/admins/course_query.rb new file mode 100644 index 000000000..e883650d0 --- /dev/null +++ b/app/queries/admins/course_query.rb @@ -0,0 +1,44 @@ +class Admins::CourseQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :created_at, default_by: :created_at, default_direction: :desc, default_table: 'courses' + + def initialize(params) + @params = params + end + + def call + courses = Course.all + + courses = courses.where(id: params[:id]) if params[:id].present? + + # 状态过滤 + status = + case params[:status].to_s.strip + when 'processing' then 0 + when 'ended' then 1 + end + courses = courses.where(is_end: status) if status + + # 单位 + if params[:school_id].present? + courses = courses.where(school_id: params[:school_id]) + end + + # 首页展示 + if params[:homepage_show].present? && params[:homepage_show].to_s == 'true' + courses = courses.where(homepage_show: true) + end + + # 关键字 + keyword = params[:keyword].to_s.strip + if keyword + sql = 'CONCAT(lastname, firstname) LIKE :keyword OR courses.name LIKE :keyword OR course_lists.name LIKE :keyword' + courses = courses.joins(:teacher, :course_list).where(sql, keyword: "%#{keyword}%") + end + + custom_sort(courses, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/views/admins/course_lists/index.html.erb b/app/views/admins/course_lists/index.html.erb new file mode 100644 index 000000000..cd814ed8a --- /dev/null +++ b/app/views/admins/course_lists/index.html.erb @@ -0,0 +1,22 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('课程列表') %> +<% end %> + +
+ <%= form_tag(admins_course_lists_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> +
+ + <% auto_trial_options = [['创建者姓名', 0], ['课程名称', 1]] %> + <%= select_tag(:search_type, options_for_select(auto_trial_options), class: 'form-control') %> +
+ <%= 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': '搜索中...') %> + <%= link_to "清除",admins_course_lists_path,class: "btn btn-default",id:"course-lists-clear-search",'data-disable-with': '清除中...' %> + <% end %> +
+ +
+ <%= render partial: 'admins/course_lists/shared/list', locals: { courses: @course_lists } %> +
+ +<%= render 'admins/course_lists/shared/merge_course_list_modal' %> \ No newline at end of file diff --git a/app/views/admins/course_lists/index.js.erb b/app/views/admins/course_lists/index.js.erb new file mode 100644 index 000000000..e4bfead7d --- /dev/null +++ b/app/views/admins/course_lists/index.js.erb @@ -0,0 +1 @@ +$(".course-list-list-container").html("<%= j render partial: 'admins/course_lists/shared/list', locals: { courses: @course_lists }%>"); \ No newline at end of file diff --git a/app/views/admins/course_lists/shared/_list.html.erb b/app/views/admins/course_lists/shared/_list.html.erb new file mode 100644 index 000000000..228385b3e --- /dev/null +++ b/app/views/admins/course_lists/shared/_list.html.erb @@ -0,0 +1,37 @@ + + + + + + + + + + + + <% if courses.present? %> + <% courses.each_with_index do |course_list,index| %> + + + + + <% course_count = course_list.courses.size %> + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
序号ID课程名称课堂数创建者<%= sort_tag('创建时间', name: 'created_at', path: admins_course_lists_path) %>操作
<%= list_index_no(@params_page.to_i, index) %><%= course_list.id %><%= course_list.name %><%= course_count %><%= link_to course_list.user.try(:real_name),"/users/#{course_list.user.try(:login)}",target:'_blank' %><%= format_time course_list.created_at %> + <% if course_count == 0 %> + <%= delete_link '删除', admins_course_list_path(course_list, element: ".course-list-item-#{course_list.id}"), class: 'delete-department-action' %> + <% end %> + <%= javascript_void_link '修改', class: 'action', data: { course_list_id: course_list.id, + toggle: 'modal', target: '.admin-merge-course-list-modal', url: merge_admins_course_lists_path } %> +
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: courses } %> \ No newline at end of file diff --git a/app/views/admins/course_lists/shared/_merge_course_list_modal.html.erb b/app/views/admins/course_lists/shared/_merge_course_list_modal.html.erb new file mode 100644 index 000000000..4858f5372 --- /dev/null +++ b/app/views/admins/course_lists/shared/_merge_course_list_modal.html.erb @@ -0,0 +1,29 @@ + \ No newline at end of file diff --git a/app/views/admins/courses/destroy.js.erb b/app/views/admins/courses/destroy.js.erb new file mode 100644 index 000000000..811038193 --- /dev/null +++ b/app/views/admins/courses/destroy.js.erb @@ -0,0 +1,2 @@ +alert("删除成功"); +$(".course-item-<%= @course.id %>").find(".delete-course-action").remove(); \ No newline at end of file diff --git a/app/views/admins/courses/index.html.erb b/app/views/admins/courses/index.html.erb new file mode 100644 index 000000000..a46cabe24 --- /dev/null +++ b/app/views/admins/courses/index.html.erb @@ -0,0 +1,33 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('课堂列表') %> +<% end %> + +
+ <%= form_tag(admins_courses_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> +
+ + <% status_options = [['全部', ''], ["正在进行(#{@processed_courses})", 'processing'], ["已结束#{@ended_courses}", 'ended']] %> + <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> +
+ +
+ + <%= select_tag :school_id, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %> +
+ + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/课堂名称/课程名称检索') %> + +
+ <%= hidden_field_tag(:homepage_show, false, id:'') %> + <%= check_box_tag(:homepage_show, true, params[:homepage_show].to_s == 'true', class: 'form-check-input') %> + +
+ + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + + <% end %> +
+ +
+ <%= render partial: 'admins/courses/shared/list', locals: { courses: @courses } %> +
\ No newline at end of file diff --git a/app/views/admins/courses/index.js.erb b/app/views/admins/courses/index.js.erb new file mode 100644 index 000000000..7073c2a81 --- /dev/null +++ b/app/views/admins/courses/index.js.erb @@ -0,0 +1 @@ +$('.course-list-container').html("<%= j( render partial: 'admins/courses/shared/list', locals: { courses: @courses } ) %>"); \ No newline at end of file diff --git a/app/views/admins/courses/shared/_list.html.erb b/app/views/admins/courses/shared/_list.html.erb new file mode 100644 index 000000000..225437ba9 --- /dev/null +++ b/app/views/admins/courses/shared/_list.html.erb @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + <% if courses.present? %> + <% courses.each do |course| %> + + + + + + + + + + + + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
ID课堂名称成员资源普通作业分组作业实训作业试卷评测次数私有状态单位创建者<%= sort_tag('创建时间', name: 'created_at', path: admins_courses_path) %>首页邮件通知操作
<%= course.id %> + <%= link_to(course.name, "/courses/#{course.id}", target: '_blank') %> + <%= course.course_members_count %><%= get_attachment_count(course, 0) %><%= course.course_homework_count(1) %><%= course.course_homework_count(3) %><%= course.course_homework_count(4) %><%= course.exercises_count %><%= course.evaluate_count %><%= course.is_public == 1 ? "--" : "√" %><%= course.is_end ? "已结束" : "正在进行" %><%= course.school.name %><%= course.teacher&.real_name %><%= course.created_at&.strftime('%Y-%m-%d %H:%M') %> + class="magic-checkbox" id="course_homepage_show_<%= course.id %>"> + + + class="magic-checkbox" id="course_email_notify_<%= course.id %>"> + + + <% if course.is_delete == 0 %> + <%= delete_link '删除', admins_course_path(course, element: ".course-item-#{course.id}"), class: 'delete-course-action' %> + <% end %> +
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: courses } %> \ 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 7b1f5db7a..33749f467 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -32,8 +32,17 @@
  • <%= sidebar_item_group('#subject-submenu', '实践课程', icon: 'th-list') do %> -
  • <%= sidebar_item(admins_subjects_path, '课程列表', icon: 'cog', controller: 'admins-subjects') %>
  • - <% end %> +
  • <%= sidebar_item(admins_subjects_path, '课程列表', icon: 'cog', controller: 'admins-subjects') %>
  • + <% end %> + + +
  • + <%= sidebar_item_group('#course-submenu', '课堂管理', icon: 'book') do %> +
  • <%= sidebar_item(admins_course_lists_path, '课程列表', icon: 'list', controller: 'admins-course_lists') %>
  • +
  • <%= sidebar_item(admins_courses_path, '课堂列表', icon: 'list', controller: 'admins-courses') %>
  • + + + <% end %>
  • diff --git a/config/routes.rb b/config/routes.rb index 577428c7a..5c7437614 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1172,6 +1172,16 @@ Rails.application.routes.draw do resources :partners, only: [:index, :create, :destroy] do resources :customers, only: [:index, :create, :destroy] end + + resources :course_lists, only: [:index, :destroy] do + post :merge, on: :collection + end + + resources :courses, only: [:index, :destroy] do + post :hidden, on: :member + post :homepage_show, on: :member + post :email_notify, on: :member + end end namespace :cooperative do