diff --git a/.gitignore b/.gitignore index 349c0cdc1..544539736 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # Ignore bundler config. /.bundle /bundle +/node_modules # Ignore lock config file *.lock @@ -46,6 +47,8 @@ /public/h5build /public/npm-debug.log +/dist + # avatars /public/images/avatars diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 124fc1094..d701575e7 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -30,7 +30,7 @@ class CoursesController < ApplicationController :informs, :update_informs, :online_learning, :update_task_position, :tasks_list, :join_excellent_course, :export_couser_info, :export_member_act_score, :new_informs, :delete_informs, :change_member_role, :course_groups, :join_course_group, :statistics, - :work_score, :act_score, :calculate_all_shixun_scores, :move_to_category] + :work_score, :act_score, :calculate_all_shixun_scores, :move_to_category, :watch_video_histories] before_action :user_course_identity, except: [:join_excellent_course, :index, :create, :new, :apply_to_join_course, :search_course_list, :get_historical_course_students, :mine, :search_slim, :board_list] before_action :teacher_allowed, only: [:update, :destroy, :settings, :search_teacher_candidate, @@ -114,7 +114,7 @@ class CoursesController < ApplicationController #sql = "left join videos on videos.id=course_videos.video_id AND (videos.transcoded=1 OR videos.user_id = #{current_user.id})" #@videos = paginate videos.joins(sql).includes(video: [user: :user_extension], user: :user_extension) - videos = videos.includes(video: [user: :user_extension], user: :user_extension) + videos = videos.includes(video: [user: :user_extension],user: :user_extension).select("course_videos.id, course_videos.title, course_videos.link, course_videos.user_id") videos = videos.where(videos: {transcoded: true}) .or(videos.where(videos: {user_id: current_user.id})) .or(videos.where(course_videos: {is_link: true})) @@ -1481,6 +1481,23 @@ class CoursesController < ApplicationController end end + def watch_video_histories + @videos = CourseVideo.find_by_sql(" + SELECT course_videos.id, videos.user_id, videos.title, IFNULL(hisotries.time,0) AS time, IFNULL(hisotries.num,0) AS num + FROM course_videos + JOIN videos ON course_videos.course_id = #{@course.id} AND videos.id = course_videos.video_id + LEFT JOIN ( + SELECT watch_course_videos.course_video_id, sum(watch_course_videos.total_duration) AS time, count(watch_course_videos.course_video_id) AS num + FROM watch_course_videos + JOIN course_videos ON course_videos.id = watch_course_videos.course_video_id + WHERE course_videos.course_id = #{@course.id} + GROUP BY watch_course_videos.course_video_id + ) AS hisotries ON hisotries.course_video_id = course_videos.id + ") + @count = @videos.count + @videos = paginate @videos + end + private # Use callbacks to share common setup or constraints between actions. diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 6a7f7b4b0..8e6356201 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -367,9 +367,9 @@ class FilesController < ApplicationController @category_name = category.try(:module_name) else @category = CourseSecondCategory.find category_id - @category_id = category.try(:id) - @category_name = category.try(:name) - @parent_category_id = category&.parent_id.to_i + @category_id = @category.try(:id) + @category_name = @category.try(:name) + @parent_category_id = @category&.parent_id.to_i end end diff --git a/app/controllers/watch_video_histories_controller.rb b/app/controllers/watch_video_histories_controller.rb index 15ee62113..fe1fbf31b 100644 --- a/app/controllers/watch_video_histories_controller.rb +++ b/app/controllers/watch_video_histories_controller.rb @@ -5,6 +5,6 @@ class WatchVideoHistoriesController < ApplicationController watch_log = CreateWatchVideoService.new(current_user, request, params).call render_ok(log_id: watch_log&.id) rescue CreateWatchVideoService::Error => ex - render_error(ex.message) + render_ok(log_id: watch_log&.id) end end diff --git a/app/controllers/weapps/attendances_controller.rb b/app/controllers/weapps/attendances_controller.rb index da22aa300..9740da15f 100644 --- a/app/controllers/weapps/attendances_controller.rb +++ b/app/controllers/weapps/attendances_controller.rb @@ -114,6 +114,8 @@ class Weapps::AttendancesController < ApplicationController @course_members = @course.students if @_is_current_attendance @all_attendances = @attendance.course_member_attendances + + @user = @attendance.user end def update diff --git a/app/controllers/weapps/course_member_attendances_controller.rb b/app/controllers/weapps/course_member_attendances_controller.rb index 5e92d5928..21a687d60 100644 --- a/app/controllers/weapps/course_member_attendances_controller.rb +++ b/app/controllers/weapps/course_member_attendances_controller.rb @@ -14,6 +14,9 @@ class Weapps::CourseMemberAttendancesController < ApplicationController @members = @members.where(course_group_id: params[:group_ids]) end + @page = params[:page] || 1 + @limit = params[:limit] || 5 + if params[:attendance_status].present? @members = @members.joins(:course_member_attendances).where(course_member_attendances: {course_attendance_id: attendance.id, attendance_status: params[:attendance_status]}) end diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index 27444b3c9..4e088c0fd 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -81,6 +81,8 @@ module CoursesHelper "/classrooms/#{course.id}/statistics" when "video" "/classrooms/#{course.id}/course_videos" + when "attendance" + "/classrooms/#{course.id}/attendances" end end @@ -131,31 +133,33 @@ module CoursesHelper # 课堂模块的任务数 def course_task_count(course, module_type) case module_type - when "shixun_homework" - get_homework_commons_count(course, 4, 0) - when "common_homework" - get_homework_commons_count(course, 1, 0) - when "group_homework" - get_homework_commons_count(course, 3, 0) - when "graduation" - 0 - when "exercise" - course.exercises_count - when "poll" - course.polls_count - when "attachment" - get_attachment_count(course, 0) - when "board" - course_board = course.course_board - course_board.present? ? course_board.messages.size : 0 - when "course_group" - course.course_groups_count - when "announcement" - course.informs.count - when "online_learning" - course.shixuns.count - when "video" - course.videos_count + course.live_links.count + when "shixun_homework" + get_homework_commons_count(course, 4, 0) + when "common_homework" + get_homework_commons_count(course, 1, 0) + when "group_homework" + get_homework_commons_count(course, 3, 0) + when "graduation" + 0 + when "exercise" + course.exercises_count + when "poll" + course.polls_count + when "attachment" + get_attachment_count(course, 0) + when "board" + course_board = course.course_board + course_board.present? ? course_board.messages.size : 0 + when "course_group" + course.course_groups_count + when "announcement" + course.informs.count + when "online_learning" + course.shixuns.count + when "video" + course.videos_count + course.live_links.count + when "attendance" + course.course_attendances.count end end diff --git a/app/models/course.rb b/app/models/course.rb index abe17b3cd..bd36e65eb 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -226,7 +226,7 @@ class Course < ApplicationRecord end def all_course_module_types - %w[activity announcement online_learning shixun_homework common_homework group_homework exercise attachment course_group graduation poll board statistics video] + %w[activity announcement online_learning shixun_homework common_homework group_homework exercise attachment course_group graduation poll board statistics video attendance] end def get_course_module_by_type(type) @@ -429,6 +429,7 @@ class Course < ApplicationRecord when 'video' then '视频直播' when 'board' then '讨论' when 'course_group' then '分班' + when 'attendance' then '签到' when 'statistics' then '统计' else '' end @@ -449,7 +450,8 @@ class Course < ApplicationRecord when 'video' then 11 when 'board' then 12 when 'course_group' then 13 - when 'statistics' then 14 + when 'attendance' then 14 + when 'statistics' then 15 else 100 end end diff --git a/app/services/create_watch_video_service.rb b/app/services/create_watch_video_service.rb index 28cf36838..0f1b32814 100644 --- a/app/services/create_watch_video_service.rb +++ b/app/services/create_watch_video_service.rb @@ -10,31 +10,36 @@ class CreateWatchVideoService < ApplicationService def call ActiveRecord::Base.transaction do current_time = Time.now + params[:watch_duration] = params[:watch_duration].to_f.round(2) + params[:total_duration] = params[:total_duration].to_f.round(2) + params[:duration] = params[:duration].to_f.round(2) + if params[:log_id].present? - if params[:total_duration].to_f < params[:watch_duration].to_f || params[:watch_duration].to_f < 0 - raise Error, '观看时长错误' + watch_video_history = user.watch_video_histories.find(params[:log_id]) + if params[:total_duration] < params[:watch_duration] + return watch_video_history end # 更新观看时长 - watch_video_history = user.watch_video_histories.find(params[:log_id]) - - if watch_video_history.present? && watch_video_history.watch_duration <= params[:watch_duration].to_f && params[:total_duration].to_f > watch_video_history.total_duration + 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] # 如果观看总时长没变,说明视频没有播放,无需再去记录 - watch_video_history.end_at = current_time watch_video_history.total_duration = params[:total_duration] - watch_video_history.watch_duration = params[:watch_duration].to_f > watch_video_history.duration ? watch_video_history.duration : params[:watch_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.save! watch_course_video = watch_video_history.watch_course_video - if watch_course_video.present? && !watch_course_video.is_finished && watch_course_video.watch_duration < params[:watch_duration].to_f - # 更新课程视频的时长及是否看完状态 - watch_course_video.watch_duration = params[:watch_duration] - if params[:ed].present? - watch_course_video.is_finished = watch_course_video.watch_video_histories.sum(:total_duration) >= watch_course_video.duration - end + 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 !watch_course_video.is_finished && watch_course_video.watch_duration < params[:watch_duration] + # 更新课程视频的时长及是否看完状态 + watch_course_video.watch_duration = params[:watch_duration] + if params[:ed].present? + watch_course_video.is_finished = watch_course_video.total_duration >= watch_course_video.duration + end + end watch_course_video.save! end end @@ -47,11 +52,10 @@ class CreateWatchVideoService < ApplicationService d.start_at = current_time d.duration = params[:duration] end - - watch_video_history = build_video_log(current_time, course_video.video_id, watch_course_video.id) - watch_video_history.save! watch_course_video.save! unless watch_course_video.persisted? + watch_video_history = build_video_log(current_time, course_video.video_id, watch_course_video.id) + watch_video_history.save! else # 非课堂视频 video = Video.find(params[:video_id]) diff --git a/app/views/attendances/index.json.jbuilder b/app/views/attendances/index.json.jbuilder index 8a4dd2bb1..b44f9a4fe 100644 --- a/app/views/attendances/index.json.jbuilder +++ b/app/views/attendances/index.json.jbuilder @@ -1,5 +1,5 @@ json.attendances @attendances do |attendance| - json.(attendance, :id, :name, :normal_count, :all_count, :mode) + json.(attendance, :id, :name, :normal_count, :all_count, :mode, :attendance_code) json.author do user = attendance.user json.user_name user.real_name diff --git a/app/views/courses/course_videos.json.jbuilder b/app/views/courses/course_videos.json.jbuilder index bee5e89cb..c2a4c1282 100644 --- a/app/views/courses/course_videos.json.jbuilder +++ b/app/views/courses/course_videos.json.jbuilder @@ -10,6 +10,8 @@ json.videos @videos do |video| json.user_login user&.login else json.partial! 'users/videos/video', locals: { video: video.video } + json.total_time video.watch_course_videos.sum(:total_duration).round(0) + json.people_num video.watch_course_videos.count(:user_id) end end diff --git a/app/views/courses/watch_video_histories.json.jbuilder b/app/views/courses/watch_video_histories.json.jbuilder new file mode 100644 index 000000000..4e7a4b174 --- /dev/null +++ b/app/views/courses/watch_video_histories.json.jbuilder @@ -0,0 +1,10 @@ +json.videos do + json.array! @videos do |v| + json.id v.id + json.title v.title + json.user_name v.user&.real_name + json.people_num v.num + json.total_time v.time + end +end +json.count @count \ No newline at end of file diff --git a/app/views/weapps/attendances/show.json.jbuilder b/app/views/weapps/attendances/show.json.jbuilder index b3f13ca60..b16971741 100644 --- a/app/views/weapps/attendances/show.json.jbuilder +++ b/app/views/weapps/attendances/show.json.jbuilder @@ -9,6 +9,10 @@ json.name @attendance.name json.attendance_date @attendance.attendance_date.strftime("%Y-%m-%d") json.start_time @attendance.start_time.strftime("%H:%M") json.end_time @attendance.end_time.strftime("%H:%M") +json.author do + json.user_name @user.real_name + json.user_login @user.login +end # json.course_groups @group_ids do |group| # json.(group, :id, :name, :course_members_count) diff --git a/app/views/weapps/course_member_attendances/index.json.jbuilder b/app/views/weapps/course_member_attendances/index.json.jbuilder index cec70b3fe..765de5833 100644 --- a/app/views/weapps/course_member_attendances/index.json.jbuilder +++ b/app/views/weapps/course_member_attendances/index.json.jbuilder @@ -4,8 +4,9 @@ # json.student_id member.user&.student_id # end -json.member_attendances @members.each do |member| +json.member_attendances @members.each_with_index.to_a do |member, index| json.(member, :user_id) + json.index (@page.to_i - 1) * @limit.to_i + index + 1 json.user_name member.user&.real_name json.student_id member.user&.student_id json.attendance_status @member_attendances.select{|attendance| attendance.course_member_id == member.id}.first&.attendance_status || "ABSENCE" diff --git a/config/routes.rb b/config/routes.rb index 6c3efcfe8..881324e61 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -531,6 +531,7 @@ Rails.application.routes.draw do post :inform_up post :inform_down get :calculate_all_shixun_scores + get :watch_video_histories end collection do diff --git a/db/migrate/20200312075912_add_attendance_to_course_module.rb b/db/migrate/20200312075912_add_attendance_to_course_module.rb new file mode 100644 index 000000000..02bb48fe1 --- /dev/null +++ b/db/migrate/20200312075912_add_attendance_to_course_module.rb @@ -0,0 +1,16 @@ +class AddAttendanceToCourseModule < ActiveRecord::Migration[5.2] + def change + Course.all.each do |course| + unless course.course_modules.exists?(module_type: "attendance") + atta_position = course.course_modules.find_by(module_type: 'course_group')&.position.to_i + attendance_position = atta_position != 0 ? (atta_position + 1) : 14 + course.course_modules.where("position >= #{attendance_position}").update_all("position = position + 1") + if course.is_end + course.course_modules << CourseModule.new(module_type: "attendance", hidden: 1, module_name: "签到", position: attendance_position) + else + course.course_modules << CourseModule.new(module_type: "attendance", hidden: 0, module_name: "签到", position: attendance_position) + end + end + end + end +end diff --git a/db/migrate/20200313104522_add_total_duration_to_watch_course_duration.rb b/db/migrate/20200313104522_add_total_duration_to_watch_course_duration.rb new file mode 100644 index 000000000..400e52ac8 --- /dev/null +++ b/db/migrate/20200313104522_add_total_duration_to_watch_course_duration.rb @@ -0,0 +1,8 @@ +class AddTotalDurationToWatchCourseDuration < ActiveRecord::Migration[5.2] + def change + add_column :watch_course_videos, :total_duration, :float, default: 0 + WatchVideoHistory.where("created_at < '2020-03-14 00:00:00'").each do |d| + d.watch_course_video.increment!(:total_duration, d.total_duration) if d.watch_course_video.present? + end + end +end diff --git a/public/images/qiandao/daoke.png b/public/images/qiandao/daoke.png new file mode 100644 index 000000000..7bdcac50e Binary files /dev/null and b/public/images/qiandao/daoke.png differ diff --git a/public/images/qiandao/kuangke.png b/public/images/qiandao/kuangke.png new file mode 100644 index 000000000..13c9972ee Binary files /dev/null and b/public/images/qiandao/kuangke.png differ diff --git a/public/images/qiandao/lishi.png b/public/images/qiandao/lishi.png new file mode 100644 index 000000000..98c72702a Binary files /dev/null and b/public/images/qiandao/lishi.png differ diff --git a/public/images/qiandao/qingjia.png b/public/images/qiandao/qingjia.png new file mode 100644 index 000000000..2d885f432 Binary files /dev/null and b/public/images/qiandao/qingjia.png differ diff --git a/public/react/package.json b/public/react/package.json index d29adb905..e644e2166 100644 --- a/public/react/package.json +++ b/public/react/package.json @@ -61,6 +61,7 @@ "postcss-loader": "2.0.8", "promise": "8.0.1", "prop-types": "^15.6.1", + "qrcode.react": "^1.0.0", "qs": "^6.6.0", "quill": "^1.3.7", "quill-delta-to-html": "^0.11.0", diff --git a/public/react/public/css/demo_index.html b/public/react/public/css/demo_index.html index 7b0854698..59a7d4aec 100644 --- a/public/react/public/css/demo_index.html +++ b/public/react/public/css/demo_index.html @@ -30,6 +30,24 @@
共 {videoData && videoData.count} 个视频
+ +播放数据从2020-03-13 24:00开始统计
++ {item && item.name} +
+ +{ + jsCopy("file_path" + 1) + }}> + 复制签到码 +
++ {item&&item.code} +
+签到码:
+暂无相关数据
+this.props.qiandaoxiangq(true,item.id)}> + { + item.name + } + +
+ +this.props.qiandaoxiangq(false)}> + +
返回
+ + +共{attendances_count}个签到正在进行
+已完成{attendances_count}次签到
+ { + isAdmin===false? +旷课:{absence_count}
+请假:{leave_count}
+正常签到:{normal_count}
+ +this.Createsign()}>创建签到
+