class CreateWatchVideoService < ApplicationService attr_reader :user, :params, :request def initialize(user, request, params) @user = user @request = request @params = params end 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? watch_video_history = user.watch_video_histories.find(params[:log_id]) # 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.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 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] 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 end else # 开始播放时记录一次 if params[:course_id].present? # 课堂视频 course_video = CourseVideo.find_by(video_id: params[:video_id], course_id: params[:course_id]) watch_course_video = WatchCourseVideo.find_or_initialize_by(course_video_id: course_video.id, user_id: user.id) do |d| d.start_at = current_time d.duration = params[:duration] end 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 # 非课堂视频 video = Video.find(params[:video_id]) watch_video_history = build_video_log(current_time, video.id) watch_video_history.save! end end watch_video_history end end def build_video_log(current_time, video_id, watch_course_video_id=nil) WatchVideoHistory.new( user_id: user.id, watch_course_video_id: watch_course_video_id, start_at: current_time, duration: params[:duration], video_id: video_id, device: params[:device], ip: request.remote_ip ) end end