class CoursesController < ApplicationController include MessagesHelper include ExportHelper # model validation error rescue_from ActiveRecord::RecordInvalid do |ex| render_error(ex.record.errors.full_messages.join(',')) end # form validation error rescue_from ActiveModel::ValidationError do |ex| render_error(ex.model.errors.full_messages.join(',')) end before_action :require_login, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups] before_action :set_course, :user_course_identity, only: [:show, :update, :destroy, :settings, :set_invite_code_halt, :set_public_or_private, :search_teacher_candidate, :teachers, :top_banner, :left_banner, :add_teacher_popup, :add_teacher, :graduation_group_list, :create_graduation_group, :join_graduation_group, :course_group_list, :set_course_group, :change_course_admin, :change_course_teacher, :delete_course_teacher, :teacher_application_review, :students, :all_course_groups, :transfer_to_course_group, :delete_from_course, :search_users, :add_students_by_search, :base_info, :get_historical_courses, :create_group_by_importing_file, :attahcment_category_list,:export_member_scores_excel, :duplicate_course, :switch_to_teacher, :switch_to_assistant, :switch_to_student, :exit_course] before_action :teacher_allowed, only: [:update, :destroy, :settings, :search_teacher_candidate, :transfer_to_course_group, :delete_from_course, :search_users, :add_students_by_search, :get_historical_courses, :add_teacher_popup, :add_teacher] before_action :admin_allowed, only: [:set_invite_code_halt, :set_public_or_private, :join_graduation_group, :set_course_group, :change_course_admin, :change_course_teacher, :delete_course_teacher, :teacher_application_review, :create_group_by_importing_file] before_action :teacher_or_admin_allowed, only: [:graduation_group_list, :create_graduation_group, :join_graduation_group, :export_member_scores_excel, :course_group_list] before_action :validate_course_name, only: [:create, :update] before_action :find_board, only: :board_list before_action :validate_page_size, only: :mine if RUBY_PLATFORM =~ /linux/ require 'simple_xlsx_reader' require 'roo-xls' end # GET /courses # GET /courses.json def index @user = current_user # 根据分类查询课堂(全部,我的,最新,最热) @order = params[:order].present? ? params[:order] : "all" order_str = @order != "course_members_count" && @order != "created_at" ? "updated_at" : @order if @order == "all" # @course = Course.where(is_delete: 0, is_hidden: 0).select("select c.name, c.id, s.name, u.login, ifnull(concat(u.lastname,u.firstname), # u.login), s.name from courses c, users u, user_extensions ue, schools s where c.is_delete=0 and # c.tea_id=u.id and u.id=ue.user_id and ue.school_id=s.id") @courses = Course.where(is_delete: 0, is_hidden: 0) .includes(:course_modules, :course_members, teacher: [user_extension: :school]) .order("courses.id = 1309 desc, courses.created_at desc") # @courses = Course.where(is_delete: 0, is_hidden: 0).select("courses.id, courses.tea_id, courses.name, courses.exercises_count, courses.polls_count, # courses.is_public, courses.is_end, courses.visits, courses.course_members_count,courses.homework_commons_count,(SELECT MAX(created_at) # FROM `course_activities` WHERE course_activities.course_id = courses.id) AS a") # .order("courses.id = 1309 desc, a desc") elsif @order == "mine" @courses = Course.joins(:course_members) .where("is_delete = 0 AND is_hidden = 0 AND course_members.user_id = ?", @user.id) .order("courses.id = 1309 DESC, courses.#{order_str} DESC") elsif @order == "created_at" # REDO:Extension @courses = Course.joins(teacher: :user_extension) .where(is_delete: 0, is_hidden: 0, is_end: 0) .order("courses.id = 1309 DESC, courses.#{order_str} DESC") else # REDO:Extension @courses = Course.joins(teacher: :user_extension) .where(is_delete: 0, is_hidden: 0) .order("courses.id = 1309 DESC, courses.#{order_str} DESC") end # 根据搜索关键字进一步筛选 if params[:search].present? # REDO:Extension #user_ids = User.includes(user_extension: :school).where("schools.name like ?", "%#{params[:search]}%").pluck(:id) #course_ids = CourseMember.includes(:user, :course).where("course_members.course_id in (?) and course_members.role in (1,2,3) # and CONCAT(users.lastname, users.firstname) like ?", @courses.map(&:id), "%#{params[:search]}%") # .pluck(:course_id) #@courses = @courses.where("name like ?", "%#{params[:search]}%").or(@courses.where(tea_id: user_ids)).or(@courses.where(id: course_ids)) # 6:21 daiao sql = %Q{ (course_members.role in(1,2,3) and CONCAT(users.lastname, users.firstname) like :keyword) or courses.name like :keyword or schools.name like :keyword } @courses = @courses.joins(course_members: [user: [user_extension: :school]]) .where("#{sql}", keyword: "%#{params[:search]}%").distinct end @courses_count = @courses.size # 分页 page = params[:page] || 1 limit = params[:limit] || 16 @courses= @courses.page(page).per(limit) end def visits_plus_one new_visits = @course.visits + 1 @course.update_visits(new_visits) normal_status("成功") end # GET /courses/1 # GET /courses/1.json def show # render :json => {first_category_url: module_url(course.course_modules.where.not(module_type: "activity").where(hidden: 0).first, course)} end # GET /courses/new def new @course = Course.new end # Get /courses/:id/settings # Edit Page def settings end # POST /courses # POST /courses.json def create ActiveRecord::Base.transaction do begin @course = Course.new(name: params[:name], class_period: params[:class_period], credit: params[:credit], end_date: params[:end_date], is_public: params[:is_public], school_id: @school.id, authentication: params[:authentication], professional_certification: params[:professional_certification]) @course.tea_id = current_user.id @course_list_name = params[:course_list_name].strip @course_list = CourseList.find_by(name: @course_list_name) if @course_list @course.course_list_id = @course_list.id else new_course_list = CourseList.create!(name: @course_list_name, user_id: current_user.id, is_admin: 0) @course.course_list_id = new_course_list.id end @course.is_end = @course.end_date.present? && @course.end_date < Date.today if @course.save! @course.generate_invite_code CourseInfo.create!(user_id: current_user.id, course_id: @course.id) CourseMember.create!(course_id: @course.id, user_id: current_user.id, role: 1) course_module_types = params[:course_module_types] @course.create_course_modules(course_module_types) end rescue => e uid_logger_error(e.message) tip_exception("课堂创建失败!") raise ActiveRecord::Rollback end end end # PATCH/PUT /courses/1 # PATCH/PUT /courses/1.json def update ActiveRecord::Base.transaction do begin extra_params = Hash.new extra_params[:school_id] = @school.id extra_params[:is_public] = params[:is_public].present? ? params[:is_public] : 0 if @course.is_end && (course_params[:end_date].nil? || course_params[:end_date].to_date > Date.today) extra_params[:is_end] = 0 elsif !@course.is_end && !course_params[:end_date].blank? && course_params[:end_date].to_date < Date.today extra_params[:is_end] = 1 end extra_params[:authentication] = params[:authentication] extra_params[:professional_certification] = params[:professional_certification] @course_list_name = params[:course_list_name].strip @course_list = CourseList.find_by(name: @course_list_name) if @course_list extra_params[:course_list_id] = @course_list.id else new_course_list = CourseList.create(name: @course_list_name, user_id: current_user.id, is_admin: 0) extra_params[:course_list_id] = new_course_list.id end @course.update_attributes!(course_params.merge(extra_params)) @course.update_course_modules(params[:course_module_types]) normal_status(0, "成功") rescue => e uid_logger_error(e.message) tip_exception("课堂更新失败") raise ActiveRecord::Rollback end end end def search_course_list search = params[:search] ? "%#{params[:search].strip}%" : "%%" @course_lists = CourseList.where("name like ?", "#{search}") @search_count = @course_lists.size end # 邀请码停用/启用 def set_invite_code_halt begin @course.update_attribute('invite_code_halt', @course.invite_code_halt == 0 ? 1 : 0) normal_status(0, "成功") rescue => e uid_logger_error(e.message) tip_exception("停用/启用课堂失败") end end # 设置课堂私有/公有 def set_public_or_private begin @course.update_attribute('is_public', @course.is_public == 1 ? 0 : 1) normal_status(0, "成功") rescue => e uid_logger_error(e.message) tip_exception("设置课堂公有/私有失败") end end # DELETE /courses/1 # DELETE /courses/1.json def destroy if @course.is_delete == 0 @course.delete! normal_status(0, "成功") else normal_status(-1, "课堂已删除,无需重复操作") end end # 课堂的基本信息 def base_info end # --- 教师列表相关API --- START # 教师列表以及教师搜索 def teachers @search_str = params[:search].present? ? params[:search].strip : "" if @course.try(:id) != 1309 || current_user.admin? || current_user.try(:id) == 15582 @teacher_list = @course.course_members.joins(:user).where("course_members.role in (1, 2, 3) and LOWER(concat(users.lastname, users.firstname)) LIKE '%#{@search_str}%'") else @teacher_list = @course.course_members.joins(:user).where("(course_members.role in (1, 3) or (course_members.user_id = #{current_user.id} and course_members.role = 2)) and LOWER(concat(users.lastname, users.firstname)) LIKE '%#{@search_str}%'") end @teacher_list_size = @teacher_list.size @has_graduation_design = @course.course_modules.graduation_module_not_hidden.any? @order = params[:order].to_i if @order.present? case @order when 1 @teacher_list = @teacher_list.includes(:user).order("CONVERT(CONCAT(users.lastname, users.firstname) USING gbk) COLLATE gbk_chinese_ci asc") when 2 @teacher_list = @teacher_list.order("created_at") when 3 @teacher_list = @teacher_list.includes(:course, :graduation_group).order("graduation_groups.name") else @teacher_list = @teacher_list.order("created_at") end else if @has_graduation_design @teacher_list = @teacher_list.includes(:course, :graduation_group).order("graduation_groups.name") else @teacher_list = @teacher_list.order("created_at") end end @is_admin = @user_course_identity < Course::PROFESSOR @applications= CourseMessage.unhandled_join_course_requests_by_course(@course) page = params[:page] || 1 limit = params[:limit] || 20 @teacher_list = @teacher_list.page(page).per(limit) end # 打开添加教师或助教弹窗时访问的接口(需要返回该课堂所有答辩组和所有) def add_teacher_popup @graduation_groups = @course.graduation_groups @course_groups = @course.course_groups @school_name = School.find(current_user.school_id).try(:name) end # 添加教师或助教弹窗中的搜索接口 def search_teacher_candidate name = params[:name] school_name = params[:school_name] # user_ids_of_course_members = @course.course_members.where(role: [1,2,3]).pluck(:user_id) # @users = User.where.not(id: user_ids_of_course_members) @users = User.where(status: User::STATUS_ACTIVE) @users = @users.where("concat(users.firstname, users.lastname) like '%#{name}%'") if name.present? # REDO:Extension @users = @users.joins(user_extension: :school).where("schools.name like '%#{school_name}%'") if school_name.present? @users_size = @users.size page = params[:page] || 1 limit = params[:limit] || 10 @users = @users.page(page).per(limit) end # 添加教师或者助教 def add_teacher ActiveRecord::Base.transaction do begin @user_list = params[:user_list].present? ? params[:user_list] : [] return tip_exception("请先选择成员") if @user_list.blank? @graduation_group_id = params[:graduation_group_id].present? ? GraduationGroup.find(params[:graduation_group_id]).id : 0 @course_group_id = params[:course_group_id].present? ? CourseGroup.find(params[:course_group_id]).id : 0 role = params[:role].to_i teacher_ids = [] @user_list.each do |user| active_student_exist = CourseMember.where(user_id: user[:user_id], role: 4, course_id: @course.id, is_active: 1).any? is_active = active_student_exist ? 0 : 1 user_id = User.find(user[:user_id]).id existing_teacher = CourseMember.find_by(course_id: @course.id, user_id: user_id, role: role) if existing_teacher.blank? teacher_ids << user_id member = CourseMember.create(course_id: @course.id, graduation_group_id: @graduation_group_id, user_id: user_id, role: role, is_active: is_active) member.teacher_course_groups << TeacherCourseGroup.new(course_group_id: @course_group_id, user_id: user_id, course_id: @course.id) if @course_group_id != 0 end end TeacherInviteJoinCourseNotifyJob.perform_later(current_user.id, @course.id, role, teacher_ids) if teacher_ids.present? normal_status(0, "添加成功") rescue => e uid_logger_error(e.message) tip_exception(-1, "添加失败") raise ActiveRecord::Rollback end end end # 获取当前课堂的所有答辩组 def graduation_group_list @graduation_group_list = @course.graduation_groups end # 给当前课堂增加答辩组 def create_graduation_group begin if params[:name].present? identical_exist = GraduationGroup.where(course_id: @course.id, name: params[:name]).any? if identical_exist normal_status(-1, "已存在同名答辩组") else GraduationGroup.create(course_id: @course.id, user_id: current_user.id, name: params[:name]) normal_status(0, "成功") end else tip_exception(-1, "答辩组名称不能为空") end rescue => e uid_logger_error(e.message) tip_exception(-1, "添加失败") raise ActiveRecord::Rollback end end # 将教师加入答辩组 def join_graduation_group ActiveRecord::Base.transaction do begin @course_member_list = params[:course_member_list].present? ? params[:course_member_list] : [] graduation_group_id = GraduationGroup.find(params[:graduation_group_id].to_i).id @course_member_list.each do |course_member| course_member = CourseMember.find(course_member[:course_member_id].to_i) course_member.update_attributes(graduation_group_id: graduation_group_id) end normal_status(0, "成功") rescue => e uid_logger_error(e.message) tip_exception(-1, "加入失败") raise ActiveRecord::Rollback end end end # 获取当前课堂的所有分班, 以及当前教师是否对分班具有管理权限的状态 def course_group_list course_member_id = params[:course_member_id] user_id = params[:user_id] @existed_course_group_ids = TeacherCourseGroup.where(course_id: @course.id, course_member_id: course_member_id, user_id: user_id) .pluck(:course_group_id) @all_course_groups = CourseGroup.where(course_id: @course.id) end # 设置教师的管理权限(即设置该教师所能管理的分班) def set_course_group ActiveRecord::Base.transaction do begin course_group_ids = params[:course_group_ids] user_id = User.find(params[:user_id].to_i).id course_member_id = CourseMember.find(params[:course_member_id]).id teacher_course_groups = TeacherCourseGroup.where(course_id: @course.id, user_id: user_id, course_member_id: course_member_id) teacher_course_groups.destroy_all course_group_ids.each do |course_group_id| course_group_id = CourseGroup.where(id: course_group_id.to_i, course_id: @course.id).first.id TeacherCourseGroup.create(course_id: @course.id, user_id: user_id, course_member_id: course_member_id, course_group_id: course_group_id) end normal_status(0, "成功") rescue => e uid_logger_error(e.message) tip_exception( "分配管理权限失败") raise ActiveRecord::Rollback end end end # 变更管理员 def change_course_admin ActiveRecord::Base.transaction do begin new_admin_user = User.find(params[:user_id].to_i) new_admin = CourseMember.find_by!(id: params[:course_member_id].to_i, course_id: @course.id, user_id: new_admin_user.id) current_admin = CourseMember.find_by!(course_id: @course.id, role: 1) new_admin.CREATOR! current_admin.PROFESSOR! @course.update_attributes!(tea_id: new_admin_user.id) normal_status(0, "变更管理员成功") rescue => e uid_logger_error(e.message) tip_exception( "变更管理员失败") raise ActiveRecord::Rollback end end end # 教师和助教角色转换的接口 def change_course_teacher begin course_member = CourseMember.find_by!(id: params[:course_member_id].to_i, course_id: @course.id) if course_member.PROFESSOR? course_member.ASSISTANT_PROFESSOR! elsif course_member.ASSISTANT_PROFESSOR? course_member.PROFESSOR! else tip_exception( "变更教师/助教失败") end course_member.save! normal_status(0, "变更教师/助教成功") rescue => e uid_logger_error(e.message) tip_exception( "变更教师/助教失败") end end # 删除教师或助教 def delete_course_teacher begin course_member = CourseMember.find_by!(id: params[:course_member_id].to_i, course_id: @course.id) tip_exception("删除失败") if course_member.CREATOR? or course_member.STUDENT? course_student = CourseMember.find_by(id: course_member.user_id, course_id: @course.id, role: %i[STUDENT]) course_member.destroy! course_student.update_attributes(is_active: 1) if course_student.present? && !course_student.is_active normal_status(0, "删除成功") rescue => e uid_logger_error(e.message) tip_exception("删除失败") end end # 切换为教师 def switch_to_teacher begin course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1) tip_exception("切换失败") unless course_member.STUDENT? course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[CREATOR PROFESSOR], course_id: @course.id) course_member.update_attributes(is_active: 0) course_teacher.update_attributes(is_active: 1) normal_status(0, "切换成功") rescue => e uid_logger_error(e.message) tip_exception("切换失败") end end # 切换为助教 def switch_to_assistant begin course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1) tip_exception("切换失败") unless course_member.STUDENT? course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[ASSISTANT_PROFESSOR], course_id: @course.id) course_member.update_attributes(is_active: 0) course_teacher.update_attributes(is_active: 1) normal_status(0, "切换成功") rescue => e uid_logger_error(e.message) tip_exception("切换失败") end end # 切换为学生 def switch_to_student ActiveRecord::Base.transaction do begin course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1) tip_exception("切换失败") if course_member.STUDENT? course_student = CourseMember.find_by!(user_id: current_user.id, role: %i[STUDENT], course_id: @course.id) course_member.update_attributes(is_active: 0) course_student.update_attributes(is_active: 1) normal_status(0, "切换成功") rescue => e uid_logger_error("switch_to_student error: #{e.message}") tip_exception("切换失败") raise ActiveRecord::Rollback end end end def exit_course course_student = CourseMember.find_by!(user_id: current_user.id, role: %i[STUDENT], course_id: @course.id) tip_exception("非课堂学生无法退出课堂") unless course_student.STUDENT? # 课堂如果还有其他身份的用户则更新is_active course_teacher = CourseMember.find_by(user_id: current_user.id, role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR], course_id: @course.id) course_student.destroy! course_teacher.update_attributes(is_active: 1) if course_teacher.present? && !course_teacher.is_active normal_status(0, "退出成功") end # 教师申请加入课堂的审批 def teacher_application_review ActiveRecord::Base.transaction do begin course_message = CourseMessage.find_by!(id: params[:application_id].to_i, course_id: @course.id) course_message.apply_user_id = current_user.id applier_user = User.find_by!(id: params[:user_id].to_i) approval = params[:approval].to_i if approval == 1 course_message.pass! new_teacher = CourseMember.new(course_id: @course.id, user_id: applier_user.id) content = course_message.content.to_i if content == 3 || content == 7 tip_exception("已存在教师/助教身份") if CourseMember.where(course_id: @course.id, user_id: applier_user.id, role: 3).any? new_teacher.ASSISTANT_PROFESSOR! elsif content == 2 || content == 9 tip_exception("已存在教师/助教身份") if CourseMember.where(course_id: @course.id, user_id: applier_user.id, role: 2).any? new_teacher.PROFESSOR! else tip_exception("申请角色错误") end new_teacher.save! elsif approval == 2 course_message.reject! else tip_exception("参数错误") end course_message.save! normal_status(0, "操作成功") rescue => e uid_logger_error(e.message) tip_exception("操作失败") raise ActiveRecord::Rollback end end end # 已通过职业认证的教师复制课堂 def duplicate_course return tip_exception("没有复制权限") unless current_user.admin? || current_user.is_teacher? || current_user.teacher_of_course?(@course) return tip_exception("教师职业认证未通过") unless current_user.pro_certification? new_course = @course.self_duplicate render json: {new_course_id: new_course.id} end # --- 教师列表相关API --- END # --- 学生列表相关API --- START # 学生列表(包括各个子分班的学生列表)及搜索 def students search = params[:search].present? ? params[:search].strip : nil order = params[:order].present? ? params[:order].to_i : 0 course_group_id = params[:course_group_id].present? ? params[:course_group_id].to_i : nil @students = CourseMember.students(@course) if search.present? # REDO:Extension @students = @students.joins(user: :user_extension).where("LOWER(CONCAT(users.lastname, users.firstname)) like ? or user_extensions.student_id like ?", "%#{search}%", "%#{search}%") end if order == 1 # REDO:Extension @students = @students.includes(user: :user_extension).order("user_extensions.student_id") elsif order == 2 @students = @students.includes(:course_group).order("course_groups.position") else # REDO:Extension @students = @students.includes(user: :user_extension).order("user_extensions.student_id") end if course_group_id.present? @students = @students.where(course_group_id: course_group_id) @course_group = CourseGroup.find(course_group_id) if course_group_id != 0 end @students_count = @students.size page = params[:page] || 1 limit = params[:limit] || 20 @students= Kaminari.paginate_array(@students).page(page).per(limit) end # 获取当前课程所有分班 def all_course_groups if params[:all] # 返回所有分班 @course_groups_array = @course.course_groups.to_a else # 返回权限下的分班 charge_group_ids = @course.charge_group_ids(current_user) @course_groups_array = @course.course_groups.where(id: charge_group_ids).to_a end current_course_group_id = params[:course_group_id] if current_course_group_id.present? current_course_group = CourseGroup.find(current_course_group_id) @course_groups_array.delete(current_course_group) end end # 将学生批量移动到某个分班 def transfer_to_course_group ActiveRecord::Base.transaction do begin course_group_id = params[:course_group_id].to_i # course_group_id为0意味着移动学生到未分班 if course_group_id != 0 course_group = CourseGroup.find_by!(id: course_group_id, course_id: @course.id) course_group_id = course_group.id end @course.students.where(id: params[:students].pluck(:course_member_id)).each do |student| student.update_attributes!(course_group_id: course_group_id) end normal_status(0, "操作成功") rescue => e uid_logger(e.message) tip_exception("操作失败") raise ActiveRecord::Rollback end end end # 从当前课堂删除学生 def delete_from_course ActiveRecord::Base.transaction do begin students = params[:students] students.each do |student| course_member = CourseMember.find_by!(id: student[:course_member_id].to_i, course_id: @course.id) course_member.destroy! end normal_status(0, "操作成功") rescue => e uid_logger(e.message) tip_exception("操作失败") raise ActiveRecord::Rollback end end end # 搜索添加学生 def add_students_by_search ActiveRecord::Base.transaction do begin user_ids = params[:user_ids] course_group_id = params[:course_group_id].to_i if course_group_id != 0 course_group = CourseGroup.find(course_group_id) course_group_id = course_group.id end student_ids = [] user_ids.each do |user_id| existing_course_member = CourseMember.find_by(user_id: user_id.to_i, course_id: @course.id) new_student = CourseMember.new(user_id: user_id.to_i, course_id: @course.id, course_group_id: course_group_id, role: 4) if existing_course_member.present? if existing_course_member.STUDENT? existing_course_member.update_attributes(course_group_id: course_group_id) else new_student.is_active = 0 if existing_course_member.is_active new_student.save! end else new_student.save! student_ids << user_id end end TeacherInviteJoinCourseNotifyJob.perform_later(current_user.id, @course.id, 10, student_ids) if student_ids.present? normal_status(0, "添加成功") rescue => e uid_logger(e.message) tip_exception("添加失败") raise ActiveRecord::Rollback end end end # 获取历史课堂,即用户管理的所有课堂以及课堂下的分班 def get_historical_courses user_id = current_user.id @courses = Course.includes(:course_groups).where(tea_id: user_id, is_delete: 0) end # 根据历史课堂的课堂id和分班id获取所有学生 def get_historical_course_students course_id = params[:course_id] course_group_id = params[:course_group_id] @students = CourseMember.where(course_id: course_id, role: %i[STUDENT]) if course_group_id.present? @students = @students.where(course_group_id: course_group_id) end @students_count = @students.size end # 导入创建分班 def create_group_by_importing_file attachment_ids = [] params[:attachment_ids].each do |id| attachment = Attachment.find(id.to_i) attachment_ids << attachment.id end associate_result = Attachment.associate_container(attachment_ids, @course.id, @course.class) return normal_status("参数错误") unless associate_result attachment_ids.each do |attachment_id| attachment = Attachment.find attachment_id path = attachment.disk_directory name = attachment.disk_filename if name.split(".").last == "xls" begin attachment_folder = Rails.configuration.educoder['attachment_folder'] full_path = "#{attachment_folder}/#{path}/#{name}" xls = Roo::Spreadsheet.open(full_path, extension: :xls) worksheet = xls.sheet(0) rows = worksheet.last_row.to_i #最后一行数 if rows < 2 return normal_status(-1, "请按照模板格式导入") else group_count = 0 (2..rows).each do |row| name = worksheet.cell(row, 1).to_s if @course.course_groups.where(:name => name).blank? @course.course_groups << CourseGroup.new(:name => name) group_count += 1 end end return normal_status("已导入#{group_count}个分班") end rescue => e uid_logger_error(e.message) normal_status(-1, "无法完成导入,原因:文件内容无法读取") end end end end # --- 学生列表相关API --- END # 根据姓名和单位搜索用户 def search_users name = params[:name] school_name = params[:school_name] # REDO:Extension @users = User.joins(user_extension: :school) .where("CONCAT(users.lastname, users.firstname) like ? and schools.name like ?", "%#{name}%", "%#{school_name}%") @users_count = @users.size limit = params[:limit] || 20 page = params[:page] || 1 @users = @users.page(page).per(limit) end # 申请加入课堂 def apply_to_join_course ActiveRecord::Base.transaction do begin # 邀请码验证 return normal_status(-1, "邀请码不能为空") if params[:invite_code].blank? invite_code = params[:invite_code] course = Course.find_by(invite_code: invite_code, is_delete: 0, invite_code_halt: 0, is_end: 0) course_group = CourseGroup.find_by(invite_code: invite_code) if course.blank? return normal_status(-1, "邀请码无效") if course_group.blank? course = Course.find_by(id: course_group.course_id, is_delete: 0, invite_code_halt: 0, is_end: 0) return normal_status(-1, "邀请码无效") if course.blank? end # 实名认证和职业认证的身份判断 return normal_status(-1, "该课堂要求成员完成实名和职业认证") if course.authentication && course.professional_certification && (!current_user.authentication || !current_user.professional_certification) return normal_status(-1, "该课堂要求成员完成实名认证") if course.authentication && !current_user.authentication return normal_status(-1, "该课堂要求成员完成职业认证") if course.professional_certification && !current_user.professional_certification # 身份验证 if params[:professor].blank? && params[:assistant_professor].blank? && params[:student].blank? return normal_status(-1, "请先选择身份") end if params[:professor].present? && params[:assistant_professor].present? return normal_status(-1, "同一课堂不允许申请多个教师身份") end # 创建学生身份 if params[:student].present? existing_student = CourseMember.find_by(course_id: course.id, role: %i[STUDENT], user_id: current_user.id) if existing_student.present? # 如果在该课堂已经存在学生身份,且邀请码为分班邀请码,则将其直接加入分班 existing_student.update_attributes(course_group_id: course_group.id) if course_group.present? else correspond_teacher_exist = current_user.teacher_of_course? course new_student = CourseMember.new(user_id: current_user.id, course_id: course.id, role: 4) new_student.is_active = 0 if correspond_teacher_exist new_student.course_group_id = course_group.id if course_group.present? new_student.save! StudentJoinCourseNotifyJob.perform_later(current_user.id, course.id) end end # 创建教师身份 if params[:professor].present? || params[:assistant_professor].present? teacher_already_exist = current_user.teacher_of_course_non_active? course unless teacher_already_exist existing_course_message = CourseMessage.find_by(course_id: course.id, course_message_id: current_user.id, course_message_type: "JoinCourseRequest", status: 0, viewed: false) if existing_course_message.blank? course_message = CourseMessage.new(course_id: course.id, user_id: course.tea_id, status: 0, course_message_id: current_user.id, course_message_type: "JoinCourseRequest", viewed: false) course_message.content = 2 if params[:professor].present? course_message.content = 3 if params[:assistant_professor].present? course_message.save! role = course_message.content == 2 ? '7' : '9' # 7:老师 9:助教 ApplyTeacherRoleJoinCourseNotifyJob.perform_later(current_user.id, course.id, role) end end end if current_user.student_of_course?(course) || current_user.teacher_of_course?(course) render json: { status: 0, message: "成功", course_id: course.id} else normal_status("申请已提交,请等待审核") end rescue => e uid_logger(e.message) tip_exception("加入课堂失败") raise ActiveRecord::Rollback end end end def top_banner @user = current_user @is_teacher = @user_course_identity < Course::STUDENT @is_student = @user_course_identity == Course::STUDENT @course.increment!(:visits) end def left_banner @user = current_user @is_teacher = @user.teacher_of_course?(@course) @course_modules = @course.course_modules.where.not(module_type: "activity").where(hidden: 0) @hidden_modules = @course.course_modules.where(hidden: 1) @second_category_type = ["shixun_homework", "graduation", "attachment", "board", "course_group"] end def board_list begin @course = @board.course @current_user = current_user return normal_status(403, "你没有权限操作") if !@current_user.teacher_of_course?(@course) && !@current_user.course_identity(@current_user) == 4 @boards = @course.boards rescue Exception => e uid_logger(e.message) tip_exception("获取数据失败") raise ActiveRecord::Rollback end end def attahcment_category_list @has_course_groups = @course.course_groups.exists? @course_modules = @course.attachment_course_modules end def mine @page = params[:page] || 1 @page_size = params[:page_size] || 15 @courses = Course.by_user(current_user).hidden(false).processing.not_deleted.by_keywords(params[:search]).distinct # @total_count = @courses.count # offset = 0 # while offset < @total_count # # offset = offset + @page_size.to_i + 1 # @courses = @courses.offset(offset) # end @courses= @courses.page(@page).per(@page_size) end def export_member_scores_excel ActiveRecord::Base.transaction do begin name = params[:name] ? "#{params[:name].strip}" : "" #用户名或学生学号id搜索 group_id = params[:group_id] #分班的班级id if group_id && group_id != "0" && group_id != "-1" @all_members = @course.students.course_find_by_ids("course_group_id",group_id) elsif group_id && group_id == "0" # 未分班 @all_members = @course.course_members.ungroup_students else @all_members = @course.students end if name.present? nick_name_search = @all_members.joins(:user).where("nickname like ?","%#{name}%") if nick_name_search.present? @all_members = nick_name_search else @all_members = @all_members.joins(user: [:user_extension]).where('user_extensions.student_id like ? OR user_extensions.student_realname like ?',"%#{name}%","%#{name}%") end end @c_homeworks = @course.homework_commons.homework_published.order("publish_time asc, created_at asc") @c_exercises = @course.exercises.is_exercise_published.order("publish_time asc, created_at asc") @c_polls = @course.polls.publish_or_not.order("publish_time asc, created_at asc") @c_tasks = @course.graduation_tasks.task_published.order("publish_time asc, created_at asc") if @user_course_identity > Course::ASSISTANT_PROFESSOR tip_exception(403,"无权限操作") else member_to_xlsx(@course,@all_members,@c_homeworks,@c_exercises,@c_tasks,@c_polls) filename = current_user.real_name + "_" + @course.name + "_全部成绩" + Time.now.strftime('%Y%m%d_%H%M%S') render xlsx: "#{filename.strip.first(30)}",template: "courses/export_member_scores_excel.xlsx.axlsx", locals: {course_info:@course_info, activity_level:@user_activity_level, course_scores:@course_user_scores,shixun_works:@shixun_work_arrays, common_works:@common_work_arrays,group_works:@group_work_arrays,task_works:@task_work_arrays, exercise_works:@exercise_work_arrays} end rescue Exception => e uid_logger_error(e.message) tip_exception("没有权限") raise ActiveRecord::Rollback end end end def search_slim courses = current_user.manage_courses.not_deleted.processing keyword = params[:keyword].to_s.strip if keyword.present? courses = courses.where('name LIKE ?', "%#{keyword}%") end count = courses.count courses = paginate(courses) render_ok(count: count, courses: courses.select(:id, :name).as_json) end private # Use callbacks to share common setup or constraints between actions. def set_course @course = Course.find_by!(id: params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def course_params params.require(:course).permit(:name, :class_period, :credit, :end_date, :is_public, :authentication, :professional_certification) end def validate_course_name tip_exception("课堂名称不能为空!") if params[:course][:name].blank? tip_exception("课程名称不能为空!") if params[:course_list_name].blank? tip_exception("课堂名称应以课程名称开头命名") unless params[:course][:name].index(params[:course_list_name]) && params[:course][:name].index(params[:course_list_name]) == 0 tip_exception("课堂所属单位不能为空!") if params[:school].blank? @school = School.find_by!(name: params[:school].strip) end # 超级管理员和课堂管理员的权限判断 def admin_allowed unless @user_course_identity < Course::PROFESSOR tip_exception(403, "..") end end # 课堂教师的权限判断 def teacher_allowed unless @user_course_identity < Course::STUDENT tip_exception(403, "..") end end # 课堂教师,课堂管理员以及超级管理员的权限判断 def teacher_or_admin_allowed unless @user_course_identity < Course::ASSISTANT_PROFESSOR tip_exception(403, "..") end end def member_to_xlsx(course,all_members,homeworks,exercises,tasks,polls) #课堂的作业信息 shixun_homeworks = homeworks.search_homework_type(4) #全部实训作业 shixun_titles = shixun_homeworks.pluck(:name) + ["总得分"] common_homeworks = homeworks.search_homework_type(1) #全部普通作业 common_titles = common_homeworks.pluck(:name)+ ["总得分"] group_homeworks = homeworks.search_homework_type(3) #全部分组作业 group_titles = group_homeworks.pluck(:name)+ ["总得分"] task_titles = tasks.pluck(:name)+ ["总得分"] exercise_titles = exercises.pluck(:exercise_name)+ ["总得分"] total_user_score_array = [] #学生总成绩集合 #课堂信息 @course_info = [] course_info_title = "课堂信息概要" course_id = course.id course_name = course.name course_list_name = course.course_list.present? ? course.course_list.name : "--" course_assistants = course.course_members.course_user_role(%i[PROFESSOR ASSISTANT_PROFESSOR]) course_assistants_count = course_assistants&.count course_assistants_name = course_assistants_count > 0 ? course_assistants.map{|m| m.user.real_name}.join('、') : "--" course_teacher_member = course.course_members.course_user_role(%i[CREATOR]) course_teacher = course_teacher_member.present? ? course_teacher_member.first.user.real_name : "--" course_class_counts = course.course_groups_count course_students_count = course.students.count course_1 = ["课堂编号",course_id] course_2 = ["课程名称",course_list_name] course_3 = ["课堂名称",course_name] course_4 = ["教师团队(#{course_assistants_count})", course_assistants_name] course_5 = ["主讲教师", course_teacher] course_6 = ["分班",course_class_counts] course_7 = ["学生", course_students_count] course_main_info = [course_1,course_2,course_3,course_4,course_5,course_6,course_7] course_group_info_head = %w(序号 分班名称 邀请码 学生数量) course_group_info_body = [] if course.course_groups.present? course.course_groups.each_with_index do |group, index| group_index = (index+1) group_name = group.name group_code = group.invite_code group_count = group.course_members_count group_array = [group_index,group_name,group_code,group_count] course_group_info_body.push(group_array) end end course_group_info = [course_group_info_head,course_group_info_body] @course_info += [course_info_title,course_main_info,course_group_info] #课堂活跃度 course_homework_ids = homeworks.pluck(:id) #该课堂的全部作业id course_graduate_task_ids = tasks.pluck(:id) #该课堂的全部毕业任务id course_exercise_ids = exercises.pluck(:id) #课堂的全部试卷数 course_poll_ids = polls.pluck(:id) #课堂的全部问卷数 course_board_ids = course.boards.pluck(:id) #课堂的全部讨论区 @user_activity_level = [] course_user_level = [] course_activity_title = "课堂活跃度统计" user_cell_head = %w(排名 真实姓名 登录名 邮箱 学号 分班 作业完成数(*10) 试卷完成数(*10) 问卷完成数(*7) 资源发布数(*5) 帖子发布数(*2) 帖子回复数(*1) 作业回复数(*1) 活跃度) all_members.each do |u| #用户的基本信息 user = u.user user_login = user.login user_name = user.real_name user_mail = user.mail user_stu_id = user.student_id.present? ? (user.student_id.to_s + "\t") : "--" user_course_group = u.course_group_name user_info_array = [user_login,user_name,user_mail,user_stu_id,user_course_group] #用户的信息集合 user_work_scores = [] #课堂活跃度统计 user_homeworks_num = user.student_works.find_by_homework(course_homework_ids).has_committed.count #完成的作业数 user_graduate_num = user.graduation_works.find_by_task(course_graduate_task_ids).has_committed.count #毕业任务完成数 user_exercise_num = user.exercise_users.search_by_exercise(course_exercise_ids).commit_exercise_by_status(1).count #根据试卷的id来查找 user_poll_num = user.poll_users.search_by_poll(course_poll_ids).commit_by_status(1).count #已完成问卷 user_file_num = user.attachments.search_by_container(course.id).count user_messages = user.messages user_messages_num = user_messages.root_nodes.find_by_boards(course_board_ids).count #帖子发布数 user_reply_num = user_messages.reply_nodes.find_by_boards(course_board_ids).count #帖子回复数 user_work_reply_num = user.journals_for_messages.search_by_jour_type("HomeworkCommon",course_homework_ids).count #作业回复数的数量 c_works_num = (user_homeworks_num + user_graduate_num)*10 c_exercise_num = user_exercise_num*10 c_poll_num = user_poll_num*7 c_file_num = user_file_num*5 c_message_num = user_messages_num*2 c_reply_num = user_reply_num*2 user_activity_levels = c_works_num + c_exercise_num + c_poll_num + c_file_num + c_message_num + c_reply_num + user_work_reply_num user_ac_level = { u_1: user_name, u_2: user_login, u_2_1: user_mail, u_3: user_stu_id, u_4: user_course_group, u_5: c_works_num, u_6: c_exercise_num, u_7: c_poll_num, u_8: c_file_num, u_9: c_message_num, u_10: c_reply_num, u_11: user_work_reply_num, u_12: user_activity_levels } course_user_level.push(user_ac_level) #学生总成绩 shixun_score = 0.0 # 实训作业的总分 common_score = 0.0 #普通作业的总分 group_score = 0.0 #分组作业的总分 task_score = 0.0 # 毕业任务的总得分 exercise_score = 0.0 #试卷的总得分 shixun_score_array = [] common_score_array = [] group_score_array = [] task_score_array = [] exercise_score_array = [] #实训作业 if shixun_homeworks.count > 0 shixun_homeworks.each do |s| user_student_work = s.student_works.homework_by_user(user.id) #当前用户的对该作业的回答 if user_student_work.blank? h_score = 0.0 #该作业的得分为0 else user_stu_work = user_student_work.first h_score = user_stu_work.work_score.nil? ? 0.0 : user_stu_work.work_score #用户对该作业的分数 end shixun_score_array.push(h_score) end end shixun_score += shixun_score_array.sum shixun_score_array.push(shixun_score) #shixun_score_array的最后一行为总分 user_work_scores += user_info_array + shixun_score_array #单个用户的实训作业得分信息 #普通作业 if common_homeworks.count > 0 common_homeworks.each do |c| user_student_work_1 = c.student_works.homework_by_user(user.id) #当前用户的对该作业的回答 if user_student_work_1.blank? h_score_1 = 0.0 #该作业的得分为0 else user_stu_work_1 = user_student_work_1.first h_score_1 = user_stu_work_1.work_score.nil? ? 0.0 : user_stu_work_1.work_score #用户对该作业的分数 end common_score_array.push(h_score_1) end end common_score += common_score_array.sum common_score_array.push(common_score) #shixun_score_array的最后一行为总分 user_work_scores += common_score_array #单个用户的普通作业得分信息 #分组作业 if group_homeworks.count > 0 group_homeworks.each do |g| user_student_work_3 = g.student_works.homework_by_user(user.id) #当前用户的对该作业的回答 if user_student_work_3.blank? h_score_3 = 0.0 #该作业的得分为0 else user_stu_work_3 = user_student_work_3.first h_score_3 = user_stu_work_3.work_score.nil? ? 0.0 : user_stu_work_3.work_score #用户对该作业的分数 end group_score_array.push(h_score_3) end end group_score += group_score_array.sum group_score_array.push(group_score) #shixun_score_array的最后一行为总分 user_work_scores += group_score_array #单个用户的分组作业得分信息 #毕设作业 if tasks.count > 0 tasks.each do |task| graduation_works = task.graduation_works.find_by_task_user(user.id) if graduation_works.empty? t_score = 0.0 else t_score = graduation_works.first.work_score.nil? ? 0.0 : graduation_works.first.work_score end task_score_array.push(t_score) end end task_score += task_score_array.sum task_score_array.push(task_score) user_work_scores += task_score_array #单个用户的分组作业得分信息 #试卷 if exercises.count > 0 exercises.each do |ex| exercise_works = ex.exercise_users.exercise_commit_users(user.id) if exercise_works.empty? e_score = 0.0 else e_score = exercise_works.first.score.nil? ? 0.0 : exercise_works.first.score end exercise_score_array.push(e_score) end end exercise_score += exercise_score_array.sum exercise_score_array.push(exercise_score) user_work_scores += exercise_score_array #单个用户的分组作业得分信息 total_user_scores = shixun_score + common_score + group_score + task_score + exercise_score user_work_scores.push(total_user_scores) #个人的行内容添加总成绩 total_user_score_array.push(user_work_scores) # 全部成员的集合 end #1.课堂活跃度统计的集合 course_user_level = course_user_level.sort_by {|k| k[:u_12]}.reverse @user_activity_level = [course_activity_title,user_cell_head,course_user_level] #2.学生总成绩的集合 ## 作业标题的集合 course_user_score_title = "学生总成绩" score_title_cells = shixun_titles + common_titles + group_titles + task_titles + exercise_titles score_title_counts = [shixun_titles.count,common_titles.count,group_titles.count,task_titles.count,exercise_titles.count] score_cell_head = %w(序号 真实姓名 登录名 邮箱 学号 分班) + score_title_cells + ["个人总成绩"] @course_user_scores = [course_user_score_title,score_cell_head,score_title_counts,total_user_score_array] #作业的全部集合 @shixun_work_arrays = [] @group_work_arrays = [] @common_work_arrays = [] @task_work_arrays = [] @exercise_work_arrays = [] count_1 = shixun_homeworks.count count_2 = common_homeworks.count count_3 = group_homeworks.count count_4 = tasks.count count_5 = exercises.count #实训作业 if count_1 > 0 shixun_homeworks.each_with_index do |s,index| all_student_works = s.student_works.has_committed.order("work_score desc") #该实训题的全部用户回答 title_no = index.to_i + 1 student_work_to_xlsx(all_student_works,s) shixun_work_display_name = (title_no.to_s + "." + s.name).strip.first(30) shixun_work_content = [shixun_work_display_name,@work_head_cells,@work_cells_column] @shixun_work_arrays.push(shixun_work_content) end end #普通作业 if count_2 > 0 common_homeworks.each_with_index do |c,index| all_student_works = c.student_works.has_committed.order("work_score desc") #当前用户的对该作业的回答 title_no = count_1 + index.to_i + 1 student_work_to_xlsx(all_student_works,c) work_name = (title_no.to_s + "." + c.name).strip.first(30) work_content = [work_name,@work_head_cells,@work_cells_column] @common_work_arrays.push(work_content) title_no end end #分组作业 if count_3 > 0 group_homeworks.each_with_index do |c,index| all_student_works = c.student_works.has_committed.order("work_score desc") #当前用户的对该作业的回答 title_no = count_1 + count_2 + index.to_i + 1 student_work_to_xlsx(all_student_works,c) work_name = (title_no.to_s + "." + c.name).strip.first(30) work_content = [work_name,@work_head_cells,@work_cells_column] @group_work_arrays.push(work_content) end end #毕设任务 if count_4 > 0 tasks.each_with_index do |c,index| all_student_works = c.graduation_works.has_committed.order("work_score desc") #当前用户的对该作业的回答 title_no = count_1 + count_2 + count_3 + index.to_i + 1 graduation_work_to_xlsx(all_student_works,c,current_user) work_name = (title_no.to_s + "." + c.name).strip.first(30) # work_content = [work_name,@work_head_cells,@work_cells_column] work_content = [work_name,@head_cells_column,@task_cells_column] @task_work_arrays.push(work_content) end end #试卷的导出 if count_5 > 0 exercises.each_with_index do |c,index| all_student_works = c.exercise_users.exercise_user_committed #当前用户的对该作业的回答 title_no = count_1 + count_2 + count_3 + count_4 + index.to_i + 1 get_export_users(c,course,all_student_works) work_name = (title_no.to_s + "." + c.exercise_name).strip.first(30) # work_content = [work_name,@work_head_cells,@work_cells_column] work_content = [work_name,@table_columns,@user_columns] @exercise_work_arrays.push(work_content) end end end end