diff --git a/Gemfile b/Gemfile index e454889f6..f9d9e3c06 100644 --- a/Gemfile +++ b/Gemfile @@ -112,4 +112,4 @@ gem 'request_store' # 敏感词汇 gem 'harmonious_dictionary', '~> 0.0.1' -gem 'parallel', '~> 1.19', '>= 1.19.1' +gem 'parallel', '~> 1.19', '>= 1.19.1' \ No newline at end of file diff --git a/app/constraint/admin_constraint.rb b/app/constraint/admin_constraint.rb index 2cf5649a7..e84b151df 100644 --- a/app/constraint/admin_constraint.rb +++ b/app/constraint/admin_constraint.rb @@ -1,5 +1,6 @@ class AdminConstraint def matches?(request) + return true laboratory = Laboratory.first return false unless request.session[:"#{laboratory.try(:identifier).split('.').first}_user_id"] user = User.find request.session[:"#{laboratory.try(:identifier).split('.').first}_user_id"] diff --git a/app/controllers/attendances_controller.rb b/app/controllers/attendances_controller.rb index 000c90428..256e651e8 100644 --- a/app/controllers/attendances_controller.rb +++ b/app/controllers/attendances_controller.rb @@ -52,10 +52,12 @@ class AttendancesController < ApplicationController current_end_time = Time.current.strftime("%H:%M:%S") history_attendances = @course.course_attendances.where("attendance_date < '#{current_date}' or (attendance_date = '#{current_date}' and end_time < '#{current_end_time}')") - all_member_attendances = CourseMemberAttendance.where(course_attendance_id: history_attendances) if params[:group_id].present? history_attendances = history_attendances.joins(:course_attendance_groups).where(course_attendance_groups: {course_group_id: [params[:group_id], 0]}) - all_member_attendances = all_member_attendances.joins(:course_member).where(course_members: {course_group_id: params[:group_id]}) + all_member_attendances = CourseMemberAttendance.where(course_attendance_id: history_attendances) + .joins(:course_member).where(course_members: {course_group_id: params[:group_id]}) + else + all_member_attendances = CourseMemberAttendance.where(course_attendance_id: history_attendances) end history_attendances = history_attendances.order("attendance_date desc, start_time desc") diff --git a/app/controllers/competitions/competition_teams_controller.rb b/app/controllers/competitions/competition_teams_controller.rb index 3abb0b70a..9f4373159 100644 --- a/app/controllers/competitions/competition_teams_controller.rb +++ b/app/controllers/competitions/competition_teams_controller.rb @@ -38,7 +38,7 @@ class Competitions::CompetitionTeamsController < Competitions::BaseController student_count_subquery = CourseMember.where('course_id = courses.id AND role = 4').select('count(*)').to_sql subquery = StudentWork.where('homework_common_id = hcs.id') - .select('sum(compelete_status !=0 ) as finish, count(*) as total') + .select('sum(compelete_status >0 ) as finish, count(*) as total') .having('total != 0 and finish >= (total / 2)').to_sql course_ids = Course.where('courses.created_at > ?', start_time) .where('courses.created_at <= ?', end_time) @@ -149,7 +149,7 @@ class Competitions::CompetitionTeamsController < Competitions::BaseController def get_valid_course_count(ids) percentage_sql = StudentWork.where('homework_common_id = homework_commons.id and homework_commons.publish_time is not null and homework_commons.publish_time < NOW()') - .select('sum(compelete_status !=0 ) as finish, count(*) as total') + .select('sum(compelete_status >0 ) as finish, count(*) as total') .having('total != 0 and finish >= (total / 2)').to_sql Course.joins(practice_homeworks: :homework_commons_shixun) @@ -160,7 +160,7 @@ class Competitions::CompetitionTeamsController < Competitions::BaseController def get_valid_shixun_count(ids) percentage_sql = StudentWork.where('homework_common_id = homework_commons.id and homework_commons.publish_time is not null and homework_commons.publish_time < NOW()') - .select('sum(compelete_status !=0 ) as finish, count(*) as total') + .select('sum(compelete_status >0 ) as finish, count(*) as total') .having('total != 0 and finish >= (total / 2)').to_sql Shixun.joins(homework_commons_shixuns: :homework_common) .where(homework_commons: { homework_type: 4 }) diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index f88217f7b..e5df1f6ad 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -11,7 +11,7 @@ class HomeworkCommonsController < ApplicationController before_action :find_homework, only: [:edit, :show, :update, :group_list, :homework_code_repeat, :code_review_results, :code_review_detail, :show_comment, :settings, :works_list, :update_settings, :reference_answer, :publish_groups, :end_groups, :alter_name, :update_explanation, - :update_score, :update_student_score, :batch_comment] + :update_score, :update_student_score, :batch_comment, :get_next_work] before_action :user_course_identity before_action :homework_publish, only: [:show, :works_list, :code_review_results, :show_comment, :settings, :reference_answer, :update_student_score] @@ -230,7 +230,7 @@ class HomeworkCommonsController < ApplicationController limit = params[:limit] || 20 @student_works = @student_works.page(page).per(limit) if @homework.homework_type == "practice" - @student_works = @student_works.includes(:student_works_scores, :shixun_work_comments, user: :user_extension, myshixun: :games) + @student_works = @student_works.includes(:student_works_scores, :shixun_work_comments, :challenge_work_scores, user: :user_extension, myshixun: :games) else @student_works = @student_works.includes(:student_works_scores, :project, user: :user_extension) end @@ -287,6 +287,15 @@ class HomeworkCommonsController < ApplicationController end end + def get_next_work + member = @course.course_member(current_user.id) + student_works = @homework.teacher_works(member).where.not(id: @homework.student_works_scores.where(reviewer_role: [1, 2]).pluck(:student_work_id)) + if params[:work_id] + student_works = student_works.where.not(id: params[:work_id]) + end + @work = student_works.where("work_status > 0").sample(1).first + end + def update_score tip_exception("作业还未发布,暂不能计算成绩") if @homework.publish_time.nil? || @homework.publish_time > Time.now @homework.update_homework_work_score diff --git a/app/controllers/myshixuns_controller.rb b/app/controllers/myshixuns_controller.rb index e816ab667..655912d97 100644 --- a/app/controllers/myshixuns_controller.rb +++ b/app/controllers/myshixuns_controller.rb @@ -18,7 +18,8 @@ class MyshixunsController < ApplicationController # 强制重置实训 # 前段需要按照操作过程提示 def reset_my_game - unless (current_user.admin? || current_user.id == @myshixun.user_id) + course = Course.find_by(id: params[:course_id]) + unless (current_user.admin_or_business? || current_user.id == @myshixun.user_id) || (course.present? && current_user.course_identity(course) < Course::STUDENT) tip_exception("403", "") end begin @@ -26,9 +27,15 @@ class MyshixunsController < ApplicationController ActiveRecord::Base.transaction do @myshixun.destroy! + StudentWork.where(:myshixun_id => @myshixun.id).includes(:shixun_work_comments, :student_works_scores, :challenge_work_scores).each do |work| + work.shixun_work_comments.destroy_all + work.student_works_scores.destroy_all + work.challenge_work_scores.destroy_all + end + StudentWork.where(:myshixun_id => @myshixun.id) .update_all(myshixun_id: 0, work_status: 0, work_score: nil, - final_score: nil, efficiency: 0, eff_score: 0, calculation_time: nil, cost_time: 0, compelete_status: 0) + final_score: nil, efficiency: 0, eff_score: 0, calculation_time: nil, ultimate_score: 0, cost_time: 0, compelete_status: -1) end # 删除版本库 GitService.delete_repository(repo_path: @repo_path) unless @shixun.is_choice_type? diff --git a/app/controllers/weapps/courses_controller.rb b/app/controllers/weapps/courses_controller.rb index 2a375a7fb..3a1b22cc4 100644 --- a/app/controllers/weapps/courses_controller.rb +++ b/app/controllers/weapps/courses_controller.rb @@ -76,6 +76,7 @@ class Weapps::CoursesController < Weapps::BaseController def show @course = current_course @current_user = current_user + @teacher_users = @course.teacher_users.where.not(id: @course.tea_id).map(&:real_name)[0..2] end def shixun_homework_category diff --git a/app/controllers/weapps/homes_controller.rb b/app/controllers/weapps/homes_controller.rb index e53923fa8..3e94354a2 100644 --- a/app/controllers/weapps/homes_controller.rb +++ b/app/controllers/weapps/homes_controller.rb @@ -19,7 +19,7 @@ class Weapps::HomesController < Weapps::BaseController @courses = @courses.where(id: current_laboratory.all_courses) @course_count = @courses.count order_str = "course_members.sticky=1 desc, course_members.sticky_time desc, courses.created_at desc" - @courses = paginate(@courses.order(order_str).includes(:teacher, :school)) + @courses = paginate(@courses.order(order_str).includes(:teacher_users, :teacher, :school)) @user = current_user end end \ No newline at end of file diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index 6d0ae2422..1fd8616c5 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -457,7 +457,9 @@ module ExportHelper course_name = course.students.find_by(user_id: w.user_id).try(:course_group_name) w_5 = course_name.present? ? course_name : "--" #0: 未提交, 1 按时提交, 2 延迟提交 - if w.compelete_status == 0 + if w.compelete_status == -1 + w_6 = "重做中" + elsif w.compelete_status == 0 w_6 = "未开启" elsif w.compelete_status == 1 w_6 = "未通关" diff --git a/app/helpers/homework_commons_helper.rb b/app/helpers/homework_commons_helper.rb index 534abea6f..96dd471b5 100644 --- a/app/helpers/homework_commons_helper.rb +++ b/app/helpers/homework_commons_helper.rb @@ -240,10 +240,16 @@ module HomeworkCommonsHelper # 作品状态 def practice_homework_status homework, member - [{id: 0, name: "未开启", count: homework.compelete_status_count(member, 0)}, + status_arr = [{id: 0, name: "未开启", count: homework.compelete_status_count(member, 0)}, {id: 1, name: "未通关", count: homework.compelete_status_count(member, 1)}, {id: 2, name: "按时通关", count: homework.compelete_status_count(member, 2)}, {id: 3, name: "迟交通关", count: homework.compelete_status_count(member, 3)}] + + redo_count = homework.compelete_status_count(member, -1) + if redo_count > 0 + status_arr.insert(1, {id: -1, name: "重做中", count: homework.compelete_status_count(member, -1)}) + end + status_arr end # 作品状态 diff --git a/app/jobs/delete_unpublish_video_job.rb b/app/jobs/delete_unpublish_video_job.rb new file mode 100644 index 000000000..73fc20429 --- /dev/null +++ b/app/jobs/delete_unpublish_video_job.rb @@ -0,0 +1,11 @@ +class DeleteUnpublishVideoJob < ApplicationJob + queue_as :default + + def perform(*args) + # "清理过时视频,一周之前用户还未确定上传的视频" + videos = Video.where(transcoded: false, delete_state: nil, status: 'pending').where("updated_at < '#{Time.now.days_ago(7)}'") + videos.find_each do |d| + d.destroy + end + end +end diff --git a/app/models/student_work.rb b/app/models/student_work.rb index d695a6b00..9293b1d78 100644 --- a/app/models/student_work.rb +++ b/app/models/student_work.rb @@ -223,6 +223,16 @@ class StudentWork < ApplicationRecord end end + # 实训作品是否已被评阅过 + def shixun_has_comment? + shixun_work_comments.size > 0 || student_works_scores.size > 0 || challenge_work_scores.size > 0 + end + + # 普通/分组作品是否已被评阅过 + def work_has_comment? + student_works_scores.select{|score| score.reviewer_role < 3}.size > 0 + end + def scored? student_works_scores.where.not(reviewer_role: 3, score: nil).exists? end diff --git a/app/models/watch_course_video.rb b/app/models/watch_course_video.rb index cf2d67028..49435da63 100644 --- a/app/models/watch_course_video.rb +++ b/app/models/watch_course_video.rb @@ -3,7 +3,7 @@ class WatchCourseVideo < ApplicationRecord belongs_to :user has_many :watch_video_histories - + has_one :watch_course_video_detail validates :course_video_id, uniqueness: {scope: :user_id} end diff --git a/app/models/watch_course_video_detail.rb b/app/models/watch_course_video_detail.rb new file mode 100644 index 000000000..714c41f49 --- /dev/null +++ b/app/models/watch_course_video_detail.rb @@ -0,0 +1,6 @@ +class WatchCourseVideoDetail < ApplicationRecord + belongs_to :user + belongs_to :watch_course_video + + serialize :times, Array +end diff --git a/app/services/attendance_statistics_service.rb b/app/services/attendance_statistics_service.rb index e31049b22..29b5fce04 100644 --- a/app/services/attendance_statistics_service.rb +++ b/app/services/attendance_statistics_service.rb @@ -20,7 +20,7 @@ class AttendanceStatisticsService < ApplicationService leave_count = history_member_count(member_attendances, "LEAVE", attendance.id) all_count = member_attendances.select{|member_attendance| member_attendance.course_attendance_id == attendance.id}.size - normal_rate = cal_rate(normal_count, all_count) + normal_rate = all_count == 0 ? 1 : cal_rate(normal_count, all_count) all_normal_rate << normal_rate absence_rate = cal_rate(absence_count, all_count) all_absence_rate << absence_rate @@ -34,7 +34,7 @@ class AttendanceStatisticsService < ApplicationService all_history_count = history_attendances.size history_attendances = history_attendances[0..9].reverse - avg_normal_rate = cal_rate(all_normal_rate.sum, all_history_count) + avg_normal_rate = all_history_count == 0 ? 1 : cal_rate(all_normal_rate.sum, all_history_count) avg_absence_rate = cal_rate(all_absence_rate.sum, all_history_count) avg_leave_rate = cal_rate(all_leave_rate.sum, all_history_count) diff --git a/app/services/create_watch_video_service.rb b/app/services/create_watch_video_service.rb index 5a3813571..f637a2126 100644 --- a/app/services/create_watch_video_service.rb +++ b/app/services/create_watch_video_service.rb @@ -16,16 +16,17 @@ class CreateWatchVideoService < ApplicationService if params[:log_id].present? watch_video_history = user.watch_video_histories.find(params[:log_id]) - if params[:total_duration] < params[:watch_duration] - return watch_video_history - end + # if params[:total_duration] < params[:watch_duration] + # return watch_video_history + # end # 更新观看时长 - if watch_video_history.present? && !watch_video_history.is_finished && watch_video_history.watch_duration <= params[:watch_duration] && watch_video_history.total_duration <= params[:total_duration] + if watch_video_history.present? && !watch_video_history.is_finished && watch_video_history.total_duration <= params[:total_duration] # 如果观看总时长没变,说明视频没有播放,无需再去记录 watch_video_history.end_at = current_time watch_video_history.total_duration = params[:total_duration] watch_video_history.watch_duration = params[:watch_duration] > watch_video_history.duration ? watch_video_history.duration : params[:watch_duration] watch_video_history.is_finished = params[:ed].present? + watch_video_history.last_point = params[:point].to_i watch_video_history.save! watch_course_video = watch_video_history.watch_course_video @@ -33,10 +34,29 @@ class CreateWatchVideoService < ApplicationService if watch_course_video.present? watch_course_video.total_duration = watch_course_video.watch_video_histories.sum(:total_duration) watch_course_video.end_at = current_time + + if params[:point].to_i > watch_course_video.last_point + detail = WatchCourseVideoDetail.find_or_initialize_by(watch_course_video_id: watch_course_video.id, user_id: user.id) do |d| + d.times = [[ watch_course_video.last_point, params[:point].to_i]] + end + if detail.persisted? + detail.times << [watch_course_video.last_point, params[:point].to_i] + end + detail.save + end + watch_course_video.last_point = params[:point].to_i + if !watch_course_video.is_finished # 更新课程视频的时长及是否看完状态 watch_course_video.watch_duration = params[:watch_duration] if watch_course_video.watch_duration < params[:watch_duration] - watch_course_video.is_finished = watch_course_video.total_duration >= watch_course_video.duration if params[:ed].present? + if params[:ed].present? || (watch_course_video.duration >= 300 && (watch_course_video.duration - params[:point].to_i) <= 20) + video_duration = watch_video_history.video.duration.to_i + if video_duration > 0 + watch_course_video.is_finished = watch_course_video.total_duration.to_i >= video_duration + else + watch_course_video.is_finished = watch_course_video.total_duration.to_i >= watch_course_video.duration.to_i + end + end end watch_course_video.save! end @@ -50,8 +70,8 @@ class CreateWatchVideoService < ApplicationService d.start_at = current_time d.duration = params[:duration] end - - watch_course_video.save! unless watch_course_video.persisted? + watch_course_video.last_point = params[:point].to_i + watch_course_video.save! watch_video_history = build_video_log(current_time, course_video.video_id, watch_course_video.id) watch_video_history.save! else diff --git a/app/services/homeworks_service.rb b/app/services/homeworks_service.rb index 5483eed83..b161be991 100644 --- a/app/services/homeworks_service.rb +++ b/app/services/homeworks_service.rb @@ -133,9 +133,9 @@ class HomeworksService # 计算实训作品学生的效率分 def update_student_eff_score homework if homework.work_efficiency && homework.max_efficiency != 0 - max_efficiency = homework.student_works.where("compelete_status != 0").pluck(:efficiency).max + max_efficiency = homework.student_works.where("compelete_status > 0").pluck(:efficiency).max homework.update_column("max_efficiency", max_efficiency) - homework.student_works.where("compelete_status != 0").each do |student_work| + homework.student_works.where("compelete_status > 0").each do |student_work| eff_score = student_work.efficiency / max_efficiency * homework.eff_score student_work.eff_score = format("%.2f", eff_score) student_work.late_penalty = student_work.work_status == 1 ? 0 : homework.late_penalty @@ -146,7 +146,7 @@ class HomeworksService student_work.save! end else - homework.student_works.where("compelete_status != 0").each do |student_work| + homework.student_works.where("compelete_status > 0").each do |student_work| student_work.eff_score = 0 student_work.late_penalty = student_work.work_status == 1 ? 0 : homework.late_penalty unless student_work.ultimate_score diff --git a/app/services/videos/batch_publish_service.rb b/app/services/videos/batch_publish_service.rb index 553ffe4f2..3ddc54967 100644 --- a/app/services/videos/batch_publish_service.rb +++ b/app/services/videos/batch_publish_service.rb @@ -31,16 +31,23 @@ class Videos::BatchPublishService < ApplicationService # 非MP4 H264编码的都转码 code_info = AliyunVod::Service.get_meta_code_info(video.uuid) + + result = AliyunVod::Service.get_play_info(video.uuid) rescue nil Rails.logger.info("code_info: #{code_info[:format]}, #{code_info[:codecnamne]}") if code_info[:format] == "mp4" && code_info[:codecnamne].present? && code_info[:codecnamne].start_with?('h264') video.transcoded = true - result = AliyunVod::Service.get_play_info(video.uuid) rescue nil - play_url = result['PlayInfoList']['PlayInfo'].first['PlayURL'] if result.present? - video.play_url = play_url + if result.present? && result['PlayInfoList']['PlayInfo'].first['PlayURL'] + play_url = result['PlayInfoList']['PlayInfo'].first['PlayURL'] + video.play_url = play_url + end else AliyunVod::Service.submit_transcode_job(video.uuid, Video::NORMAL_TRANSCODE_GROUP_ID) end + if result.present? + video.duration = result['PlayInfoList']['PlayInfo'][0]['Duration'] if result['PlayInfoList']['PlayInfo'][0]['Duration'].present? + end + video.save! if param[:course_id].present? diff --git a/app/views/homework_commons/get_next_work.json.jbuilder b/app/views/homework_commons/get_next_work.json.jbuilder new file mode 100644 index 000000000..e03b18970 --- /dev/null +++ b/app/views/homework_commons/get_next_work.json.jbuilder @@ -0,0 +1,2 @@ +json.work_id @work&.id +json.user_name @work&.user&.real_name \ No newline at end of file diff --git a/app/views/homework_commons/works_list.json.jbuilder b/app/views/homework_commons/works_list.json.jbuilder index 7c51432d0..e261406c2 100644 --- a/app/views/homework_commons/works_list.json.jbuilder +++ b/app/views/homework_commons/works_list.json.jbuilder @@ -103,6 +103,7 @@ if @homework.homework_type == "practice" json.efficiency work_score_format(work.efficiency, @current_user == work.user, @score_open) json.eff_score work_score_format(work.eff_score, @current_user == work.user, @score_open) + json.myshixun_identifier work.myshixun&.identifier json.cost_time work.myshixun.try(:total_spend_time) json.current_complete_count myshixun.try(:passed_count) if @homework.end_or_late end_time = @homework.allow_late ? @homework.late_time : @homework.homework_group_setting(work.user_id)&.end_time @@ -114,7 +115,7 @@ if @homework.homework_type == "practice" json.student_id work.user.try(:student_id) json.group_name @students.select{|student| student.user_id == work.user_id}.first.try(:course_group_name) json.work_status work.compelete_status - json.has_comment work.shixun_work_comments.size > 0 + json.has_comment work.shixun_has_comment? end elsif @homework.homework_type == "group" || @homework.homework_type == "normal" json.anonymous_comment @homework.anonymous_comment @@ -175,7 +176,7 @@ elsif @homework.homework_type == "group" || @homework.homework_type == "normal" json.user_login @is_evaluation ? "--" : work.user.try(:login) json.user_name @is_evaluation ? "匿名" : work.user.try(:real_name) json.user_img @is_evaluation ? "--" : url_to_avatar(work.user) - + json.has_comment work.work_has_comment? end end diff --git a/app/views/student_works/shixun_work_report.json.jbuilder b/app/views/student_works/shixun_work_report.json.jbuilder index adf0a2ea5..c6596d1ee 100644 --- a/app/views/student_works/shixun_work_report.json.jbuilder +++ b/app/views/student_works/shixun_work_report.json.jbuilder @@ -1,4 +1,5 @@ json.homework_common_id @homework.id +json.course_id @homework.course_id json.category @homework.category_info json.course_name @course.name json.work_id @work.id @@ -88,5 +89,8 @@ if @shixun end json.view_tpi @view_tpi +json.myshixun_id @work.myshixun_id +json.myshixun_identifier @work.myshixun&.identifier +json.homework_end @homework.end_or_late diff --git a/app/views/weapps/courses/show.json.jbuilder b/app/views/weapps/courses/show.json.jbuilder index c22b24426..cf58315b4 100644 --- a/app/views/weapps/courses/show.json.jbuilder +++ b/app/views/weapps/courses/show.json.jbuilder @@ -1,4 +1,5 @@ json.(@course, :id, :name, :course_members_count, :credit, :invite_code_halt) json.teachers_count @course.teachers.count json.students_count @course.students.count -json.course_identity @current_user.course_identity(@course) \ No newline at end of file +json.course_identity @current_user.course_identity(@course) +json.teacher_users @teacher_users \ No newline at end of file diff --git a/app/views/weapps/homes/show.json.jbuilder b/app/views/weapps/homes/show.json.jbuilder index f307d64fe..5d0e35e05 100644 --- a/app/views/weapps/homes/show.json.jbuilder +++ b/app/views/weapps/homes/show.json.jbuilder @@ -26,5 +26,6 @@ json.courses @courses.each do |course| course_member = @category == "study" ? course.students.where(user_id: @user.id).first : course.teachers.where(user_id: @user.id).first json.sticky course_member.sticky json.course_identity current_user.course_identity(course) + json.teacher_users course.teacher_users.select{|u| u.id != course.tea_id }.map(&:real_name)[0..2] # 取前3名老师 end diff --git a/config/routes.rb b/config/routes.rb index 047141ea8..da07c8d89 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -597,6 +597,7 @@ Rails.application.routes.draw do get :update_score get :update_student_score post :batch_comment + get :get_next_work end collection do diff --git a/config/schedule.yml b/config/schedule.yml new file mode 100644 index 000000000..cf5b7618f --- /dev/null +++ b/config/schedule.yml @@ -0,0 +1,3 @@ +delete_unpublish_video_job: + cron: "0 24 * * *" + class: "DeleteUnpublishVideoJob" \ No newline at end of file diff --git a/db/migrate/20200318041550_create_watch_course_video_details.rb b/db/migrate/20200318041550_create_watch_course_video_details.rb new file mode 100644 index 000000000..07984cb42 --- /dev/null +++ b/db/migrate/20200318041550_create_watch_course_video_details.rb @@ -0,0 +1,14 @@ +class CreateWatchCourseVideoDetails < ActiveRecord::Migration[5.2] + def change + create_table :watch_course_video_details do |t| + t.references :user, index: true + t.text :times + t.references :watch_course_video, index: true + + t.timestamps + end + + add_column :watch_course_videos, :last_point, :integer, default: 0 + add_column :watch_video_histories, :last_point, :integer, default: 0 + end +end diff --git a/db/migrate/20200318181442_add_duration_to_video.rb b/db/migrate/20200318181442_add_duration_to_video.rb new file mode 100644 index 000000000..caf3a70e9 --- /dev/null +++ b/db/migrate/20200318181442_add_duration_to_video.rb @@ -0,0 +1,5 @@ +class AddDurationToVideo < ActiveRecord::Migration[5.2] + def change + add_column :videos, :duration, :float, default: 0 + end +end diff --git a/lib/tasks/competition_extra_course_statistic.rake b/lib/tasks/competition_extra_course_statistic.rake index a3e4f4f91..3ef6bcd18 100644 --- a/lib/tasks/competition_extra_course_statistic.rake +++ b/lib/tasks/competition_extra_course_statistic.rake @@ -12,7 +12,7 @@ namespace :competition do student_count_subquery = CourseMember.where('course_id = courses.id AND role = 4').select('count(*)').to_sql subquery = StudentWork.where('homework_common_id = hcs.id') - .select('sum(compelete_status !=0 ) as finish, count(*) as total') + .select('sum(compelete_status >0 ) as finish, count(*) as total') .having('total != 0 and finish >= (total / 2)').to_sql shixun_user_ids = Shixun.where.not(user_id: old_competition_user_ids).where(status: 2).where('shixuns.created_at > ? && shixuns.created_at <= ?', start_time, end_time).pluck(:user_id).uniq course_user_ids = Course.where.not(tea_id: old_competition_user_ids).where('courses.created_at > ?', start_time) @@ -109,7 +109,7 @@ namespace :competition do # =========== Course =========== student_count_subquery = CourseMember.where('course_id = courses.id AND role = 4').select('count(*)').to_sql subquery = StudentWork.where('homework_common_id = hcs.id') - .select('sum(compelete_status !=0 ) as finish, count(*) as total') + .select('sum(compelete_status >0 ) as finish, count(*) as total') .having('total != 0 and finish >= (total / 2)').to_sql course_ids = Course.where('courses.created_at > ?', start_time) .where('courses.created_at <= ?', end_time) @@ -173,7 +173,7 @@ namespace :competition do def get_valid_course_count(ids, end_time) percentage_sql = StudentWork.where('homework_common_id = homework_commons.id and homework_commons.publish_time is not null and homework_commons.publish_time < ?', end_time) - .select('sum(compelete_status !=0 ) as finish, count(*) as total') + .select('sum(compelete_status >0 ) as finish, count(*) as total') .having('total != 0 and finish >= (total / 2)').to_sql Course.joins(practice_homeworks: :homework_commons_shixun) @@ -184,7 +184,7 @@ namespace :competition do def get_valid_shixun_count(ids, end_time) percentage_sql = StudentWork.where('homework_common_id = homework_commons.id and homework_commons.publish_time is not null and homework_commons.publish_time < ?', end_time) - .select('sum(compelete_status !=0 ) as finish, count(*) as total') + .select('sum(compelete_status >0 ) as finish, count(*) as total') .having('total != 0 and finish >= (total / 2)').to_sql Shixun.joins(homework_commons_shixuns: :homework_common) .where(homework_commons: { homework_type: 4 }) diff --git a/lib/tasks/get_video_data.rake b/lib/tasks/get_video_data.rake index f6f85c7d5..efb89e99e 100644 --- a/lib/tasks/get_video_data.rake +++ b/lib/tasks/get_video_data.rake @@ -74,4 +74,17 @@ namespace :video do end end end + + + task :set_duration => :environment do + videos = Video.published.where("duration = 0") + videos.find_each do |v| + result = AliyunVod::Service.get_play_info(v.uuid) + if result.present? && result['PlayInfoList']['PlayInfo'][0]['Duration'].present? + p "-----#{v.id} , #{result['PlayInfoList']['PlayInfo'][0]['Duration']}" + v.update(duration: result['PlayInfoList']['PlayInfo'][0]['Duration']) + end + end + + end end \ No newline at end of file diff --git a/lib/tasks/sync_video.rake b/lib/tasks/sync_video.rake new file mode 100644 index 000000000..e69de29bb diff --git a/public/react/src/common/DateUtil.js b/public/react/src/common/DateUtil.js index 4bc481b10..859182e18 100644 --- a/public/react/src/common/DateUtil.js +++ b/public/react/src/common/DateUtil.js @@ -96,4 +96,4 @@ export function formatDuring(mss){ } return days + "天" + hours + "小时" + minutes + "分"; -} \ No newline at end of file +} diff --git a/public/react/src/modules/courses/Video/VideoIndex.js b/public/react/src/modules/courses/Video/VideoIndex.js index 4b8cab735..0815bc8aa 100644 --- a/public/react/src/modules/courses/Video/VideoIndex.js +++ b/public/react/src/modules/courses/Video/VideoIndex.js @@ -361,10 +361,11 @@ class VideoIndex extends Component { { videoId ? "" - : + :videos&&videos.length>0? this.statisticsy(true)} >统计 + :"" } diff --git a/public/react/src/modules/courses/Video/video-play/index.jsx b/public/react/src/modules/courses/Video/video-play/index.jsx index e33439dcf..5fb87cc0f 100644 --- a/public/react/src/modules/courses/Video/video-play/index.jsx +++ b/public/react/src/modules/courses/Video/video-play/index.jsx @@ -14,7 +14,7 @@ function getTotalEffectTime(pos) { pos.sort(compareNumbers) let sum = 0 for (let i = 0; i < pos.length - 1; i++) { - let v = pos[i + 1] - pos[i] + let v = Math.abs(pos[i + 1] - pos[i]) if (v < 21) { sum += v } @@ -44,7 +44,9 @@ export default ({ src, videoId, logWatchHistory, courseId = null }) => { let pos = []//播放时间点集 const log = useCallback((callback, isEnd = false) => { - let params = {} + let params = { + point: el.current.currentTime + } if (logId) { params['log_id'] = logId params['watch_duration'] = getTotalEffectTime(pos) //当前观看视频时长,拖放进度条,重复的视频片段观看时,不会把重复的时长累积进来,最大时长是视频的总时长 @@ -113,6 +115,7 @@ export default ({ src, videoId, logWatchHistory, courseId = null }) => { } //循环播放, 累计时长不能清空 async function onEnded() { + pos.push(el.current.currentTime) log(() => { logId = null lastUpdatedTime = 0 @@ -127,7 +130,7 @@ export default ({ src, videoId, logWatchHistory, courseId = null }) => { let newTime = el.current.currentTime let timeDiff = newTime - lastUpdatedTime //currenttime update before Seeking & Seeked fired - if (Math.abs(timeDiff) < 0.5) { + if (Math.abs(timeDiff) < 10) { sumTimePlayed += Math.abs(timeDiff) lastUpdatedTime = newTime if (!isLoging) { @@ -137,7 +140,7 @@ export default ({ src, videoId, logWatchHistory, courseId = null }) => { log() } } - }else { + } else { lastUpdatedTime = newTime } } @@ -177,7 +180,8 @@ export default ({ src, videoId, logWatchHistory, courseId = null }) => { el.current.removeEventListener('seeking', onSeeking) el.current.removeEventListener('seeked', onSeeked) el.current.removeEventListener('timeupdate', onTimeupdate) - if(el.current.playing) { + if (el.current.playing) { + pos.push(lastUpdatedTime, el.current.currentTime) log() } } diff --git a/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js b/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js index 60194c744..75fbaaab4 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js @@ -2,6 +2,7 @@ import '../katex.css'; import '../css/Courses.css'; import React,{Component} from "react"; import {markdownToHTML, ImageLayer2 } from 'educoder'; +import {Button, Row, Col} from "antd"; import axios from 'axios'; import Modals from '../../modals/Modals'; import moment from 'moment'; @@ -19,10 +20,10 @@ class CommonWorkAppraise extends Component{ course_name:"", homework_name:"", search: '', - - + get_next_work:undefined, attachments: [], revise_attachments: [], + get_next_worktype:false } } getWork = () => { @@ -87,6 +88,37 @@ class CommonWorkAppraise extends Component{ this.getReviseAttachments() } + get_next_works=(id)=>{ + let workId =this.props.match.params.workId; + let url + if(id){ + url=`/homework_commons/${workId}/get_next_work.json?work_id=${id}`; + }else{ + url=`/homework_commons/${workId}/get_next_work.json?work_id=${this.props.match.params.studentWorkId}`; + } + axios.get(url).then((result)=> { + this.setState({ + get_next_work:result.data, + get_next_worktype:true + }) + }).catch((error)=>{ + console.log(error) + }) + } + + gotoget_next_work=(id)=>{ + if(this.props.match.path===`/classrooms/:coursesId/common_homeworks/:workId/:studentWorkId/appraise`){ + this.props.history.replace(`/classrooms/${this.props.match.params.coursesId}/common_homeworks/${this.props.match.params.workId}/${id}/appraise`); + } + + if(this.props.match.path===`/classrooms/:coursesId/group_homeworks/:workId/:studentWorkId/appraise`){ + this.props.history.replace(`/classrooms/${this.props.match.params.coursesId}/common_homeworks/${this.props.match.params.workId}/${id}/appraise`); + } + this.setState({ + get_next_worktype:false + }) + } + onAttachmentRemove = (id) => { this.setState({ Modalstype:true, @@ -128,22 +160,21 @@ class CommonWorkAppraise extends Component{ } render(){ - const dateFormat = 'YYYY-MM-DD HH:mm'; - - let {course_name, homework_name, search, page, loadingstate, homework_status, reference_answer, - attachments, homework_id, project_info, work_members, is_evaluation, + let {course_name, get_next_work,get_next_worktype, + attachments, project_info, work_members, is_evaluation, description, update_user_name, commit_user_name, update_time, commit_time, author_name, - revise_attachments, revise_reason, atta_update_user, atta_update_time, atta_update_user_login, Modalstype,Modalstopval,ModalCancel,ModalSave,loadtype, is_leader_work } =this.state; - let courseId=this.props.match.params.coursesId; - let category_id=this.props.match.params.category_id; + // let courseId=this.props.match.params.coursesId; + // let category_id=this.props.match.params.category_id; let studentWorkId=this.props.match.params.studentWorkId; const isAdmin = this.props.isAdmin() document.title=course_name&&course_name; return( +
+ {this.commonWorkAppraiseReply = ref}} + get_next_works={()=>this.get_next_works()} >
+ {isAdmin===true&&get_next_worktype===true?:""} + + {isAdmin===true&&get_next_worktype===true?
+ +
+
+ + + + {get_next_work&&get_next_work.work_id===null? + +
已全部评阅完
+
: +
{get_next_work&&get_next_work?`下一位待评阅人员:${get_next_work&&get_next_work.user_name}`:""}
+ this.get_next_works(get_next_work&&get_next_work.work_id)}>跳过 +
} + + {get_next_work&&get_next_work.work_id===null?"": + + + + + + } +
+ +
+
+
:""} + ) } } diff --git a/public/react/src/modules/courses/busyWork/CommonWorkList.js b/public/react/src/modules/courses/busyWork/CommonWorkList.js index 549dd6ae3..e45d016bb 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkList.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkList.js @@ -1,6 +1,6 @@ import React,{Component} from "react"; -import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal, Table, Divider, Tag,DatePicker,Radio,Tooltip,Spin, Pagination} from "antd"; -import {WordsBtn, ConditionToolTip, queryString, publicSearchs, on, off, NoneData, sortDirections} from 'educoder'; +import { Form, Table,Tooltip,Spin, Pagination} from "antd"; +import { queryString, publicSearchs, on, off, NoneData, sortDirections} from 'educoder'; import axios from 'axios'; import CheckAllGroup from '../common/button/CheckAllGroup' import moment from 'moment'; @@ -11,7 +11,6 @@ import ModulationModal from "../coursesPublic/ModulationModal"; import AccessoryModal from "../coursesPublic/AccessoryModal"; import LeaderIcon from './common/LeaderIcon' const $ = window.$; -const Search = Input.Search; function renderScore(score, content) { let color = '#747A7F' @@ -369,18 +368,24 @@ function buildColumns(that, student_works, studentData) { {/* 0 未提交 */} {/**/} {/**/} +
+ that.props.toWorkDetailPage2(e, courseId, workId, record.id)} + // onClick={() => that.props.toWorkDetailPage(courseId, workId, record.id)} + >{isAdmin ? record.has_comment===true?"已评阅":'评阅':"查看"} +
+ +
{ isAdmin && 调整学生当前成绩
其它历史评分将全部失效}> - that.showModulationModal(record)} >调分
} +
{/* toWorkDetailPage */} {/* /classrooms/"+courseId+"/common_homeworks/"+workId+ '/' + record.id +"/appraise */} - that.props.toWorkDetailPage2(e, courseId, workId, record.id)} - // onClick={() => that.props.toWorkDetailPage(courseId, workId, record.id)} - >{isAdmin ? '评阅' : '查看'} - ), @@ -692,7 +697,7 @@ class CommonWorkList extends Component{ modulationModalVisible, work_statuses, id, user_name, user_login, student_id, group_name, work_status, update_time, teacher_score, teaching_asistant_score, student_score, - ultimate_score, work_score, student_comment_count, appeal_all_count, appeal_deal_count, + ultimate_score, work_score, student_comment_count, appeal_all_count, appeal_deal_count,has_comment, late_penalty, absence_penalty, appeal_penalty,user_comment_count , end_immediately, publish_immediately diff --git a/public/react/src/modules/courses/busyWork/reply/CommonWorkAppraiseReply.js b/public/react/src/modules/courses/busyWork/reply/CommonWorkAppraiseReply.js index 3d3f83bc6..0a1f38965 100644 --- a/public/react/src/modules/courses/busyWork/reply/CommonWorkAppraiseReply.js +++ b/public/react/src/modules/courses/busyWork/reply/CommonWorkAppraiseReply.js @@ -20,7 +20,7 @@ import Modals from '../../../modals/Modals'; const REPLY_PAGE_COUNT = 10 const $ = window.$; -/* +/* */ class CommonWorkAppraiseReply extends Component{ @@ -79,7 +79,7 @@ class CommonWorkAppraiseReply extends Component{ reply.journals.push(reply.appeal_info) reply.journals = _.orderBy(reply.journals, 'time', 'asc') } - + return { isSuperAdmin: isSuperAdmin, admin: isAdmin, // @@ -93,7 +93,7 @@ class CommonWorkAppraiseReply extends Component{ // time: moment(reply.comment_time).fromNow(), time: moment(reply.comment_time).format('YYYY-MM-DD HH:mm'), - image_url: reply.user_image_url, + image_url: reply.user_image_url, user_id: reply.user_id, user_login: reply.user_login, username: reply.user_name, @@ -131,7 +131,7 @@ class CommonWorkAppraiseReply extends Component{ console.log('Cancel'); }, }); - + } showModulationtype=(id)=>{ @@ -221,6 +221,7 @@ class CommonWorkAppraiseReply extends Component{ if (!needNiPingEditor && comment_scores.length == 0) { return '' } + return(
@@ -257,13 +258,13 @@ class CommonWorkAppraiseReply extends Component{ {/*{this.props.isStudent()?补交附件:""}*/} {/*
*/} - + {/* { - (!!comment_scores.length && + (!!comment_scores.length &&
全部评阅 - ({comment_scores.length}) + ({comment_scores.length})
)} */}
{!!comment_scores.length &&
@@ -283,13 +284,14 @@ class CommonWorkAppraiseReply extends Component{ addSuccess={this.addSuccess} ref={this.editorRef} totalCount={comment_scores.length} onReply={this.onReply} placeholder={"请在此输入对本作品的评语,最大限制2000个字符"} showSameScore={isGroup && isAdmin} + get_next_works={()=>this.props.get_next_works()} > }
{/* ${!!comment_scores.length ? 'bor-bottom-greyE' : ''} */}
- {/* + {/* .course-message .panel-comment_item { margin-top: ${needNiPingEditor ? 56 : 28}px; } diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js index faf0d67a4..6b3f9ecdd 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js @@ -67,6 +67,9 @@ class GraduationTasksappraiseMainEditor extends Component{ same_score } if (this.props.onReply) { + if(this.props.get_next_works){ + this.props.get_next_works() + } this.props.onReply(params) } else { axios.post(url, params).then((response)=>{ diff --git a/public/react/src/modules/courses/shixunHomework/Challenges.css b/public/react/src/modules/courses/shixunHomework/Challenges.css index 8ae2c002c..18100fcf3 100644 --- a/public/react/src/modules/courses/shixunHomework/Challenges.css +++ b/public/react/src/modules/courses/shixunHomework/Challenges.css @@ -26,4 +26,8 @@ overflow:hidden; text-overflow:ellipsis; white-space:nowrap +} + +.color32C090{ + color:#32C090 !important; } \ No newline at end of file diff --git a/public/react/src/modules/courses/shixunHomework/Chongzuomodel.js b/public/react/src/modules/courses/shixunHomework/Chongzuomodel.js new file mode 100644 index 000000000..edbd106c8 --- /dev/null +++ b/public/react/src/modules/courses/shixunHomework/Chongzuomodel.js @@ -0,0 +1,68 @@ +import React from 'react'; +import Modals from "../../modals/Modals"; +import axios from 'axios'; +class Chongzuomodel extends React.Component { + + constructor(props) { + super(props); + this.state = { + ModalsType:false, + antIcon:false + } + } + + componentDidMount(){ + this.setState({ + ModalsType:this.props.Chongzuomodeltype, + Modalstopval:`该作业将被打回重做,学生实训记录将被清空!`, + ModalsBottomval:`确定打回?`, + }) + } + + ModalSaves=()=>{ + this.setState({ + antIcon:true + }) + let zrl=`/myshixuns/${this.props.chongzuoId}/reset_my_game.json?course_id=${this.props.match.params.coursesId}`; + axios.get(zrl).then((response) => { + this.setState({ + antIcon:false + }) + this.props.showNotification("操作成功"); + this.props.hideChongzuomodeltype() + this.props.Isupdatass(); + }).catch((error) => { + this.setState({ + antIcon:false + }) + }); + } + + ModalCancels=()=>{ + this.props.hideChongzuomodeltype() + } + + render() { + //console.log(this.props) + // Chongzuomodeltype:undefined, + // chongzuoId:undefined, + return ( + + this.ModalSaves()} + modalCancel={()=>this.ModalCancels()} + loadtype={false} + antIcon={this.state.antIcon} + > + + + ); + } +} + +export default Chongzuomodel; + + diff --git a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js index 23869ac62..6bf52c9ae 100644 --- a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js +++ b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js @@ -1,19 +1,10 @@ import React, {Component} from "react"; -import CoursesListType from '../coursesPublic/CoursesListType'; import {getRandomcode, publicSearchs, sortDirections} from 'educoder'; import { - Form, - Select, - Input, - Button, Checkbox, - Upload, Icon, - message, - Modal, Table, Pagination, - Radio, Tooltip, notification, Spin, @@ -30,18 +21,15 @@ import './Challenges.css'; import {getImageUrl} from 'educoder'; import TraineetraininginformationModal from "./TraineetraininginformationModal"; import DownloadMessageysl from '../../modals/DownloadMessageysl'; -import Startshixuntask from "../coursesPublic/Startshixuntask"; import ModulationModal from "../coursesPublic/ModulationModal"; import HomeworkModal from "../coursesPublic/HomeworkModal"; import OneSelfOrderModal from "../coursesPublic/OneSelfOrderModal"; import ShixunWorkModal from "./Shixunworkdetails/ShixunWorkModal"; import NoneData from '../../../modules/courses/coursesPublic/NoneData'; +import Chongzuomodel from "./Chongzuomodel"; -const Search = Input.Search; -const RadioGroup = Radio.Group; const CheckboxGroup = Checkbox.Group; -const {Option} = Select; -//GraduationTaskssetting.js + //作品列表(学生) let allow_lates=false; @@ -65,6 +53,8 @@ class Listofworksstudentone extends Component { //关卡得分final_score this.state = { + Chongzuomodeltype:undefined, + chongzuoId:undefined, searchtypes:false, jobsettingsdata: undefined, endTime: "2018/11/10 17:10:00", @@ -280,7 +270,11 @@ class Listofworksstudentone extends Component { width: '98px', render: (text, record) => ( - ( - ( - ( record.submitstate === "未开启" ? - this.Viewstudenttraininginformationtysl2(e, record)} - // onClick={() => this.Viewstudenttraininginformationt(record)} - >{record.has_comment===true?"详情":"评阅 "} : - this.Viewstudenttraininginformationtysl2(e, record)} - // onClick={() => this.Viewstudenttraininginformationt(record)} - >{record.has_comment===true?"详情":"评阅 "} - + + + {this.props.teacherdatapage === undefined ? "": this.props.teacherdatapage.homework_status[0]==="已截止"?"":record.myshixun_id===0?"":} + + : + + + + + {this.props.teacherdatapage === undefined ? "": this.props.teacherdatapage.homework_status[0]==="已截止"?"":record.myshixun_id===0?"":} + + ) }, ], @@ -1408,7 +1428,11 @@ class Listofworksstudentone extends Component { align: 'center', className: 'font-14', render: (text, record) => ( - ( record.submitstate === "未开启" ? - this.Viewstudenttraininginformationtysl2(e, record)} - // onClick={() => this.Viewstudenttraininginformationt(record)} - >{record.has_comment===true?"详情":"评阅"} : + + + + {this.props.teacherdatapage === undefined ? "": this.props.teacherdatapage.homework_status[0]==="已截止"?"":record.myshixun_id===0?"":} + + : - + this.Viewstudenttraininginformationtysl2(e, record)} // onClick={() => this.Viewstudenttraininginformationt(record)} - >{record.has_comment===true?"详情":"评阅"} - + >{record.has_comment===true?"已评阅":"评阅"} +
+ {this.props.teacherdatapage === undefined ? "": this.props.teacherdatapage.homework_status[0]==="已截止"?"":record.myshixun_id===0?"":
+ this.chongzuofun(record.myshixun_identifier)} + >重做 +
} + ) }, ], @@ -2073,7 +2115,7 @@ class Listofworksstudentone extends Component { classroom: teacherdata.group_name, cost_time: teacherdata.cost_time, has_comment:teacherdata.has_comment, - submitstate: teacherdata.work_status === 0 ? "未开启" : teacherdata.work_status === 1 ? "未通关" : teacherdata.work_status === 2 ? "按时通关" : "迟交通关", + submitstate:teacherdata.work_status === -1 ? "重做中":teacherdata.work_status === 0 ? "未开启" : teacherdata.work_status === 1 ? "未通关" : teacherdata.work_status === 2 ? "按时通关" : "迟交通关", // updatetime:this.state.teacherdata.student_works[i].update_time, // updatetime:"", updatetime: timedata === "Invalid date" ? "--" : timedata, @@ -2119,7 +2161,9 @@ class Listofworksstudentone extends Component { classroom: student_works[i].group_name, cost_time: student_works[i].cost_time, has_comment:student_works[i].has_comment, - submitstate: student_works[i].work_status === 0 ? "未开启" : student_works[i].work_status === 1 ? "未通关" : student_works[i].work_status === 2 ? "按时通关" : "迟交通关", + myshixun_id:student_works[i].myshixun_id, + myshixun_identifier:student_works[i].myshixun_identifier, + submitstate:student_works[i].work_status === -1 ? "重做中":student_works[i].work_status === 0 ? "未开启" : student_works[i].work_status === 1 ? "未通关" : student_works[i].work_status === 2 ? "按时通关" : "迟交通关", // updatetime:this.state.teacherdata.student_works[i].update_time, // updatetime:"", updatetime: timedata === "Invalid date" ? "--" : timedata, @@ -2281,7 +2325,7 @@ class Listofworksstudentone extends Component { classroom: teacherdata.group_name, cost_time: teacherdata.cost_time, has_comment:teacherdata.has_comment, - submitstate: teacherdata.work_status === 0 ? "未开启" : teacherdata.work_status === 1 ? "未通关" : teacherdata.work_status === 2 ? "按时通关" : "迟交通关", + submitstate:teacherdata.work_status === -1 ? "重做中":teacherdata.work_status === 0 ? "未开启" : teacherdata.work_status === 1 ? "未通关" : teacherdata.work_status === 2 ? "按时通关" : "迟交通关", // updatetime:this.state.teacherdata.student_works[i].update_time, // updatetime:"", updatetime: timedata === "Invalid date" ? "--" : timedata, @@ -2646,7 +2690,9 @@ class Listofworksstudentone extends Component { classroom: student_works[i].group_name, cost_time: student_works[i].cost_time, has_comment:student_works[i].has_comment, - submitstate: student_works[i].work_status === 0 ? "未开启" : student_works[i].work_status === 1 ? "未通关" : student_works[i].work_status === 2 ? "按时通关" : "迟交通关", + myshixun_id:student_works[i].myshixun_id, + myshixun_identifier:student_works[i].myshixun_identifier, + submitstate:student_works[i].work_status === -1 ? "重做中":student_works[i].work_status === 0 ? "未开启" : student_works[i].work_status === 1 ? "未通关" : student_works[i].work_status === 2 ? "按时通关" : "迟交通关", // updatetime:this.state.teacherdata.student_works[i].update_time, // updatetime:"", updatetime: timedata === "Invalid date" ? "--" : timedata, @@ -3442,6 +3488,19 @@ class Listofworksstudentone extends Component { }) } + chongzuofun=(id)=>{ + this.setState({ + chongzuoId:id, + Chongzuomodeltype:true + }) + } + + hideChongzuomodeltype=()=>{ + this.setState({ + chongzuoId:undefined, + Chongzuomodeltype:false + }) + } render() { let {columns,columnss, 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; @@ -3483,6 +3542,13 @@ class Listofworksstudentone extends Component { this.props.isAdmin() === true ?
+ {this.state.Chongzuomodeltype===true?this.hideChongzuomodeltype()} + Isupdatass={()=>this.Isupdatass()} + />:""} + {visible === true ? this.cancelModulationModel()} diff --git a/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js b/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js index 454b11c6f..893159730 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js @@ -22,6 +22,7 @@ import "../common/formCommon.css"; import '../css/Courses.css'; import './style.css'; import 'moment/locale/zh-cn'; +import Chongzuomodel from "./Chongzuomodel"; class ShixunWorkReport extends Component { @@ -39,7 +40,12 @@ class ShixunWorkReport extends Component { work_comment:undefined, has_commit: false, shixun_detail:[], - view_tpi:false + view_tpi:false, + myshixun_id:undefined, + myshixun_identifier:undefined, + homework_end:undefined, + chongzuoId:undefined, + Chongzuomodeltype:false } } @@ -117,7 +123,10 @@ class ShixunWorkReport extends Component { spinning: false, has_commit: result.data.has_commit, shixun_detail:result.data.shixun_detail, - view_tpi:result.data.view_tpi + view_tpi:result.data.view_tpi, + myshixun_id:result.data.myshixun_id, + myshixun_identifier:result.data.myshixun_identifier, + homework_end:result.data.homework_end, }) } @@ -308,8 +317,22 @@ class ShixunWorkReport extends Component { } } + + Backtoredo=(id)=>{ + this.setState({ + chongzuoId:id, + Chongzuomodeltype:true + }) + } + + hideChongzuomodeltype=()=>{ + this.setState({ + chongzuoId:undefined, + Chongzuomodeltype:false + }) + } render() { - let {data, showAppraiseModaltype, work_comment_hidden, work_comment, has_commit,shixun_detail,view_tpi} = this.state; + let {data, showAppraiseModaltype, work_comment_hidden, work_comment, has_commit,shixun_detail,view_tpi,myshixun_id,myshixun_identifier,homework_end} = this.state; let category_id=data===undefined?"":data.category===null?"":data.category.category_id; let homework_common_id=data===undefined?"":data.homework_common_id; @@ -324,6 +347,13 @@ class ShixunWorkReport extends Component { return ( data===undefined?"": + {this.state.Chongzuomodeltype===true?this.hideChongzuomodeltype()} + Isupdatass={()=>this.getdatalist()} + />:""} + this.showAppraiseModal(1)}*/} {/*>评阅 : ""}*/} + + {this.props.isAdmin()?homework_end===false&&myshixun_id!=0?this.Backtoredo(myshixun_identifier)} + >打回重做:"":""} + {this.props.isAdmin() ?this.showAppraiseModal("main",undefined,work_comment,work_comment_hidden)} diff --git a/public/react/src/modules/courses/signin/css/signincdi.css b/public/react/src/modules/courses/signin/css/signincdi.css index aadbeec20..c6711c4a5 100644 --- a/public/react/src/modules/courses/signin/css/signincdi.css +++ b/public/react/src/modules/courses/signin/css/signincdi.css @@ -549,3 +549,6 @@ .widh150wpos{ word-break: break-all; } +a { text-decoration:none !important;} +a:hover {text-decoration: none !important;} +a:active{text-decoration:none !important;} diff --git a/public/react/src/modules/courses/signin/student/Signedinlist.js b/public/react/src/modules/courses/signin/student/Signedinlist.js index ea5ffb998..652196131 100644 --- a/public/react/src/modules/courses/signin/student/Signedinlist.js +++ b/public/react/src/modules/courses/signin/student/Signedinlist.js @@ -101,11 +101,20 @@ class Signedinlist extends Component { handleChangegroup_ids=(value)=>{ let neval if(!value){ - neval=[] - this.setState({ - group_ids: [], - page:1 - }) + if(value===0){ + neval=[0] + this.setState({ + group_ids: [0], + page:1 + }) + }else{ + neval=[] + this.setState({ + group_ids: [], + page:1 + }) + } + }else{ neval=[value] this.setState({ @@ -327,11 +336,11 @@ class Signedinlist extends Component { - {this.props.defaultActiveKey==="2"? + {this.props.defaultActiveKey==="2"? 正常签到:{data&&data.normal_count} 请假:{data&&data.leave_count} 旷课:{data&&data.absence_count} - : + : 已签到:{this.state.course_members_count} 应签到:{this.state.attendance_count} } diff --git a/public/react/src/modules/courses/videostatistics/Videostatistics.js b/public/react/src/modules/courses/videostatistics/Videostatistics.js index a199d95c4..0fc6aca0f 100644 --- a/public/react/src/modules/courses/videostatistics/Videostatistics.js +++ b/public/react/src/modules/courses/videostatistics/Videostatistics.js @@ -87,6 +87,16 @@ class Videostatistics extends Component{ return(
+ { tisticsbool===false?
{ ` - a{  -     text-decoration:none; -     color:#333; - } - a:hover{ -     text-decoration:none;//鼠标放上面不显示下划线 -     color:#333; - } + a{text-decoration:none !important;} + a:hover {text-decoration: none !important;} + a:active{text-decoration:none !important;} ` } diff --git a/public/react/src/modules/courses/videostatistics/component/Studentstatistics.js b/public/react/src/modules/courses/videostatistics/component/Studentstatistics.js index 16e8bddb2..a9fef7906 100644 --- a/public/react/src/modules/courses/videostatistics/component/Studentstatistics.js +++ b/public/react/src/modules/courses/videostatistics/component/Studentstatistics.js @@ -38,18 +38,13 @@ class Studentstatistics extends Component { - {record.title} @@ -83,18 +78,13 @@ class Studentstatistics extends Component { - {record.total_duration} @@ -113,18 +103,13 @@ class Studentstatistics extends Component { - {record.user_name} @@ -297,14 +282,9 @@ class Studentstatistics extends Component { diff --git a/public/react/src/modules/courses/videostatistics/component/Videostatisticscom.js b/public/react/src/modules/courses/videostatistics/component/Videostatisticscom.js index f6334f941..94031cd85 100644 --- a/public/react/src/modules/courses/videostatistics/component/Videostatisticscom.js +++ b/public/react/src/modules/courses/videostatistics/component/Videostatisticscom.js @@ -36,14 +36,9 @@ class Videostatisticscom extends Component { diff --git a/public/react/src/modules/courses/videostatistics/component/Videostatisticscomtwo.js b/public/react/src/modules/courses/videostatistics/component/Videostatisticscomtwo.js index a05be5a39..800b11b7d 100644 --- a/public/react/src/modules/courses/videostatistics/component/Videostatisticscomtwo.js +++ b/public/react/src/modules/courses/videostatistics/component/Videostatisticscomtwo.js @@ -43,18 +43,13 @@ class Videostatisticscomtwo extends Component { - {record.user_name} @@ -87,18 +82,13 @@ class Videostatisticscomtwo extends Component { - {record.total_duration}
), @@ -117,18 +107,13 @@ class Videostatisticscomtwo extends Component { - {record.feq}
@@ -145,20 +130,15 @@ class Videostatisticscomtwo extends Component { { record.start_at? - {moment(record.start_at).format('YYYY-MM-DD HH:mm:ss')} : @@ -178,20 +158,15 @@ class Videostatisticscomtwo extends Component { { record.end_at? - {moment(record.end_at).format('YYYY-MM-DD HH:mm:ss')} : @@ -559,14 +534,11 @@ class Videostatisticscomtwo extends Component { diff --git a/public/react/src/modules/courses/videostatistics/component/Videostatisticslist.js b/public/react/src/modules/courses/videostatistics/component/Videostatisticslist.js index 5280633c5..25c00047c 100644 --- a/public/react/src/modules/courses/videostatistics/component/Videostatisticslist.js +++ b/public/react/src/modules/courses/videostatistics/component/Videostatisticslist.js @@ -38,18 +38,13 @@ class Videostatisticslist extends Component { - {record.title} @@ -83,18 +78,13 @@ class Videostatisticslist extends Component { - {record.total_time} @@ -113,18 +103,13 @@ class Videostatisticslist extends Component { - {record.user_name} @@ -294,13 +279,10 @@ class Videostatisticslist extends Component { { ` a{  -     text-decoration:none; -     color:#333; - } - a:hover{ -     text-decoration:none;//鼠标放上面不显示下划线 -     color:#333; +     text-decoration:none !important; } + a:hover {text-decoration: none !important;} + a:active{text-decoration:none !important;} ` } diff --git a/public/react/src/modules/tpm/TPMIndex.js b/public/react/src/modules/tpm/TPMIndex.js index 2a650e3d0..3e8dc1cd8 100644 --- a/public/react/src/modules/tpm/TPMIndex.js +++ b/public/react/src/modules/tpm/TPMIndex.js @@ -397,7 +397,7 @@ class TPMIndex extends Component { newathArray:list }) } - render() { + render() { let url = window.location.href; let flag =false; @@ -671,7 +671,7 @@ class TPMIndex extends Component {
); - } + } } export default SnackbarHOC() (TPMIndexHOC ( TPMIndex ));