class SubjectsController < ApplicationController before_action :require_login, :check_auth, except: [:index] # before_action :check_auth, except: [:index] before_action :find_subject, except: [:index, :create, :append_to_stage] before_action :allowed, only: [:update, :edit, :destroy, :publish, :cancel_publish, :cancel_has_publish, :search_members, :add_subject_members, :statistics, :shixun_report, :school_report, :up_member_position, :down_member_position] include ApplicationHelper include SubjectsHelper def index @tech_system = Repertoire.where(nil).order("updated_at desc") select = params[:select] # 路径导航类型 reorder = params[:order] || "publish_time" search = params[:search] ## 分页参数 page = params[:page] || 1 limit = params[:limit] || 16 offset = (page.to_i-1) * limit # 最热排序 if reorder == "myshixun_count" if select @subjects = Subject.find_by_sql("SELECT subjects.id, subjects.user_id, subjects.name, subjects.stages_count, subjects.repertoire_id, subjects.status, subjects.shixuns_count, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id where subjects.hidden = 0 AND subjects.status = 2 AND subjects.name like '%#{search}%' AND subjects.repertoire_id = #{select} GROUP BY subjects.id ORDER BY myshixun_member_count DESC") else @subjects = Subject.find_by_sql("SELECT subjects.id, subjects.user_id, subjects.name, subjects.stages_count, subjects.repertoire_id, subjects.status, subjects.shixuns_count, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id where subjects.hidden = 0 AND subjects.status = 2 AND subjects.name like '%#{search}%' GROUP BY subjects.id ORDER BY myshixun_member_count DESC") end else # 我的路径 if reorder == "mine" tip_exception(401, "..") unless current_user.logged? mine_subject_id = StageShixun.find_by_sql("select DISTINCT(subject_id) from stage_shixuns where shixun_id in (select distinct(shixun_id) from myshixuns where user_id=#{current_user.id})").map(&:subject_id) manage_subject_id = SubjectMember.where(user_id: current_user.id).pluck(:subject_id) total_subject_id = (mine_subject_id + manage_subject_id).uniq @subjects = Subject.where(id: total_subject_id) elsif reorder == "publish_time" @subjects = Subject.unhidden else @subjects = Subject.visible.unhidden end # 类型 if select @subjects = @subjects.where(repertoire_id: select) end if search.present? @subjects = @subjects.where("name like ?", "%#{search}%") end # 排序 order_str = reorder == "publish_time" ? "status = 2 desc, publish_time asc" : "updated_at desc" @subjects = @subjects.reorder(order_str) end @total_count = @subjects.size if reorder != "myshixun_count" @subjects = @subjects.page(page).per(limit).includes(:shixuns, :repertoire) else @subjects = @subjects[offset, limit] subject_ids = @subjects.pluck(:id) order_ids = subject_ids.size > 0 ? subject_ids.join(',') : -1 @subjects = Subject.where(id: subject_ids).order("field(id,#{order_ids})").includes(:shixuns, :repertoire) end end def show @user = current_user @is_creator = current_user.creator_of_subject?(@subject) # 合作团队 @members = @subject.subject_members.includes(:user) @shixuns = @subject.shixuns.published.pluck(:id) challenge_ids = Challenge.where(shixun_id: @shixuns).pluck(:id) # 实训路径中的所有实训标签 @tags = ChallengeTag.where(challenge_id: challenge_ids).pluck(:name).uniq # 用户获取的实训标签 # @user_tags = @subject.shixuns.map(&:user_tags_name).flatten.uniq @user_tags = user_shixun_tags challenge_ids, @user.id # 访问数变更 @subject.increment!(:visits) end def create ActiveRecord::Base.transaction do begin @subject = Subject.new(subject_params) @subject.user_id = current_user.id @subject.save! @subject.subject_members.create!(role: 1, user_id: current_user.id) rescue Exception => e uid_logger_error(e.message) tip_exception("实训路径创建失败") raise ActiveRecord::Rollback end end end def edit end def update begin @subject.update_attributes(subject_params) rescue Exception => e uid_logger_error(e.message) tip_exception("实训路径更新失败") raise ActiveRecord::Rollback end end def destroy ActiveRecord::Base.transaction do begin ApplyAction.where(container_type: "ApplySubject", container_id: @subject.id).destroy_all @subject.destroy rescue Exception => e uid_logger_error(e.message) tip_exception("实训路径删除失败") raise ActiveRecord::Rollback end end end def choose_subject_shixun @search = params[:search] @type = params[:type] # 超级管理员用户显示所有未隐藏的实训、非管理员显示合作团队用户的实训(对本单位公开且未隐藏) if current_user.admin? @shixuns = Shixun.select([:id, :name, :status, :myshixuns_count, :identifier]).where(hidden: 0) else none_shixun_ids = ShixunSchool.where("school_id != #{current_user.user_extension.try(:school_id).to_i}").pluck(:shixun_id) @shixuns = Shixun.select([:id, :name, :status, :myshixuns_count, :identifier]).where.not(id: none_shixun_ids).where(hidden: 0) end # 实训课程的所有标签 tag_ids = @shixuns.joins(:shixun_tag_repertoires).pluck(:tag_repertoire_id).uniq @tags = TagRepertoire.select([:id, :name]).where(id: tag_ids) if params[:search] @shixuns = @shixuns.where("name like ?", "%#{@search}%") end unless @type.nil? || @type == "" || @type == "all" shixun_ids = ShixunTagRepertoire.where(tag_repertoire_id: @type).pluck(:shixun_id).uniq @shixuns = @shixuns.where(id: shixun_ids) end @shixuns_count = @shixuns.count ## 分页参数 page = params[:page] || 1 @shixuns = @shixuns.includes(:myshixuns).reorder("created_at desc").page(page).per(10) end def append_to_stage @shixuns = Shixun.where(id: params[:shixun_id]).order("id desc") end def choose_course course_ids = Course.find_by_sql("SELECT c.id FROM courses c, course_members m WHERE m.course_id = c.id AND m.role in (1,2,3) AND m.user_id=#{current_user.id} AND c.is_delete = 0 AND c.is_end = 0").map(&:id) @courses = Course.where(id: course_ids) @none_shixun_ids = ShixunSchool.where("school_id != #{current_user.user_extension.try(:school_id).to_i}").pluck(:shixun_id) end def send_to_course @course = Course.find_by!(id: params[:course_id]) stages = @subject.stages.where(id: @subject.stage_shixuns.where(shixun_id: params[:shixun_ids]).pluck(:stage_id)) course_module = @course.course_modules.where(module_type: "shixun_homework").first ActiveRecord::Base.transaction do begin # 将实训课程下的所有已发布实训按顺序发送到课堂,同时创建与章节同名的实训作业目录 stages.each do |stage| category = CourseSecondCategory.where(name: stage.name, course_id: @course.id, category_type: "shixun_homework").first || CourseSecondCategory.create!(name: stage.name, course_id: @course.id, category_type: "shixun_homework", course_module_id: course_module.id, position: course_module.course_second_categories.count + 1) stage.shixuns.where(id: params[:shixun_ids], status: 2).each do |shixun| homework = HomeworksService.new.create_homework shixun, @course, category, current_user end end rescue Exception => e uid_logger(e.message) tip_exception("发送失败") raise ActiveRecord::Rollback end end end def publish apply = ApplyAction.where(container_type: "ApplySubject", container_id: @subject.id).order("created_at desc").first if apply && apply.status == 0 @status = 0 else @subject.update_attributes(status: 1) ApplyAction.create(container_type: "ApplySubject", container_id: @subject.id, user_id: current_user.id, status: 0) begin status = Trustie::Sms.send(mobile: '18711011226', send_type:'publish_subject' , name: '管理员') rescue => e uid_logger_error("发送验证码出错: #{e}") end @status = 1 end end def cancel_publish begin apply = ApplyAction.where(container_type: "ApplySubject", container_id: @subject.id).order("created_at desc").first if apply && apply.status == 0 apply.update_attributes(status: 3) apply.tidings.destroy_all end @subject.update_attributes(status: 0) rescue => e uid_logger_error(e.message) tip_exception("撤销申请失败") raise ActiveRecord::Rollback end end def cancel_has_publish begin @subject.update_attributes(:status => 0) rescue => e uid_logger_error(e.message) tip_exception("撤销发布失败") raise ActiveRecord::Rollback end end def search_members tip_exception("搜索内容不能为空") unless params[:search] page = params[:page] || 1 member_ids = @subject.subject_members.map(&:user_id).join(',') condition = "%#{params[:search].strip}%".gsub(" ","") @users = User.where("id not in (?) and status = 1 and LOWER(concat(lastname, firstname, login, mail)) LIKE ?", member_ids, "#{condition}") @users = @users.page(page).per(10) @users = @users.includes(:user_extension) end def add_subject_members tip_exception(403, "没权限操作") if !current_user.admin? tip_exception("user_ids 不能为空!") if params[:user_ids].blank? memberships = params[:user_ids] memberships.each do |member| if SubjectMember.where(user_id: member, subject_id: @subject.id).count == 0 user = User.find_by!(id: member) SubjectMember.create!(user_id: member, subject_id: @subject.id, role: 2, position: @subject.subject_members.size + 1) if user.present? end end end # 删除实训 # DELETE: /api/subejcts/:id/delete_member def delete_member tip_exception(403, "没权限操作") if !current_user.admin? tip_exception('用户id不能为空') if params[:user_id].blank? user = @subject.subject_members.where(:user_id => params[:user_id], :role => 2).first tip_exception("管理员用户不允许删除,或用户不存在") if user.blank? ActiveRecord::Base.transaction do begin @subject.subject_members.where("position > #{user.position}").update_all("position = position - 1") user.destroy rescue Exception => e uid_logger_error(e.message) tip_exception(e.message) raise ActiveRecord::Rollback end end end # 合作者上移 def up_member_position tip_exception('用户id不能为空') if params[:user_id].blank? ActiveRecord::Base.transaction do begin member = @subject.subject_members.where(user_id: params[:user_id]).first # position为1时不能再往上移 tip_exception('不能再上移了') if member.position == 1 up_member = @subject.subject_members.where(position: member.position - 1).first up_member.update_attribute(:position, member.position) member.update_attribute(:position, member.position - 1) rescue Exception => e uid_logger_error(e.message) tip_exception(e.message) raise ActiveRecord::Rollback end end end # 合作者下移 def down_member_position tip_exception('用户id不能为空') if params[:user_id].blank? ActiveRecord::Base.transaction do begin member = @subject.subject_members.where(user_id: params[:user_id]).first # position已经是最大值时不能再往下移 tip_exception('不能再下移了') if member.position == @subject.subject_members.size down_member = @subject.subject_members.where(:position => member.position + 1).first down_member.update_attribute(:position, member.position) member.update_attribute(:position, member.position + 1) rescue Exception => e uid_logger_error(e.message) tip_exception(e.message) raise ActiveRecord::Rollback end end end def statistics @learn_count = @subject.member_count shixun_ids = @subject.stage_shixuns.pluck(:shixun_id) # 受用课堂(已经发布的实训(在此路径中的实训)作业的个数) homework_common_id = HomeworkCommonsShixun.where(shixun_id: shixun_ids).pluck(:homework_common_id).uniq homework_common_id = homework_common_id.blank? ? -1 : homework_common_id.join(",") courses = Course.find_by_sql("select c.id, c.school_id from courses c right join homework_commons hc on c.id = hc.course_id where c.is_delete = 0 and c.school_id is not null and hc.publish_time < '#{Time.now}' and hc.id in (#{(homework_common_id)})") course_ids = courses.pluck(:id).uniq @course_count = course_ids.length # 受用院校 school_ids = courses.pluck(:school_id).uniq @schools_count = school_ids.length # 采用课堂情况 @schools = School.select([:id, :name]).where(id: school_ids) @schools = @schools.map do |s| school_courses = Course.where(id: course_ids, school_id: s.id) course_count = school_courses.count student_count = StudentsForCourse.where(course_id: school_courses.pluck(:id)).count homework_count = HomeworkCommon.find_by_sql("select count(*) cnt from homework_commons hc join courses c on hc.course_id = c.id where c.school_id = #{s.id} and hc.id in(#{homework_common_id})").first.try(:cnt) s.attributes.dup.merge({name: s.name, course_count: course_count, student_count: student_count,homework_count: homework_count}) end @schools = @schools.sort{|x,y| y['homework_count'] <=> x['homework_count']} @school_total_count = @schools.size page = params[:page] || 1 @schools = @schools[(page.to_i-1)*10, 10] # TODO: 这个可以异步加载,让页面刷新完成后再加载图形数据 # 章节使用情况 @stage_user_info = [] @sum = 0 #总数 @subject.stages.includes(:stage_shixuns).each do |stage| shixun_ids = stage.stage_shixuns.pluck(:shixun_id) if shixun_ids.present? homework_common_id = HomeworkCommonsShixun.where(shixun_id: shixun_ids).pluck(:homework_common_id).uniq if homework_common_id.present? publish_homework = HomeworkDetailManual.where("homework_common_id in(?) and comment_status > 0", homework_common_id.join(",")).pluck(:homework_common_id) use_count = publish_homework.present? ? HomeworkCommon.find_by_sql("select count(*) cnt from homework_commons hc join courses c on hc.course_id = c.id where hc.id in(#{publish_homework.join(",")}) and c.school_id is not null").first.try(:cnt) : 0 @sum += use_count else @sum += 0 use_count = 0 end @stage_user_info << use_count else @sum += 0 @stage_user_info << 0 end end end def shixun_report end def school_report @schools = School.find_by_sql("select count(ms.id) ue_count, s.id, s.name school_name from user_extensions ue, myshixuns ms, schools s where ue.user_id = ms.user_id and ms.shixun_id in (select shixun_id from stage_shixuns where subject_id = '#{@subject.id}') and s.id = ue.school_id group by ue.school_id order by ue_count desc limit 10") end private def subject_params tip_exception("实训路径名称不能为空") if params[:name].blank? tip_exception("实训路径简介不能为空") if params[:description].blank? tip_exception("实训路径学习须知不能为空") if params[:learning_notes].blank? params.require(:subject).permit(:name, :description, :learning_notes) end def find_subject @subject = Subject.find_by!(id: params[:id]) unless @subject.status == 2 || current_user.manager_of_subject?(@subject) tip_exception("403", "") end end def allowed unless current_user.manager_of_subject?(@subject) tip_exception("403", "") end end end