class AttendancesController < ApplicationController before_action :require_login before_action :find_course, only: [:index, :statistics] before_action :find_attendance, except: [:index, :statistics] before_action :user_course_identity def index current_date = Date.current current_end_time = Time.current.strftime("%H:%M:%S") member = @course.students.find_by(user_id: current_user.id) if params[:history] if @user_course_identity == Course::STUDENT history_attendance_ids = member.course_member_attendances.where(course_id: @course.id).pluck(:course_attendance_id) @attendances = @course.course_attendances.where(id: history_attendance_ids.uniq). where("attendance_date < '#{current_date}' or (attendance_date = '#{current_date}' and end_time < '#{current_end_time}')") else @attendances = @course.course_attendances.where("attendance_date < '#{current_date}' or (attendance_date = '#{current_date}' and end_time < '#{current_end_time}')") end else @attendances = @course.course_attendances.where("attendance_date > '#{current_date}' or (attendance_date = '#{current_date}' and end_time > '#{current_end_time}')") end if @user_course_identity == Course::STUDENT group_ids = [member&.course_group_id.to_i, 0] @attendances = @attendances.joins(:course_attendance_groups).where(course_attendance_groups: {course_group_id: group_ids}) if params[:history] attendance_ids = @attendances.pluck(:id) @normal_count = @course.course_member_attendances.where(course_member_id: member&.id, course_attendance_id: attendance_ids, attendance_status: "NORMAL").size @leave_count = @course.course_member_attendances.where(course_member_id: member&.id, course_attendance_id: attendance_ids, attendance_status: "LEAVE").size @absence_count = @course.course_member_attendances.where(course_member_id: member&.id, course_attendance_id: attendance_ids, attendance_status: "ABSENCE").size else @attendances = @attendances.where("attendance_date = '#{current_date}' and start_time <= '#{current_end_time}' and end_time > '#{current_end_time}'") end end @attendances_count = @attendances.size @attendances = @attendances.order("attendance_date desc, start_time desc") @attendances = paginate @attendances.includes(:user, :course_member_attendances) end def statistics current_date = Date.current 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}')") 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 = 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") data = AttendanceStatisticsService.call history_attendances, all_member_attendances @all_history_count = data[:all_history_count] @history_attendances = data[:history_attendances] @avg_normal_rate = data[:avg_normal_rate] @avg_absence_rate = data[:avg_absence_rate] @avg_leave_rate = data[:avg_leave_rate] end def edit @groups = @course.course_groups.where(id: @attendance.course_attendance_groups.pluck(:course_group_id)) end def update tip_exception(403, "") unless @user_course_identity < Course::PROFESSOR || @attendance.user_id == current_user.id a_end_time = "#{@attendance.attendance_date} #{@attendance.end_time}".to_time new_end_time = "#{params[:attendance_date]} #{params[:end_time]}".to_time @attendance.update!(update_params) # 如果历史签到变为了正在签到,将未创建的学生签到数据补上 if a_end_time < Time.current && new_end_time > Time.current create_absence_student_data end render_ok end private def find_attendance @attendance = CourseAttendance.find params[:id] @course = @attendance.course end def update_params params.permit(:name, :mode, :attendance_date, :start_time, :end_time) end def create_absence_student_data group_ids = @attendance.course_attendance_groups.pluck(:course_group_id) if group_ids.include?(0) students = @course.students else students = @course.students.where(course_group_id: group_ids) end none_users = students.where.not(user_id: @attendance.course_member_attendances.pluck(:user_id)) attrs = %i[course_attendance_id user_id course_member_id course_id course_group_id created_at updated_at] same_attrs = {course_attendance_id: @attendance.id, course_id: @course.id} CourseMemberAttendance.bulk_insert(*attrs) do |worker| none_users.each do |student| next if @attendance.course_member_attendances.exists?(user_id: student.user_id) worker.add same_attrs.merge(user_id: student.user_id, course_member_id: student.id, course_group_id: student.course_group_id) end end end end