jingquan huang 5 years ago
commit e36b86b0dc

@ -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)

@ -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

@ -110,7 +110,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

@ -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)

@ -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, "试卷截止成功!")

@ -12,6 +12,7 @@ class GitsController < ApplicationController
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"}

@ -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

@ -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)

@ -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

@ -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)

@ -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

@ -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

@ -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)

@ -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

@ -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) % container&.homework_common.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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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?

@ -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"

@ -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

@ -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(core: 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

@ -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

@ -1,4 +1,5 @@
class GraduationWorkScore < ApplicationRecord
# reviewer_role 1 老师评分 2 交叉评分
belongs_to :graduation_work
belongs_to :user
belongs_to :graduation_task

@ -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)

@ -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

@ -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

@ -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

@ -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) : ""
json.last_shixun @start_learning ? last_subject_shixun(@course, @myshixuns) : ""

@ -0,0 +1,2 @@
json.course_targets @course_targets, partial: 'ecs/course_targets/shared/ec_course_target_with_achievement_methods', as: :ec_course_target

@ -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

@ -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

@ -10,9 +10,13 @@ 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.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

@ -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

@ -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

@ -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

@ -58,8 +58,8 @@
"2_end": "你提交的试用授权申请,审核未通过<br/><span>原因:%{reason}</span>"
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:

@ -540,6 +540,7 @@ Rails.application.routes.draw do
post 'relate_project'
get 'cancel_relate_project'
post 'revise_attachment'
delete 'delete_work'
end
member do
@ -557,6 +558,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

@ -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

@ -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

@ -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

@ -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

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 0 B

After

Width:  |  Height:  |  Size: 8.8 KiB

@ -32,7 +32,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: "eval-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.

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
<!--<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->
<!-- width=device-width, initial-scale=1 , shrink-to-fit=no -->
<!-- <meta name="viewport" content=""> -->

@ -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;
}
/* 兼容性 */

@ -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
@ -203,4 +204,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:
'网络异常,请检测网络后重试。',
})
});
}

@ -110,7 +110,7 @@ class CommentItemMDEditor extends Component {
<img alt="0?1442652658" height="33" src={`/images/${user.image_url}`} width="33"></img>
</a>
</div>
<div id={`reply_message_${item.id}`} className="reply_to_message commentItemMDEditor"
<div id={`reply_message_${item.id}`} className="reply_to_message commentItemMDEditor editormd-image-click-expand"
style={{ paddingTop: '0px', paddingBottom: '0px', marginTop: '36px' }}
>
<div id={`reply_message_editorMd_${item.id}`} className="editorMD" style={{ marginBottom: '0px'}}>

@ -116,6 +116,7 @@ class Boards extends Component{
this.setState({
isSpin:true
})
this.clearAllCheck()
this.fetchAll(null, 1)
}
}

@ -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(
<Modal
@ -48,6 +48,7 @@ class ModalWrapper extends Component{
}
</style>:""
}
<Spin spinning={!!this.props.loading}>
<div className="newupload_conbox clearfix">
{this.props.children}
{this.props.checkBoxValuestype===true?<div className={"mt10 color-red"}>
@ -59,6 +60,7 @@ class ModalWrapper extends Component{
</div>
{ bottomRender }
</div>
</Spin>
</Modal>
)
}

@ -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(
<div>
@ -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%'}
>
<Spin spinning={this.state.isspinning}>
@ -380,7 +462,7 @@ class NewShixunModel extends Component{
<Search
style={{ width: "780px"}}
className="packinput"
placeholder="实训信息 / 院校名称 / 创建者"
placeholder={this.props.type==='shixuns'?"实训信息 / 院校名称 / 创建者":"课程名称 / 院校名称 / 创建者"}
value={this.state.keyword}
enterButton={<span>搜索</span>}
onInput={(e)=>this.setdatafunsval(e)}
@ -391,34 +473,50 @@ class NewShixunModel extends Component{
<div className="font-12 ml5 fl">
<span className="fl color-grey-9 mr20">已选 <span className={"color-blue"}>{Grouplist.length}</span> </span>
<span className="fl color-grey-9 mr20"> <span className={"color-blue"}>{shixuns_count===undefined?"":shixuns_count}</span> </span>
<span className="fl color-grey-9 mr20">已选 <span className={"color-blue"}>{Grouplist.length}</span> {this.props.type==='shixuns'?'':''}</span>
<span className="fl color-grey-9 mr20"> <span className={"color-blue"}>{shixuns_count===undefined?"":shixuns_count}</span> {this.props.type==='shixuns'?'':''}</span>
<span className="fl color-grey-9 pointer mr30">
{this.props.type==='shixuns'?"":<span className="fl color-grey-9 pointer mr30">
<a className={" color-grey-6"} onClick={()=>this.updatepathlist("shixuns_count",order)}>实训数</a>
<sapn className="relativef ml5 " >
<i className={order==="asc"&&sort==="shixuns_count"?"iconfont icon-sanjiaoxing-up font-12 ntopsj color-grey-9 color-blue":"iconfont icon-sanjiaoxing-up font-12 ntopsj color-grey-9"}></i>
<i className={order==="desc"&&sort==="shixuns_count"?"iconfont icon-sanjiaoxing-down font-12 nyslbottomsj color-grey-9 color-blue":"iconfont icon-sanjiaoxing-down font-12 nyslbottomsj color-grey-9"}></i>
</sapn>
</span>}
{this.props.type==='shixuns'?"":<span className="fl color-grey-9 pointer mr30">
<a className={" color-grey-6"} onClick={()=>this.updatepathlist("myshixuns_count",order)}>使用人数</a>
<sapn className="relativef ml5 " >
<i className={order==="asc"&&sort==="myshixuns_count"?"iconfont icon-sanjiaoxing-up font-12 ntopsj color-grey-9 color-blue":"iconfont icon-sanjiaoxing-up font-12 ntopsj color-grey-9"}></i>
<i className={order==="desc"&&sort==="myshixuns_count"?"iconfont icon-sanjiaoxing-down font-12 nyslbottomsj color-grey-9 color-blue":"iconfont icon-sanjiaoxing-down font-12 nyslbottomsj color-grey-9"}></i>
</sapn>
</span>}
{this.props.type==='shixuns'?<span className="fl color-grey-9 pointer mr30">
<a className={" color-grey-6"} onClick={()=>this.updatedlist(order)}>学习人数</a>
<sapn className="relativef ml5 " >
<i className={order==="asc"?"iconfont icon-sanjiaoxing-up font-12 ntopsj color-grey-9 color-blue":"iconfont icon-sanjiaoxing-up font-12 ntopsj color-grey-9"}></i>
<i className={order==="desc"?"iconfont icon-sanjiaoxing-down font-12 nyslbottomsj color-grey-9 color-blue":"iconfont icon-sanjiaoxing-down font-12 nyslbottomsj color-grey-9"}></i>
</sapn>
</span>
</span>:""}
{this.props.statustype===undefined?<Dropdown overlay={statusmenus}>
{this.props.type==='shixuns'?this.props.statustype===undefined?<Dropdown overlay={statusmenus}>
<a className="ant-dropdown-link color-grey-6 mr20">
{status==='all'?"发布状态":status==='published'?"已发布":status==="unpublished"?"未发布":""}<Icon type="down" className={"color-grey-6"}/>
</a>
</Dropdown>:""}
</Dropdown>:"":""}
<Dropdown overlay={menus}>
{this.props.type==='shixuns'? <Dropdown overlay={menus}>
<a className="ant-dropdown-link color-grey-6">
{diff===0?"难度":diff===1?"初级":diff===2?"中级":diff===3?"高级":diff===4?"顶级":""}<Icon type="down" className={"color-grey-6"}/>
</a>
</Dropdown>
</Dropdown>:""}
</div>
<div className="font-12 alltopiscright ml25 fr">
{/*<span className={"fr pointer color-grey-3"} onClick={()=>this.props.hideNewShixunModelType()}>返回</span>*/}
<span className={type==="mine"?"fr topcsactive pointer color-grey-3 color-blue":"fr pointer color-grey-3"} onClick={()=>this.belongto("mine")}>我的实训</span>
<span className={type==="all"?"fr mr30 topcsactive pointer color-grey-3 color-blue":"fr mr30 pointer color-grey-3"} onClick={()=>this.belongto("all")}>全部实训</span>
<span className={type==="mine"?"fr topcsactive pointer color-grey-3 color-blue":"fr pointer color-grey-3"} onClick={()=>this.belongto("mine")}>我的{this.props.type==='shixuns'?'实训':"课程"}</span>
<span className={type==="all"?"fr mr30 topcsactive pointer color-grey-3 color-blue":"fr mr30 pointer color-grey-3"} onClick={()=>this.belongto("all")}>全部{this.props.type==='shixuns'?'实训':"课程"}</span>
</div>
</div>
@ -461,7 +559,7 @@ class NewShixunModel extends Component{
{JSON.stringify(item.description) == "{}"?"":<div className="newshixunmodelmidfont newradioStyles" dangerouslySetInnerHTML={{__html: item.description}}>
</div>}
{item.challenge_names.length===0?"":<div className="newshixunmodelbotfont">
{item.challenge_names===undefined?"":item.challenge_names.length===0?"":<div className="newshixunmodelbotfont">
{item.challenge_names.map((item,key)=>{
return(
<span>{key+1}{item}</span>
@ -498,7 +596,7 @@ class NewShixunModel extends Component{
</Breadcrumb>
</div>
{item.subjects.length===0?"":<Dropdown overlay={()=>this.ItsCourse(item.subjects)}>
{item.subjects===undefined?"":item.subjects.length===0?"":<Dropdown overlay={()=>this.ItsCourse(item.subjects)}>
<a className="ant-dropdown-link fl ml30 newshixunfont12 color-blue" >
所属课程<Icon className={"color-blue"} type="down" />
</a>

@ -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;
}

@ -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(
<span className="fl task-hide" style={{width:"69px"}} title={user_name}>{user_name}</span>
)
}
},{
title: '学号',
dataIndex: 'student_id',
key: 'student_id',
render: (student_id, line, index) => {
return(
<span className="fl task-hide" style={{width:"127px"}} title={student_id}>{student_id}</span>
)
}
},{
title: '分班',
dataIndex: 'course_group_name',
key: 'course_group_name',
filters:filter,
render: (course_group_name, line, index) => {
return(
<span className="fl task-hide" style={{width:"160px"}} title={course_group_name}>{course_group_name}</span>
)
}
}
];
if(that.state.comment_status == 2){
columns.push({
title: '交叉评阅老师',
dataIndex: 'cross_teachers',
key: 'cross_teachers',
width:"200px",
render: (cross_teachers, line, index) => {
return(
<span className="fl task-hide" style={{width:"200px",paddingRight:"20px"}} title={cross_teachers}>{cross_teachers}</span>
)
}
})
}else{
columns.push({
title: '答辩组',
dataIndex: 'cross_groups',
key: 'cross_groups',
width:"200px",
render: (cross_groups, line, index) => {
return(
<span className="fl task-hide" style={{width:"200px",paddingRight:"20px"}} title={cross_groups}>{cross_groups}</span>
)
}
})
}
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(
<Modal
className={"AcrossModal"}
title={"交叉评阅设置"}
visible={modalVisible}
closable={false}
footer={null}
width="775px"
destroyOnClose={true}
>
{modalVisible===true?<style>
{
`
body{
overflow: hidden !important;
}
.closeIcon{
font-size: 22px !important;
}
`
}
</style>:""}
<div id="closeIcon" onClick={()=>this.props.modalCloss()}>
<i className="iconfont icon-shanchudiao"></i>
</div>
<style>
{`
.AcrossModal .ant-modal-body{
padding:0px;
}
.AcrossModal span.ant-radio + *{
padding-right:0px;
}
.AcrossModal .ant-table-thead > tr > th,.AcrossModal .ant-table-tbody > tr > td{
padding:7px 5px;
border-bottom:none!important;
}
.AcrossModal .ant-table-tbody{
background:#F7FBFF;
}
.AcrossModal .ant-table-placeholder{
border:none!important;
}
.AcrossModal .ant-table-tbody .ant-table-selection-column,.AcrossModal .ant-table-thead .ant-table-selection-column{
padding-left: 23px!important;
}
.AcrossModal .ant-select-selection--multiple{
padding-top:0px;
}
.AcrossModal .ant-select-selection--multiple .ant-select-selection__rendered>ul>li,.AcrossModal .ant-select-selection--multiple>ul>li{
margin-top:3px;
margin-bottom:0px;
}
.AcrossModal .ant-select-selection__rendered{
height:30px;
line-height:30px;
overflow-y:auto;
overflow-x:hidden;
margin-right:0px;
}
.ant-table-filter-dropdown{
width:200px;
}
.ant-table-filter-dropdown .ant-dropdown-menu{
height:200px
}
.ant-dropdown-menu-item > label{
float:left
}
.ant-dropdown-menu-item > span{
float: left;
max-width: 153px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.pd8px{
padding: 8px;
}
`}
</style>
<div className="pt20 pl30 pr30 acrossHead">
<span className={"fl mt5"} style={{fontWeight: "400",color: "#05101A"}}>评阅分配方式</span>
<span>
<RadioGroup onChange={this.funcommentstatus} value={comment_status}>
<Radio style={radioStyle} value={2}>手动分配评阅<span className={"font-14 color-grey-c ml5"}>逐一指定每个学生的交叉评阅老师</span></Radio>
<Radio style={radioStyle} value={4}>答辩组分配评阅<span className={"font-14 color-grey-c ml5"}>将老师加入不同答辩组指定每个学生的交叉评阅答辩组
<a href={"/courses/"+courseId+"/teachers"} target="_blank">
<span className={"color-blue"}>立即设置答辩组</span></a>
</span></Radio>
</RadioGroup>
</span>
</div>
<div className="clearfix mb15 mt15 pl30 pr30" id="acrossContent">
<span className="fl color-grey-c mt5">已选 { chooseCount == 0 ? 0 : <span className="color-blue">{chooseCount}</span>} </span>
<span className="fr">
<span className={"fl mt5"}><span className={"color-orange"}>分配</span>{ comment_status && comment_status == 2 ? "":""}</span>
<span className={"fl"} style={{height:"32px"}} id="selectTags">
<Select
mode="tags"
placeholder={ comment_status && comment_status == 2 ? "请选择老师":"请选择答辩组"}
value={AcrossTeamIds}
style={{width:"300px",height:"30px"}}
onChange={this.changeSelect}
open={showflag}
onFocus={()=>this.changeFlag(true)}
dropdownRender={menu => (
<div id="selectDropdown">
{comment_status == 2 &&teachers&&teachers.length>10?<div className="padding10-20">
<Input
type='input'
value={searchValue}
onChange={this.changeSearchValue}
placeholder='请输入名称搜索'
style={{height:"30px"}}
className="searchInput"
></Input>
</div>:""}
{comment_status != 2 &&course_groups&&course_groups.length>10?<div className="padding10-20">
<Input
type='input'
value={searchValue}
onChange={this.changeSearchValue}
placeholder='请输入名称搜索'
style={{height:"30px"}}
className="searchInput"
></Input>
</div>:""}
{comment_status == 2 &&teacherList&&teacherList.length>2? <Checkbox className={"pd8px"} onChange={(e)=>this.checkonChange(e,teacherList)}>全选</Checkbox>:""}
{comment_status != 2 &&course_groupsList&&course_groupsList.length>2? <Checkbox className={"pd8px"} onChange={(e)=>this.checkonChange(e,course_groupsList)}>全选</Checkbox>:""}
{menu}
<Divider style={{ margin: '4px 0 0' }} />
<div style={{ padding: '8px 12px', cursor: 'pointer' }}>
<a onClick={this.sureAcross} className="acrossSureBtn color-orange">提交</a>
<a onClick={this.clearSelect} className="ml20"><span className="acrossResetBtn color-blue">重置</span></a>
</div>
</div>
)}
>
{ comment_status == 2 ?
teacherList && teacherList.map((i,key)=>{
return <Option key={i.user_id} value={String(i.user_id)}>{i.user_name}</Option>
}):
course_groupsList && course_groupsList.map((i,key)=>{
return <Option key={i.id} value={String(i.id)}>{i.name}</Option>
})
}
</Select>
</span>
</span>
</div>
{
<style>
{
`
.ant-table-thead > tr > th .anticon-filter, .ant-table-thead > tr > th .ant-table-filter-icon{
left: 40px;
}
`
}
</style>
}
<Table rowSelection={rowSelection} columns={bindTableColumn(this)} dataSource={users} pagination={false} onChange={this.handleTableChange} loading={tableLoading}></Table>
<div className="clearfix mt20 pb30 pl30 pr30 acrossfoot">
<div className="fl">
{
user_count > limit ?
<Pagination defaultCurrent={page} current={page} pageSize={limit} total={user_count} onChange={this.onPageChange}></Pagination>:""
}
</div>
<div className="fr">
<a className="task-btn color-white mr30" onClick={this.props.modalCloss}>取消</a>
<a className="task-btn task-btn-orange" onClick={this.props.modalCloss}>确认</a>
</div>
</div>
</Modal>
)
}
}
export default GraduationAcross;

@ -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(
<div className="newMain clearfix">
@ -353,6 +371,20 @@ class GraduationTaskDetail extends Component{
destroyOnClose={true}
centered={true}
/>
{
acrossVisible &&
<GraduationAcross
{...this.props}
{...this.state}
task_Id={task_Id}
modalVisible={acrossVisible}
modalCloss={this.closeAcross}
resetFun={this.resetList}
comment_status={ questionslist && questionslist.comment_status }
/>
}
<p className="clearfix mt10">
<a onClick={this.goback} className="color-grey-9 fl">{questionslist.course_name}</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
@ -419,9 +451,9 @@ class GraduationTaskDetail extends Component{
</li>:""}
{questionslist.work_status===undefined||questionslist.work_status===null||questionslist.work_status.length===0?"":questionslist.work_status.map((item,key)=>{
return(
<span key={key} className="fr mt20">
{item==="提交作品"?<a className={"fr color-blue font-16 ml20"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/works/new"}>提交作品</a>:""}
{item==="补交作品"?<a className={"fr color-blue font-16 ml20"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/works/new"}>补交作品</a>:""}
<span key={key} className="fr mt20">
{item==="提交作品"?<a className={"fr color-blue font-16 ml20"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/works/"+task_Id+"/new"}>提交作品</a>:""}
{item==="补交作品"?<a className={"fr color-blue font-16 ml20"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/works/"+task_Id+"/new"}>补交作品</a>:""}
{item==="修改作品"?<a className={"fr color-blue font-16 ml20"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/works"+"/"+ questionslist.work_id + "/edit"}>修改作品</a>:""}
{item==="查看作品"?<a className={"fr color-blue font-16 ml20"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/works"+"/"+ questionslist.work_id + "/edit"}>查看作品</a> :""}
{item==="创建项目"?<a className={"fr color-blue font-16 ml20"} href={'/projects/new'} target="_blank">创建项目</a>:""}
@ -436,7 +468,7 @@ class GraduationTaskDetail extends Component{
{/*<a className={"fr color-blue font-16"}>项目在线质量检测</a>*/}
{ this.props.isAdmin() ? questionslist.status===1 ? <a className={"fr color-blue font-16 mr20"} onClick={() => { this.end()} }>立即截止</a> : "" : "" }
{ this.props.isAdmin() ? questionslist.status===0 ? <a className={"fr color-blue font-16 mr20"} onClick={() => { this.publish()} }>立即发布</a> : "" : "" }
{ this.props.isAdmin() && questionslist.cross_comment ? <a className={"fr color-blue font-16"} onClick={this.openAcross}>交叉评阅设置</a> : "" }
{ this.props.isAdmin() ? <a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+task_Id+"/edit"}>编辑任务</a> : "" }
</div>
</div>

@ -209,7 +209,7 @@ class GraduationTasksappraiseMainEditor extends Component{
`}</style>
{this.props.title && <span className="mainEditorTitle color-grey-6">{this.props.title}</span>}
<TPMMDEditor ref={this.mdRef} mdID={'appraiseEditor'} placeholder={placeholder || "请在此输入对本作品的评语最大限制2000个字符"}
watch={false} height={160} className={errorMessage ? 'editorInputError' : ''}></TPMMDEditor>
watch={false} height={160} className={errorMessage ? 'editorInputError' : ''} imageExpand={true}></TPMMDEditor>
{ showSameScore == true && <div>
<Checkbox checked={same_score} onChange={this.same_score_change}>整组同评</Checkbox>
<span className={"font-14 color-grey-9"}>(选中则本次评阅对象指小组全部成员否则仅评阅此成员1人 )</span>

@ -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(
<React.Fragment>
@ -1206,7 +1205,7 @@ class GraduationTaskssettingapp extends Component{
{crosscomment===true&&commenttimetype===true?<div className={"color-red ml70"}>{commenttimevalue}</div>:""}
</div>
<div className={"mb20 ml30 ml87 ml87"}>
{/* <div className={"mb20 ml30 ml87 ml87"}>
<span className={"fl mt6"}>评阅方式</span>
<span>
@ -1221,10 +1220,10 @@ class GraduationTaskssettingapp extends Component{
</RadioGroup>
</span>
</div>
</div> */}
<div style={{display:crosscomment===false?"none":commentstatus===0?"none":commentstatus===2?"none":commentstatus===4?"":"none"}}>
{/* <div style={{display:crosscomment===false?"none":commentstatus===0?"none":commentstatus===2?"none":commentstatus===4?"":"none"}}>
<div className={"h20 mb30 ml30 ml87"}>
<span>评阅数</span>
<Input className="mr20" style={{width:"200px" }} value={commentnum} disabled={this.props.isAdmin()===true?flagPageEdit===true?false:true:true} onInput={this.setcommentnum} />
@ -1261,7 +1260,7 @@ class GraduationTaskssettingapp extends Component{
)
})}
</div>
</div> */}
</div>:""}

@ -847,28 +847,28 @@ class GraduationTaskssettinglist extends Component{
</Tooltip>
</span>
),
}, {
}, {
title: '操作',
key: 'operation',
width:'100px',
dataIndex: 'operation',
className:'edu-txt-center',
render: operation => (
<div>
<div style={{cursor: 'pointer'}}>
{this.props.isAdmin()?operation.map((tag,key) => {
return(
<React.Fragment>
{
tag.name &&
<Tooltip key={key} placement="bottom" title={tag.name==="分配"?"指定该作品的交叉评阅人":tag.name==="调分"?<pre>调整学生最终成绩<br/>其它历史评分将全部失效</pre>:""}>
{tag.name==="评阅"?<a style={{color:'#4CACFF',padding:"0px 5px"}} href={"/courses/"+courseId+"/graduation_tasks/"+tag.id+"/appraise"} >
<Tooltip key={key} placement="bottom" title={tag.name==="分配"?taskslistdata&&taskslistdata.cross_comment===true?"":"指定该作品的交叉评阅人":tag.name==="调分"?<pre>调整学生最终成绩<br/>其它历史评分将全部失效</pre>:""}>
{tag.name==="评阅"?<p style={{color:'#4CACFF',padding:"0px 5px"}} href={"/courses/"+courseId+"/graduation_tasks/"+tag.id+"/appraise"} >
{tag.name}
</a>
</p>
:
<a style={{color:tag.name==="调分"?"#000":'#4CACFF',padding:"0px 5px"}}
onClick={tag.name==="调分"?()=>this.showModulationtype(tag.id):tag.name==="分配"?()=>this.showAllocationModal(tag.id):""}>
{tag.name}
</a>
<p style={{color:tag.name==="调分"?"#000":'#4CACFF',padding:"0px 5px"}}
onClick={tag.name==="调分"?()=>this.showModulationtype(tag.id):tag.name==="分配"?taskslistdata&&taskslistdata.cross_comment===true?"":()=>this.showAllocationModal(tag.id):""}>
{tag.name==="分配"?taskslistdata&&taskslistdata.cross_comment===true?"":tag.name:tag.name}
</p>
}
</Tooltip>
}
@ -971,9 +971,8 @@ class GraduationTaskssettinglist extends Component{
white-space: nowrap;
}
.ant-table-tbody>tr>td, .ant-table-thead>tr>th{
padding: 16px 10px
padding:16px 8px;
}
`
}
</style>

@ -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 && <div className="df" style={{ marginTop: '12px' }} >
<span className="mr10" style={{ width: '148px' }}>所选学生分班至(选填):</span>
<Select style={{ width: 236 }} onChange={this.handleCourseGroupChange} value={courseGroup}>
<Option value={'0'}>{'未分班'}</Option>
{ course_groups.map((item) => {
return <Option value={item.id}>{item.name}</Option>
})}

@ -270,12 +270,13 @@ class studentsList extends Component{
addStudentSuccessListener=(e, data)=>{
const params = JSON.parse(data)
this.props.updataleftNavfun()
const course_group_id = this.props.match.params.course_group_id
const coursesId = this.props.match.params.coursesId
if (params.course_group_id == course_group_id) {
this.fetchAll(1)
} else {
this.props.history.push(`/courses/${coursesId}/course_groups/${params.course_group_id}`)
this.props.history.push(`/courses/${coursesId}/course_groups/${params.course_group_id || '0'}`)
}
// console.log('addStudentSuccessListener', data)
}
@ -465,6 +466,7 @@ class studentsList extends Component{
}).then((result)=>{
if (result.data.status == 0) {
this.props.showNotification('删除成功')
this.props.updataleftNavfun()
this.fetchAll()
this.setState({checkBoxValues: []})
trigger('updatabanner')

@ -2643,7 +2643,7 @@ class Listofworksstudentone extends Component {
//学号
//学号排序是从大到小
this.setState({
order: "student_id",
orders: "student_id",
loadingstate: true,
})
this.Startsortingt("student_id", this.state.course_groupyslstwo, this.state.checkedValuesineinfo, this.state.searchtext, this.state.page, this.state.limit);
@ -3047,32 +3047,9 @@ class Listofworksstudentone extends Component {
let {columns,course_groupysls,datajs,isAdmin,homework_status, course_groupyslstwo, unlimited, unlimitedtwo, course_group_info, orders, task_status, checkedValuesine, searchtext, teacherlist, visible,visibles, game_list,columnsstu,columnsstu2, limit,experience, boolgalist,viewtrainingdata, teacherdata, page, data, jobsettingsdata, styletable, datas, order, loadingstate,computeTimetype} = this.state;
const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;
// console.log(this.state.student_works);
// console.log("841");
// console.log(this.state.columns);
// console.log(datajs);
// console.log("2202");
// console.log(this.props.isAdmin());
// console.log("2498");
// console.log(data);
// console.log(datas);
// console.log(this.props.isAdmin());
let course_is_end = this.props.current_user&&this.props.current_user.course_is_end;
// try {
// if(this.props.isAdmin() === false){
// if(teacherdata&&teacherdata.student_works){
// if(teacherdata&&teacherdata.student_works.length>0){
// console.log("这是双层页面。。。。");
//
// }
// }
//
// }
// }catch (e) {
// console.log("Listofworksstudentone123");
// console.log(e);
// }
// console.log("Listofworksstudentone.js");
// console.log(orders);
return (

@ -1708,7 +1708,7 @@ class Trainingjobsetting extends Component {
whethertopays=false;
}
if(this.state.jobsettingsdata!==undefined){
}
try {

@ -908,7 +908,8 @@ class ShixunHomework extends Component{
}
hideNewShixunModelType=()=>{
this.setState({
NewShixunModelType:false
NewShixunModelType:false,
shixunpath:false
})
}
render(){
@ -971,6 +972,20 @@ class ShixunHomework extends Component{
statustype={'published'}
/>:""}
{/*新版实训model*/}
{shixunpath===true?<NewShixunModel
{...this.props}
{...this.state}
category_id={this.props.match.params.category_id}
type={'path'}
hideNewShixunModelType={()=>this.hideNewShixunModelType()}
coursesId={this.props.match.params.coursesId}
homeworkupdatalists={(Coursename,page,order)=>this.homeworkupdatalist(Coursename,page,order)}
Coursename={Coursename}
page={page}
order={order}
/>:""}
{/*提示*/}
{Modalstype&&Modalstype===true?<Modals
@ -1005,23 +1020,6 @@ class ShixunHomework extends Component{
getcourse_groupslist={(id)=>this.getcourse_groupslist(id)}
/>:""}
{/*/!*选择实训*!/*/}
{/*{shixunmodal===true?<ShixunModal*/}
{/*{...this.props}*/}
{/*{...this.state}*/}
{/*datas={datas}*/}
{/*category_id={this.props.match.params.category_id}*/}
{/*visible={shixunmodal}*/}
{/*shixunmodallist={shixunmodallist}*/}
{/*homeworkupdatalists={(Coursename,page,order)=>this.homeworkupdatalist(Coursename,page,order)}*/}
{/*hometypepvisible={hometypepvisible}*/}
{/*hidecouseShixunModal={this.hidecouseShixunModal}*/}
{/*newshixunmodallist={newshixunmodallist}*/}
{/*coursesId={this.props.match.params.coursesId}*/}
{/*courseshomeworkstart={(category_id,homework_ids)=>this.newhomeworkstart(category_id,homework_ids)}*/}
{/*funpatheditarry={(patheditarry)=>this.funpatheditarry(patheditarry)}*/}
{/*patheditarry={patheditarry}*/}
{/*/>:""}*/}
{shixunmodal===true||shixunpath===true?<style>
{
@ -1032,25 +1030,7 @@ class ShixunHomework extends Component{
`
}
</style>:""}
{/*选择实训路径*/}
{shixunpath===true? <PathModal
{...this.props}
{...this.state}
datas={datas}
visible={shixunpath}
shixunmodallist={this.state.shixunpathlist}
newshixunmodallist={this.state.newshixunpathlist}
// funshixunpathlist={(search,type,loading,page)=>this.funshixunpathlist(search,type,loading,page)}
hometypepvisible={hometypepvisible}
hidecouseShixunModal={this.hidecouseShixunModal}
coursesId={this.props.match.params.coursesId}
homeworkupdatalists={(Coursename,page,order)=>this.homeworkupdatalist(Coursename,page,order)}
courseshomeworkstart={(category_id,homework_ids)=>this.newhomeworkstart(category_id,homework_ids)}
Coursename={Coursename}
page={page}
order={order}
// courseshomeworkstart={(category_id,homework_ids)=>this.newhomeworkstart(category_id,homework_ids)}
/>:""}
{/*添加目录/选择目录*/}

@ -493,7 +493,7 @@ class MessagSub extends Component {
//belong_container_id course的id
return window.open(`/courses/${item.belong_container_id}/graduation_tasks/${item.parent_container_id}`);
default :
return window.open("/")
return
}
}
@ -575,7 +575,16 @@ class MessagSub extends Component {
boolps = false;
}
}
if (item.container_type === "DeleteCourse") {
if (item.tiding_type === "System") {
boolps = false;
}
}
if (item.container_type === "DeleteCourseMember") {
if (item.tiding_type === "System") {
boolps = false;
}
}
return (
<div className="pl25 ridinglist edu-back-white" key={key}>
<div

@ -89,8 +89,8 @@ export function TPMIndexHOC(WrappedComponent) {
// header里面需要有user
initCommonState(user) {
// 更新头像后,需要改变参数,不然会被图片缓存影响到
const newUser = Object.assign({}, {...user}, { image_url: `${user.image_url}?t=${new Date().getTime()}`});
// 更新头像后,需要改变参数,不然会被图片缓存影响到 --> 后台已加 ?t=${new Date().getTime()
const newUser = Object.assign({}, {...user}, { image_url: `${user.image_url}`});
this.setState({
user: newUser,
current_user: newUser

@ -151,7 +151,7 @@ class Repository extends Component {
</p>
</div>
<p className="inviteTipbtn with100"><a
onClick={() => { $('#repository_url_tip').hide(); }}>知道了</a></p>
onClick={() => { $('#repository_url_tip').css('display') === 'none'}}>知道了</a></p>
</div>
</a>

@ -92,7 +92,7 @@ class RepositoryAddFile extends Component {
if(!value){
callback('文件名不能为空');
}else if (value == "/" || value.indexOf('.') == -1 ) {
callback('请输入正确的文件路径src/HelloWord.java');
callback('请输入正确的文件路径src/HelloWorld.java');
}else{
callback();
}
@ -162,7 +162,7 @@ class RepositoryAddFile extends Component {
validator:this.checkPath
}]
})(
<Input placeholder="输入文件路径名src/HelloWord.java" className="winput-300-35 fl"/>
<Input placeholder="输入文件路径名src/HelloWorld.java" className="winput-300-35 fl"/>
)}
</Form.Item>
</div>

@ -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
})
})

@ -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 })}
>
<style>{`
#changeHeader_imagePreview {

@ -39,7 +39,7 @@ class InfosBanner extends Component{
<div className="bannerPanel mb60">
<div className="educontent">
<div className="clearfix color-white mb25">
<p className="myPhoto mr20 fl"><img alt="头像" src={data && `${getImageUrl('images/'+data.avatar_url)}?t=${new Date().getTime()}`}/></p>
<p className="myPhoto mr20 fl"><img alt="头像" src={data && `${getImageUrl('images/'+data.avatar_url)}`}/></p>
<div className="fl">
<p className="clearfix mt20">
<span className="username task-hide" style={{"maxWidth":'370px'}}>{data && data.name}</span>

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe CourseDeleteStudentNotifyJob, type: :job do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe ResubmitStudentWorkNotifyJob, type: :job do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save