Merge branch 'dev_aliyun' into dev_cxt2

dev_local_2
cxt 6 years ago
commit 4f231f3d9a

@ -92,6 +92,6 @@ class Admins::ShixunSettingsController < Admins::BaseController
end end
def setting_params def setting_params
params.permit(:use_scope,:excute_time,:close,:status,:can_copy,:webssh,:hidden,:homepage_show,:task_pass,:code_hidden,:id,tag_repertoires:[]) params.permit(:use_scope,:excute_time,:close,:status,:can_copy,:webssh,:hidden,:homepage_show,:task_pass,:code_hidden,:page_no, :id,tag_repertoires:[])
end end
end end

@ -12,10 +12,10 @@ class CoursesController < ApplicationController
end end
before_action :require_login, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups, before_action :require_login, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups,
:left_banner, :top_banner, :informs, :online_learning] :left_banner, :top_banner, :informs, :online_learning, :course_groups]
before_action :check_account, only: [:new, :create, :apply_to_join_course, :join_excellent_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, 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] :left_banner, :top_banner, :apply_to_join_course, :exit_course, :course_groups]
before_action :set_course, only: [:show, :update, :destroy, :settings, :set_invite_code_halt, before_action :set_course, only: [:show, :update, :destroy, :settings, :set_invite_code_halt,
:set_public_or_private, :search_teacher_candidate, :teachers, :apply_teachers, :set_public_or_private, :search_teacher_candidate, :teachers, :apply_teachers,
:top_banner, :left_banner, :add_teacher_popup, :add_teacher, :top_banner, :left_banner, :add_teacher_popup, :add_teacher,
@ -27,7 +27,8 @@ class CoursesController < ApplicationController
:attahcment_category_list,:export_member_scores_excel, :duplicate_course, :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, :online_learning, :update_task_position, :tasks_list, :informs, :update_informs, :online_learning, :update_task_position, :tasks_list,
:join_excellent_course, :export_couser_info, :export_member_act_score, :new_informs, :delete_informs] :join_excellent_course, :export_couser_info, :export_member_act_score, :new_informs,
:delete_informs, :change_member_role, :course_groups, :join_course_group]
before_action :user_course_identity, except: [:join_excellent_course, :index, :create, :new, :apply_to_join_course, before_action :user_course_identity, except: [:join_excellent_course, :index, :create, :new, :apply_to_join_course,
:search_course_list, :get_historical_course_students, :mine, :search_slim, :board_list] :search_course_list, :get_historical_course_students, :mine, :search_slim, :board_list]
before_action :teacher_allowed, only: [:update, :destroy, :settings, :search_teacher_candidate, before_action :teacher_allowed, only: [:update, :destroy, :settings, :search_teacher_candidate,
@ -39,7 +40,7 @@ class CoursesController < ApplicationController
:set_course_group, :create_group_by_importing_file, :set_course_group, :create_group_by_importing_file,
:update_task_position, :tasks_list] :update_task_position, :tasks_list]
before_action :teacher_or_admin_allowed, only: [:graduation_group_list, :create_graduation_group, :join_graduation_group, before_action :teacher_or_admin_allowed, only: [:graduation_group_list, :create_graduation_group, :join_graduation_group,
:change_course_teacher, :course_group_list, :change_course_teacher, :course_group_list, :change_member_role,
:teacher_application_review, :apply_teachers, :delete_course_teacher] :teacher_application_review, :apply_teachers, :delete_course_teacher]
before_action :validate_course_name, only: [:create, :update] before_action :validate_course_name, only: [:create, :update]
before_action :find_board, only: :board_list before_action :find_board, only: :board_list
@ -340,8 +341,8 @@ class CoursesController < ApplicationController
@has_graduation_design = @course.course_modules.graduation_module_not_hidden.any? @has_graduation_design = @course.course_modules.graduation_module_not_hidden.any?
sort = params[:sort] || "desc" sort = params[:sort] || "asc"
@order = params[:order].to_i @order = params[:order] ? params[:order].to_i : 1
if @order.present? if @order.present?
case @order case @order
when 1 when 1
@ -547,6 +548,61 @@ class CoursesController < ApplicationController
end end
end end
# 修改角色
def change_member_role
tip_exception("请至少选择一个角色") if params[:roles].blank?
tip_exception("不能具有老师、助教两种角色") if params[:roles].include?("PROFESSOR") && params[:roles].include?("ASSISTANT_PROFESSOR")
tip_exception("管理员不能切换为助教或老师") if params[:user_id].to_i == @course.tea_id &&
(params[:roles].include?("PROFESSOR") || params[:roles].include?("ASSISTANT_PROFESSOR"))
course_members = @course.course_members.where(user_id: params[:user_id])
tip_exception("非课堂成员不能修改角色") if course_members.blank?
ActiveRecord::Base.transaction do
# 第一次修改为教师或助教身份时直接创建数据
if params[:roles].include?("CREATOR")
teacher_member = course_members.where(role: %i[CREATOR]).take
elsif (params[:roles].include?("PROFESSOR") || params[:roles].include?("ASSISTANT_PROFESSOR")) && !course_members.exists?(role: %i[PROFESSOR ASSISTANT_PROFESSOR])
teacher_member = CourseMember.create!(course_id: @course.id, user_id: params[:user_id], role: params[:roles].include?("PROFESSOR") ? 2 : 3)
elsif course_members.exists?(role: %i[PROFESSOR ASSISTANT_PROFESSOR])
teacher_member = course_members.where(role: %i[PROFESSOR ASSISTANT_PROFESSOR]).take
if params[:roles].include?("PROFESSOR") || params[:roles].include?("ASSISTANT_PROFESSOR")
# 如果之前有老师身份且老师身份要调整时只需要修改role字段
if !params[:roles].include?(teacher_member.role) && params[:roles].include?("PROFESSOR")
teacher_member.PROFESSOR!
elsif !params[:roles].include?(teacher_member.role) && params[:roles].include?("ASSISTANT_PROFESSOR")
teacher_member.ASSISTANT_PROFESSOR!
end
teacher_member.save!
else
# 不含教师的参数时删除记录
teacher_member.destroy!
# CourseDeleteStudentNotifyJob.perform_later(@course.id, [teacher_member.user_id], current_user.id)
end
end
# 学生身份的处理
student_member = course_members.where(role: %i[STUDENT]).take
if params[:roles].include?("STUDENT") && student_member.blank?
correspond_teacher_exist = CourseMember.exists?(user_id: params[:user_id], is_active: 1, course_id: @course.id, role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR])
new_student = CourseMember.new(user_id: params[:user_id], course_id: @course.id, role: 4)
new_student.is_active = 0 if correspond_teacher_exist
new_student.save!
CourseAddStudentCreateWorksJob.perform_later(@course.id, [params[:user_id]])
# StudentJoinCourseNotifyJob.perform_later(current_user.id, course.id)
elsif !params[:roles].include?("STUDENT") && student_member.present?
# 删除学生身份时激活老师身份
teacher_member.update_attributes!(is_active: 1) if student_member.is_active && teacher_member.present?
student_member.destroy!
CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, [params[:user_id]])
# CourseDeleteStudentNotifyJob.perform_later(@course.id, [params[:user_id]], current_user.id)
end
normal_status(0, "修改成功")
end
end
# 教师和助教角色转换的接口 # 教师和助教角色转换的接口
def change_course_teacher def change_course_teacher
begin begin
@ -715,8 +771,8 @@ class CoursesController < ApplicationController
# 学生列表(包括各个子分班的学生列表)及搜索 # 学生列表(包括各个子分班的学生列表)及搜索
def students def students
search = params[:search].present? ? params[:search].strip : nil search = params[:search].present? ? params[:search].strip : nil
order = params[:order].present? ? params[:order].to_i : 0 order = params[:order].present? ? params[:order].to_i : 1
sort = params[:sort].present? ? params[:sort] : "desc" sort = params[:sort].present? ? params[:sort] : "asc"
course_group_id = params[:course_group_id].present? ? params[:course_group_id].to_i : nil course_group_id = params[:course_group_id].present? ? params[:course_group_id].to_i : nil
@students = CourseMember.students(@course) @students = CourseMember.students(@course)
@ -766,6 +822,26 @@ class CoursesController < ApplicationController
end end
end end
# 分班列表
def course_groups
@course_groups = @course.course_groups
@course_groups = @course_groups.where("name like ?", "%#{params[:search]}%") unless params[:search].blank?
@all_group_count = @course_groups.size
@teachers = @course.teachers.includes(:user, :teacher_course_groups) if @user_course_identity < Course::NORMAL
@current_group_id = @course.students.where(user_id: current_user.id).take&.course_group_id if @user_course_identity == Course::STUDENT
end
# 学生自动加入分班
def join_course_group
tip_exception("学生才能加入分班") if @user_course_identity != Course::STUDENT
course_group = CourseGroup.find_by!(id: params[:course_group_id], course_id: @course.id)
member = CourseMember.find_by!(user_id: current_user.id, course_id: @course.id, role: 4)
if course_group && member
member.update_attributes!(course_group_id: course_group.id)
normal_status(0, "加入成功")
end
end
# 将学生批量移动到某个分班 # 将学生批量移动到某个分班
def transfer_to_course_group def transfer_to_course_group
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do

@ -683,12 +683,34 @@ class ExercisesController < ApplicationController
end end
end end
# 详情页的立即发布弹框
def publish_groups
@current_user = current_user
# 可立即发布的分班:当前用户管理的分班去除已发布的分班
group_ids = @course.charge_group_ids(@current_user) - @exercise.exercise_group_settings.exercise_group_published.pluck(:course_group_id)
@course_groups = @course.course_groups.where(id: group_ids)
@group_settings = @exercise.exercise_group_settings.where(course_group_id: group_ids)
end
#首页批量或单独 立即发布,应是跳出弹窗,设置开始时间和截止时间。 #首页批量或单独 立即发布,应是跳出弹窗,设置开始时间和截止时间。
def publish def publish
tip_exception("缺少截止时间参数") if params[:end_time].blank? if params[:detail].blank?
tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) tip_exception("缺少截止时间参数") if params[:end_time].blank?
tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now)
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
else
group_end_times = params[:group_end_times].reject(&:blank?).map{|time| time.to_time}
group_ids = params[:group_ids].reject(&:blank?)
tip_exception("缺少截止时间参数") if group_end_times.blank?
tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length
group_end_times.each do |time|
tip_exception("分班截止时间不能早于当前时间") if time <= Time.now
tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && time > @course.end_date.end_of_day
end
end
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
check_ids = Exercise.where(id: params[:check_ids]) check_ids = Exercise.where(id: params[:check_ids])
@ -702,28 +724,30 @@ class ExercisesController < ApplicationController
.exercise_group_not_published.present? ? 1 : 0 .exercise_group_not_published.present? ? 1 : 0
end end
if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过 if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过
g_course = params[:group_ids] #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改 g_course = group_ids #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改
tiding_group_ids = g_course tiding_group_ids = g_course
if g_course if g_course
user_course_groups = @course.charge_group_ids(current_user) user_course_groups = @course.course_groups.pluck(:id)
if g_course.map(&:to_i).sort == user_course_groups.sort # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置 if g_course.map(&:to_i).sort == user_course_groups.sort &&
((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?) # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置
exercise.exercise_group_settings.destroy_all exercise.exercise_group_settings.destroy_all
ex_unified = true ex_unified = true
e_time = ex_end_time e_time = params[:detail] ? group_end_times.max : ex_end_time
tiding_group_ids = [] tiding_group_ids = []
else else
ex_unified = false ex_unified = false
g_course.each do |i| g_course.each_with_index do |i, index|
exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id",i).first #根据课堂分班的id寻找试卷所在的班级 exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id",i).first #根据课堂分班的id寻找试卷所在的班级
group_end_time = params[:detail] ? group_end_times[index] : ex_end_time
if exercise_group_setting #如果该试卷分组存在,则更新,否则新建 if exercise_group_setting #如果该试卷分组存在,则更新,否则新建
exercise_group_setting.update_attributes(publish_time:Time.now,end_time:ex_end_time) exercise_group_setting.update_attributes(publish_time: Time.now, end_time: group_end_time)
else else
p_course_group = { p_course_group = {
:exercise_id => exercise.id, :exercise_id => exercise.id,
:course_group_id => i, :course_group_id => i,
:course_id => exercise.course.id, :course_id => exercise.course.id,
:publish_time => Time.now, :publish_time => Time.now,
:end_time => ex_end_time, :end_time => group_end_time,
} }
new_exercise_group = exercise.exercise_group_settings.new p_course_group new_exercise_group = exercise.exercise_group_settings.new p_course_group
new_exercise_group.save new_exercise_group.save
@ -954,7 +978,8 @@ class ExercisesController < ApplicationController
:status => nil, :status => nil,
:commit_status => 0, :commit_status => 0,
:objective_score => 0.0, :objective_score => 0.0,
:subjective_score => -1.0 :subjective_score => -1.0,
:commit_method => 0
} }
redo_exercise_users = @exercise_users.exercise_commit_users(user_ids) redo_exercise_users = @exercise_users.exercise_commit_users(user_ids)
redo_exercise_users.update_all(redo_option) redo_exercise_users.update_all(redo_option)
@ -1077,22 +1102,39 @@ class ExercisesController < ApplicationController
def commit_exercise def commit_exercise
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 can_commit_exercise = false
objective_score = calculate_student_score(@exercise,current_user)[:total_score] if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时
subjective_score = @answer_committed_user.subjective_score if params[:commit_method].to_i == 2 #自动提交时
total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score user_left_time = get_exercise_left_time(@exercise,current_user)
total_score = objective_score + total_score_subjective_score Rails.logger.info("######__________auto_commit_user_left_time_________################{user_left_time}")
commit_option = { if user_left_time.to_i <= 0
can_commit_exercise = true
end
else
can_commit_exercise = true
end
if can_commit_exercise
objective_score = calculate_student_score(@exercise,current_user)[:total_score]
subjective_score = @answer_committed_user.subjective_score
total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score
total_score = objective_score + total_score_subjective_score
commit_option = {
:status => 1, :status => 1,
:commit_status => 1, :commit_status => 1,
:end_at => Time.now, :end_at => Time.now,
:objective_score => objective_score, :objective_score => objective_score,
:score => total_score, :score => total_score,
:subjective_score => subjective_score :subjective_score => subjective_score,
} :commit_method => @answer_committed_user&.commit_method.to_i > 0 ? @answer_committed_user&.commit_method.to_i : params[:commit_method].to_i
@answer_committed_user.update_attributes(commit_option) }
CommitExercsieNotifyJobJob.perform_later(@exercise.id, current_user.id) @answer_committed_user.update_attributes(commit_option)
normal_status(0,"试卷提交成功!") CommitExercsieNotifyJobJob.perform_later(@exercise.id, current_user.id)
normal_status(0,"试卷提交成功!")
else
normal_status(-1,"提交失败,未到截止时间!")
end
else
normal_status(-1,"提交失败,当前用户不为课堂学生!")
end end
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)

@ -1036,6 +1036,7 @@ class HomeworkCommonsController < ApplicationController
# 可立即发布的分班:当前用户管理的分班去除已发布的分班 # 可立即发布的分班:当前用户管理的分班去除已发布的分班
group_ids = @course.charge_group_ids(@current_user) - @homework.homework_group_settings.group_published.pluck(:course_group_id) group_ids = @course.charge_group_ids(@current_user) - @homework.homework_group_settings.group_published.pluck(:course_group_id)
@course_groups = @course.course_groups.where(id: group_ids) @course_groups = @course.course_groups.where(id: group_ids)
@group_settings = @homework.homework_group_settings.where(course_group_id: group_ids)
else else
tip_exception("没有可发布的分班") tip_exception("没有可发布的分班")
end end
@ -1043,16 +1044,28 @@ class HomeworkCommonsController < ApplicationController
def publish_homework def publish_homework
tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0 tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0
tip_exception("缺少截止时间参数") if params[:end_time].blank? if params[:detail].blank?
tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) tip_exception("缺少截止时间参数") if params[:end_time].blank?
tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now)
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
else
group_end_times = params[:group_end_times].reject(&:blank?).map{|time| time.to_time}
group_ids = params[:group_ids].reject(&:blank?)
tip_exception("缺少截止时间参数") if group_end_times.blank?
tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length
group_end_times.each do |time|
tip_exception("分班截止时间不能早于当前时间") if time <= Time.now
tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && time > @course.end_date.end_of_day
end
end
homeworks = @course.homework_commons.where(id: params[:homework_ids]) homeworks = @course.homework_commons.where(id: params[:homework_ids])
homeworks = homeworks.includes(:homework_group_settings, :homework_detail_manual) homeworks = homeworks.includes(:homework_group_settings, :homework_detail_manual)
charge_group_ids = @course.charge_group_ids(current_user) charge_group_ids = @course.charge_group_ids(current_user)
publish_groups = charge_group_ids & params[:group_ids] if params[:group_ids] publish_groups = charge_group_ids & group_ids if group_ids
# ActiveRecord::Base.transaction do # ActiveRecord::Base.transaction do
begin begin
@ -1062,18 +1075,26 @@ class HomeworkCommonsController < ApplicationController
if !params[:group_ids].blank? if !params[:group_ids].blank?
# 全选即统一设置unified_setting为true # 全选即统一设置unified_setting为true
if @course.course_groups.where(id: publish_groups).size == @course.course_groups.size if @course.course_groups.where(id: publish_groups).size == @course.course_groups.size &&
((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?)
homework.homework_group_settings.destroy_all homework.homework_group_settings.destroy_all
homework.unified_setting = true homework.unified_setting = true
homework.end_time = params[:end_time] homework.end_time = params[:detail] ? group_end_times.max : params[:end_time]
else else
homework.unified_setting = false homework.unified_setting = false
# 创建作业分班设置homework_group_setting # 创建作业分班设置homework_group_setting
create_homework_group_settings(homework) create_homework_group_settings(homework)
# 选中的分班设置的发布时间改为当前时间,截止时间改为传的截止时间参数 # 选中的分班设置的发布时间改为当前时间,截止时间改为传的截止时间参数
homework.homework_group_settings.where(course_group_id: publish_groups).update_all(publish_time: Time.now, if params[:detail]
end_time: params[:end_time]) group_ids.each_with_index do |group_id, index|
homework.homework_group_settings.find_by(course_group_id: group_id)&.update_attributes!(publish_time: Time.now,
end_time: group_end_times[index])
end
else
homework.homework_group_settings.where(course_group_id: publish_groups).update_all(publish_time: Time.now,
end_time: params[:end_time])
end
# 发消息 # 发消息
tiding_group_ids = publish_groups tiding_group_ids = publish_groups
end end
@ -1086,7 +1107,7 @@ class HomeworkCommonsController < ApplicationController
# 截止时间的处理 # 截止时间的处理
if homework.end_time.nil? if homework.end_time.nil?
homework.end_time = params[:end_time] homework.end_time = params[:detail] ? group_end_times.max : params[:end_time]
elsif homework.max_group_end_time elsif homework.max_group_end_time
homework.end_time = homework.max_group_end_time homework.end_time = homework.max_group_end_time
end end
@ -1101,12 +1122,22 @@ class HomeworkCommonsController < ApplicationController
create_homework_group_settings(homework) create_homework_group_settings(homework)
none_publish_settings = homework.homework_group_settings.where(course_group_id: publish_groups).none_published none_publish_settings = homework.homework_group_settings.where(course_group_id: publish_groups).none_published
none_publish_settings.update_all(publish_time: Time.now, end_time: params[:end_time]) if params[:detail]
group_ids.each_with_index do |group_id, index|
none_publish_settings.find_by(course_group_id: group_id)&.update_attributes!(publish_time: Time.now,
end_time: group_end_times[index])
end
else
none_publish_settings.update_all(publish_time: Time.now, end_time: params[:end_time])
end
if homework.max_group_end_time if homework.max_group_end_time
homework.end_time = homework.max_group_end_time homework.end_time = homework.max_group_end_time
end end
HomeworkCommonPushNotifyJob.perform_later(homework.id, none_publish_settings.pluck(:course_group_id)) HomeworkCommonPushNotifyJob.perform_later(homework.id, none_publish_settings.pluck(:course_group_id))
end end
if homework.end_time > Time.now && homework.homework_detail_manual.try(:comment_status) > 1 if homework.end_time > Time.now && homework.homework_detail_manual.try(:comment_status) > 1
homework.homework_detail_manual.update_attribute("comment_status", 1) homework.homework_detail_manual.update_attribute("comment_status", 1)
end end

@ -2,10 +2,10 @@ class PollsController < ApplicationController
# before_action :check_poll_status 问卷的发消息和定时任务没有做 # before_action :check_poll_status 问卷的发消息和定时任务没有做
before_action :require_login, :check_auth,except: [:index] before_action :require_login, :check_auth,except: [:index]
before_action :find_course, except: [:show,:poll_setting,:commit_setting,:edit,:update,:start_answer,:commit_poll, before_action :find_course, except: [:show,:poll_setting,:commit_setting,:edit,:update,:start_answer,:commit_poll,
:commit_result,:poll_lists,:cancel_publish,:cancel_publish_modal,:common_header] :commit_result,:poll_lists,:cancel_publish,:cancel_publish_modal,:common_header,:publish_groups]
before_action :get_poll_and_course, only: [:show,:poll_setting,:commit_setting,:edit,:update,:start_answer, before_action :get_poll_and_course, only: [:show,:poll_setting,:commit_setting,:edit,:update,:start_answer,
:commit_poll,:commit_result,:poll_lists,:cancel_publish, :commit_poll,:commit_result,:poll_lists,:cancel_publish,
:cancel_publish_modal,:common_header] :cancel_publish_modal,:common_header, :publish_groups]
before_action :user_course_identity before_action :user_course_identity
before_action :is_course_teacher, except: [:index,:start_answer,:poll_setting,:commit_poll,:commit_result,:poll_lists,:common_header] #判断是否为课堂老师 before_action :is_course_teacher, except: [:index,:start_answer,:poll_setting,:commit_poll,:commit_result,:poll_lists,:common_header] #判断是否为课堂老师
before_action :check_user_status before_action :check_user_status
@ -242,12 +242,35 @@ class PollsController < ApplicationController
end end
end end
end end
# 详情页的立即发布弹框
def publish_groups
@current_user = current_user
# 可立即发布的分班:当前用户管理的分班去除已发布的分班
group_ids = @course.charge_group_ids(@current_user) - @poll.poll_group_settings.poll_group_published.pluck(:course_group_id)
@course_groups = @course.course_groups.where(id: group_ids)
@group_settings = @poll.poll_group_settings.where(course_group_id: group_ids)
end
#首页批量或单独 立即发布,应是跳出弹窗,设置开始时间和截止时间。 #首页批量或单独 立即发布,应是跳出弹窗,设置开始时间和截止时间。
def publish def publish
tip_exception("缺少截止时间参数") if params[:end_time].blank? if params[:detail].blank?
tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) tip_exception("缺少截止时间参数") if params[:end_time].blank?
tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now)
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
else
group_end_times = params[:group_end_times].reject(&:blank?).map{|time| time.to_time}
group_ids = params[:group_ids].reject(&:blank?)
tip_exception("缺少截止时间参数") if group_end_times.blank?
tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length
group_end_times.each do |time|
tip_exception("分班截止时间不能早于当前时间") if time <= Time.now
tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && time > @course.end_date.end_of_day
end
end
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
check_ids = Poll.where(id: params[:check_ids]) check_ids = Poll.where(id: params[:check_ids])
@ -259,26 +282,28 @@ class PollsController < ApplicationController
pl_status = poll.poll_group_settings.find_in_poll_group("course_group_id",params[:group_ids]).poll_group_not_published.present? ? 1 : 0 #立即发布针对分组设置的全部未发布的班级才生效 pl_status = poll.poll_group_settings.find_in_poll_group("course_group_id",params[:group_ids]).poll_group_not_published.present? ? 1 : 0 #立即发布针对分组设置的全部未发布的班级才生效
end end
if pl_status == 1 #如果问卷存在已发布的,或者是已截止的,那么则直接跳过 if pl_status == 1 #如果问卷存在已发布的,或者是已截止的,那么则直接跳过
g_course = params[:group_ids] #表示是否传入分班参数,如果传入分班的参数那么poll的统一设置需修改 g_course = group_ids #表示是否传入分班参数,如果传入分班的参数那么poll的统一设置需修改
if g_course if g_course
user_course_groups = @course.charge_group_ids(current_user) user_course_groups = @course.course_groups.pluck(:id)
if g_course.map(&:to_i).sort == user_course_groups.sort # 如果是设置为全部班级,则问卷不用分组,且问卷设定为统一设置,否则则分组设置 if g_course.map(&:to_i).sort == user_course_groups.sort &&
((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?) # 如果是设置为全部班级,则问卷不用分组,且问卷设定为统一设置,否则则分组设置
poll.poll_group_settings.destroy_all poll.poll_group_settings.destroy_all
poll_unified = true poll_unified = true
e_time = ex_end_time e_time = params[:detail] ? group_end_times.max : ex_end_time
else else
poll_unified = false poll_unified = false
g_course.each do |i| g_course.each_with_index do |i, index|
poll_group_setting = poll.poll_group_settings.find_in_poll_group("course_group_id",i).first #根据课堂分班的id寻找问卷所在的班级 poll_group_setting = poll.poll_group_settings.find_in_poll_group("course_group_id",i).first #根据课堂分班的id寻找问卷所在的班级
group_end_time = params[:detail] ? group_end_times[index] : ex_end_time
if poll_group_setting #如果该问卷分组存在,则更新,否则新建 if poll_group_setting #如果该问卷分组存在,则更新,否则新建
poll_group_setting.update_attributes(publish_time:Time.now,end_time:ex_end_time) poll_group_setting.update_attributes(publish_time: Time.now, end_time: group_end_time)
else else
p_course_group = { p_course_group = {
:poll_id => poll.id, :poll_id => poll.id,
:course_group_id => i, :course_group_id => i,
:course_id => poll.course.id, :course_id => poll.course.id,
:publish_time => Time.now, :publish_time => Time.now,
:end_time => ex_end_time, :end_time => group_end_time,
} }
new_poll_group = poll.poll_group_settings.new p_course_group new_poll_group = poll.poll_group_settings.new p_course_group
new_poll_group.save new_poll_group.save

@ -90,23 +90,25 @@ class QuestionBanksController < ApplicationController
def send_to_course def send_to_course
banks = @object_type.classify.constantize.where(id: params[:object_id]) banks = @object_type.classify.constantize.where(id: params[:object_id])
course = current_user.manage_courses.find_by!(id: params[:course_id]) course = current_user.manage_courses.find_by!(id: params[:course_id])
task_ids = []
banks.each do |bank| banks.each do |bank|
case @object_type case @object_type
when 'HomeworkBank' # 作业 when 'HomeworkBank' # 作业
quote_homework_bank bank, course task = quote_homework_bank bank, course
when 'ExerciseBank' when 'ExerciseBank'
if bank.container_type == 'Exercise' # 试卷 if bank.container_type == 'Exercise' # 试卷
quote_exercise_bank bank, course task = quote_exercise_bank bank, course
else # 问卷 else # 问卷
quote_poll_bank bank, course task = quote_poll_bank bank, course
end end
when 'GtaskBank' when 'GtaskBank'
quote_gtask_bank bank, course task = quote_gtask_bank bank, course
when 'GtopicBank' when 'GtopicBank'
quote_gtopic_bank bank, course task = quote_gtopic_bank bank, course
end end
task_ids << task.id if task
end end
normal_status("发送成功") render :json => {task_ids: task_ids, status: 0, message: "发送成功"}
end end
def destroy def destroy

@ -1,6 +1,18 @@
module CoursesHelper module CoursesHelper
# 是否有切换为学生的入口 def member_manager group, teachers
str = ""
members = teachers.select{|teacher| teacher.teacher_course_groups.pluck(:course_group_id).include?(group.id) || teacher.teacher_course_groups.size == 0}
str = members.uniq.size == teachers.size ? "全部教师" : members.map{|member| member.user.real_name}.join("")
str
# teachers.each do |member|
# if member.teacher_course_groups.exists?(course_group_id: group.id) || member.teacher_course_groups.size == 0
# str << member.user.real_name
# end
# end
end
# 是否有切换为学生的入口
def switch_student_role is_teacher, course, user def switch_student_role is_teacher, course, user
is_teacher && course.course_members.where(user_id: user.id, role: %i(STUDENT)).exists? is_teacher && course.course_members.where(user_id: user.id, role: %i(STUDENT)).exists?
end end

@ -19,7 +19,8 @@ class EndExerciseCalculateJob < ApplicationJob
:end_at => Time.now, :end_at => Time.now,
:objective_score => objective_score, :objective_score => objective_score,
:score => total_score, :score => total_score,
:subjective_score => user_sub_score :subjective_score => user_sub_score,
:commit_method => user&.commit_method.to_i > 0 ? user&.commit_method.to_i : 4
} }
user.update_attributes(commit_option) user.update_attributes(commit_option)
end end

@ -48,8 +48,8 @@ module Util
return if str.blank? return if str.blank?
case type case type
when :phone then "#{str[0..2]}***#{str[-4..-1]}" when :phone then "#{str[0..2]}***#{str[-3..-1]}"
when :email then "#{str[0..2]}***#{str[str.rindex('@')..-1]}" when :email then "#{str[0]}***#{str[(str.rindex('@')-1)..-1]}"
else "#{str[0..2]}***#{str[-3..-1]}" else "#{str[0..2]}***#{str[-3..-1]}"
end end
end end

@ -1,4 +1,5 @@
class ExerciseUser < ApplicationRecord class ExerciseUser < ApplicationRecord
# commit_method 0 为默认, 1为学生的手动提交2为倒计时结束后自动提交3为试卷定时截止的自动提交, 4为教师手动的立即截止
belongs_to :user belongs_to :user
belongs_to :exercise belongs_to :exercise

@ -1,5 +1,6 @@
class Shixun < ApplicationRecord class Shixun < ApplicationRecord
include Searchable::Shixun include Searchable::Shixun
attr_accessor :page_no #管理员页面 实训配置更新状态时需要接受page_no参数
# status: 0编辑 1申请发布 2正式发布 3关闭 -1软删除 # status: 0编辑 1申请发布 2正式发布 3关闭 -1软删除
# hide_code 隐藏代码窗口 # hide_code 隐藏代码窗口

@ -242,6 +242,11 @@ class User < ApplicationRecord
user_extension&.department&.name || '' user_extension&.department&.name || ''
end end
# 课堂的所有身份
def course_role course
course.course_members.where(user_id: id).pluck(:role)
end
# 课堂的老师(创建者、老师、助教) # 课堂的老师(创建者、老师、助教)
def teacher_of_course?(course) def teacher_of_course?(course)
course.course_members.exists?(user_id: id, role: [1,2,3], is_active: 1) || admin? || business? course.course_members.exists?(user_id: id, role: [1,2,3], is_active: 1) || admin? || business?
@ -583,6 +588,16 @@ class User < ApplicationRecord
mail.present? mail.present?
end end
# 手机号123***123
def hidden_phone
Util.conceal(phone, :phone).to_s
end
# 邮箱w***l@qq.com
def hidden_mail
Util.conceal(mail, :email).to_s
end
# 学院的url标识 # 学院的url标识
def college_identifier def college_identifier
Department.find_by_id(department_members.pluck(:department_id).first)&.identifier Department.find_by_id(department_members.pluck(:department_id).first)&.identifier

@ -66,7 +66,8 @@ class ExercisePublishTask
:end_at => Time.now, :end_at => Time.now,
:objective_score => s_score, :objective_score => s_score,
:score => total_score, :score => total_score,
:subjective_score => subjective_score :subjective_score => subjective_score,
:commit_method => exercise_user&.commit_method.to_i > 0 ? exercise_user&.commit_method.to_i : 3
} }
exercise_user.update_attributes(commit_option) exercise_user.update_attributes(commit_option)
end end
@ -108,7 +109,8 @@ class ExercisePublishTask
:end_at => Time.now, :end_at => Time.now,
:objective_score => s_score, :objective_score => s_score,
:score => total_score, :score => total_score,
:subjective_score => subjective_score :subjective_score => subjective_score,
:commit_method => exercise_user&.commit_method.to_i > 0 ? exercise_user&.commit_method.to_i : 3
} }
exercise_user.update_attributes(commit_option) exercise_user.update_attributes(commit_option)
end end

@ -0,0 +1,11 @@
json.course_groups @course_groups.each do |group|
json.(group, :id, :course_members_count, :name)
json.invite_code group.invite_code if @user_course_identity < Course::STUDENT
json.member_manager member_manager(group, @teachers) if @user_course_identity < Course::NORMAL
end
if @user_course_identity == Course::STUDENT
json.current_group_id @current_group_id
end
json.none_group_member_count @course.none_group_count
json.group_count @all_group_count

@ -1,12 +1,17 @@
json.students do json.students do
json.array! @students do |student| json.array! @students do |student|
json.user_id student.user_id json.user_id student.user_id
json.login student.user.try(:login) # json.login student.user.try(:login)
json.name student.user.try(:real_name) json.name student.user.try(:real_name)
json.name_link user_path(student.user) json.name_link user_path(student.user)
json.student_id student.user.try(:student_id) json.student_id student.user.try(:student_id)
json.course_group_name student.course_group.try(:name) json.course_group_name student.course_group.try(:name)
json.course_member_id student.id json.course_member_id student.id
if @user_course_identity < Course::ASSISTANT_PROFESSOR && !params[:course_group_id].present?
json.member_roles student.user.course_role(@course)
end
json.user_phone student.user.hidden_phone
json.user_mail student.user.hidden_mail
end end
end end
json.students_count @students_count json.students_count @students_count

@ -16,6 +16,9 @@ json.teacher_list do
end end
json.graduation_group teacher.graduation_group.try(:name) json.graduation_group teacher.graduation_group.try(:name)
json.graduation_group_id teacher.graduation_group.try(:id) json.graduation_group_id teacher.graduation_group.try(:id)
if @user_course_identity < Course::ASSISTANT_PROFESSOR
json.member_roles teacher.user.course_role(@course)
end
end end
end end
json.teacher_list_size @teacher_list_size json.teacher_list_size @teacher_list_size

@ -8,6 +8,7 @@ json.user_group_name ex_user_info[:user_group_name]
json.student_id ex_user_info[:student_id] json.student_id ex_user_info[:student_id]
json.commit_status ex_user_info[:commit_status] json.commit_status ex_user_info[:commit_status]
json.end_at ex_user_info[:end_at] json.end_at ex_user_info[:end_at]
json.commit_method exercise_user&.commit_method.to_i
if subjective_type == 1 if subjective_type == 1
json.objective_score ex_user_info[:ex_object_score] json.objective_score ex_user_info[:ex_object_score]
json.subjective_score ex_user_info[:ex_subject_score] json.subjective_score ex_user_info[:ex_subject_score]

@ -9,6 +9,7 @@ json.exercise_answer_user do
json.user_id ex_answerer.id json.user_id ex_answerer.id
json.login ex_answerer.login json.login ex_answerer.login
if exercise_user.present? if exercise_user.present?
json.commit_method exercise_user&.commit_method.to_i
json.start_at exercise_user.start_at json.start_at exercise_user.start_at
json.score exercise_user.score.present? ? exercise_user.score.round(1).to_s : "0.0" json.score exercise_user.score.present? ? exercise_user.score.round(1).to_s : "0.0"
end end

@ -1,6 +1,6 @@
json.course_is_end @course.is_end # true表示已结束false表示未结束 json.course_is_end @course.is_end # true表示已结束false表示未结束
json.extract! @exercise, :id,:exercise_name,:exercise_description,:show_statistic json.extract! @exercise, :id,:exercise_name,:exercise_description,:show_statistic
json.time @user_left_time json.time (@user_left_time.to_i / 60)
json.exercise_status @ex_status json.exercise_status @ex_status

@ -0,0 +1,6 @@
json.course_groups @course_groups do |group|
json.id group.id
json.name group.name
json.end_time @group_settings.select{|group_setting| group_setting.course_group_id == group.id}.first&.end_time
end
json.end_time @exercise.end_time

@ -3,3 +3,4 @@ json.task_status task_curr_status(graduation, course)[:status]
json.task_name graduation.name json.task_name graduation.name
json.task_id graduation.id json.task_id graduation.id
json.status graduation.status json.status graduation.status
json.end_time graduation.end_time

@ -1,4 +1,6 @@
json.course_groups @course_groups do |group| json.course_groups @course_groups do |group|
json.id group.id json.id group.id
json.name group.name json.name group.name
json.end_time @group_settings.select{|group_setting| group_setting.course_group_id == group.id}.first&.end_time
end end
json.end_time @homework.end_time

@ -0,0 +1,6 @@
json.course_groups @course_groups do |group|
json.id group.id
json.name group.name
json.end_time @group_settings.select{|group_setting| group_setting.course_group_id == group.id}.first&.end_time
end
json.end_time @poll.end_time

@ -1,5 +1,7 @@
json.extract! observed_user, :id, :nickname, :phone, :mail, :show_realname json.extract! observed_user, :id, :nickname, :show_realname
json.phone observed_user.hidden_phone
json.mail observed_user.hidden_mail
json.avatar_url url_to_avatar(observed_user) json.avatar_url url_to_avatar(observed_user)
user = ActiveDecorator::Decorator.instance.decorate(observed_user) user = ActiveDecorator::Decorator.instance.decorate(observed_user)
json.name user.name json.name user.name

@ -331,6 +331,7 @@ Rails.application.routes.draw do
post 'join_graduation_group' post 'join_graduation_group'
post 'set_course_group' post 'set_course_group'
post 'change_course_admin' post 'change_course_admin'
post 'change_member_role'
post 'change_course_teacher' post 'change_course_teacher'
post 'delete_course_teacher' post 'delete_course_teacher'
post 'teacher_application_review' post 'teacher_application_review'
@ -369,6 +370,8 @@ Rails.application.routes.draw do
post 'join_excellent_course' post 'join_excellent_course'
get 'tasks_list' get 'tasks_list'
post 'update_task_position' post 'update_task_position'
get 'course_groups'
post 'join_course_group'
end end
collection do collection do
@ -584,6 +587,7 @@ Rails.application.routes.draw do
post :cancel_publish #撤销发布 post :cancel_publish #撤销发布
get :cancel_publish_modal #撤销发布的弹窗 get :cancel_publish_modal #撤销发布的弹窗
get :common_header get :common_header
get :publish_groups
end end
resources :poll_questions,only:[:new,:create] resources :poll_questions,only:[:new,:create]
end end
@ -615,6 +619,7 @@ Rails.application.routes.draw do
get :exercise_result get :exercise_result
post :cancel_exercise post :cancel_exercise
get :begin_commit #提交前的弹窗 get :begin_commit #提交前的弹窗
get :publish_groups
end end
resources :exercise_questions,only:[:new,:create,:index] resources :exercise_questions,only:[:new,:create,:index]
end end

@ -0,0 +1,5 @@
class AddCommitMethodToExerciseUser < ActiveRecord::Migration[5.2]
def change
add_column :exercise_users, :commit_method, :integer, :default => 0
end
end

@ -84,9 +84,9 @@ export function initAxiosInterceptors(props) {
} }
config.url = `${proxy}${url}`; config.url = `${proxy}${url}`;
if (config.url.indexOf('?') == -1) { if (config.url.indexOf('?') == -1) {
config.url = `${config.url}?debug=${debugType}`; config.url = `${config.url}?debug=${'student'}`;
} else { } else {
config.url = `${config.url}&debug=${debugType}`; config.url = `${config.url}&debug=${'student'}`;
} }
} else { } else {
// 加api前缀 // 加api前缀

@ -8,15 +8,21 @@ class WordsBtn extends Component {
} }
render() { render() {
let{to, href,targets}=this.props let{to, href,targets, style2 }=this.props
return( return(
<React.Fragment> <React.Fragment>
{ {
to==undefined&&targets==undefined ? to==undefined&&targets==undefined ?
<a href={href || "javascript:void(0)"} onClick={this.props.onClick} className={"btn "+`${map[this.props.style]} ${this.props.className}`}>{this.props.children}</a>: <a href={href || "javascript:void(0)"} onClick={this.props.onClick} className={"btn "+`${map[this.props.style]} ${this.props.className}`}
targets!=undefined? <a href={to} target="_blank" className={"btn "+`${map[this.props.style]} ${this.props.className}`}>{this.props.children}</a> style={style2}
>{this.props.children}</a>:
targets!=undefined? <a href={to} target="_blank" className={"btn "+`${map[this.props.style]} ${this.props.className}`}
style={style2}
>{this.props.children}</a>
: :
<Link to={to} className={"btn "+`${map[this.props.style]} ${this.props.className}`}>{this.props.children}</Link> <Link to={to} className={"btn "+`${map[this.props.style]} ${this.props.className}`}
style={style2}
>{this.props.children}</Link>
} }
</React.Fragment> </React.Fragment>
) )

@ -85,3 +85,7 @@
white-space:nowrap; white-space:nowrap;
cursor: default; cursor: default;
} }
.changeRolePop .ant-checkbox-group {
width: 230px !important;
}

@ -127,22 +127,25 @@ class ExerciseReviewAndAnswer extends Component{
} }
//自动交卷 //自动交卷
autoCommitExercise=()=>{ autoCommitExercise=()=>{
let eId=this.props.match.params.Id; let eId=this.props.match.params.Id;
let url=`/exercises/${eId}/commit_exercise.json`; let url=`/exercises/${eId}/commit_exercise.json`;
axios.post(url).then((result)=>{ axios.post(url,{
if(result){ commit_method:2
this.setState({ }).then((result)=>{
Modalstype:true, if(result){
Modalstopval:'答题结束了,系统已自动提交试卷', this.setState({
modalsBottomval:"不能再修改答题", Modalstype:true,
ModalCancel:undefined, Modalstopval:'答题结束了,系统已自动提交试卷',
ModalSave:this.sureCommit, modalsBottomval:"不能再修改答题",
Loadtype:true ModalCancel:undefined,
}) ModalSave:this.sureCommit,
} Loadtype:true
}).catch((error)=>{ })
console.log(error); this.props.showNotification(`${result.data.message}`);
}) }
}).catch((error)=>{
console.log(error);
})
} }
sureCommit=()=>{ sureCommit=()=>{
@ -485,7 +488,9 @@ class ExerciseReviewAndAnswer extends Component{
//交卷 //交卷
let eId=this.props.match.params.Id; let eId=this.props.match.params.Id;
let url=`/exercises/${eId}/commit_exercise.json`; let url=`/exercises/${eId}/commit_exercise.json`;
axios.post(url).then((result)=>{ axios.post(url,{
commit_method:1
}).then((result)=>{
if(result){ if(result){
this.setState({ this.setState({
Modalstype:false, Modalstype:false,

@ -0,0 +1,72 @@
import React, { useState, useEffect } from 'react'
import { trigger, WordsBtn } from 'educoder'
import { Input, Checkbox, Popconfirm } from "antd";
import axios from 'axios'
/**
角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生
*/
function ChangeRolePop({ member_roles = [], record, courseId, onChangeRoleSuccess, showNotification }) {
const [checkBoxRoles, setCheckBoxRoles] = useState(member_roles)
useEffect(() => {
setCheckBoxRoles(member_roles)
}, [member_roles])
function onCheckBoxChange(val) {
console.log(val)
const isTeacher = checkBoxRoles.indexOf('PROFESSOR')
const isAssitant = checkBoxRoles.indexOf('ASSISTANT_PROFESSOR')
const isTeacherNew = val.indexOf('PROFESSOR')
const isAssitantNew = val.indexOf('ASSISTANT_PROFESSOR')
if (isTeacherNew > -1 && isTeacher == -1 && isAssitantNew > -1) {
val.splice(isAssitantNew, 1)
}
if (isAssitantNew > -1 && isAssitant == -1 && isTeacherNew > -1) {
val.splice(isTeacherNew, 1)
}
setCheckBoxRoles(val)
}
function onCancel() {
setCheckBoxRoles(member_roles)
}
const onConfirm = async () => {
if (checkBoxRoles && checkBoxRoles.length == 0) {
showNotification('请至少选择一个角色')
return;
}
const url = `/courses/${courseId}/change_member_role.json`
const response = await axios.post(url, {
roles: checkBoxRoles,
user_id: record.user_id
})
if (response.data.status == 0) {
onChangeRoleSuccess()
}
console.log(response)
}
const isAdmin = checkBoxRoles.indexOf('CREATOR') != -1
const isTeacher = checkBoxRoles.indexOf('PROFESSOR') != -1
const isAssitant = checkBoxRoles.indexOf('ASSISTANT_PROFESSOR') != -1
const isStudent = checkBoxRoles.indexOf('STUDENT') != -1
return (
<Popconfirm
overlayClassName="changeRolePop"
placement="bottom"
icon={null}
onConfirm={onConfirm}
onCancel={onCancel}
title={
<Checkbox.Group style={{ width: '100%' }} onChange={onCheckBoxChange} value={checkBoxRoles}>
{isAdmin && <Checkbox disabled={isAdmin} value="CREATOR">管理员</Checkbox>}
{!isAdmin && <Checkbox value="PROFESSOR">教师</Checkbox>}
<Checkbox disabled={isAdmin} value="ASSISTANT_PROFESSOR">助教</Checkbox>
<Checkbox value="STUDENT">学生</Checkbox>
</Checkbox.Group>
}
>
<WordsBtn style={'blue'}>修改角色</WordsBtn>
</Popconfirm>
)
}
export default ChangeRolePop

@ -0,0 +1,3 @@
.stu_table .ant-table-thead > tr > th, .stu_table .ant-table-tbody > tr > td {
padding: 14px 6px;
}

@ -1,5 +1,5 @@
import React,{ Component } from "react"; import React,{ Component } from "react";
import { Input,Checkbox,Table, Pagination, Modal,Menu ,Spin, Tooltip , Divider } from "antd"; import { Input,Checkbox,Table, Pagination, Modal,Menu ,Spin, Tooltip , Divider, Popconfirm } from "antd";
import ClipboardJS from 'clipboard' import ClipboardJS from 'clipboard'
import '../css/Courses.css' import '../css/Courses.css'
import '../css/members.css' import '../css/members.css'
@ -14,6 +14,8 @@ import _ from 'lodash'
import NoneData from "../coursesPublic/NoneData" import NoneData from "../coursesPublic/NoneData"
import DownloadMessageysl from "../../modals/DownloadMessageysl"; import DownloadMessageysl from "../../modals/DownloadMessageysl";
import CreateGroupByImportModal from './modal/CreateGroupByImportModal' import CreateGroupByImportModal from './modal/CreateGroupByImportModal'
import ChangeRolePop from './ChangeRolePop'
import "./studentsList.css"
const Search =Input.Search; const Search =Input.Search;
const TYPE_STUDENTS = 1 const TYPE_STUDENTS = 1
@ -22,6 +24,7 @@ const TYPE_COURSE_GOURP_CHILD = 3
const buildColumns = (that,isParent) => { const buildColumns = (that,isParent) => {
const { course_groups , sortedInfo } = that.state const { course_groups , sortedInfo } = that.state
let showSorter = isParent==true let showSorter = isParent==true
const courseId = that.props.match.params.coursesId
const columns=[{ const columns=[{
title: '序号', title: '序号',
dataIndex: 'id', dataIndex: 'id',
@ -32,19 +35,21 @@ const buildColumns = (that,isParent) => {
render: (id, student, index) => { render: (id, student, index) => {
return (that.state.page - 1) * 20 + index + 1 return (that.state.page - 1) * 20 + index + 1
} }
}, { },
title: '用户id', // {
dataIndex: 'login', // title: '用户id',
key: 'login', // dataIndex: 'login',
align:'center', // key: 'login',
width:"10%", // align:'center',
className:"color-grey-6", // width:"10%",
render: (login, record) => { // className:"color-grey-6",
return <span className="color-dark overflowHidden1" style={{maxWidth: '160px'}} // render: (login, record) => {
title={login && login.length > 10 ? login : ''} // return <span className="color-dark overflowHidden1" style={{maxWidth: '160px'}}
>{login}</span> // title={login && login.length > 10 ? login : ''}
} // >{login}</span>
}, { // }
// },
{
title: '姓名', title: '姓名',
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
@ -69,14 +74,45 @@ const buildColumns = (that,isParent) => {
return <span className="color-dark overflowHidden1 " title={student_id && student_id.length > 10 ? student_id : ''} return <span className="color-dark overflowHidden1 " title={student_id && student_id.length > 10 ? student_id : ''}
style={{maxWidth: '160px'}} >{student_id}</span> style={{maxWidth: '160px'}} >{student_id}</span>
} }
}]; }
, {
title: '手机号',
dataIndex: 'user_phone',
key: 'user_phone',
align:'center',
width:"10%",
className:"color-grey-6",
// sorter: true,
// sortDirections: sortDirections,
// sortOrder: sortedInfo.columnKey === 'user_phone' && sortedInfo.order,
render: (user_phone, record) => {
return <span className="color-dark overflowHidden1 " title={user_phone && user_phone.length > 10 ? user_phone : ''}
style={{maxWidth: '160px'}} >{user_phone}</span>
}
}
, {
title: '邮箱',
dataIndex: 'user_mail',
key: 'user_mail',
align:'center',
width:"10%",
className:"color-grey-6",
// sorter: true,
// sortDirections: sortDirections,
// sortOrder: sortedInfo.columnKey === 'user_mail' && sortedInfo.order,
render: (user_mail, record) => {
return <span className="color-dark overflowHidden1 " title={user_mail && user_mail.length > 10 ? user_mail : ''}
style={{maxWidth: '160px'}} >{user_mail}</span>
}
}
];
if (course_groups && course_groups.length) { if (course_groups && course_groups.length) {
columns.push({ columns.push({
title: '分班', title: '分班',
dataIndex: 'course_group_name', dataIndex: 'course_group_name',
key: 'course_group_name', key: 'course_group_name',
align:'center', align:'center',
width:"40%", width:"25%",
className:"color-grey-6", className:"color-grey-6",
sorter:showSorter, sorter:showSorter,
sortDirections: sortDirections, sortDirections: sortDirections,
@ -95,14 +131,36 @@ const buildColumns = (that,isParent) => {
const isAdmin = that.props.isAdmin() const isAdmin = that.props.isAdmin()
if (isAdmin) { if (isAdmin) {
columns.unshift({ columns.unshift({
title: '', title: '',
dataIndex: 'check', dataIndex: 'check',
key: 'check', key: 'check',
render: (text, item) => { render: (text, item) => {
return <Checkbox value={item.course_member_id} key={item.course_member_id} ></Checkbox> return <Checkbox value={item.course_member_id} key={item.course_member_id} ></Checkbox>
}, },
width:"5%" width:"5%"
}) })
columns.push({
title: '操作',
key: 'action',
width: '20%',
align:'center',
render: (text, record) => {
return (
<React.Fragment>
<WordsBtn style2={{ marginRight: '12px' }} onClick={() => that.onDelete(record)} style={'grey'}>删除学生</WordsBtn>
<ChangeRolePop
courseId={courseId}
record={record}
member_roles={record.member_roles}
onChangeRoleSuccess={that.onChangeRoleSuccess}
showNotification={that.props.showNotification}
></ChangeRolePop>
</React.Fragment>
)
},
})
} }
return columns; return columns;
@ -242,7 +300,9 @@ class studentsList extends Component{
onChange=()=>{ onChange=()=>{
} }
onChangeRoleSuccess = () => {
this.fetchAll()
}
componentDidMount() { componentDidMount() {
this.setState({ this.setState({
isSpin:true isSpin:true
@ -451,11 +511,13 @@ class studentsList extends Component{
} }
} }
// 多选 // 多选
onDelete = () => { onDelete = (record) => {
const len = this.state.checkBoxValues.length if (!record) {
if (len == 0) { const len = this.state.checkBoxValues.length
this.props.showNotification('请先从列表选择要删除的学生') if (len == 0) {
return; this.props.showNotification('请先从列表选择要删除的学生')
return;
}
} }
this.props.confirm({ this.props.confirm({
@ -465,7 +527,7 @@ class studentsList extends Component{
let id = this.props.match.params.coursesId let id = this.props.match.params.coursesId
let url=`/courses/${id}/delete_from_course.json`; let url=`/courses/${id}/delete_from_course.json`;
axios.post((url), { axios.post((url), {
students: this.state.checkBoxValues.map(item => {return {course_member_id: item} }), students: [{course_member_id: record.course_member_id}] // this.state.checkBoxValues.map(item => {return {course_member_id: item} }),
}).then((result)=>{ }).then((result)=>{
if (result.data.status == 0) { if (result.data.status == 0) {
this.props.showNotification('删除成功') this.props.showNotification('删除成功')
@ -701,7 +763,7 @@ class studentsList extends Component{
<div className="clearfix stu_head" style={{paddingLeft: '15px'}}> <div className="clearfix stu_head" style={{paddingLeft: '15px'}}>
{isAdmin && <Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue} >已选 {checkBoxValues.length} </Checkbox>} {isAdmin && <Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue} >已选 {checkBoxValues.length} </Checkbox>}
<div className="studentList_operation_ul"> <div className="studentList_operation_ul">
{isAdmin && <li className="li_line"><a href="javascript:void(0)" className="color-grey-9" onClick={this.onDelete}>删除</a></li>} {/* {isAdmin && <li className="li_line"><a href="javascript:void(0)" className="color-grey-9" onClick={this.onDelete}>删除</a></li>} */}
{isAdmin && <li className="drop_down"> {isAdmin && <li className="drop_down">
移动到...<i className="iconfont icon-xiajiantou font-12 ml2"></i> 移动到...<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu" style={{"right":"0px","left":"unset", width: '200px', maxHeight: '324px', overflowY: 'auto'}}> <ul className="drop_down_menu" style={{"right":"0px","left":"unset", width: '200px', maxHeight: '324px', overflowY: 'auto'}}>
@ -752,7 +814,7 @@ class studentsList extends Component{
</div> </div>
<Spin size="large" spinning={this.state.isSpin}> <Spin size="large" spinning={this.state.isSpin}>
<div className="clearfix stu_table"> <div className="clearfix stu_table">
{!this.state.isSpin && <Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}> {students && students.length && <Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
<Table columns={buildColumns(this,isParent)} dataSource={students} onChange={this.onTableChange} pagination={false}></Table> <Table columns={buildColumns(this,isParent)} dataSource={students} onChange={this.onTableChange} pagination={false}></Table>
</Checkbox.Group> } </Checkbox.Group> }
</div> </div>

@ -1,5 +1,5 @@
import React,{ Component } from "react"; import React,{ Component } from "react";
import { Input,Checkbox,Table, Divider, Tooltip,Spin, Menu } from "antd"; import { Input,Checkbox,Table, Divider, Tooltip,Spin, Menu, Popconfirm } from "antd";
import CourseLayoutcomponent from '../common/CourseLayoutComponent' import CourseLayoutcomponent from '../common/CourseLayoutComponent'
import NoneData from "../coursesPublic/NoneData" import NoneData from "../coursesPublic/NoneData"
@ -24,6 +24,7 @@ import AddAdminModal from './modal/AddAdminModal'
import CourseGroupChooserModal from './modal/CourseGroupChooserModal' import CourseGroupChooserModal from './modal/CourseGroupChooserModal'
import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from './common' import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from './common'
import CourseGroupChooser from './CourseGroupChooser' import CourseGroupChooser from './CourseGroupChooser'
import ChangeRolePop from './ChangeRolePop'
const Search = Input.Search; const Search = Input.Search;
const ROLE_ADMIN = "管理员" const ROLE_ADMIN = "管理员"
@ -38,6 +39,8 @@ function buildColumns(that) {
const isAdminOrTeacher = that.props.isAdminOrTeacher() const isAdminOrTeacher = that.props.isAdminOrTeacher()
const { course_groups, filterKey } = that.state const { course_groups, filterKey } = that.state
const showSorter = filterKey == '1' const showSorter = filterKey == '1'
const courseId = that.props.match.params.coursesId
const columns = [{ const columns = [{
title: '序号', title: '序号',
dataIndex: 'name', dataIndex: 'name',
@ -117,7 +120,7 @@ function buildColumns(that) {
const hasGraduationModule = that.hasGraduationModule() const hasGraduationModule = that.hasGraduationModule()
if (hasGraduationModule && showSorter) { if (hasGraduationModule && showSorter) {
columns.push({ columns.push({
title: '答辩组', title: '所在答辩组',
// width: 90, // width: 90,
sorter: showSorter, sorter: showSorter,
sortDirections: sortDirections, sortDirections: sortDirections,
@ -141,6 +144,9 @@ function buildColumns(that) {
width: 150, width: 150,
align:'center', align:'center',
render: (text, record) => { render: (text, record) => {
const isAdmin = record.role == ROLE_ADMIN
const isTeacher = record.role == ROLE_TEACHER
const isAssitant = record.role == ROLE_TEACHER_ASSISTANT
if (record.application_id) { if (record.application_id) {
return ( return (
<span> <span>
@ -149,16 +155,43 @@ function buildColumns(that) {
<a onClick={() => that.onAgree(record)} style={{color: '#4CACFF'}}>同意</a> <a onClick={() => that.onAgree(record)} style={{color: '#4CACFF'}}>同意</a>
</span> ) </span> )
} else { } else {
return ( return (
<span> <React.Fragment>
{record.role != ROLE_ADMIN && <WordsBtn onClick={() => that.onDelete(record)} style={'grey'}>删除</WordsBtn>} <WordsBtn style2={{ marginRight: '12px' }} onClick={() => that.onDelete(record)} style={'grey'}>删除</WordsBtn>
{(record.role == ROLE_TEACHER || record.role == ROLE_TEACHER_ASSISTANT || isAdminOrCreator) && record.role != ROLE_ADMIN <ChangeRolePop
&& <Divider type="vertical" />} courseId={courseId}
{ record.role == ROLE_TEACHER ? <a style={{color: '#4CACFF'}} onClick={() => that.changeToAssistant(record)}>变更为助教</a> : '' } record={record}
{ record.role == ROLE_TEACHER_ASSISTANT ? <a style={{color: '#4CACFF'}} onClick={() => that.changeToTeacher(record)}>变更为教师</a> : '' } member_roles={record.member_roles}
{ record.role == ROLE_ADMIN && isAdminOrCreator ? <a style={{color: '#4CACFF', marginLeft: '44px'}} onClick={() => that.showChangeAdminModal(record)}>更换管理员</a> : '' } onChangeRoleSuccess={that.onChangeRoleSuccess}
showNotification={that.props.showNotification}
></ChangeRolePop>
{/* <Popconfirm
placement="bottom"
icon={null}
title={
<React.Fragment>
<Checkbox disable={isAdmin}>管理员</Checkbox>
<Checkbox disable={isAdmin}>助教</Checkbox>
<Checkbox >学生</Checkbox>
</React.Fragment>
}
>
<WordsBtn style={'blue'}>修改角色</WordsBtn>
</Popconfirm> */}
</React.Fragment>
</span> )
// <span>
// {record.role != ROLE_ADMIN && <WordsBtn onClick={() => that.onDelete(record)} style={'grey'}>删除</WordsBtn>}
// {(record.role == ROLE_TEACHER || record.role == ROLE_TEACHER_ASSISTANT || isAdminOrCreator) && record.role != ROLE_ADMIN
// && <Divider type="vertical" />}
// { record.role == ROLE_TEACHER ? <a style={{color: '#4CACFF'}} onClick={() => that.changeToAssistant(record)}>变更为助教</a> : '' }
// { record.role == ROLE_TEACHER_ASSISTANT ? <a style={{color: '#4CACFF'}} onClick={() => that.changeToTeacher(record)}>变更为教师</a> : '' }
// { record.role == ROLE_ADMIN && isAdminOrCreator ? <a style={{color: '#4CACFF', marginLeft: '44px'}} onClick={() => that.showChangeAdminModal(record)}>更换管理员</a> : '' }
// </span>
)
} }
}, },
@ -344,6 +377,9 @@ class studentsList extends Component{
console.log(error); console.log(error);
}); });
} }
onChangeRoleSuccess = () => {
this.fetchAll()
}
fetchAll = async (argPage) => { fetchAll = async (argPage) => {
this.setState({ this.setState({
isSpin:true isSpin:true

@ -2627,9 +2627,11 @@ class Listofworksstudentone extends Component {
// return // return
// } // }
this.setState({ this.setState({
loadingstate: true loadingstate: true,
page:1,
limit:20,
}) })
this.Startsortingt(this.state.orders, this.state.course_groupyslstwo, this.state.checkedValuesineinfo, value, this.state.page, this.state.limit); this.Startsortingt(this.state.orders, this.state.course_groupyslstwo, this.state.checkedValuesineinfo, value, 1,20);
// console.log(value) // console.log(value)
@ -2641,9 +2643,11 @@ class Listofworksstudentone extends Component {
// this.onSearch(); // this.onSearch();
// console.log("使用了回车键"); // console.log("使用了回车键");
this.setState({ this.setState({
loadingstate: true loadingstate: true,
page:1,
limit:20,
}) })
this.Startsortingt(this.state.orders, this.state.course_groupyslstwo, this.state.checkedValuesineinfo, this.state.searchtext, this.state.page, this.state.limit); this.Startsortingt(this.state.orders, this.state.course_groupyslstwo, this.state.checkedValuesineinfo, this.state.searchtext, 1,20);
} }
} }
//排序 //排序

@ -354,8 +354,8 @@ class ShixunhomeWorkItem extends Component{
<span className="mr50 df"> <span className="mr50 df">
{/* <a href="/users/innov" className="panel-name-small hide fl mr15 mr30 color-grey3">{discussMessage.author.name}</a> */} {/* <a href="/users/innov" className="panel-name-small hide fl mr15 mr30 color-grey3">{discussMessage.author.name}</a> */}
{ discussMessage.author && <span className="mr15 color-grey-3">{discussMessage.author}</span> } { discussMessage.author && <span className="mr15 color-grey-3">{discussMessage.author}</span> }
{discussMessage.commit_count===undefined?"":<span className="mr15 color-grey9">{discussMessage.commit_count} 已交</span>} {discussMessage.commit_count===undefined?"":<span className="mr15 color-grey9">已开始做题 {discussMessage.commit_count}</span>}
{discussMessage.uncommit_count===undefined?"":<span className="mr15 color-grey9">{discussMessage.uncommit_count} 未交</span>} {discussMessage.uncommit_count===undefined?"":<span className="mr15 color-grey9">未开始做题 {discussMessage.uncommit_count}</span>}
{/*<span className="mr15 color-grey9">{discussMessage.replies_count} 3 未评</span>*/} {/*<span className="mr15 color-grey9">{discussMessage.replies_count} 3 未评</span>*/}
{ {
@ -381,7 +381,7 @@ class ShixunhomeWorkItem extends Component{
{ {
discussMessage && discussMessage.upper_category_name && discussMessage && discussMessage.upper_category_name &&
<ConditionToolTip title={discussMessage.upper_category_name} condition={ discussMessage.upper_category_name.length > 22 }> <ConditionToolTip title={discussMessage.upper_category_name} condition={ discussMessage.upper_category_name.length > 22 }>
{ <span className="mr15 color-grey9 task-hide" style={discussMessage.time_status===1||discussMessage.time_status===2||discussMessage.time_status===3||discussMessage.time_status===4?{"maxWidth":"200px"}:{"maxWidth":"272px"}} title={discussMessage.upper_category_name}>{discussMessage.upper_category_name}</span>} { <span className="mr15 color-grey9 task-hide" style={discussMessage.time_status===1||discussMessage.time_status===2||discussMessage.time_status===3||discussMessage.time_status===4?{"maxWidth":"111px"}:{"maxWidth":"272px"}} title={discussMessage.upper_category_name}>{discussMessage.upper_category_name}</span>}
</ConditionToolTip> </ConditionToolTip>
} }

Loading…
Cancel
Save