You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
educoder/app/controllers/subjects_controller.rb

525 lines
21 KiB

class SubjectsController < ApplicationController
before_action :require_login, :check_auth, except: [:index, :show, :right_banner]
# before_action :check_auth, except: [:index]
before_action :check_account, except: [:index, :show, :right_banner]
before_action :find_subject, except: [:index, :create, :new, :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, :update_team_title]
before_action :require_admin, only: [:copy_subject]
include ApplicationHelper
include SubjectsHelper
def index
@tech_system = current_laboratory.subject_repertoires
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"
5 years ago
if current_laboratory.main_site?
5 years ago
not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{current_laboratory.id}").pluck(:id)
5 years ago
not_subject_ids = not_subject_ids.length > 0 ? "(" + not_subject_ids.join(",") + ")" : "(-1)"
laboratory_join = " AND subjects.id not in #{not_subject_ids} "
else
5 years ago
subject_ids = Subject.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: current_laboratory.id }).pluck(:id)
5 years ago
subject_ids = subject_ids.length > 0 ? "(" + subject_ids.join(",") + ")" : "(-1)"
laboratory_join = " AND subjects.id in #{subject_ids} "
end
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, subjects.excellent, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns
5 years ago
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}%' #{laboratory_join}
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, subjects.excellent, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns
5 years ago
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}%' #{laboratory_join}
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
# 云上实验室过滤
unless current_laboratory.main_site?
@subjects = @subjects.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: current_laboratory.id })
else
not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{current_laboratory.id}")
@subjects = @subjects.where.not(id: not_subject_ids)
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)
@is_manager = @user.manager_of_subject?(@subject)
# 合作团队
@shixuns = @subject.shixuns.published.pluck(:id)
@courses = @subject.courses if @subject.excellent
@members = @subject.subject_members.includes(:user)
# 访问数变更
@subject.increment!(:visits)
end
def right_banner
@user = current_user
# 合作团队
@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_subject_progress(challenge_ids)
end
def new
normal_status("")
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)
# 将实践课程标记为该云上实验室建立
Laboratory.current.laboratory_subjects.create!(subject: @subject, ownership: true)
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].strip if params[:search]
@type = params[:type]
# 超级管理员用户显示所有未隐藏的实训、非管理员显示合作团队用户的实训(对本单位公开且未隐藏)
if current_user.admin?
@shixuns = Shixun.select([:id, :name, :status, :myshixuns_count, :identifier, :averge_star]).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, :averge_star]).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)
unless params[:search].blank?
@shixuns = @shixuns.joins(:user).where("shixuns.name like ? or concat(users.lastname, users.firstname) like ?",
"%#{@search}%", "%#{@search}%").distinct
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 = @shixuns.reorder("created_at desc")
@shixuns_count = @shixuns.size
## 分页参数
page = params[:page] || 1
@shixuns = @shixuns.page(page).per(10)
@shixuns = @shixuns.includes(:myshixuns)
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)
## 云上实验室过滤
unless current_laboratory.main_site?
@courses = @courses.where(laboratory_id: current_laboratory.id )
end
@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
homework_ids = []
ActiveRecord::Base.transaction do
# 将实训课程下的所有已发布实训按顺序发送到课堂,同时创建与章节同名的实训作业目录
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
homework_ids << homework.id
end
end
end
homework_ids.each do |homework_id|
CreateStudentWorkJob.perform_later(homework_id)
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 = Educoder::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 update_team_title
tip_exception("team_title参数不能为空") if params[:team_title].blank?
@subject.update_attributes!(team_title: params[:team_title])
normal_status("更新成功")
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, ifnull(firstname, ''), login)) LIKE ?", member_ids, "#{condition}")
@users = @users.where(laboratory_id: current_laboratory.id) unless current_laboratory.main_site?
@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, "没权限操作") unless current_user.manager_of_subject?(@subject)
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 = CourseMember.where(course_id: school_courses.pluck(:id), role: 4).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
5 years ago
# 预约报名
def appointment
tip_exception("还存在未结束的课堂") unless @subject.max_course_end_date.nil? || @subject.max_course_end_date < Date.today
tip_exception("无需重复报名") if @subject.subject_appointments.exists?(user_id: current_user.id)
ActiveRecord::Base.transaction do
@subject.subject_appointments << SubjectAppointment.new(user_id: current_user.id)
@subject.increment!(:participant_count)
if @subject.participant_count == @subject.student_count
@subject.start_course_notify
end
normal_status("预约成功")
end
end
# 复制实践课程
def copy
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
# 用户进展和获取的标签
def user_subject_progress challenge_ids
pass_games = Game.select(:id, :cost_time, :challenge_id).where(status: 2, user_id: current_user.id, challenge_id: challenge_ids) if current_user.logged?
@all_score = Challenge.where(id: challenge_ids).size
# 如果没有通关的,没必要再继续统计了
if pass_games.blank?
@my_score = 0
@learned = 0
@time = 0
@user_tags = []
else
pass_challenge_ids = pass_games.map(&:challenge_id).uniq # 按道理是不用去重的,但是历史数据与重复
# subject_challenge_count = @subject.shixuns.sum(:challenges_count)
# 用户通关获得的标签
@user_tags = ChallengeTag.where(challenge_id: pass_challenge_ids).pluck(:name)
# 用户学习进度
@learned =
@all_score == 0 ? 0 :
((pass_challenge_ids.size.to_f / @all_score).round(2) * 100).to_i
# 用户通关分数
@my_score = Challenge.where(id: pass_challenge_ids).size
@time = pass_games.map(&:cost_time).sum
end
end
end