diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 4ce1d7487..4bfc236a1 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -269,9 +269,10 @@ class CoursesController < ApplicationController def online_learning @subject = @course.subject - @stages = @course.course_stages + @stages = @course.course_stages.includes(:shixuns) @user = current_user - @start_learning = @user_course_identity == Course::STUDENT && @course.learning?(current_user.id) + @myshixuns = @user.myshixuns.where(shixun_id: @course.course_stage_shixuns.pluck(:shixun_id)) + @start_learning = @user_course_identity == Course::STUDENT && @myshixuns.present? end def search_course_list @@ -307,8 +308,8 @@ class CoursesController < ApplicationController def destroy if @course.is_delete == 0 @course.delete! - Tiding.create!(user_id: @course.tea_id, trigger_user_id: 0, container_id: @course.id, - container_type: 'Course', tiding_type: 'Delete', extra: @course.name) + Tiding.create!(user_id: current_user.id, trigger_user_id: current_user.id, container_id: @course.id, + container_type: 'DeleteCourse', tiding_type: 'System', belong_container: @course, extra: @course.name) normal_status(0, "成功") else normal_status(-1, "课堂已删除,无需重复操作") @@ -572,6 +573,10 @@ class CoursesController < ApplicationController tip_exception("删除失败") if course_member.CREATOR? or course_member.STUDENT? course_student = CourseMember.find_by(user_id: course_member.user_id, course_id: @course.id, role: %i[STUDENT]) + # Tiding.create!(user_id: course_member.user_id, trigger_user_id: current_user.id, container_id: @course.id, + # container_type: 'DeleteCourseMember', tiding_type: 'System', belong_container: @course, extra: @course.name) + CourseDeleteStudentNotifyJob.perform_later(@course.id, [course_member.user_id], current_user.id) + course_member.destroy! course_student.update_attributes(is_active: 1) if course_student.present? && !course_student.is_active normal_status(0, "删除成功") @@ -802,6 +807,7 @@ class CoursesController < ApplicationController end end CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, student_ids) if student_ids.present? + CourseDeleteStudentNotifyJob.perform_later(@course.id, student_ids, current_user.id) if student_ids.present? normal_status(0, "操作成功") rescue => e uid_logger(e.message) diff --git a/app/controllers/ecs/course_targets_controller.rb b/app/controllers/ecs/course_targets_controller.rb index 744840c39..e5ac4b36e 100644 --- a/app/controllers/ecs/course_targets_controller.rb +++ b/app/controllers/ecs/course_targets_controller.rb @@ -19,7 +19,9 @@ class Ecs::CourseTargetsController < Ecs::CourseBaseController end def with_achievement_methods - @course_targets = current_course.ec_course_targets.includes(:ec_graduation_subitems, :ec_course_achievement_methods) + @course_targets = current_course.ec_course_targets + .includes(:ec_graduation_subitems, + ec_course_achievement_methods: [:ec_course_evaluation, :ec_course_evaluation_subitems]) end private diff --git a/app/controllers/exercise_answers_controller.rb b/app/controllers/exercise_answers_controller.rb index 3fc27c8f2..b1e23071b 100644 --- a/app/controllers/exercise_answers_controller.rb +++ b/app/controllers/exercise_answers_controller.rb @@ -14,19 +14,15 @@ class ExerciseAnswersController < ApplicationController else ea = @exercise_question.exercise_answers.search_answer_users("user_id",current_user.id) #试卷的当前用户的答案 if q_type == Exercise::SINGLE || q_type == Exercise::JUDGMENT #选择题(单选)/判断题 - ea_choice = ea.search_exercise_answer("exercise_choice_id",choice_id).first - answer_option = { + if ea.exists? + ea.first.update_attribute(:exercise_choice_id,choice_id ) + else + answer_option = { :user_id => current_user.id, :exercise_question_id => @exercise_question.id, :exercise_choice_id => choice_id, :answer_text => "" - } - if ea_choice.present? #如果当前用户的答案存在,再次点击,即为删除 - ea_choice.destroy - else - if @exercise_question.exercise_standard_answers.count <= 1 #单选题的时候 - ea.first.destroy if ea.present? - end + } ex_a = ExerciseAnswer.new(answer_option) ex_a.save! end @@ -110,7 +106,7 @@ class ExerciseAnswersController < ApplicationController elsif @exercise_user.commit_status == 1 normal_status(-1,"已提交/已结束的试卷不允许修改!") else - if (@exercise_user_status == Exercise::DEADLINE && @exercise_user.commit_status == 0) || (@exercise.time > 0 && @exercise_user.start_at.present? && ((@exercise_user.start_at + (@exercise.time.to_i + 1).minutes) < Time.now)) + if (@exercise_user_status == Exercise::DEADLINE && @exercise_user.commit_status == 0) || (@exercise.time > 0 && @exercise_user.start_at.present? && ((@exercise_user.start_at + @exercise.time.to_i.minutes) < Time.now)) objective_score = calculate_student_score(@exercise,current_user)[:total_score] subjective_score = @exercise_user.subjective_score < 0.0 ? 0.0 : @exercise_user.subjective_score total_score = objective_score + subjective_score diff --git a/app/controllers/exercise_questions_controller.rb b/app/controllers/exercise_questions_controller.rb index bb28fff54..9eeba6adc 100644 --- a/app/controllers/exercise_questions_controller.rb +++ b/app/controllers/exercise_questions_controller.rb @@ -656,7 +656,17 @@ class ExerciseQuestionsController < ApplicationController :exercise_answer_id => ex_answer_comment_id } @exercise_comments = ExerciseAnswerComment.new(comment_option) - @exercise_comments.save + @exercise_comments.save! + + # 给被评阅人发送消息,同一个教师评阅无需重复发消息 + + unless Tiding.where(user_id: @user_id, trigger_user_id: current_user.id, parent_container_id: @exercise.id, parent_container_type: "ExerciseScore").exists? + Tiding.create!(user_id: @user_id, trigger_user_id: current_user.id, container_id: @exercise.id, + container_type: "Exercise", parent_container_id: @exercise.id, + parent_container_type: "ExerciseScore", belong_container_id: @course.id, + belong_container_type: 'Course', tiding_type: "Exercise") + end + end rescue Exception => e uid_logger_error(e.message) diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 3be35345e..f2e8508f0 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -25,85 +25,83 @@ class ExercisesController < ApplicationController include ExercisesHelper def index - ActiveRecord::Base.transaction do - begin - # 按发布时间或创建时间排序 - @exercises_all = @course.exercises - member_show_exercises = @exercises_all.is_exercise_published #已发布的或已截止的试卷 - @current_user_ = current_user - - # 课堂的学生人数 - @course_all_members = @course.students #当前课堂的全部学生 - @current_student = @course_all_members.course_find_by_ids("user_id",current_user.id) #当前用户是否为课堂的学生 - - # exercises的不同用户群体的显示 - if @user_course_identity < Course::STUDENT # @is_teacher_or 1为老师/管理员/助教 - @is_teacher_or = 1 - @exercises = @exercises_all #老师能看到全部的试卷,不管是已发布的/未发布的/已截止的/统一设置的/私有设置的(看到内容不同) - elsif @user_course_identity == Course::STUDENT # 2为课堂成员,能看到统一设置的和自己班级的 - @is_teacher_or = 2 - @member_group_id = @current_student.first.try(:course_group_id).to_i # 成员的分班id,默认为0 - if @member_group_id == 0 #表示是课堂的未分班成员,只能查看统一设置的试卷(已发布的/已截止的) - @exercises = member_show_exercises.exists? ? member_show_exercises.unified_setting : [] - else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 - # 已发布 当前用户班级分组的 试卷id - not_exercise_ids = @course.exercise_group_settings.exercise_group_not_published.where("course_group_id = #{@member_group_id}").pluck(:exercise_id) - @exercises = member_show_exercises.where.not(id: not_exercise_ids) - end - else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 - @is_teacher_or = 0 - @exercises = member_show_exercises.unified_setting + begin + # 按发布时间或创建时间排序 + @exercises_all = @course.exercises + member_show_exercises = @exercises_all.is_exercise_published #已发布的或已截止的试卷 + @current_user_ = current_user + + # 课堂的学生人数 + @course_all_members = @course.students #当前课堂的全部学生 + @current_student = @course_all_members.course_find_by_ids("user_id",current_user.id) #当前用户是否为课堂的学生 + + # exercises的不同用户群体的显示 + if @user_course_identity < Course::STUDENT # @is_teacher_or 1为老师/管理员/助教 + @is_teacher_or = 1 + @exercises = @exercises_all #老师能看到全部的试卷,不管是已发布的/未发布的/已截止的/统一设置的/私有设置的(看到内容不同) + elsif @user_course_identity == Course::STUDENT # 2为课堂成员,能看到统一设置的和自己班级的 + @is_teacher_or = 2 + @member_group_id = @current_student.first.try(:course_group_id).to_i # 成员的分班id,默认为0 + if @member_group_id == 0 #表示是课堂的未分班成员,只能查看统一设置的试卷(已发布的/已截止的) + @exercises = member_show_exercises.exists? ? member_show_exercises.unified_setting : [] + else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 + # 已发布 当前用户班级分组的 试卷id + not_exercise_ids = @course.exercise_group_settings.exercise_group_not_published.where("course_group_id = #{@member_group_id}").pluck(:exercise_id) + @exercises = member_show_exercises.where.not(id: not_exercise_ids) end + else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 + @is_teacher_or = 0 + @exercises = member_show_exercises.unified_setting + end - if @exercises.size > 0 - if params[:type].present? - choose_type = params[:type].to_i - ex_setting_ids = [] - if @is_teacher_or != 2 - @exercises = @exercises.where("exercise_status = #{choose_type}") - else - case choose_type - when 1 - ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_not_published.pluck(:exercise_id) - when 2 - ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}") - .where("publish_time is not null and publish_time <= ? and end_time > ?",Time.now,Time.now).pluck(:exercise_id) - when 3 - ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_ended.pluck(:exercise_id) - end - unified_setting_ids = @exercises.unified_setting.where("exercise_status = #{choose_type}").pluck(:id) - ex_ids = (ex_setting_ids + unified_setting_ids).uniq - @exercises = @exercises.where(id: ex_ids) + if @exercises.size > 0 + if params[:type].present? + choose_type = params[:type].to_i + ex_setting_ids = [] + if @is_teacher_or != 2 + @exercises = @exercises.where("exercise_status = #{choose_type}") + else + case choose_type + when 1 + ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_not_published.pluck(:exercise_id) + when 2 + ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}") + .where("publish_time is not null and publish_time <= ? and end_time > ?",Time.now,Time.now).pluck(:exercise_id) + when 3 + ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_ended.pluck(:exercise_id) end + unified_setting_ids = @exercises.unified_setting.where("exercise_status = #{choose_type}").pluck(:id) + ex_ids = (ex_setting_ids + unified_setting_ids).uniq + @exercises = @exercises.where(id: ex_ids) end + end - if params[:search].present? - search_type = params[:search].to_s.strip - @exercises = @exercises.exercise_search(search_type) - end - - @exercises_select_count = @exercises.size # 全部页面,需返回 - @exercises = @exercises.distinct.order( "IF(ISNULL(publish_time),0,1), publish_time DESC,created_at DESC") #出现错误 - - # 分页 - @page = params[:page] || 1 - @limit = params[:limit] || 15 - @exercises = @exercises.page(@page).per(@limit) - @exercises = @exercises&.includes(:published_settings) - else - @exercises = [] + if params[:search].present? + search_type = params[:search].to_s.strip + @exercises = @exercises.exercise_search(search_type) end - @course_all_members_count = @course_all_members.size #当前课堂的学生数 - @exercises_count = @exercises_all.size # 全部页面,需返回 - @exercises_unpublish_counts = @exercises_all.exercise_by_status(1).size #未发布的试卷数 - @exercises_published_counts = @exercises_count - @exercises_unpublish_counts # 已发布的试卷数,包含已截止的 + @exercises_select_count = @exercises.size # 全部页面,需返回 + @exercises = @exercises.distinct.order( "IF(ISNULL(publish_time),0,1), publish_time DESC,created_at DESC") #出现错误 - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - raise ActiveRecord::Rollback + # 分页 + @page = params[:page] || 1 + @limit = params[:limit] || 15 + @exercises = @exercises.page(@page).per(@limit) + @exercises = @exercises&.includes(:published_settings) + else + @exercises = [] end + + @course_all_members_count = @course_all_members.size #当前课堂的学生数 + @exercises_count = @exercises_all.size # 全部页面,需返回 + @exercises_unpublish_counts = @exercises_all.exercise_by_status(1).size #未发布的试卷数 + @exercises_published_counts = @exercises_count - @exercises_unpublish_counts # 已发布的试卷数,包含已截止的 + + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + raise ActiveRecord::Rollback end end @@ -785,6 +783,7 @@ class ExercisesController < ApplicationController # 首页批量或单独 立即截止,截止时间为当前时间 def end_exercise + ActiveRecord::Base.transaction do begin check_ids = Exercise.where(id:params[:check_ids]) @@ -844,23 +843,27 @@ class ExercisesController < ApplicationController exercise_users = exercise.exercise_users exercise.update_attributes(:exercise_status => 3, :end_time => Time.now,:unified_setting => true) end - exercise_users.each do |user| - if user.commit_status == 0 && user.start_at.present? - objective_score = calculate_student_score(exercise,user.user)[:total_score] - user_sub_score = user.subjective_score - subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score - total_score = objective_score + subjective_score - commit_option = { - :status => 1, - :commit_status => 1, - :end_at => Time.now, - :objective_score => objective_score, - :score => total_score, - :subjective_score => user_sub_score - } - user.update_attributes(commit_option) - end - end + + ex_user_ids = exercise_users.pluck(:id) + + EndExerciseCalculateJob.perform_later(ex_user_ids,exercise) + # exercise_users.each do |user| + # if user.commit_status == 0 && user.start_at.present? + # objective_score = calculate_student_score(exercise,user.user)[:total_score] + # user_sub_score = user.subjective_score + # subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score + # total_score = objective_score + subjective_score + # commit_option = { + # :status => 1, + # :commit_status => 1, + # :end_at => Time.now, + # :objective_score => objective_score, + # :score => total_score, + # :subjective_score => user_sub_score + # } + # user.update_attributes(commit_option) + # end + # end end end normal_status(0, "试卷截止成功!") diff --git a/app/controllers/gits_controller.rb b/app/controllers/gits_controller.rb index b52e75353..e94c197ed 100644 --- a/app/controllers/gits_controller.rb +++ b/app/controllers/gits_controller.rb @@ -8,7 +8,11 @@ class GitsController < ApplicationController # 供 git-workhorse反向调用认证 def auth # HTTP_AUTHORIZATION: "Basic 这里base64编码的的密码(user:passwd)" + decodes = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) + rand_code = decodes.sample(10).join logger.info("11111112222223333 HTTP_AUTHORIZATION: #{request.env["HTTP_AUTHORIZATION"]}") + logger.info("1111111 git auth start: code is #{rand_code}, time is #{Time.now}") + # logger.info("#########-----request_env: #{request.env}") # {"service"=>"git-receive-pack", "controller"=>"gits", "action"=>"auth", # "url"=>"forge01/cermyt39.git/info/refs"} @@ -68,6 +72,7 @@ class GitsController < ApplicationController authenticate_or_request_with_http_basic do |username, password| result + logger.info("1111111 git auth end: code is #{rand_code}, time is #{Time.now}") end end diff --git a/app/controllers/graduation_tasks_controller.rb b/app/controllers/graduation_tasks_controller.rb index ecde1eef5..864eac3f5 100644 --- a/app/controllers/graduation_tasks_controller.rb +++ b/app/controllers/graduation_tasks_controller.rb @@ -1,13 +1,16 @@ class GraduationTasksController < ApplicationController before_action :require_login, :check_auth, except: [:index] - before_action :find_course, except: [:edit, :update, :settings, :update_settings, :tasks_list, :show, :show_comment] - before_action :find_task, only: [:edit, :update, :settings, :update_settings, :tasks_list, :show, :show_comment] + before_action :find_course, except: [:edit, :update, :settings, :update_settings, :tasks_list, :show, :show_comment, + :cross_comment_setting, :assign_works, :commit_comment_setting] + before_action :find_task, only: [:edit, :update, :settings, :update_settings, :tasks_list, :show, :show_comment, + :cross_comment_setting, :assign_works, :commit_comment_setting] before_action :user_course_identity before_action :task_publish, only: [:show, :show_comment, :tasks_list, :settings] before_action :teacher_allowed, only: [:new, :create, :edit, :update, :set_public,:multi_destroy, :publish_task, :end_task, - :update_settings, :add_to_bank] + :update_settings, :add_to_bank, :cross_comment_setting, :assign_works, :commit_comment_setting] before_action :require_id_params, only: [:set_public ,:multi_destroy, :publish_task, :end_task, :add_to_bank] before_action :valid_params, only: [:update_settings] + before_action :allow_cross_comment, only: [:cross_comment_setting, :assign_works, :commit_comment_setting] include ExportHelper def index @@ -104,6 +107,15 @@ class GraduationTasksController < ApplicationController @work_list = @task.graduation_works.where(id: graduation_work_id) end + # 组员、组长作品的筛选 + if @task.task_type == 2 && !params[:member_work].blank? + if params[:member_work].to_i == 1 + @work_list = @work_list.where("user_id = commit_user_id") + elsif params[:member_work].to_i == 0 + @work_list = @work_list.where("user_id != commit_user_id") + end + end + # 输入姓名和学号搜索 # TODO user_extension 如果修改 请调整 unless params[:search].blank? @@ -453,22 +465,27 @@ class GraduationTasksController < ApplicationController tip_exception("评阅时间应当大于截止时间") if @task.cross_comment && params[:comment_time] <= @task.end_time @task.comment_time = @task.cross_comment ? params[:comment_time] : nil - @task.comment_num = @task.cross_comment ? params[:comment_num].to_i : 3 - @task.comment_status = @task.cross_comment ? params[:comment_status] : 0 - if @task.cross_comment && params[:comment_status].to_i == 4 - tip_exception("评阅数不能为空") if params[:comment_num].blank? - tip_exception("评阅数应大于0") if params[:comment_num].to_i < 1 - - @course.graduation_groups.each_with_index do |group, index| - ass_group = @task.graduation_task_group_assignations.find_by(graduation_group_id: group.id) - if ass_group.present? && params[:comment_group][index].present? && params[:comment_group][index] != "0" - ass_group.update_attributes(assign_graduation_group_id: params[:comment_group][index]) - else - @task.graduation_task_group_assignations << GraduationTaskGroupAssignation.new(graduation_group_id: group.id, - assign_graduation_group_id: params[:comment_group][index]) - end - end - end + + @task.comment_status = 2 if @task.cross_comment && @task.comment_status == 0 + + @task.graduation_work_comment_assignations.destroy_all if !@task.cross_comment + # 去掉评阅设置 + # @task.comment_num = @task.cross_comment ? params[:comment_num].to_i : 3 + # @task.comment_status = @task.cross_comment ? params[:comment_status] : 0 + # if @task.cross_comment && params[:comment_status].to_i == 4 + # tip_exception("评阅数不能为空") if params[:comment_num].blank? + # tip_exception("评阅数应大于0") if params[:comment_num].to_i < 1 + # + # @course.graduation_groups.each_with_index do |group, index| + # ass_group = @task.graduation_task_group_assignations.find_by(graduation_group_id: group.id) + # if ass_group.present? && params[:comment_group][index].present? && params[:comment_group][index] != "0" + # ass_group.update_attributes(assign_graduation_group_id: params[:comment_group][index]) + # else + # @task.graduation_task_group_assignations << GraduationTaskGroupAssignation.new(graduation_group_id: group.id, + # assign_graduation_group_id: params[:comment_group][index]) + # end + # end + # end end # 公开设置 @@ -493,6 +510,107 @@ class GraduationTasksController < ApplicationController end end + def cross_comment_setting + @comment_status = params[:comment_status] || (@task.cross_comment ? @task.comment_status : 2) + group_ids = @course.charge_group_ids(current_user) + @course_groups = @course.course_groups.where(id: group_ids) + + # 如果传了分班id则取合集 + group_ids = group_ids & params[:group_ids].map(&:to_i) unless params[:group_ids].blank? + page = params[:page] ? params[:page].to_i : 1 + limit = params[:limit] ? params[:limit].to_i : 10 + + # 取所有课堂的作品 + if group_ids.sort == @course.course_groups.pluck(:id).sort + @work_list = @task.graduation_works + else + @work_list = @task.graduation_works.joins("join course_members on graduation_works.user_id=course_members.user_id"). + where(course_members: {course_group_id: group_ids}) + end + @user_count = @work_list.size + @work_list = @work_list.page(page).per(limit).includes(user: [:user_extension]) + @students = @course.students.where(user_id: @work_list.pluck(:user_id)) + end + + def assign_works + tip_exception("请先选择作品") if params[:work_ids].blank? + tip_exception("请指定要分配的老师或答辩组") if params[:user_ids].blank? && params[:graduation_group_ids].blank? + + ActiveRecord::Base.transaction do + begin + works = @task.graduation_works.where(id: params[:work_ids]) + # 手动分配:分配给老师 + if !params[:user_ids].blank? + @task.update_attributes(comment_status: 2) + works.each do |work| + # 之前分配的老师但现在未分配时需要删除 + work.graduation_work_comment_assignations.where.not(user_id: params[:user_ids]).destroy_all + @course.teachers.where(user_id: params[:user_ids]).pluck(:user_id).uniq.each do |user_id| + unless work.graduation_work_comment_assignations.exists?(user_id: user_id) + GraduationWorkCommentAssignation.create!(graduation_task_id: @task.id, graduation_work_id: work.id, + user_id: user_id) + end + end + end + + # 答辩组分配:分配答辩组 + elsif !params[:graduation_group_ids].blank? + @task.update_attributes(comment_status: 4) + works.each do |work| + work.graduation_task_group_assignations.where.not(graduation_group_id: params[:graduation_group_ids]).destroy_all + @course.graduation_groups.where(id: params[:graduation_group_ids]).pluck(:id).uniq.each do |graduation_group_id| + unless work.graduation_task_group_assignations.exists?(graduation_group_id: graduation_group_id) + GraduationTaskGroupAssignation.create!(graduation_task_id: @task.id, graduation_work_id: work.id, + graduation_group_id: graduation_group_id) + end + end + end + end + normal_status("分配成功") + rescue Exception => e + uid_logger(e.message) + tip_exception(e.message) + raise ActiveRecord::Rollback + end + end + end + + def commit_comment_setting + tip_exception("type参数有误") if params[:type].blank? || !["commit", "cancel"].include?(params[:type]) + ActiveRecord::Base.transaction do + begin + # 提交弹框 + # if params[:type] == "commit" + # tip_exception("comment_status参数有误") if params[:comment_status].blank? || ![2, 4].include?(params[:comment_status].to_i) + # @task.update_attributes(comment_status: params[:comment_status]) + # if params[:comment_status].to_i == 2 + # @task.temporary_graduation_work_comment_assignations.update_all(temporary: 0) # 临时数据转正 + # @task.delete_graduation_work_comment_assignations.destroy_all # 删除置了删除位的数据 + # @task.graduation_task_group_assignations.destroy_all # 删除答辩组分配数据 + # else + # @task.temporary_graduation_task_group_assignations.update_all(temporary: 0) + # @task.delete_graduation_task_group_assignations.destroy_all + # @task.graduation_work_comment_assignations.destroy_all + # + # GraduationTaskCrossCommentJob.perform_later(@task.id) + # end + # else + # # 取消时删除临时数据,恢复删除位数据 + # @task.temporary_graduation_work_comment_assignations.destroy_all # 删除临时数据 + # @task.delete_graduation_work_comment_assignations.update_all(temporary: 0) # 恢复置了删除位的数据 + # + # @task.temporary_graduation_task_group_assignations.destroy_all # 删除临时数据 + # @task.delete_graduation_task_group_assignations.update_all(temporary: 0) # 恢复置了删除位的数据 + # end + normal_status("操作成功") + rescue Exception => e + uid_logger(e.message) + tip_exception(e.message) + raise ActiveRecord::Rollback + end + end + end + private def find_task begin @@ -533,6 +651,11 @@ class GraduationTasksController < ApplicationController tip_exception("最大人数不能小于最小人数要求") if params[:min_num].to_i > params[:max_num].to_i end end + + def allow_cross_comment + tip_exception("请先开启交叉评阅再设置") unless @task.cross_comment + end + # # def graduation_work_to_xls items # xls_report = StringIO.new diff --git a/app/controllers/graduation_works_controller.rb b/app/controllers/graduation_works_controller.rb index 204e0e5d4..d50885313 100644 --- a/app/controllers/graduation_works_controller.rb +++ b/app/controllers/graduation_works_controller.rb @@ -1,18 +1,18 @@ class GraduationWorksController < ApplicationController before_action :require_login, :check_auth before_action :find_task, only: [:new, :create, :search_member_list, :check_project, :relate_project, - :cancel_relate_project] + :cancel_relate_project, :delete_work] before_action :find_work, only: [:show, :edit, :update, :revise_attachment, :supply_attachments, :comment_list, :add_score, :delete_score, :adjust_score, :assign_teacher] before_action :user_course_identity before_action :task_public before_action :teacher_allowed, only: [:add_score, :adjust_score, :assign_teacher] before_action :course_student, only: [:new, :create, :edit, :update, :search_member_list, :relate_project, - :cancel_relate_project] + :cancel_relate_project, :delete_work] before_action :my_work, only: [:edit, :update, :revise_attachment] before_action :published_task, only: [:new, :create, :edit, :update, :search_member_list, :relate_project, :cancel_relate_project, :revise_attachment] - before_action :edit_duration, only: [:edit, :update] + before_action :edit_duration, only: [:edit, :update, :delete_work] before_action :open_work, only: [:show, :supply_attachments, :comment_list] def new @@ -47,6 +47,24 @@ class GraduationWorksController < ApplicationController @members = @members.page(page).per(limit).includes(:course_group, user: :user_extension) end + def delete_work + ActiveRecord::Base.transaction do + begin + work = @task.graduation_works.find_by!(user_id: params[:user_id]) + tip_exception("只有组长才能删除组员") if work.commit_user_id != current_user.id + work.update_attributes(description: nil, project_id: 0, late_penalty: 0, work_status: 0, commit_time: nil, + update_time: nil, group_id: 0, commit_user_id: nil, final_score: nil, work_score: nil, + teacher_score: nil, teaching_asistant_score: nil, update_user_id: nil) + work.attachments.destroy_all + work.tidings.destroy_all + normal_status("删除成功") + rescue Exception => e + uid_logger(e.message) + tip_exception(e.message) + end + end + end + # 判断项目是否已有其他作品关联上了 def check_project tip_exception("项目id不能为空") if params[:project_id].blank? @@ -142,6 +160,7 @@ class GraduationWorksController < ApplicationController graduation_work.commit_time = Time.now graduation_work.update_time = Time.now graduation_work.commit_user_id = current_user.id + graduation_work.update_user_id = current_user.id graduation_work.course_id = @course.id graduation_work.group_id = @task.task_type == 2 ? @task.graduation_works.where("work_status != 0").map(&:group_id).max.to_i + 1 : 0 @@ -162,7 +181,7 @@ class GraduationWorksController < ApplicationController graduation_task_id: @task.id, project_id: graduation_work.project_id, late_penalty: graduation_work.late_penalty, work_status: graduation_work.work_status, commit_time: Time.now, update_time: Time.now, group_id: graduation_work.group_id, - commit_user_id: current_user.id) + commit_user_id: current_user.id, update_user_id: current_user.id) stu_work.save! graduation_work.attachments.each do |attachment| att = attachment.copy @@ -190,8 +209,9 @@ class GraduationWorksController < ApplicationController def edit @task_user = current_user if @task.task_type == 2 + @commit_user_id = @work.commit_user_id @work_members = @course.students.where(user_id: @task.graduation_works.where(group_id: @work.group_id).pluck(:user_id)). - order("course_members.id=#{@work.user_id} desc").includes(:course_group, user: :user_extension) + order("course_members.id=#{@work.commit_user_id} desc").includes(:course_group, user: :user_extension) end end @@ -203,7 +223,8 @@ class GraduationWorksController < ApplicationController begin @work.description = params[:description] @work.update_time = Time.now - @work.commit_user_id = current_user.id + @work.update_user_id = current_user.id + # @work.commit_user_id = current_user.id if @work.save! Attachment.associate_container(params[:attachment_ids], @work.id, @work.class) @@ -217,7 +238,7 @@ class GraduationWorksController < ApplicationController # 原成员更新描述、更新时间以及附件 @task.graduation_works.where(group_id: @work.group_id, user_id: (work_user_ids & params_user_ids)).each do |work| - work.update_attributes(update_time: Time.now, description: @work.description, commit_user_id: current_user.id) + work.update_attributes(update_time: Time.now, description: @work.description, update_user_id: current_user.id) work.attachments.destroy_all @work.attachments.each do |attachment| att = attachment.copy @@ -237,7 +258,7 @@ class GraduationWorksController < ApplicationController @task.graduation_works.where(group_id: @work.group_id, user_id: delete_user_ids). update_all(work_status: 0, description: nil, late_penalty: 0, commit_time: nil, update_time: nil, final_score: nil, teacher_score: nil, work_score: nil, project_id: 0, group_id: 0, - commit_user_id: nil) + commit_user_id: nil, update_user_id: nil) # 新增加的成员 (params_user_ids - work_user_ids).each do |user_id| @@ -246,7 +267,7 @@ class GraduationWorksController < ApplicationController stu_work.update_attributes(user_id: user_id, description: @work.description, graduation_task_id: @task.id, project_id: @work.project_id, late_penalty: @work.late_penalty, work_status: @work.work_status, commit_time: Time.now, update_time: Time.now, - group_id: @work.group_id, commit_user_id: current_user.id) + group_id: @work.group_id, commit_user_id: @work.commit_user_id, update_user_id: current_user.id) @work.attachments.each do |attachment| att = attachment.copy att.author_id = attachment.author_id @@ -308,7 +329,7 @@ class GraduationWorksController < ApplicationController end end - if @task.status == 3 && @task.graduation_work_comment_assignations.where(graduation_work_id: @work.id, user_id: current_user.id).count > 0 + if @task.cross_comment && @work.graduation_work_comment_assignations.where(user_id: current_user.id).count > 0 new_score.reviewer_role = 2 else new_score.reviewer_role = 1 @@ -371,6 +392,11 @@ class GraduationWorksController < ApplicationController new_score.save! @work.update_attributes(ultimate_score: 1, work_score: params[:score].to_f) + Tiding.create!(user_id: @work.user_id, trigger_user_id: current_user.id, container_id: new_score.id, + container_type: "AdjustScore", parent_container_id: @task.id, + parent_container_type: "GraduationTask", belong_container_id: @course.id, + belong_container_type: 'Course', tiding_type: "GraduationTask") + normal_status("调分成功") rescue Exception => e uid_logger(e.message) diff --git a/app/controllers/stages_controller.rb b/app/controllers/stages_controller.rb index b0b072f83..0abd3c362 100644 --- a/app/controllers/stages_controller.rb +++ b/app/controllers/stages_controller.rb @@ -6,7 +6,8 @@ class StagesController < ApplicationController def index @user = current_user - @stages = @subject.stages + @stages = @subject.stages.includes(:shixuns) + @myshixuns = @user.myshixuns.where(shixun_id: @subject.stage_shixuns.pluck(:shixun_id)) end def create diff --git a/app/controllers/student_works_controller.rb b/app/controllers/student_works_controller.rb index 2612510c5..b7a6953a5 100644 --- a/app/controllers/student_works_controller.rb +++ b/app/controllers/student_works_controller.rb @@ -224,7 +224,7 @@ class StudentWorksController < ApplicationController raise ActiveRecord::Rollback end - SubmitStudentWorkNotifyJob.perform_later(@homework.id, student_ids) if student_ids.present? + ResubmitStudentWorkNotifyJob.perform_later(@homework.id, student_ids) if student_ids.present? end end @@ -333,6 +333,11 @@ class StudentWorksController < ApplicationController @work.update_attributes(update_time: Time.now) + # 补交附件时给评阅过作品的教师、助教发消息 + unless @work.student_works_scores.where.not(score: nil).where(reviewer_role: [1, 2]).pluck(:user_id).uniq.blank? + ResubmitStudentWorkNotifyJob.perform_later(@homework.id, [current_user.id]) + end + normal_status(0, "提交成功") rescue Exception => e uid_logger(e.message) @@ -551,6 +556,11 @@ class StudentWorksController < ApplicationController @work.work_score = params[:score].to_f @work.save! + Tiding.create!(user_id: @work.user_id, trigger_user_id: current_user.id, container_id: new_score.id, + container_type: "AdjustScore", parent_container_id: @homework.id, + parent_container_type: "HomeworkCommon", belong_container_id: @course.id, + belong_container_type: 'Course', tiding_type: "HomeworkCommon") + normal_status(0,"调分成功") rescue Exception => e uid_logger(e.message) diff --git a/app/controllers/users/courses_controller.rb b/app/controllers/users/courses_controller.rb index c7e957e1a..2c5e29d2b 100644 --- a/app/controllers/users/courses_controller.rb +++ b/app/controllers/users/courses_controller.rb @@ -3,7 +3,7 @@ class Users::CoursesController < Users::BaseController courses = Users::CourseService.new(observed_user, query_params).call @count = courses.count - @courses = paginate(courses.includes(teacher: { user_extension: :school }), special: true) + @courses = paginate(courses.includes(teacher: { user_extension: :school }), special: observed_user.is_teacher?) end private diff --git a/app/controllers/users/projects_controller.rb b/app/controllers/users/projects_controller.rb index 07f4d5cac..8ffa8fa85 100644 --- a/app/controllers/users/projects_controller.rb +++ b/app/controllers/users/projects_controller.rb @@ -5,7 +5,7 @@ class Users::ProjectsController < Users::BaseController projects = Users::ProjectService.new(observed_user, query_params).call @count = projects.count - @projects = paginate(projects.includes(:project_score, owner: { user_extension: :school }), special: true) + @projects = paginate(projects.includes(:project_score, owner: { user_extension: :school }), special: observed_user.is_teacher?) end def search diff --git a/app/controllers/users/shixuns_controller.rb b/app/controllers/users/shixuns_controller.rb index 7b840a0a1..5d8da9684 100644 --- a/app/controllers/users/shixuns_controller.rb +++ b/app/controllers/users/shixuns_controller.rb @@ -3,7 +3,7 @@ class Users::ShixunsController < Users::BaseController shixuns = Users::ShixunService.new(observed_user, query_params).call @count = shixuns.count - @shixuns = paginate(shixuns.includes(:first_tag_repertoire), special: true) + @shixuns = paginate(shixuns.includes(:first_tag_repertoire), special: observed_user.is_teacher?) ids = @shixuns.map(&:id) @finished_challenges_count_map = Game.joins(:myshixun).where(user_id: observed_user.id, status: 2) diff --git a/app/controllers/users/subjects_controller.rb b/app/controllers/users/subjects_controller.rb index 2a4a7975f..2f8f308df 100644 --- a/app/controllers/users/subjects_controller.rb +++ b/app/controllers/users/subjects_controller.rb @@ -3,7 +3,7 @@ class Users::SubjectsController < Users::BaseController subjects = Users::SubjectService.new(observed_user, query_params).call @count = subjects.count - @subjects = paginate(subjects.includes(:user, :repertoire), special: true) + @subjects = paginate(subjects.includes(:user, :repertoire), special: observed_user.is_teacher?) end private diff --git a/app/decorators/tiding_decorator.rb b/app/decorators/tiding_decorator.rb index b4f851e5f..130e7f4b8 100644 --- a/app/decorators/tiding_decorator.rb +++ b/app/decorators/tiding_decorator.rb @@ -134,6 +134,15 @@ module TidingDecorator end end + def delete_course_content + I18n.t(locale_format) % belong_container.name + end + + def delete_course_member_content + name = Course.find_by(id: container_id)&.name + I18n.t(locale_format) % [trigger_user&.show_real_name, name] + end + def shixun_content I18n.t(locale_format) % container.name end @@ -331,13 +340,21 @@ module TidingDecorator end def student_work_content - I18n.t(locale_format(extra.nil?)) % container&.homework_common.try(:name) + I18n.t(locale_format) % container&.homework_common.try(:name) + end + + def resubmit_student_work_content + I18n.t(locale_format) % parent_container.try(:name) end def student_works_score_content I18n.t(locale_format(extra)) % container&.student_work&.homework_common.try(:name) end + def adjust_score_content + I18n.t(locale_format) % parent_container.try(:name) + end + def challenge_work_score_content I18n.t(locale_format) % container&.comment end diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index 5ca4eb773..d670614d5 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -269,8 +269,8 @@ module CoursesHelper group_info end - def last_subject_shixun user_id, course - myshixun = Myshixun.where(user_id: user_id, shixun_id: course.shixuns).order("updated_at desc").first + def last_subject_shixun course, myshixuns + myshixun = myshixuns.sort{|x,y| y[:updated_at] <=> x[:updated_at] }.first return "" unless myshixun stage_shixun = course.course_stage_shixuns.where(shixun_id: myshixun.shixun_id).take progress = stage_shixun&.course_stage&.position.to_s + "-" + stage_shixun&.position.to_s + " " + myshixun.shixun&.name diff --git a/app/helpers/stages_helper.rb b/app/helpers/stages_helper.rb index e0df514e3..93c466c46 100644 --- a/app/helpers/stages_helper.rb +++ b/app/helpers/stages_helper.rb @@ -1,8 +1,8 @@ module StagesHelper # 章节实训的通关情况 - def stage_myshixun_status shixun, user - myshixun = Myshixun.where(user_id: user.id, shixun_id: shixun.id).take + def stage_myshixun_status myshixun + # myshixun = Myshixun.where(user_id: user.id, shixun_id: shixun.id).take myshixun.try(:status) == 1 ? 1 : 0 end diff --git a/app/jobs/course_delete_student_notify_job.rb b/app/jobs/course_delete_student_notify_job.rb new file mode 100644 index 000000000..898fc97c9 --- /dev/null +++ b/app/jobs/course_delete_student_notify_job.rb @@ -0,0 +1,22 @@ +# 删除课堂用户 +class CourseDeleteStudentNotifyJob < ApplicationJob + queue_as :notify + + def perform(course_id, student_ids, trigger_user_id) + course = Course.find_by(id: course_id) + return if course.blank? + + attrs = %i[user_id trigger_user_id container_id container_type belong_container_id + belong_container_type tiding_type created_at updated_at] + + same_attrs = { + trigger_user_id: trigger_user_id, container_id: course.id, container_type: 'DeleteCourseMember', + belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'System' + } + Tiding.bulk_insert(*attrs) do |worker| + student_ids.each do |user_id| + worker.add same_attrs.merge(user_id: user_id) + end + end + end +end diff --git a/app/jobs/end_exercise_calculate_job.rb b/app/jobs/end_exercise_calculate_job.rb new file mode 100644 index 000000000..39d8bb1db --- /dev/null +++ b/app/jobs/end_exercise_calculate_job.rb @@ -0,0 +1,29 @@ +class EndExerciseCalculateJob < ApplicationJob + + include ExercisesHelper + include GitHelper + + queue_as :default + + def perform(ex_user_ids,exercise) + exercise_users = ExerciseUser.where(id: ex_user_ids) + exercise_users.each do |user| + if user.commit_status == 0 && user.start_at.present? + objective_score = calculate_student_score(exercise,user.user)[:total_score] + user_sub_score = user.subjective_score + subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score + total_score = objective_score + subjective_score + commit_option = { + :status => 1, + :commit_status => 1, + :end_at => Time.now, + :objective_score => objective_score, + :score => total_score, + :subjective_score => user_sub_score + } + user.update_attributes(commit_option) + end + end + end + +end diff --git a/app/jobs/graduation_task_cross_comment_job.rb b/app/jobs/graduation_task_cross_comment_job.rb index cf2cb613e..a2d181b50 100644 --- a/app/jobs/graduation_task_cross_comment_job.rb +++ b/app/jobs/graduation_task_cross_comment_job.rb @@ -6,31 +6,14 @@ class GraduationTaskCrossCommentJob < ApplicationJob task = GraduationTask.find_by(id: graduation_task_id) return if task.blank? - course = task.course - task.graduation_task_group_assignations.each do |assignation| + task.graduation_task_group_assignations.includes(:graduation_group, :graduation_work).each do |assignation| graduation_group = assignation.graduation_group - assign_group = assignation.assign_group - if graduation_group.present? && assign_group.present? - course_group_ids = course.teacher_course_groups.where(course_member_id: graduation_group.course_members.pluck(:id)).pluck(:course_group_id) - graduation_works = task.graduation_works.where(user_id: course.course_members.where(:course_group_id => course_group_ids).map(&:user_id), - work_status: [1, 2]) - if assign_group.course_members.count <= task.comment_num - graduation_works.each do |work| - assign_group.course_members.each do |member| - work.graduation_work_comment_assignations << GraduationWorkCommentAssignation.new( - graduation_group_id: assign_group.id, user_id: member.user_id, graduation_task_id: task.id) - end - end - else - member_user_ids = assign_group.course_members.pluck(:user_id) - count = 0 - graduation_works.each do |work| - for i in 1 .. task.comment_num - assign_user_id = member_user_ids[count % member_user_ids.size] - work.graduation_work_comment_assignations << GraduationWorkCommentAssignation.new( - graduation_group_id: assign_group.id, user_id: assign_user_id, graduation_task_id: task.id) - count += 1 - end + work = assignation.graduation_work + if graduation_group.present? && work.present? + member_ids = graduation_group.course_members.pluck(:user_id).uniq + member_ids.each do |user_id| + unless work.graduation_work_comment_assignations.exists?(user_id: user_id) + work.graduation_work_comment_assignations << GraduationWorkCommentAssignation.new(user_id: user_id, graduation_task_id: task.id) end end end diff --git a/app/jobs/resubmit_student_work_notify_job.rb b/app/jobs/resubmit_student_work_notify_job.rb new file mode 100644 index 000000000..1a67aa3ad --- /dev/null +++ b/app/jobs/resubmit_student_work_notify_job.rb @@ -0,0 +1,33 @@ +class ResubmitStudentWorkNotifyJob < ApplicationJob + queue_as :notify + + def perform(homework_id, student_ids) + homework = HomeworkCommon.find_by(id: homework_id) + return if homework.blank? || student_ids.blank? + course = homework.course + + attrs = %i[user_id trigger_user_id container_id container_type parent_container_id parent_container_type + belong_container_id belong_container_type tiding_type viewed created_at updated_at] + + same_attrs = { + container_type: 'ResubmitStudentWork', parent_container_id: homework.id, parent_container_type: 'HomeworkCommon', + belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'HomeworkCommon', viewed: 0 + } + Tiding.bulk_insert(*attrs) do |worker| + student_ids.each do |user_id| + next unless User.exists?(id: user_id) + + work = homework.student_works.find_by(user_id: user_id) + next if work.blank? + score_user_ids = work.student_works_scores.where.not(score: nil).where(reviewer_role: [1, 2]).pluck(user_id).uniq + next if score_user_ids.blank? + + attrs = same_attrs.merge(trigger_user_id: user_id, container_id: work.id) + + score_user_ids.each do |user_id| + worker.add attrs.merge(user_id: user_id) + end + end + end + end +end diff --git a/app/models/course.rb b/app/models/course.rb index ba818449e..6dd361733 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -354,9 +354,8 @@ class Course < ApplicationRecord Myshixun.where(user_id: user_id, shixun_id: shixuns).exists? end - def my_subject_progress - my_challenge_count = Game.joins(:challenge).where(user_id: User.current.id, status: 2, challenges: {shixun_id: shixuns.published_closed}). - pluck(:challenge_id).uniq.size + def my_subject_progress myshixuns + my_challenge_count = Game.where(myshixun_id: myshixuns.pluck(:id), status: 2).pluck(:challenge_id).uniq.size course_challeng_count = shixuns.pluck(:challenges_count).sum count = course_challeng_count == 0 ? 0 : ((my_challenge_count.to_f / course_challeng_count).round(2) * 100).to_i end diff --git a/app/models/ec_course_evaluation.rb b/app/models/ec_course_evaluation.rb index 6b778de66..e96f1c98b 100644 --- a/app/models/ec_course_evaluation.rb +++ b/app/models/ec_course_evaluation.rb @@ -11,6 +11,7 @@ class EcCourseEvaluation < ApplicationRecord enum score_type: { detail: 1, average: 2 }, _suffix: :score_type # :detail_score_type?, :average_score_type? accepts_nested_attributes_for :ec_course_evaluation_subitems, allow_destroy: true + alias_attribute :evaluation_count, :evluation_count def imported? import_status? diff --git a/app/models/graduation_task.rb b/app/models/graduation_task.rb index 17309101d..c9838954a 100644 --- a/app/models/graduation_task.rb +++ b/app/models/graduation_task.rb @@ -13,8 +13,15 @@ class GraduationTask < ApplicationRecord has_many :attachments, as: :container, dependent: :destroy - has_many :graduation_task_group_assignations, dependent: :destroy has_many :graduation_work_comment_assignations, dependent: :destroy + # has_many :formal_graduation_work_comment_assignations, -> { formal }, class_name: "GraduationWorkCommentAssignation" + # has_many :temporary_graduation_work_comment_assignations, -> { temporary }, class_name: "GraduationWorkCommentAssignation" + # has_many :delete_graduation_work_comment_assignations, -> { temporary_delete }, class_name: "GraduationWorkCommentAssignation" + # + has_many :graduation_task_group_assignations, dependent: :destroy + # has_many :formal_graduation_task_group_assignations, -> { formal }, class_name: "GraduationTaskGroupAssignation" + # has_many :temporary_graduation_task_group_assignations, -> { temporary }, class_name: "GraduationTaskGroupAssignation" + # has_many :delete_graduation_task_group_assignations, -> { temporary_delete }, class_name: "GraduationTaskGroupAssignation" has_many :graduation_works, -> { where("is_delete = 0") } has_many :score_graduation_works, -> { where("is_delete = 0 and work_status != 0").order("work_score desc") }, class_name: "GraduationWork" diff --git a/app/models/graduation_task_group_assignation.rb b/app/models/graduation_task_group_assignation.rb index 52da65191..b7e857c35 100644 --- a/app/models/graduation_task_group_assignation.rb +++ b/app/models/graduation_task_group_assignation.rb @@ -1,6 +1,12 @@ class GraduationTaskGroupAssignation < ApplicationRecord + # temporary 0: 正式分配 1:临时分配(交叉评阅设置中临时分配的作品,点取消时会删除) 2: 删除标志 belongs_to :graduation_task belongs_to :graduation_group - belongs_to :assign_group, class_name: 'GraduationGroup', foreign_key: :assign_graduation_group_id # 分配的互评组 + belongs_to :assign_group, class_name: 'GraduationGroup', foreign_key: :assign_graduation_group_id, optional: true # 分配的互评组 + belongs_to :graduation_work, optional: true + scope :temporary, -> {where(temporary: 1)} + scope :formal, -> {where(temporary: 0)} + scope :temporary_delete, -> {where(temporary: 2)} + scope :temporary_formal, -> {where(temporary: [0, 1])} end diff --git a/app/models/graduation_work.rb b/app/models/graduation_work.rb index c7420ffef..96dce0c49 100644 --- a/app/models/graduation_work.rb +++ b/app/models/graduation_work.rb @@ -6,10 +6,18 @@ class GraduationWork < ApplicationRecord belongs_to :graduation_task, optional: true belongs_to :commit_user, class_name: 'User', foreign_key: :commit_user_id, optional: true + belongs_to :update_user, class_name: 'User', foreign_key: :update_user_id, optional: true has_many :attachments, as: :container, dependent: :destroy has_many :tidings, as: :container, dependent: :destroy has_many :graduation_work_scores, dependent: :destroy + has_many :graduation_work_comment_assignations, dependent: :destroy + # has_many :formal_graduation_work_comment_assignations, -> { formal }, class_name: "GraduationWorkCommentAssignation" + # has_many :temporary_graduation_work_comment_assignations, -> { temporary }, class_name: "GraduationWorkCommentAssignation" + + has_many :graduation_task_group_assignations, dependent: :destroy + # has_many :formal_graduation_task_group_assignations, -> { formal }, class_name: "GraduationTaskGroupAssignation" + # has_many :temporary_graduation_task_group_assignations, -> { temporary }, class_name: "GraduationTaskGroupAssignation" validates :description, length: { maximum: 5000 } @@ -108,11 +116,29 @@ class GraduationWork < ApplicationRecord end end + # 作品被交叉评阅的次数 def cross_comment_num graduation_work_scores.where(reviewer_role: 2).group_by(&:user_id).count end + # 作品是否被评阅过 def scored? - graduation_work_scores.where.not(reviewer_role: 3).exists? + graduation_work_scores.where.not(score: nil).exists? + end + + def work_cross_teacher_ids + graduation_work_comment_assignations.temporary_formal.pluck(:user_id) + end + + def work_cross_teachers + User.where(id: work_cross_teacher_ids).map(&:real_name).join("、") + end + + def work_cross_group_ids + graduation_task_group_assignations.temporary_formal.pluck(:graduation_group_id) + end + + def work_cross_groups + course.graduation_groups.where(id: work_cross_group_ids).pluck(:name).join("、") end end diff --git a/app/models/graduation_work_comment_assignation.rb b/app/models/graduation_work_comment_assignation.rb index 33f30d2a0..7225dbcbf 100644 --- a/app/models/graduation_work_comment_assignation.rb +++ b/app/models/graduation_work_comment_assignation.rb @@ -1,8 +1,13 @@ class GraduationWorkCommentAssignation < ApplicationRecord + # temporary 0: 正式分配 1:临时分配(交叉评阅设置中临时分配的作品,点取消时会删除) 2: 删除标志 belongs_to :graduation_work belongs_to :graduation_task belongs_to :user - belongs_to :graduation_group + belongs_to :graduation_group, optional: true + scope :temporary, -> {where(temporary: 1)} + scope :formal, -> {where(temporary: 0)} + scope :temporary_delete, -> {where(temporary: 2)} + scope :temporary_formal, -> {where(temporary: [0, 1])} scope :myself, ->(user_id) {where(user_id: user_id)} end diff --git a/app/models/graduation_work_score.rb b/app/models/graduation_work_score.rb index fa978b68f..eaf59ffbd 100644 --- a/app/models/graduation_work_score.rb +++ b/app/models/graduation_work_score.rb @@ -1,4 +1,5 @@ class GraduationWorkScore < ApplicationRecord + # reviewer_role: 1 老师评分 2 交叉评分 belongs_to :graduation_work belongs_to :user belongs_to :graduation_task diff --git a/app/models/student_work.rb b/app/models/student_work.rb index b4ad834de..2e7f843ae 100644 --- a/app/models/student_work.rb +++ b/app/models/student_work.rb @@ -193,7 +193,7 @@ class StudentWork < ApplicationRecord end def scored? - student_works_scores.where.not(reviewer_role: 3).exists? + student_works_scores.where.not(reviewer_role: 3, score: nil).exists? end def work_challenge_score game, score @@ -202,7 +202,7 @@ class StudentWork < ApplicationRecord if adjust_score.present? game_score = adjust_score.score else - setting = homework_common.homework_group_setting user_id + setting = homework_common.homework_group_setting game.user_id if game.status == 2 && ((game.end_time && game.end_time < setting.end_time) || (homework_common.allow_late && game.end_time && game.end_time < homework_common.late_time)) answer_open_evaluation = homework_common.homework_detail_manual.answer_open_evaluation game_score = answer_open_evaluation ? score : (game.final_score > 0 ? game.real_score(score) : 0) diff --git a/app/services/ecs/query_course_evaluation_service.rb b/app/services/ecs/query_course_evaluation_service.rb index 22e0ce1f4..fd1619076 100644 --- a/app/services/ecs/query_course_evaluation_service.rb +++ b/app/services/ecs/query_course_evaluation_service.rb @@ -29,7 +29,7 @@ class Ecs::QueryCourseEvaluationService < ApplicationService support = subitem.ec_course_supports.find_by(ec_course_id: ec_course.id) - weight = support.weights.to_f + weight = support&.weights.to_f objective_achievement = (weight * ec_course.ec_year.calculation_value.to_f).round(3) target_total_rates = 0 diff --git a/app/services/subject_search_service.rb b/app/services/subject_search_service.rb index 2366cecc2..f69c56c88 100644 --- a/app/services/subject_search_service.rb +++ b/app/services/subject_search_service.rb @@ -12,7 +12,7 @@ class SubjectSearchService < ApplicationService type = params[:type] || "all" if type == "mine" - @subjects = User.current.shixuns.visible.unhidden + @subjects = User.current.subjects.visible.unhidden else @subjects = Subject.visible.unhidden end diff --git a/app/services/users/apply_professional_auth_service.rb b/app/services/users/apply_professional_auth_service.rb index 74ee08c85..cc6f36fff 100644 --- a/app/services/users/apply_professional_auth_service.rb +++ b/app/services/users/apply_professional_auth_service.rb @@ -38,11 +38,11 @@ class Users::ApplyProfessionalAuthService < ApplicationService move_image_file! unless params[:upload_image].to_s == 'false' - # sms_cache = Rails.cache.read("apply_pro_certification") - # if sms_cache.nil? - sms_notify_admin - # Rails.cache.write("apply_pro_certification", 1) - # end + sms_cache = Rails.cache.read("apply_pro_certification") + if sms_cache.nil? + sms_notify_admin + Rails.cache.write("apply_pro_certification", 1, expires_in: 5.minutes) + end end end diff --git a/app/services/users/apply_trail_service.rb b/app/services/users/apply_trail_service.rb index 61563c301..45abd8d1b 100644 --- a/app/services/users/apply_trail_service.rb +++ b/app/services/users/apply_trail_service.rb @@ -24,7 +24,11 @@ class Users::ApplyTrailService < ApplicationService apply.status = 1 else - send_trial_apply_notify! + sms_cache = Rails.cache.read("apply_auth") + if sms_cache.nil? + send_trial_apply_notify! + Rails.cache.write("apply_auth", 1, expires_in: 5.minutes) + end end apply.save! end diff --git a/app/views/courses/online_learning.json.jbuilder b/app/views/courses/online_learning.json.jbuilder index b48cd9e23..d6b3db136 100644 --- a/app/views/courses/online_learning.json.jbuilder +++ b/app/views/courses/online_learning.json.jbuilder @@ -1,5 +1,5 @@ json.stages @stages do |stage| - json.partial! 'stages/stage', locals: {stage: stage, user:@user, subject:@subject} + json.partial! 'stages/stage', locals: {stage: stage, user: @user, subject: @subject, myshixuns: @myshixuns} end # json.description @subject&.description @@ -7,6 +7,6 @@ end json.start_learning @start_learning json.subject_id @subject.id -json.learned @start_learning ? @course.my_subject_progress : 0 +json.learned @start_learning ? @course.my_subject_progress(@myshixuns) : 0 -json.last_shixun @start_learning ? last_subject_shixun(@user.id, @course) : "" \ No newline at end of file +json.last_shixun @start_learning ? last_subject_shixun(@course, @myshixuns) : "" \ No newline at end of file diff --git a/app/views/ecs/course_targets/with_achievement_methods.json.jbuilder b/app/views/ecs/course_targets/with_achievement_methods.json.jbuilder new file mode 100644 index 000000000..689504ec3 --- /dev/null +++ b/app/views/ecs/course_targets/with_achievement_methods.json.jbuilder @@ -0,0 +1,2 @@ + +json.course_targets @course_targets, partial: 'ecs/course_targets/shared/ec_course_target_with_achievement_methods', as: :ec_course_target diff --git a/app/views/graduation_tasks/cross_comment_setting.json.jbuilder b/app/views/graduation_tasks/cross_comment_setting.json.jbuilder new file mode 100644 index 000000000..f63bc28cc --- /dev/null +++ b/app/views/graduation_tasks/cross_comment_setting.json.jbuilder @@ -0,0 +1,30 @@ +json.work_users @work_list do |work| + json.work_id work.id + json.user_name work.user&.real_name + json.student_id work.user&.student_id + json.course_group_name @students.select{|member| member.user_id == work.user_id}.first.try(:course_group_name) + if @comment_status.to_i == 2 + json.cross_teachers work.work_cross_teachers + json.cross_teacher_ids work.work_cross_teacher_ids + elsif @comment_status.to_i == 4 + json.cross_groups work.work_cross_groups + json.cross_group_ids work.work_cross_group_ids + end +end + +json.user_count @user_count + +json.course_groups @course_groups do |group| + json.(group, :id, :name) +end + +if @comment_status.to_i == 2 + json.teachers @course.teachers.includes(:user) do |teacher| + json.user_id teacher.user_id + json.user_name teacher.user&.real_name + end +elsif @comment_status.to_i == 4 + json.graduation_groups @course.graduation_groups do |group| + json.(group, :id, :name) + end +end \ No newline at end of file diff --git a/app/views/graduation_tasks/tasks_list.json.jbuilder b/app/views/graduation_tasks/tasks_list.json.jbuilder index 5a2d7e08a..dc09d759e 100644 --- a/app/views/graduation_tasks/tasks_list.json.jbuilder +++ b/app/views/graduation_tasks/tasks_list.json.jbuilder @@ -2,6 +2,7 @@ json.partial! "public_navigation", locals: {graduation: @task, course: @course} json.user_course_identity @user_course_identity json.course_group_count @course.course_groups_count json.cross_comment @task.cross_comment +json.comment_status @task.comment_status # 课程发布才有数据 if @task.published? || @user_course_identity < Course::STUDENT # 老师身份才有的分类信息 @@ -48,6 +49,7 @@ if @task.published? || @user_course_identity < Course::STUDENT json.class_grouping_name @students.select{|student| student.user_id == work.user_id}.first.try(:course_group_name) json.ultimate_score work.ultimate_score if @task.have_grouping? + json.is_leader work.user_id == work.commit_user_id json.grouping_name work.grouping_name if @task.base_on_project json.project_info project_info work, @current_user, @user_course_identity diff --git a/app/views/graduation_works/edit.json.jbuilder b/app/views/graduation_works/edit.json.jbuilder index 254579473..30ffd6720 100644 --- a/app/views/graduation_works/edit.json.jbuilder +++ b/app/views/graduation_works/edit.json.jbuilder @@ -10,9 +10,14 @@ json.attachments @work.attachments do |atta| json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: @work.delete_atta(atta)} end -json.members @work_members do |member| - json.user_id member.user_id - json.user_name member.user.real_name - json.group_name member.course_group_name - json.student_id member.user.student_id +if @task.task_type == 2 + json.is_leader_work @work.user_id == @commit_user_id + json.members @work_members do |member| + json.user_id member.user_id + json.is_leader_work @work.user_id == @commit_user_id + json.user_name member.user.real_name + json.group_name member.course_group_name + json.student_id member.user.student_id + json.is_leader member.user_id == @commit_user_id + end end \ No newline at end of file diff --git a/app/views/graduation_works/show.json.jbuilder b/app/views/graduation_works/show.json.jbuilder index efe0f52cc..669adfbe9 100644 --- a/app/views/graduation_works/show.json.jbuilder +++ b/app/views/graduation_works/show.json.jbuilder @@ -2,9 +2,12 @@ json.partial! "graduation_tasks/public_navigation", locals: {course: @course, gr json.task_type @task.task_type json.(@work, :description, :commit_time, :update_time) +json.is_leader_work @work.user_id == @work.commit_user_id if @task.task_type == 2 + json.author_name @work.user.real_name json.is_author @is_author -json.update_user_name @work.commit_user.try(:real_name) +json.commit_user_name @work.commit_user.try(:real_name) +json.update_user_name @work.update_user.try(:real_name) json.task_status @task.status #6.12 -hs json.status task_curr_status(@task, @course)[:status] json.update_atta (!@course.is_end && @task.end_time < Time.now && @task.allow_late && (@task.late_time.nil? || @task.late_time > Time.now) && @is_author) @@ -17,9 +20,11 @@ if @task.task_type == 2 && @task.base_on_project json.project_info project_info @work, @current_user, @user_course_identity end -json.work_members @work_members.each do |member| - json.user_name member.user.real_name - json.user_login member.user.login +json.work_members @work_members.each do |work| + json.user_name work.user.real_name + json.user_login work.user.login + json.work_id work.id + json.is_leader work.user_id == work.commit_user_id end diff --git a/app/views/shixun_lists/index.json.jbuilder b/app/views/shixun_lists/index.json.jbuilder index 79ce4b09c..08baeabf9 100644 --- a/app/views/shixun_lists/index.json.jbuilder +++ b/app/views/shixun_lists/index.json.jbuilder @@ -11,12 +11,12 @@ json.shixun_list do atta_reg = /!\[.*]\(\/api\/attachments\/\d+\)/ highlights[:description]&.first&.sub!(reg, '') - highlights[:description]&.map{|des| des.gsub!(atta_reg, '')} + highlights[:description]&.map{|des| des.gsub(atta_reg, '')} highlights[:content]&.first&.sub!(reg, '') - highlights[:content]&.map{|des| des.gsub!(atta_reg, '')} + highlights[:content]&.map{|des| des.gsub(atta_reg, '')} json.title highlights.delete(:name)&.join('...') || obj.searchable_title - json.description highlights[:description]&.join('...') || Util.extract_content(obj.description)[0..300]&.sub!(atta_reg, '') + json.description highlights[:description]&.join('...') || Util.extract_content(obj.description)[0..300]&.gsub(atta_reg, '') json.content highlights json.level level_to_s(obj.trainee) diff --git a/app/views/stages/_stage.json.jbuilder b/app/views/stages/_stage.json.jbuilder index db00ad844..e5d2be82d 100644 --- a/app/views/stages/_stage.json.jbuilder +++ b/app/views/stages/_stage.json.jbuilder @@ -15,7 +15,7 @@ json.shixuns_list do json.shixun_name shixun.name json.shixun_hidden shixun.hidden json.identifier shixun.identifier - json.complete_status stage_myshixun_status(shixun, user) + json.complete_status stage_myshixun_status(myshixuns.select{|ms| ms.shixun_id == shixun.id}.first) json.shixun_status stage_shixun_status(subject.status, shixun.status, shixun.hidden) end end \ No newline at end of file diff --git a/app/views/stages/index.json.jbuilder b/app/views/stages/index.json.jbuilder index d186088c4..b7c61d9cf 100644 --- a/app/views/stages/index.json.jbuilder +++ b/app/views/stages/index.json.jbuilder @@ -1,3 +1,3 @@ json.stages @stages do |stage| - json.partial! 'stage', locals: {stage: stage, user:@user, subject:@subject} + json.partial! 'stage', locals: {stage: stage, user: @user, subject: @subject, myshixuns: @myshixuns} end \ No newline at end of file diff --git a/app/views/subject_lists/index.json.jbuilder b/app/views/subject_lists/index.json.jbuilder index 6992deb1f..63ee6dcbc 100644 --- a/app/views/subject_lists/index.json.jbuilder +++ b/app/views/subject_lists/index.json.jbuilder @@ -7,15 +7,15 @@ json.subject_list do # 去除开头标点符号 reg = /^[,。?:;‘’!“”—……、]/ # 附件的替换 - atta_reg = /!\[.*]\(\/api\/attachments\/\d+\)/ + atta_reg = /!\[.*\]\(\/api\/attachments\/\d+\)/ highlights[:description]&.first&.sub!(reg, '') - highlights[:description]&.map{|des| des.gsub!(atta_reg, '')} + highlights[:description]&.map{|des| des.gsub(atta_reg, '')} highlights[:content]&.first&.sub!(reg, '') - highlights[:content]&.map{|des| des.gsub!(atta_reg, '')} + highlights[:content]&.map{|des| des.gsub(atta_reg, '')} json.title highlights.delete(:name)&.join('...') || obj.searchable_title - json.description highlights[:description]&.join('...') || Util.extract_content(obj.description)[0..300]&.sub!(atta_reg, '') + json.description highlights[:description]&.join('...') || Util.extract_content(obj.description)[0..300]&.gsub(atta_reg, '') json.content highlights end diff --git a/config/locales/tidings/zh-CN.yml b/config/locales/tidings/zh-CN.yml index 557f3f79b..f484efdc1 100644 --- a/config/locales/tidings/zh-CN.yml +++ b/config/locales/tidings/zh-CN.yml @@ -58,8 +58,8 @@ "2_end": "你提交的试用授权申请,审核未通过
原因:%{reason}" Apply_end: "提交了试用授权申请" Course_end: "你创建了课堂:%s" - Course: - Delete_end: "你删除了课堂:%s" + DeleteCourse_end: "你删除了课堂:%s" + DeleteCourseMember_end: "%s 将你从课堂中删除了:%s" Shixun_end: "你创建了实训:%s" Subject_end: "你创建了实践课程:%s" ArchiveCourse_end: "你的课堂已经归档:%s" @@ -185,13 +185,13 @@ NearlyEnd_end: "作业的提交截止时间快到啦:%{name}" AppealNearlyEnd_end: "作品的匿评申诉时间快到啦:%{name}" EvaluationNearlyEnd_end: "作业的匿评截止时间快到啦:%{name}" - StudentWork: - true_end: "提交了作品:%s" - false_end: "重新提交了作品,建议您重新评阅:%s" + StudentWork_end: "提交了作品:%s" + ResubmitStudentWork_end: "重新提交了作品,建议您重新评阅作品:%s" StudentWorksScore: 1_end: "评阅了你的作品:%s" 2_end: "评阅了你的作品:%s" 3_end: "有人匿评了你的作品:%s" + AdjustScore_end: "调整了你的作品得分:%s" ChallengeWorkScore_end: "调整了你的作品分数:%s" StudentWorksScoresAppeal: UserAppealResult: diff --git a/config/routes.rb b/config/routes.rb index abd2a58e5..e37f447bd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -545,6 +545,7 @@ Rails.application.routes.draw do post 'relate_project' get 'cancel_relate_project' post 'revise_attachment' + delete 'delete_work' end member do @@ -562,6 +563,9 @@ Rails.application.routes.draw do post 'update_settings' get 'tasks_list' get :show_comment + get :cross_comment_setting + post :assign_works + post :commit_comment_setting end collection do diff --git a/db/migrate/20190903022313_add_graduation_work_id_to_group_assignations.rb b/db/migrate/20190903022313_add_graduation_work_id_to_group_assignations.rb new file mode 100644 index 000000000..e1db275fb --- /dev/null +++ b/db/migrate/20190903022313_add_graduation_work_id_to_group_assignations.rb @@ -0,0 +1,7 @@ +class AddGraduationWorkIdToGroupAssignations < ActiveRecord::Migration[5.2] + def change + add_column :graduation_task_group_assignations, :graduation_work_id, :integer, default: 0 + + add_index :graduation_task_group_assignations, :graduation_work_id + end +end diff --git a/db/migrate/20190903025159_add_temporary_to_graduation.rb b/db/migrate/20190903025159_add_temporary_to_graduation.rb new file mode 100644 index 000000000..adf7e1aa3 --- /dev/null +++ b/db/migrate/20190903025159_add_temporary_to_graduation.rb @@ -0,0 +1,6 @@ +class AddTemporaryToGraduation < ActiveRecord::Migration[5.2] + def change + add_column :graduation_task_group_assignations, :temporary, :integer, default: 0 + add_column :graduation_work_comment_assignations, :temporary, :integer, default: 0 + end +end diff --git a/db/migrate/20190917024120_migrate_graduation_task_comment_status.rb b/db/migrate/20190917024120_migrate_graduation_task_comment_status.rb new file mode 100644 index 000000000..3b3a3fccc --- /dev/null +++ b/db/migrate/20190917024120_migrate_graduation_task_comment_status.rb @@ -0,0 +1,5 @@ +class MigrateGraduationTaskCommentStatus < ActiveRecord::Migration[5.2] + def change + GraduationTask.where(cross_comment: true, comment_status: 0).update_all(comment_status: 2) + end +end diff --git a/db/migrate/20190923094220_add_update_user_id_to_graduation_works.rb b/db/migrate/20190923094220_add_update_user_id_to_graduation_works.rb new file mode 100644 index 000000000..718c6adde --- /dev/null +++ b/db/migrate/20190923094220_add_update_user_id_to_graduation_works.rb @@ -0,0 +1,6 @@ +class AddUpdateUserIdToGraduationWorks < ActiveRecord::Migration[5.2] + def change + add_column :graduation_works, :update_user_id, :integer + GraduationWork.update_all("update_user_id = commit_user_id") + end +end diff --git a/db/migrate/20190927091948_change_user_p02389416_exercise.rb b/db/migrate/20190927091948_change_user_p02389416_exercise.rb new file mode 100644 index 000000000..c4026f75b --- /dev/null +++ b/db/migrate/20190927091948_change_user_p02389416_exercise.rb @@ -0,0 +1,33 @@ +class ChangeUserP02389416Exercise < ActiveRecord::Migration[5.2] + def change + puts "====> start_to_create user exercise_answer" + + #分别为第8,11,14,15,16,20,21,26 + # 分数分别为:2分,2分,5分,2分,2分,2分,2分,2分 合计19分 + question_ids = [37411,37414,37417,37418,37419,37423,37424,37429] + choice_ids = [117788,117797,117806,117809,117811,117816,117818,117828] + question_scores = [2,2,5,2,2,2,2,2] + question_ids.each_with_index do |q, index| + ex_exercise_user = ExerciseAnswer.where(user_id: 45442, exercise_question_id: q, exercise_choice_id: choice_ids[index]) + if ex_exercise_user.exists? + ex_exercise_user.first.update_attribute(:score,question_scores[index]) + else + ExerciseAnswer.create(user_id: 45442, exercise_question_id: q, exercise_choice_id: choice_ids[index], score: question_scores[index]) + end + end + ex_user = ExerciseUser.where(user_id: 45442, exercise_id: 2561)&.first + if ex_user.present? + if ex_user.score > 65 || ex_user.objective_score > 65 + ex_user.update_attributes(score: 65, objective_score: 65) + else + obj_score = ex_user.objective_score.to_i + 19 + total_score = ex_user.score.to_i + 19 + + ex_user.update_attributes(score: total_score, objective_score: obj_score) + end + + end + + puts "====> end_to_create user exercise_answer" + end +end diff --git a/lib/tasks/graduation_task.rake b/lib/tasks/graduation_task.rake index 58f7764d0..4d8bf80b8 100644 --- a/lib/tasks/graduation_task.rake +++ b/lib/tasks/graduation_task.rake @@ -43,6 +43,7 @@ namespace :graduation_task do task :cross_comment_start => :environment do tasks = GraduationTask.where("cross_comment = 1 and comment_time is not null and comment_time <= '#{Time.now}' and status = 2") tasks.each do |task| + # 改成设置时都实时分配 if task.comment_status == 4 GraduationTaskCrossCommentJob.perform_later(task.id) end diff --git a/public/favicon.ico b/public/favicon.ico old mode 100644 new mode 100755 diff --git a/public/react/config/webpack.config.dev.js b/public/react/config/webpack.config.dev.js index 819854745..bb8a4c2c5 100644 --- a/public/react/config/webpack.config.dev.js +++ b/public/react/config/webpack.config.dev.js @@ -33,7 +33,7 @@ module.exports = { // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s // devtool: "cheap-module-eval-source-map", // 开启调试 - // devtool: "eval-source-map", // 开启调试 + devtool: "source-map", // 开启调试 // These are the "entry points" to our application. // This means they will be the "root" imports that are included in JS bundle. // The first two entry points enable "hot" CSS and auto-refreshes for JS. diff --git a/public/react/public/index.html b/public/react/public/index.html index 4fb3fa791..5de8e13b5 100755 --- a/public/react/public/index.html +++ b/public/react/public/index.html @@ -3,6 +3,7 @@ + diff --git a/public/react/src/App.css b/public/react/src/App.css index 1c8ce15e1..07d3d718d 100644 --- a/public/react/src/App.css +++ b/public/react/src/App.css @@ -92,6 +92,10 @@ html, body { .formItemInline .ant-form-item-control-wrapper { flex: 1; } +/* AutoComplete placeholder 不显示的问题 */ +.ant-select-auto-complete.ant-select .ant-select-selection__placeholder { + z-index: 2; +} /* 兼容性 */ diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index 05baee2af..4229ac70e 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -33,6 +33,7 @@ if (isDev) { } window._debugType = debugType; export function initAxiosInterceptors(props) { + initOnlineOfflineListener() // TODO 避免重复的请求 https://github.com/axios/axios#cancellation // https://github.com/axios/axios/issues/1497 @@ -86,9 +87,9 @@ export function initAxiosInterceptors(props) { } config.url = `${proxy}${url}`; if (config.url.indexOf('?') == -1) { - config.url = `${config.url}?debug=${debugType}` + config.url = `${config.url}?debug=${debugType}`; } else { - config.url = `${config.url}&debug=${debugType}` + config.url = `${config.url}&debug=${debugType}`; } } else { // 加api前缀 @@ -206,4 +207,28 @@ export function initAxiosInterceptors(props) { }); // ----------------------------------------------------------------------------------- +} + + +function initOnlineOfflineListener() { + const $ = window.$ + $(window).bind("online", () => { + notification.destroy() + notification.success({ + duration: null, + message: '网络恢复正常', + description: + '网络恢复正常,感谢使用。', + }) + }); + $(window).bind("offline", () => { + notification.destroy() + + notification.warning({ + duration: null, + message: '网络异常', + description: + '网络异常,请检测网络后重试。', + }) + }); } \ No newline at end of file diff --git a/public/react/src/modules/comment/CommentItemMDEditor.js b/public/react/src/modules/comment/CommentItemMDEditor.js index 98afa4228..8c49d356f 100644 --- a/public/react/src/modules/comment/CommentItemMDEditor.js +++ b/public/react/src/modules/comment/CommentItemMDEditor.js @@ -110,7 +110,7 @@ class CommentItemMDEditor extends Component { 0?1442652658 -
diff --git a/public/react/src/modules/courses/boards/index.js b/public/react/src/modules/courses/boards/index.js index 6d1c402ce..b1ada5bb5 100644 --- a/public/react/src/modules/courses/boards/index.js +++ b/public/react/src/modules/courses/boards/index.js @@ -116,6 +116,7 @@ class Boards extends Component{ this.setState({ isSpin:true }) + this.clearAllCheck() this.fetchAll(null, 1) } } diff --git a/public/react/src/modules/courses/common/ModalWrapper.js b/public/react/src/modules/courses/common/ModalWrapper.js index e92a508d6..8b7e87692 100644 --- a/public/react/src/modules/courses/common/ModalWrapper.js +++ b/public/react/src/modules/courses/common/ModalWrapper.js @@ -1,5 +1,5 @@ import React,{ Component } from "react"; -import { Modal,Input, Checkbox} from "antd"; +import { Modal,Input, Checkbox, Spin} from "antd"; import '../css/members.css' class ModalWrapper extends Component{ @@ -23,7 +23,7 @@ class ModalWrapper extends Component{ } render(){ let {flag, visible}=this.state - let { onOk, cancelText, okText, title, width, className, bottomRender}=this.props; + let { onOk, cancelText, okText, title, width, className, bottomRender, loading}=this.props; return( :"" } +
{this.props.children} {this.props.checkBoxValuestype===true?
@@ -59,6 +60,7 @@ class ModalWrapper extends Component{
{ bottomRender }
+
) } diff --git a/public/react/src/modules/courses/coursesPublic/NewShixunModel.js b/public/react/src/modules/courses/coursesPublic/NewShixunModel.js index bae89a7ba..5fe9c8aa0 100644 --- a/public/react/src/modules/courses/coursesPublic/NewShixunModel.js +++ b/public/react/src/modules/courses/coursesPublic/NewShixunModel.js @@ -19,19 +19,30 @@ class NewShixunModel extends Component{ order:'desc', diff:0, limit:15, + sort:"myshixuns_count" } } componentDidMount() { - let{page,type,keyword,order,diff,limit,status}=this.state; - this.getdatalist(page,type,status,keyword,order,diff,limit) + let{page,type,keyword,order,diff,limit,status,sort}=this.state; + if(this.props.type==='shixuns'){ + this.getdatalist(page,type,status,keyword,order,diff,limit) + }else{ + this.getdatalist(page,type,undefined,keyword,order,undefined,limit,undefined,sort); + } + } - getdatalist=(page,type,newstatus,keyword,order,diff,limit,pagetype)=>{ + getdatalist=(page,type,newstatus,keyword,order,diff,limit,pagetype,sort)=>{ this.setState({ isspinning:true }) let status=this.props.statustype===undefined?newstatus:'published'; - let url="/shixun_lists.json" + let url; + if(this.props.type==='shixuns'){ + url="/shixun_lists.json"; + }else{ + url="/subject_lists.json"; + } axios.get(url,{params:{ page, type, @@ -39,20 +50,21 @@ class NewShixunModel extends Component{ keyword, order, diff, - limit + limit, + sort }}).then((response) => { if(response.data){ if(pagetype===undefined){ this.setState({ - shixun_list:response.data.shixun_list, - shixuns_count:response.data.shixuns_count, + shixun_list:response.data.shixun_list===undefined?response.data.subject_list:response.data.shixun_list, + shixuns_count:response.data.shixuns_count===undefined?response.data.subjects_count:response.data.shixuns_count, Grouplist:[], isspinning:false }) }else if(pagetype==="pagetype"){ this.setState({ - shixun_list:response.data.shixun_list, - shixuns_count:response.data.shixuns_count, + shixun_list:response.data.shixun_list===undefined?response.data.subject_list:response.data.shixun_list, + shixuns_count:response.data.shixuns_count===undefined?response.data.subjects_count:response.data.shixuns_count, isspinning:false }) } @@ -127,8 +139,13 @@ class NewShixunModel extends Component{ newallGrouplist.push({page:pageNumber,list:[]}) } - let{type,status,keyword,order,diff,limit}=this.state; - this.getdatalist(pageNumber,type,status,keyword,order,diff,limit,"pagetype") + let{type,status,keyword,order,diff,limit,sort}=this.state; + if(this.props.type==='shixuns'){ + this.getdatalist(pageNumber,type,status,keyword,order,diff,limit,"pagetype") + }else{ + this.getdatalist(pageNumber,type,undefined,keyword,order,undefined,limit,"pagetype",sort); + } + this.setState({ page:pageNumber, allGrouplist:newallGrouplist @@ -142,8 +159,14 @@ class NewShixunModel extends Component{ keyword:undefined, page:1 }) - let{status,order,diff,limit}=this.state; - this.getdatalist(1,value,status,undefined,order,diff,limit) + let{status,order,diff,limit,sort}=this.state; + if(this.props.type==='shixuns'){ + this.getdatalist(1,value,status,undefined,order,diff,limit) + }else{ + this.getdatalist(1,value,undefined,undefined,order,undefined,limit,undefined,sort) + } + + } updatedlist=(order)=>{ @@ -205,7 +228,7 @@ class NewShixunModel extends Component{ this.setState({ hometypepvisible:false }) - this.showNotification("请先选择实训") + this.showNotification(this.props.type==='shixuns'?"请先选择实训":"请先选择课程") return } @@ -231,33 +254,64 @@ class NewShixunModel extends Component{ this.props.pathShixun(Grouplist) return; } - let url="/courses/"+coursesId+"/homework_commons/create_shixun_homework.json"; - axios.post(url, { - category_id:this.props.category_id===null||this.props.category_id===undefined?undefined:parseInt(this.props.category_id), - shixun_ids:Grouplist, - } - ).then((response) => { - if(response.data.status===-1){ - // this.props.showNotification(response.data.message) - - }else{ - // this.props.courseshomeworkstart(response.data.category_id,response.data.homework_ids) - this.showNotification("操作成功") - this.props.homeworkupdatalists(this.props.Coursename,this.props.page,this.props.order); - this.props.hideNewShixunModelType() - - } - this.setState({ - hometypepvisible:false + if(this.props.type==='shixuns'){ + let url="/courses/"+coursesId+"/homework_commons/create_shixun_homework.json"; + axios.post(url, { + category_id:this.props.category_id===null||this.props.category_id===undefined?undefined:parseInt(this.props.category_id), + shixun_ids:Grouplist, + } + ).then((response) => { + if(response.data.status===-1){ + // this.props.showNotification(response.data.message) + + }else{ + // this.props.courseshomeworkstart(response.data.category_id,response.data.homework_ids) + this.showNotification("操作成功") + this.props.homeworkupdatalists(this.props.Coursename,this.props.page,this.props.order); + this.props.hideNewShixunModelType() + this.props.updataleftNavfun() + } + this.setState({ + hometypepvisible:false + }) + // category_id: 3 + // homework_ids: (5) [9171, 9172, 9173, 9174, 9175] + }).catch((error) => { + console.log(error) + this.setState({ + hometypepvisible:false + }) }) - // category_id: 3 - // homework_ids: (5) [9171, 9172, 9173, 9174, 9175] - }).catch((error) => { - console.log(error) - this.setState({ - hometypepvisible:false + }else{ + let url="/courses/"+coursesId+"/homework_commons/create_subject_homework.json"; + axios.post(url, { + category_id:this.props.category_id===null||this.props.category_id===undefined?undefined:parseInt(this.props.category_id), + subject_ids:Grouplist, + } + ).then((response) => { + if(response.data.status===-1){ + // this.props.showNotification(response.data.message) + + }else{ + // this.props.courseshomeworkstart(response.data.category_id,response.data.homework_ids) + this.showNotification("操作成功") + this.props.homeworkupdatalists(this.props.Coursename,this.props.page,this.props.order); + this.props.hideNewShixunModelType() + this.props.updataleftNavfun() + } + this.setState({ + hometypepvisible:false + }) + // category_id: 3 + // homework_ids: (5) [9171, 9172, 9173, 9174, 9175] + }).catch((error) => { + console.log(error) + this.setState({ + hometypepvisible:false + }) }) - }) + } + } poststatus=(status)=>{ @@ -268,9 +322,37 @@ class NewShixunModel extends Component{ this.getdatalist(page,type,status,keyword,order,diff,limit) } + updatepathlist=(sorts,orders)=>{ + let{page,type,keyword,order,diff,limit,status,sort}=this.state; + let seartorders; + if(sort===sorts){ + if(orders==="desc"){ + this.setState({ + sort:sorts, + order:"asc" + }) + seartorders="asc" + }else{ + this.setState({ + sort:sorts, + order:"desc" + }) + seartorders="desc" + } + }else{ + this.setState({ + sort:sorts, + order:"desc" + }) + seartorders=orders + } + + this.getdatalist(page,type,undefined,keyword,seartorders,undefined,limit,undefined,sorts) + + } render() { - let {diff,Grouplist,status,shixun_list,shixuns_count,page,type,order}=this.state; + let {diff,Grouplist,status,shixun_list,shixuns_count,page,type,order,sort}=this.state; // let {visible,patheditarry}=this.props; // console.log(Grouplist) // console.log(allGrouplist) @@ -331,7 +413,7 @@ class NewShixunModel extends Component{ ); - + console.log(shixun_list) return(
@@ -355,7 +437,7 @@ class NewShixunModel extends Component{ closable={true} destroyOnClose={true} onClose={()=>this.props.hideNewShixunModelType()} - visible={this.props.NewShixunModelType} + visible={this.props.type==='shixuns'?this.props.NewShixunModelType:this.props.shixunpath} height={'100%'} > @@ -380,7 +462,7 @@ class NewShixunModel extends Component{ 搜索} onInput={(e)=>this.setdatafunsval(e)} @@ -391,34 +473,50 @@ class NewShixunModel extends Component{
- 已选 {Grouplist.length} 个实训 - {shixuns_count===undefined?"":shixuns_count} 个实训 + 已选 {Grouplist.length} 个{this.props.type==='shixuns'?'实训':'课程'} + {shixuns_count===undefined?"":shixuns_count} 个{this.props.type==='shixuns'?'实训':'课程'} - + {this.props.type==='shixuns'?"": + this.updatepathlist("shixuns_count",order)}>实训数 + + + + + } + + {this.props.type==='shixuns'?"": + this.updatepathlist("myshixuns_count",order)}>学习人数 + + + + + } + + {this.props.type==='shixuns'? this.updatedlist(order)}>学习人数 - + :""} - {this.props.statustype===undefined? + {this.props.type==='shixuns'?this.props.statustype===undefined? {status==='all'?"发布状态":status==='published'?"已发布":status==="unpublished"?"未发布":""} - :""} + :"":""} - + {this.props.type==='shixuns'? {diff===0?"难度":diff===1?"初级":diff===2?"中级":diff===3?"高级":diff===4?"顶级":""} - + :""}
{/*this.props.hideNewShixunModelType()}>返回*/} - this.belongto("mine")}>我的实训 - this.belongto("all")}>全部实训 + this.belongto("mine")}>我的{this.props.type==='shixuns'?'实训':"课程"} + this.belongto("all")}>全部{this.props.type==='shixuns'?'实训':"课程"}
@@ -438,7 +536,7 @@ class NewShixunModel extends Component{ className="fl task-hide edu-txt-left mt3" name="shixun_homework[]" > - @@ -461,7 +559,7 @@ class NewShixunModel extends Component{ {JSON.stringify(item.description) == "{}"?"":
} - {item.challenge_names.length===0?"":
+ {item.challenge_names===undefined?"":item.challenge_names.length===0?"":
{item.challenge_names.map((item,key)=>{ return( 第{key+1}关:{item} @@ -490,15 +588,21 @@ class NewShixunModel extends Component{ } `} - + {this.props.type==='shixuns'? {item.author_name} {item.author_school_name} 难度系数:{item.level} 学习人数:{item.study_count} - - + : + + {item.author_name} + {item.author_school_name} + 学习人数:{item.myshixuns_count} + 章节:{item.stage_count} + 实训:{item.shixuns_count} + }
- {item.subjects.length===0?"":this.ItsCourse(item.subjects)}> + {item.subjects===undefined?"":item.subjects.length===0?"":this.ItsCourse(item.subjects)}> 所属课程 diff --git a/public/react/src/modules/courses/graduation/style.css b/public/react/src/modules/courses/graduation/style.css index c704a9c93..cf438a6a4 100644 --- a/public/react/src/modules/courses/graduation/style.css +++ b/public/react/src/modules/courses/graduation/style.css @@ -43,3 +43,14 @@ .TopicDetailTable .bottomBody li{border-bottom: 1px solid #eee;clear: both;} .TopicDetailTable .bottomBody li:last-child{border-bottom: none;} +.acrossSureBtn{ + width: 40px; + height: 24px; + line-height: 18px; + /* border: 1px solid rgba(76,172,255,1); */ + /* color: #4CACFF!important; */ + float: left; + /* border-radius: 4px; */ + text-align: center; +} + diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationAcross.js b/public/react/src/modules/courses/graduation/tasks/GraduationAcross.js new file mode 100644 index 000000000..46b1533f7 --- /dev/null +++ b/public/react/src/modules/courses/graduation/tasks/GraduationAcross.js @@ -0,0 +1,554 @@ +import React, { Component } from 'react'; + +import { Modal , Radio , Table , Pagination , Select ,Divider ,Icon , Input,Checkbox } from "antd"; +import {Link} from 'react-router-dom' +import axios from 'axios'; + +import '../style.css' + + +const RadioGroup = Radio.Group; + +const { Option } = Select; +const $ = window.$; + +const bindTableColumn=(that)=>{ + let { course_groups }=that.state + const filter=course_groups && course_groups.map((i,key)=>{ + let list={ + value: i.id, + text: i.name + } + return list; + }) + const columns = [ + { + title: '序号', + dataIndex: 'index', + key: 'index', + width:"50px", + className:"edu-txt-center", + render: (id, student, index) => { + return (that.state.page - 1) * that.state.limit + index + 1 + } + }, + { + title: '姓名', + dataIndex: 'user_name', + key: 'user_name', + render: (user_name, line, index) => { + return( + {user_name} + ) + } + },{ + title: '学号', + dataIndex: 'student_id', + key: 'student_id', + render: (student_id, line, index) => { + return( + {student_id} + ) + } + },{ + title: '分班', + dataIndex: 'course_group_name', + key: 'course_group_name', + filters:filter, + render: (course_group_name, line, index) => { + return( + {course_group_name} + ) + } + } + ]; + if(that.state.comment_status == 2){ + columns.push({ + title: '交叉评阅老师', + dataIndex: 'cross_teachers', + key: 'cross_teachers', + width:"200px", + render: (cross_teachers, line, index) => { + return( + {cross_teachers} + ) + } + }) + }else{ + columns.push({ + title: '答辩组', + dataIndex: 'cross_groups', + key: 'cross_groups', + width:"200px", + render: (cross_groups, line, index) => { + return( + {cross_groups} + ) + } + }) + } + + if(course_groups&&course_groups.length===0){ + columns.some((item,key)=> { + if (item.title === "分班") { + columns.splice(key, 1) + return true + } + } + ) + } + return columns; +} +class GraduationAcross extends Component{ + constructor(props){ + super(props); + this.state={ + comment_status:2, + page:1, + limit:7, + group_ids:undefined, + users:undefined, + user_count:undefined, + graduation_groups:undefined, + course_groups:undefined, + teachers:undefined, + tableLoading:false, + chooseCount:0, + chooseId:undefined, + AcrossTeamIds:undefined, + searchValue:undefined, + showflag:false + } + } + + + + // 根据分班筛选 + filterByGroup=(value,record)=>{ + console.log(value); + console.log(record) + } + + // 切换分配方式 + funcommentstatus = (e) =>{ + this.setState({ + comment_status:e.target.value, + chooseCount:0, + chooseId:[], + AcrossTeamIds:undefined, + searchValue:undefined, + showflag:false, + page:1 + }) + let { group_ids }=this.state; + this.getList(1,group_ids,e.target.value); + } + + componentDidMount =()=>{ + let { comment_status }=this.props; + let { page,group_ids }=this.state; + this.setState({ + comment_status + }) + + this.getList(page,group_ids,comment_status); + + window.addEventListener('click', this.clickOther) + } + + clickOther = (e) =>{ + if(e.target && e.target.matches('#acrossContent') || e.target.matches(".ant-modal-body") + || e.target.matches(".acrossfoot") || e.target.matches(".acrossHead") || e.target.matches ('.ant-radio-wrapper') || + e.target.matches("th") || e.target.matches("td")) { + this.setState({ + showflag:false + }) + } + } + + componentWillUnmount() { + window.removeEventListener('click', this.clickOther); + } + + getList=(page,group_ids,comment_status)=>{ + let { limit }=this.state; + let { task_Id }=this.props; + this.setState({ + tableLoading:true + }) + let url=`/graduation_tasks/${task_Id}/cross_comment_setting.json`; + axios.get((url),{params:{ + page,limit,group_ids,comment_status + }}).then((result)=>{ + if(result){ + this.setState({ + users:result.data.work_users && result.data.work_users.map((item,key)=>{ + let list = { + key:item.work_id, + course_group_name:item.course_group_name, + cross_teachers: item.cross_teachers, + student_id:item.student_id, + user_name:item.user_name, + work_id:item.work_id + } + return list; + }), + user_count:result.data.user_count, + graduation_groups:result.data.graduation_groups, + course_groups:result.data.course_groups, + teachers:result.data.teachers, + tableLoading:false, + // AcrossTeamIds:result.data + }) + } + }).catch((error)=>{ + this.setState({ + tableLoading:false + }) + console.log(error); + }) + } + + // 切换分页 + onPageChange=(page)=>{ + this.setState({ + page, + showflag:false + }) + let{group_ids,comment_status}=this.state; + this.getList(page,group_ids,comment_status); + } + + // 下拉切换 + changeSelect = (AcrossTeamIds) =>{ + console.log(AcrossTeamIds) + this.setState({ + AcrossTeamIds + }) + } + + // 重置 + clearSelect =()=>{ + this.setState({ + AcrossTeamIds:undefined, + searchValue:undefined + }) + } + + // 确定分配 + sureAcross=()=>{ + let { AcrossTeamIds , chooseId , group_ids , comment_status,page }=this.state; + let { task_Id }=this.props; + + let type = comment_status == 2 ? "user_ids" : "graduation_group_ids"; + + let url=`/graduation_tasks/${task_Id}/assign_works.json`; + if(!AcrossTeamIds || (AcrossTeamIds && AcrossTeamIds.length==0)){ + this.props.showNotification(`请先选择${ comment_status == 2 ? "老师": "答辩组" }!`); + return; + } + if(!chooseId || (chooseId && chooseId.length==0)){ + this.props.showNotification("请先选择毕设作品!"); + return; + } + axios.post((url),{ + [type]:AcrossTeamIds, + work_ids:chooseId + }).then((result)=>{ + if(result){ + this.props.showNotification(result.data.message); + this.getList(page,group_ids,comment_status); + this.setState({ + showflag:false, + AcrossTeamIds:undefined, + chooseCount:0, + chooseId:[] + }) + } + }).catch((error)=>{ + console.log(error); + }) + } + + // 筛选 + handleTableChange =(pagination, filters, sorter)=>{ + console.log(filters.course_group_name) + // if(filters.course_group_name.length > 0){ + this.setState({ + page:1, + group_ids:filters.course_group_name + }) + let { comment_status }= this.state; + this.getList(1,filters.course_group_name,comment_status); + // } + } + + // 下拉搜索 + changeSearchValue=(e)=>{ + + this.setState({ + searchValue:e.target.value + }) + } + // 显示下拉 + changeFlag=(flag)=>{ + this.setState({ + showflag:flag + }) + } + + checkonChange=(e,list)=>{ + let newlist=[] + // AcrossTeamIds + let {comment_status}=this.state; + if(e.target.checked===true){ + if(comment_status===2){ + list.map((item,key)=>{ + newlist.push(String(item.user_id)) + }) + this.setState({ + AcrossTeamIds:newlist + }) + }else{ + list.map((item,key)=>{ + newlist.push(String(item.id)) + }) + this.setState({ + AcrossTeamIds:newlist + }) + } + }else{ + this.setState({ + AcrossTeamIds:undefined + }) + } + } + render(){ + let { + comment_status, + users, + user_count, + graduation_groups, + course_groups, + teachers, + page, + limit, + tableLoading, + chooseCount, + chooseId, + AcrossTeamIds, + searchValue,showflag + } = this.state; + let { modalVisible } = this.props; + let courseId = this.props.match.params.coursesId; + + const radioStyle = { + display: 'block', + height: '30px', + lineHeight: '30px', + marginRight:'0px' + }; + + + + const rowSelection = { + // 选中行的key,选中行 + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + chooseId:selectedRowKeys, + chooseCount:selectedRowKeys.length, + showflag:false + }) + console.log(selectedRowKeys); + }, + selectedRowKeys:chooseId, + getCheckboxProps: record => ({ + disabled: record.name === 'Disabled User', // Column configuration not to be checked + name: record.name, + }), + }; + + + // 筛选下拉列表 + const teacherList = searchValue ? teachers&&teachers.filter(e=>e.user_name.indexOf(searchValue)>-1) : teachers; + const course_groupsList = searchValue ? course_groups&&course_groups.filter(e=>e.name.indexOf(searchValue)>-1) : course_groups; + return( + + {modalVisible===true?:""} +
this.props.modalCloss()}> + +
+ +
+ 评阅分配方式: + + + 手动分配评阅(逐一指定每个学生的交叉评阅老师) + 答辩组分配评阅(将老师加入不同答辩组,指定每个学生的交叉评阅答辩组, + + 立即设置答辩组 + + + +
+
+ 已选 { chooseCount == 0 ? 0 : {chooseCount}} 个 + + 分配给{ comment_status && comment_status == 2 ? "老师":"答辩组"}: + + +
:""} + {comment_status != 2 &&course_groups&&course_groups.length>10?
+ +
:""} + {comment_status == 2 &&teacherList&&teacherList.length>2? this.checkonChange(e,teacherList)}>全选:""} + {comment_status != 2 &&course_groupsList&&course_groupsList.length>2? this.checkonChange(e,course_groupsList)}>全选:""} + {menu} + +
+ 提交 + 重置 +
+
+ )} + > + { comment_status == 2 ? + teacherList && teacherList.map((i,key)=>{ + return + }): + course_groupsList && course_groupsList.map((i,key)=>{ + return + }) + } + + + +
+ {/*{*/} + {/**/} + {/*}*/} +
+
+
+ { + user_count > limit ? + :"" + } +
+
+ 取消 + 确认 +
+
+ + ) + } +} +export default GraduationAcross; \ No newline at end of file diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js index 0aff1a1bd..0a7cf509d 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js @@ -10,6 +10,7 @@ import HomeworkModal from "../../coursesPublic/HomeworkModal"; import AccessoryModal from "../../coursesPublic/AccessoryModal"; import Associationmodel from '../../coursesPublic/Associationmodel'; import CoursesListType from '../../coursesPublic/CoursesListType'; +import GraduationAcross from "./GraduationAcross"; import moment from 'moment'; import "../../css/members.css" import "../../css/Courses.css" @@ -58,7 +59,8 @@ class GraduationTaskDetail extends Component{ Modalstype:undefined, Modalstopval:undefined, ModalCancel:undefined, - ModalSave:undefined + ModalSave:undefined, + acrossVisible:undefined } } componentDidMount(){ @@ -80,6 +82,21 @@ class GraduationTaskDetail extends Component{ }) } + + // 交叉评阅设置弹框 + openAcross=()=>{ + this.setState({ + acrossVisible:true + }) + } + closeAcross=()=>{ + this.setState({ + acrossVisible:false + }) + } + + + //返回 goback=()=>{ // let courseId=this.props.match.params.coursesId; @@ -190,7 +207,6 @@ class GraduationTaskDetail extends Component{ } // 取消 cancelmodel=()=>{ - debugger this.setState({ Modalstype:false, Loadtype:false, @@ -291,11 +307,13 @@ class GraduationTaskDetail extends Component{ Modalstype, Modalstopval, ModalCancel, - ModalSave + ModalSave, + acrossVisible } = this.state const commom = { - setTab:this.setTab + setTab:this.setTab, + getdatas:this.getdatas } return(
@@ -353,6 +371,20 @@ class GraduationTaskDetail extends Component{ destroyOnClose={true} centered={true} /> + + { + acrossVisible && + + } +

{questionslist.course_name} > @@ -419,9 +451,9 @@ class GraduationTaskDetail extends Component{ :""} {questionslist.work_status===undefined||questionslist.work_status===null||questionslist.work_status.length===0?"":questionslist.work_status.map((item,key)=>{ return( - - {item==="提交作品"?提交作品:""} - {item==="补交作品"?补交作品:""} + + {item==="提交作品"?提交作品:""} + {item==="补交作品"?补交作品:""} {item==="修改作品"?修改作品:""} {item==="查看作品"?查看作品 :""} {item==="创建项目"?创建项目:""} @@ -436,7 +468,7 @@ class GraduationTaskDetail extends Component{ {/*项目在线质量检测*/} { this.props.isAdmin() ? questionslist.status===1 ? { this.end()} }>立即截止 : "" : "" } { this.props.isAdmin() ? questionslist.status===0 ? { this.publish()} }>立即发布 : "" : "" } - + { this.props.isAdmin() && questionslist.cross_comment ? 交叉评阅设置 : "" } { this.props.isAdmin() ? 编辑任务 : "" }

diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js index 7c697e31b..02e7177fa 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js @@ -335,6 +335,7 @@ class GraduationTasksSubmitedit extends Component{ } delecttask_status=(id)=>{ + let{selectmemberslist,task_status}=this.state; let newlist=task_status; let selects=selectmemberslist; @@ -350,6 +351,8 @@ class GraduationTasksSubmitedit extends Component{ selects.splice(z,1) } } + console.log(newlist) + console.log(selects) this.setState({ task_status:newlist, selectmemberslist:selects @@ -379,11 +382,9 @@ class GraduationTasksSubmitedit extends Component{ let userids=[]; for(var list of selectmemberslist){ - if(list.user_id!=undefined&&list.user_id!=null){ - userids.push(list.user_id) - } - + userids.push(list.user_id) + } } let listid=[]; @@ -392,6 +393,7 @@ class GraduationTasksSubmitedit extends Component{ listid.push(list.response == undefined ? list.id : list.response.id) } + console.log(userids) this.props.form.validateFields((err, values) => { @@ -401,6 +403,7 @@ class GraduationTasksSubmitedit extends Component{ // debugger return } + if(workslist.task_type===2){ if(userids.length { console.log(error) + this.setState({ + spinnings:false + }) }) @@ -785,6 +791,7 @@ class GraduationTasksSubmitedit extends Component{
{selectmemberslist&&selectmemberslist.map((item,key)=>{ + console.log(item) if(item.group_name!=undefined) { return (
{this.props.title && {this.props.title}} + watch={false} height={160} className={errorMessage ? 'editorInputError' : ''} imageExpand={true}> { showSameScore == true &&
整组同评 (选中,则本次评阅对象指小组全部成员,否则仅评阅此成员1人 ) diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js index 5ca6ee537..ff7564b8f 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js @@ -343,6 +343,7 @@ class GraduationTaskssettingapp extends Component{ } updatesfuncrosscomment=(types,newlatetime,newcommenttime)=>{ + debugger let {endtimetype}=this.state; if(types===1){ this.setState({ @@ -372,7 +373,7 @@ class GraduationTaskssettingapp extends Component{ funcrosscomment=(e)=>{ let {latetime,end_time,allowlate,commenttime,commenttimeone}=this.state; let commenttimetype=commenttime===null||commenttime===""; - +debugger let newlatetimea=moment(new Date()).add(7, 'days').format("YYYY-MM-DD HH:mm"); let newcommenttimea=moment(new Date()).format("YYYY-MM-DD HH:mm"); @@ -386,7 +387,7 @@ class GraduationTaskssettingapp extends Component{ let newcommenttimed=moment(end_time).add(8, 'days').format("YYYY-MM-DD HH:mm"); if(e.target.checked===true){ - if(commenttimetype===true){ + debugger if(allowlate===1||allowlate===true){ if(latetime===null||latetime===""){ @@ -401,12 +402,6 @@ class GraduationTaskssettingapp extends Component{ this.updatesfuncrosscomment(2,newend_timed,newcommenttimed) } } - }else{ - this.setState({ - crosscomment:e.target.checked, - commenttime:commenttimeone, - }) - } }else{ this.setState({ @@ -545,25 +540,29 @@ class GraduationTaskssettingapp extends Component{ endTimetypes:false }) } - + debugger if(moment(latetime)<=moment(publish_time)){ + + debugger this.setState({ latetimetype:true, latetimetypeval:"结束时间必须晚于发布时间" }) return }else if(moment(latetime)<=moment(end_time)){ + debugger this.setState({ latetimetype:true, latetimetypeval:"结束时间必须晚于截止时间" }) return }else{ + debugger this.setState({ latetimetype:false }) } - + debugger if(crosscomment===true){ if(this.state.commenttime===undefined||this.state.commenttime===null||this.state.commenttime===""){ @@ -726,7 +725,9 @@ class GraduationTaskssettingapp extends Component{ starttime:undefined, course_groupslist:[], }) - this.props.showNotification(resulet.data.message); + this.props.showNotification(resulet.data.message); + //调用父组件方法,刷新按钮 + this.props.getdatas(); } } }).catch((error)=>{ @@ -948,9 +949,7 @@ class GraduationTaskssettingapp extends Component{ // // console.log(moment(publish_time)) - // console.log(this.props.isSuperAdmin()) - - + console.log(commenttime) return( @@ -1206,7 +1205,7 @@ class GraduationTaskssettingapp extends Component{ {crosscomment===true&&commenttimetype===true?
{commenttimevalue}
:""}
-
+ {/*
评阅方式: @@ -1221,10 +1220,10 @@ class GraduationTaskssettingapp extends Component{ -
+
*/} -
+ {/*
评阅数: @@ -1261,7 +1260,7 @@ class GraduationTaskssettingapp extends Component{ ) })} -
+
*/}
:""} diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js index 0720d7240..318955479 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js @@ -514,6 +514,7 @@ class GraduationTaskssettinglist extends Component{ } showAllocationModal=(id)=>{ + this.setState({ Allocationtype:true, operationId:id @@ -847,28 +848,28 @@ class GraduationTaskssettinglist extends Component{ ), - }, { + }, { title: '操作', key: 'operation', width:'100px', dataIndex: 'operation', className:'edu-txt-center', render: operation => ( -
+
{this.props.isAdmin()?operation.map((tag,key) => { return( { tag.name && - 调整学生最终成绩
其它历史评分将全部失效:""}> + 调整学生最终成绩
其它历史评分将全部失效:""}> {tag.name==="评阅"? {tag.name} : - this.showModulationtype(tag.id):tag.name==="分配"?()=>this.showAllocationModal(tag.id):""}> - {tag.name} - +

this.showModulationtype(tag.id):tag.name==="分配"?taskslistdata&&taskslistdata.cross_comment===true?"":"":""}> + {tag.name==="分配"?taskslistdata&&taskslistdata.cross_comment===true?"":"":tag.name} +

}
} @@ -971,9 +972,8 @@ class GraduationTaskssettinglist extends Component{ white-space: nowrap; } .ant-table-tbody>tr>td, .ant-table-thead>tr>th{ - padding: 16px 10px + padding:16px 8px; } - ` } diff --git a/public/react/src/modules/courses/members/modal/AddStudentModal.js b/public/react/src/modules/courses/members/modal/AddStudentModal.js index ddd1164ea..efa801182 100644 --- a/public/react/src/modules/courses/members/modal/AddStudentModal.js +++ b/public/react/src/modules/courses/members/modal/AddStudentModal.js @@ -68,7 +68,7 @@ class AddStudentModal extends Component{ if (response.data.course_groups && response.data.course_groups.length) { this.setState({ course_groups: response.data.course_groups, - courseGroup: response.data.course_groups[0].id + courseGroup: '0' // response.data.course_groups[0].id }) } else { // showNotification('') @@ -268,6 +268,7 @@ class AddStudentModal extends Component{ {course_groups && course_groups.length &&
所选学生分班至(选填): + )}
diff --git a/public/react/src/modules/user/AccountPage.js b/public/react/src/modules/user/AccountPage.js index 3d34b3e13..7268bd7bb 100644 --- a/public/react/src/modules/user/AccountPage.js +++ b/public/react/src/modules/user/AccountPage.js @@ -60,7 +60,7 @@ class AccountPage extends Component { // "authentication": "uncertified", // "uncertified" | "applying" | "certified" this.setState({ basicInfo: Object.assign({}, {...result.data}, { - avatar_url: `${result.data.avatar_url}?t=${new Date().getTime()}`, + avatar_url: `${result.data.avatar_url}`, gender: result.data.gender == null || result.data.gender == undefined ? 0 : result.data.gender }) }) diff --git a/public/react/src/modules/user/account/ChangeHeaderPicModal.js b/public/react/src/modules/user/account/ChangeHeaderPicModal.js index 197e84a5c..0a2205261 100644 --- a/public/react/src/modules/user/account/ChangeHeaderPicModal.js +++ b/public/react/src/modules/user/account/ChangeHeaderPicModal.js @@ -1,5 +1,5 @@ import React, { Component } from "react"; -import { Modal } from "antd"; +import { Spin } from "antd"; import axios from 'axios' import ModalWrapper from "../../courses/common/ModalWrapper" import { Cropper, getUrl } from 'educoder' @@ -13,7 +13,7 @@ class ChangeHeaderPicModal extends Component{ constructor(props){ super(props); this.state={ - + uploading: false } } init = () => { @@ -85,12 +85,23 @@ class ChangeHeaderPicModal extends Component{ } - onOk = () => { + if (this.state.uploading == true) return; if (this.fileUploaded != true) { this.props.showNotification("请先上传图片") return; } + console.log(new Date().getTime()) + this.setState({ uploading: true }, () => { + window.setTimeout(() => { + console.log(new Date().getTime()) + this._onOk() + }, 10) + + }) + } + _onOk = () => { + var img_lg = document.getElementById(previewId); // https://github.com/niklasvh/html2canvas/issues/1908 // 截图小的显示框内的内容 @@ -115,9 +126,12 @@ class ChangeHeaderPicModal extends Component{ } else { this.doAfterUpdated(); } + this.setState({ uploading: false }) } }) .catch(function (error) { + this.setState({ uploading: false }) + console.log(error); }); }); @@ -142,6 +156,8 @@ class ChangeHeaderPicModal extends Component{ okText="保存" width={552} className="changeHeaderModal" + loading={this.state.uploading} + onCancel={() => this.setState({ uploading: false })} >