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 if params[:log_id].present? if params[:total_duration].to_f < params[:watch_duration].to_f || params[:watch_duration].to_f < 0 raise Error, '观看时长错误' 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 # 如果观看总时长没变,说明视频没有播放,无需再去记录 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.is_finished = (watch_video_history.duration <= params[:watch_duration].to_f) 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] watch_course_video.is_finished = (watch_course_video.duration <= params[:watch_duration].to_f) watch_course_video.end_at = current_time watch_course_video.save! end end else # 开始播放时记录一次 if params[:course_id].present? # 课堂视频 course_video = CourseVideo.find_by(course_id: params[:course_id], video_id: params[:video_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_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? else # 非课堂视频 video = Video.find_by(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