diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index db6ae7b57..d17059231 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -239,7 +239,7 @@ class ApplicationController < ActionController::Base uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous")) if !User.current.logged? && Rails.env.development? - User.current = User.find 57703 + User.current = User.find 8686 end @@ -567,6 +567,10 @@ class ApplicationController < ActionController::Base time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M:%S") end + def strf_date(date) + date.blank? ? '' : date.strftime("%Y-%m-%d") + end + def logger_error(error) Rails.logger.error(error.message) error.backtrace.each { |msg| Rails.logger.error(msg) } diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 75d515186..ce9c9af6c 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -13,7 +13,7 @@ class CoursesController < ApplicationController before_action :require_login, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups, :left_banner, :top_banner] - before_action :check_account, only: [:new, :create, :apply_to_join_course] + before_action :check_account, only: [:new, :create, :apply_to_join_course, :join_excellent_course] before_action :check_auth, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups, :left_banner, :top_banner, :apply_to_join_course, :exit_course] before_action :set_course, :user_course_identity, only: [:show, :update, :destroy, :settings, :set_invite_code_halt, @@ -25,12 +25,13 @@ class CoursesController < ApplicationController :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] + :switch_to_teacher, :switch_to_assistant, :switch_to_student, :exit_course, + :informs, :update_informs, :join_excellent_course, :online_learning] 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, :change_course_admin, - :set_course_group, :create_group_by_importing_file] + :set_course_group, :create_group_by_importing_file, :update_informs] before_action :teacher_or_admin_allowed, only: [:graduation_group_list, :create_graduation_group, :join_graduation_group, :change_course_teacher, :export_member_scores_excel, :course_group_list, :teacher_application_review, :apply_teachers, :delete_course_teacher] @@ -117,13 +118,19 @@ class CoursesController < ApplicationController 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 + if params[:subject_id].blank? + @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 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 + @course.start_date = params[:start_date] + @course.subject_id = params[:subject_id] + @course.excellent = true end @course.is_end = @course.end_date.present? && @course.end_date < Date.today @@ -133,6 +140,13 @@ class CoursesController < ApplicationController CourseInfo.create!(user_id: current_user.id, course_id: @course.id) CourseMember.create!(course_id: @course.id, user_id: current_user.id, role: 1) + # 将实践课程的教学团队成员以教师身份加入课堂 + if @course.subject + @course.subject.subject_members.where.not(user_id: current_user.id).each do |s_member| + CourseMember.create!(course_id: @course.id, user_id: s_member.user_id, role: 2) + end + end + course_module_types = params[:course_module_types] @course.create_course_modules(course_module_types) end @@ -151,7 +165,6 @@ class CoursesController < ApplicationController 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].blank? || course_params[:end_date].to_date > Date.today) extra_params[:is_end] = 0 @@ -162,13 +175,18 @@ class CoursesController < ApplicationController 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 + if @course.subject + @course.start_date = params[:start_date] 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 + extra_params[:is_public] = params[:is_public].present? ? params[:is_public] : 0 + @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 end @course.update_attributes!(course_params.merge(extra_params)) @@ -183,6 +201,42 @@ class CoursesController < ApplicationController end end + def join_excellent_course + tip_exception("您已是课堂成员") if current_user.member_of_course?(@course) + tip_exception("请通过邀请码加入课堂") unless @course.excellent + tip_exception("该课堂已结束") if @course.is_end + begin + new_student = CourseMember.new(user_id: current_user.id, course_id: @course.id, role: 4) + new_student.save! + + CourseAddStudentCreateWorksJob.perform_later(@course.id, [current_user.id]) + StudentJoinCourseNotifyJob.perform_later(current_user.id, @course.id) + normal_status(0, "加入成功") + rescue => e + uid_logger_error(e.message) + tip_exception(e.message) + end + end + + def informs + + end + + def update_informs + tip_exception("公告内容不能为空") if params[:description].blank? + inform = @course.inform || Inform.new(container: @course) + inform.description = params[:description] + inform.save! + normal_status("更新成功") + end + + def online_learning + @subject = @course.subject + @stages = @subject&.stages + @user = current_user + @start_learning = @user_course_identity == Course::STUDENT && @subject&.learning?(current_user.id) + end + def search_course_list search = params[:search] ? "%#{params[:search].strip}%" : "%%" @course_lists = CourseList.where("name like ?", "#{search}") @@ -1075,14 +1129,31 @@ class CoursesController < ApplicationController 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]) && + if params[:subject_id].blank? || @course.subject.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 + else + @subject = @course ? @course.subject : Subject.find_by!(id: params[:subject_id]) + tip_exception("开始时间不能为空") if params[:start_date].blank? + tip_exception("结束时间不能为空") if params[:end_date].blank? + tip_exception("结束时间必须晚于开始时间") if params[:end_date] <= params[:start_date] + tip_exception("开始时间和结束时间不能与往期开课时间重叠") if @course.nil? && @subject.max_course_end_date && params[:start_date] <= strf_date(@subject.max_course_end_date) + validate_start_end_date if @course.present? + tip_exception("开放课堂必须包含公告栏和在线学习模块") unless params[:course_module_types].include?("announcement") && params[:course_module_types].include?("online_learning") + end tip_exception("课堂所属单位不能为空!") if params[:school].blank? tip_exception("请至少添加一个课堂模块") if params[:course_module_types].blank? @school = School.find_by!(name: params[:school].strip) end + def validate_start_end_date + prev_course = @subject.courses.where("id < #{@course.id}").last + next_course = @subject.courses.where("id > #{@course.id}").first + tip_exception("开始时间和结束时间不能与其他期开课时间重叠") if prev_course && params[:start_date] <= strf_date(prev_course.end_date) + tip_exception("开始时间和结束时间不能与其他期开课时间重叠") if next_course && params[:end_date] >= strf_date(next_course.start_date) + end + # 超级管理员和课堂管理员的权限判断 def admin_allowed unless @user_course_identity < Course::PROFESSOR diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index 9b28d9a10..ce2154fea 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -25,13 +25,13 @@ class SubjectsController < ApplicationController 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 + subjects.shixuns_count, subjects.excellent, 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 + subjects.shixuns_count, subjects.excellent, 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") diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index f14159cc2..6a4353aa2 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -28,6 +28,10 @@ module CoursesHelper def module_url mod, course return nil if mod.blank? or course.blank? case mod.module_type + when "announcement" + "/courses/#{course.id}/informs" + when "online_learning" + "/courses/#{course.id}/online_learning" when "shixun_homework" "/courses/#{course.id}/shixun_homeworks/#{mod.id}" when "common_homework" @@ -261,4 +265,10 @@ module CoursesHelper group_info end + def last_subject_shixun user_id, subject + myshixun = Myshixun.where(user_id: user_id, shixun_id: subject&.shixuns).order("updated_at desc").first + return "" unless myshixun + stage_shixun = subject&.stage_shixuns.where(shixun_id: myshixun.shixun_id).take + progress = stage_shixun&.position.to_s + "-" + stage_shixun&.position.to_s + " " + myshixun.shixun&.name + end end diff --git a/app/helpers/stages_helper.rb b/app/helpers/stages_helper.rb index de6501fa6..e0df514e3 100644 --- a/app/helpers/stages_helper.rb +++ b/app/helpers/stages_helper.rb @@ -2,7 +2,7 @@ module StagesHelper # 章节实训的通关情况 def stage_myshixun_status shixun, user - myshixun = Myshixun.where(user_id: user.id, shixun_id: shixun.id).first + myshixun = Myshixun.where(user_id: user.id, shixun_id: shixun.id).take myshixun.try(:status) == 1 ? 1 : 0 end diff --git a/app/models/course.rb b/app/models/course.rb index 25a017faa..bab02be01 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -7,6 +7,10 @@ class Course < ApplicationRecord belongs_to :school, class_name: 'School', foreign_key: :school_id #定义一个方法school,该方法通过school_id来调用School表 belongs_to :course_list + # 所属实践课程 + belongs_to :subject, optional: true + has_one :inform, as: :container, dependent: :destroy + has_many :course_infos, dependent: :destroy # 课堂左侧导航栏的模块 has_many :course_modules, dependent: :destroy @@ -176,7 +180,7 @@ class Course < ApplicationRecord end def all_course_module_types - %w[activity shixun_homework common_homework group_homework graduation exercise poll attachment board course_group] + %w[activity announcement online_learning shixun_homework common_homework group_homework graduation exercise poll attachment board course_group] end def get_course_module_by_type(type) @@ -334,6 +338,8 @@ class Course < ApplicationRecord def get_name_by_type(type) case type when 'activity' then '动态' + when 'announcement' then '公告栏' + when 'online_learning' then '在线学习' when 'shixun_homework' then '实训作业' when 'common_homework' then '普通作业' when 'group_homework' then '分组作业' @@ -350,15 +356,17 @@ class Course < ApplicationRecord def get_position_by_type(type) case type when 'activity' then 1 - when 'shixun_homework' then 2 - when 'common_homework' then 3 - when 'group_homework' then 4 - when 'graduation' then 5 - when 'exercise' then 6 - when 'poll' then 7 - when 'attachment' then 8 - when 'board' then 9 - when 'course_group' then 10 + when 'announcement' then 2 + when 'online_learning' then 3 + when 'shixun_homework' then 4 + when 'common_homework' then 5 + when 'group_homework' then 6 + when 'graduation' then 7 + when 'exercise' then 8 + when 'poll' then 9 + when 'attachment' then 10 + when 'board' then 11 + when 'course_group' then 12 else 100 end end diff --git a/app/models/inform.rb b/app/models/inform.rb new file mode 100644 index 000000000..faf1d48e6 --- /dev/null +++ b/app/models/inform.rb @@ -0,0 +1,3 @@ +class Inform < ApplicationRecord + belongs_to :container, polymorphic: true, optional: true +end diff --git a/app/models/subject.rb b/app/models/subject.rb index eb8930e3b..113460375 100644 --- a/app/models/subject.rb +++ b/app/models/subject.rb @@ -18,6 +18,9 @@ class Subject < ApplicationRecord has_many :tidings, as: :container, dependent: :destroy has_many :stages, -> { order("stages.position ASC") }, dependent: :destroy + # 开放课堂 + has_many :courses, -> { order("courses.id ASC") } + validates :name, length: { maximum: 40 } validates :description, length: { maximum: 5000 } validates :learning_notes, length: { maximum: 500 } @@ -31,6 +34,11 @@ class Subject < ApplicationRecord self.tidings << Tiding.new(user_id: self.user_id, trigger_user_id: self.user_id, belong_container_id: self.id, belong_container_type: 'Subject', tiding_type: "System", viewed: 0) end + # 所有开课课堂的最大结束时间 + def max_course_end_date + courses.pluck(:end_date).max + end + # 挑战过路径的成员数 def member_count shixuns.pluck(:myshixuns_count).sum @@ -92,4 +100,8 @@ class Subject < ApplicationRecord challenges = Challenge.where(shixun_id: shixuns.unhidden) @tags = ChallengeTag.where(challenge_id: challenges).pluck(:name).uniq end + + def learning? user_id + Myshixun.where(user_id: user_id, shixun_id: shixuns).exists? + end end \ No newline at end of file diff --git a/app/views/courses/index.json.jbuilder b/app/views/courses/index.json.jbuilder index 7b404211b..8a0d06475 100644 --- a/app/views/courses/index.json.jbuilder +++ b/app/views/courses/index.json.jbuilder @@ -12,5 +12,6 @@ json.courses @courses do |course| json.is_accessible course.is_public == 1 || @user.course_identity(course) < Course::NORMAL json.is_end course.is_end json.first_category_url module_url(course.none_hidden_course_modules.first, course) + json.excellent course.excellent end json.courses_count @courses_count diff --git a/app/views/courses/informs.json.jbuilder b/app/views/courses/informs.json.jbuilder new file mode 100644 index 000000000..d584be917 --- /dev/null +++ b/app/views/courses/informs.json.jbuilder @@ -0,0 +1 @@ +json.description @course.inform&.description \ No newline at end of file diff --git a/app/views/courses/online_learning.json.jbuilder b/app/views/courses/online_learning.json.jbuilder new file mode 100644 index 000000000..bec8ff301 --- /dev/null +++ b/app/views/courses/online_learning.json.jbuilder @@ -0,0 +1,11 @@ +json.stages @stages do |stage| + json.partial! 'stages/stage', locals: {stage: stage, user:@user, subject:@subject} +end + +json.description @subject&.description + +json.start_learning @start_learning + +json.learned @start_learning ? @subject&.my_subject_progress : 0 + +json.last_shixun @start_learning ? last_subject_shixun(@user.id, @subject) : "" \ No newline at end of file diff --git a/app/views/courses/settings.json.jbuilder b/app/views/courses/settings.json.jbuilder index 8c82d15ea..1a67fbe27 100644 --- a/app/views/courses/settings.json.jbuilder +++ b/app/views/courses/settings.json.jbuilder @@ -9,4 +9,6 @@ json.end_date @course.end_date json.is_public @course.is_public json.course_module_types @course.course_modules.where(hidden: 0).pluck(:module_type) json.authentication @course.authentication -json.professional_certification @course.professional_certification \ No newline at end of file +json.professional_certification @course.professional_certification +json.subject_id @course.subject_id +json.excellent @course.excellent \ No newline at end of file diff --git a/app/views/courses/top_banner.json.jbuilder b/app/views/courses/top_banner.json.jbuilder index c0a1ff956..916fccb05 100644 --- a/app/views/courses/top_banner.json.jbuilder +++ b/app/views/courses/top_banner.json.jbuilder @@ -21,6 +21,7 @@ json.switch_to_assistant switch_assistant_role(@is_student, @course, @user) #json.join_course !@user.member_of_course?(@course) #json.copy_course !@user.member_of_course?(@course) && @user.is_teacher? json.course_identity @user_course_identity +json.excellent @course.excellent if @course.is_end == 0 json.days_remaining (@course.end_date.to_date - Time.now.to_date).to_i end diff --git a/app/views/subjects/_subject.json.jbuilder b/app/views/subjects/_subject.json.jbuilder index b9a322530..fb52578dd 100644 --- a/app/views/subjects/_subject.json.jbuilder +++ b/app/views/subjects/_subject.json.jbuilder @@ -1,5 +1,6 @@ json.array! subjects do |subject| json.id subject.id + json.excellent subject.excellent json.image_url url_to_avatar(subject) json.name subject.name json.tag_name subject.repertoire.try(:name) diff --git a/app/views/users/get_user_info.json.jbuilder b/app/views/users/get_user_info.json.jbuilder index fc2eca762..24f7b21b0 100644 --- a/app/views/users/get_user_info.json.jbuilder +++ b/app/views/users/get_user_info.json.jbuilder @@ -14,6 +14,7 @@ if @course json.course_identity @course_identity json.course_name @course.name json.course_public @course.is_public + json.course_excellent @course.excellent if params[:group_info] json.group_info @course.teacher_group(@user.id) if @course_identity < Course::STUDENT end diff --git a/config/routes.rb b/config/routes.rb index 9e115c3a9..45690fbad 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -346,6 +346,10 @@ Rails.application.routes.draw do post 'switch_to_assistant' post 'switch_to_student' post 'exit_course' + get 'informs' + post 'update_informs' + get 'online_learning' + post 'join_excellent_course' end collection do diff --git a/db/migrate/20190813015633_add_new_column_to_course.rb b/db/migrate/20190813015633_add_new_column_to_course.rb new file mode 100644 index 000000000..cfadc4ce4 --- /dev/null +++ b/db/migrate/20190813015633_add_new_column_to_course.rb @@ -0,0 +1,8 @@ +class AddNewColumnToCourse < ActiveRecord::Migration[5.2] + def change + add_column :courses, :start_date, :date + add_column :courses, :subject_id, :integer, default: 0 + + add_index :courses, :subject_id + end +end diff --git a/db/migrate/20190813074730_add_excellent_to_courses.rb b/db/migrate/20190813074730_add_excellent_to_courses.rb new file mode 100644 index 000000000..c83fcc702 --- /dev/null +++ b/db/migrate/20190813074730_add_excellent_to_courses.rb @@ -0,0 +1,5 @@ +class AddExcellentToCourses < ActiveRecord::Migration[5.2] + def change + add_column :courses, :excellent, :boolean, default: false + end +end diff --git a/dump.rdb b/dump.rdb index 63b8abb0a..c4edd44ed 100644 Binary files a/dump.rdb and b/dump.rdb differ diff --git a/spec/models/inform_spec.rb b/spec/models/inform_spec.rb new file mode 100644 index 000000000..0bcf9eceb --- /dev/null +++ b/spec/models/inform_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Inform, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end