小程序签到

video_log
cxt 5 years ago
parent 1eef20bda1
commit e541871eb6

@ -321,7 +321,7 @@ class ApplicationController < ActionController::Base
end
if !User.current.logged? && Rails.env.development?
User.current = User.find 3117
User.current = User.find 1
end

@ -1,9 +1,10 @@
class Weapps::AttendancesController < ApplicationController
before_action :require_login
before_action :find_course, only: [:create, :index, :student_attendances]
before_action :find_attendance, except: [:create, :index, :student_attendances]
before_action :find_course, only: [:create, :index, :student_attendances, :history_attendances]
before_action :find_attendance, except: [:create, :index, :student_attendances, :history_attendances]
before_action :user_course_identity
before_action :teacher_allowed, only: [:create]
before_action :edit_auth, only: [:update, :destroy, :end]
def create
ActiveRecord::Base.transaction do
@ -13,8 +14,10 @@ class Weapps::AttendancesController < ApplicationController
group_ids.each do |group_id|
@course.course_attendance_groups.create!(course_group_id: group_id, course_attendance: attendance)
end
CreateStudentAttendanceRecordJob.perform_now(attendance.id, group_ids)
else
@course.course_attendance_groups.create!(course_group_id: 0, course_attendance: attendance)
CreateStudentAttendanceRecordJob.perform_later(attendance.id, [0])
end
render_ok({attendance_id: attendance.id})
end
@ -25,7 +28,7 @@ class Weapps::AttendancesController < ApplicationController
end
def student_attendances
tip_exception(403, "") if @user_course_identity != Course::STUDENT
tip_exception("学生身份的签到列表") if @user_course_identity != Course::STUDENT
member = @course.students.find_by(user_id: current_user.id)
current_date = Date.current
current_end_time = Time.current.strftime("%H:%M:%S")
@ -49,8 +52,8 @@ class Weapps::AttendancesController < ApplicationController
@leave_count = 0
@absence_count = 0
else
@normal_count = @course.course_member_attendances.where(course_attendance_id: student_attendance_ids, attendance_status: 1).size
@leave_count = @course.course_member_attendances.where(course_attendance_id: student_attendance_ids, attendance_status: 2).size
@normal_count = @course.course_member_attendances.where(course_attendance_id: student_attendance_ids, attendance_status: "NORMAL").size
@leave_count = @course.course_member_attendances.where(course_attendance_id: student_attendance_ids, attendance_status: "LEAVE").size
@absence_count = student_attendance_ids.uniq.size - @normal_count - @leave_count
end
@ -59,17 +62,48 @@ class Weapps::AttendancesController < ApplicationController
end
def show
@normal_count = @attendance.normal_count
@leave_count = @attendance.leave_count
@absence_count = @attendance.absence_count
@all_count = @attendance.course_member_attendances.size
@_is_current_attendance = @attendance.current_attendance?
if @attendance.course_attendance_groups.first&.course_group_id.to_i == 0
@groups = @course.course_groups
else
@groups = @course.course_groups.where(id: @attendance.course_attendance_groups.pluck(:course_group_id))
end
@groups = @groups.includes(:course_members) if @_is_current_attendance
@all_attendances = @attendance.course_member_attendances
end
def update
tip_exception(403, "") unless @user_course_identity < Course::PROFESSOR || @attendance.user_id == current_user.id
@attendance.update!(name: params[:name])
render_ok
end
def destroy
@attendance.destroy!
render_ok
end
def history_attendances
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}')").order("id desc")
@all_history_count = @history_attendances.size
@history_attendances = paginate @history_attendances.includes(:course_member_attendances)
end
def end
tip_exception("该签到不在签到时间内,无法截止") unless @attendance.current_attendance?
@attendance.update!(end_time: Time.current)
render_ok
end
private
@ -81,4 +115,8 @@ class Weapps::AttendancesController < ApplicationController
@attendance = CourseAttendance.find params[:id]
@course = @attendance.course
end
def edit_auth
tip_exception(403, "") unless @user_course_identity < Course::PROFESSOR || @attendance.user_id == current_user.id
end
end

@ -1,10 +1,21 @@
class Weapps::CourseMemberAttendancesController < ApplicationController
before_action :require_login
before_action :find_course, :user_course_identity, only: [:update]
before_action :find_course, :user_course_identity, only: [:update_status]
def index
attendance = CourseAttendance.find params[:attendance_id]
@member_attendances = attendance.course_member_attendances
if params[:group_ids].present?
@member_attendances = @member_attendances.joins(:course_member).where(course_members: {course_group_id: params[:group_ids]})
end
@member_attendances = @member_attendances.where(attendance_status: params[:attendance_status]) if params[:attendance_status].present?
@member_attendances = @member_attendances.joins(user: :user_extension).order("user_extensions.student_id asc")
@member_attendances = paginate @member_attendances.preload(user: :user_extension)
end
def create
tip_exception("签到码不能为空") if params[:code].blank?
tip_exception("attendance_mode参数不对") if ["NUMBER", "QRCODE"].include?(params[:attendance_mode])
tip_exception("attendance_mode参数不对") unless ["NUMBER", "QRCODE"].include?(params[:attendance_mode])
attendance = CourseAttendance.find_by(attendance_code: params[:code])
tip_exception("签到码输入有误") if attendance.blank? || attendance.course.blank?
@ -12,32 +23,40 @@ class Weapps::CourseMemberAttendancesController < ApplicationController
member = attendance.course.students.find_by(user_id: current_user.id)
tip_exception("签到码输入有误") if member.blank?
start_time = "#{attendance.attendance_date} #{attendance.start_time}".to_time
end_time = "#{attendance.attendance_date} #{attendance.end_time}".to_time
Rails.logger.info("##############{start_time} #{end_time}")
tip_exception("不在签到时间内") unless start_time < Time.current && Time.current < end_time
tip_exception("不在签到时间内") unless attendance.current_attendance?
tip_exception("只支持数字签到") if attendance.mode != "ALL" && attendance.mode == "NUMBER" && params[:attendance_mode] == "QRCODE"
tip_exception("只支持二维码签到") if attendance.mode != "ALL" && attendance.mode == "QRCODE" && params[:attendance_mode] == "NUMBER"
current_attendance = attendance.course_member_attendances.find_by(user_id: current_user.id)
tip_exception("请勿重复签到") if current_attendance.present? && current_attendance.attendance_status == "NORMAL"
tip_exception("您当前是请假状态,无法签到") if current_attendance.present? && current_attendance.attendance_status == "LEAVE"
tip_exception("您当前是旷课状态,无法签到") if current_attendance.present? && current_attendance.attendance_status == "ABSENCE"
unless current_attendance.present?
if current_attendance.present?
tip_exception("请勿重复签到") if current_attendance.attendance_status == "NORMAL"
tip_exception("您当前是请假状态,无法签到") if current_attendance.attendance_status == "LEAVE"
tip_exception("您当前是旷课状态,无法签到") if current_attendance.attendance_status == "ABSENCE" && current_attendance.attendance_mode == "TEACHER"
current_attendance.update!(attendance_status: "NORMAL", attendance_mode: params[:attendance_mode])
else
attendance.course_member_attendances.create!(course_member_id: member.id, user_id: current_user.id, course_id: attendance.course_id,
course_group_id: member.course_group_id, attendance_status: 1, attendance_mode: params[:attendance_mode])
course_group_id: member.course_group_id, attendance_status: "NORMAL", attendance_mode: params[:attendance_mode])
end
render_ok
end
def update
def update_status
tip_exception("user_id不能为空") if params[:user_id].blank?
tip_exception(403, "无权限调整签到状态") if @user_course_identity > Course::ASSISTANT_PROFESSOR
tip_exception("attendance_status参数不对") unless ["NORMAL", "LEAVE", "ABSENCE"].include?(params[:attendance_status])
attendance = @course.course_attendances.find_by!(id: params[:attendance_id])
current_attendance = attendance.course_member_attendances.find_by(user_id: params[:user_id])
if current_attendance
current_attendance.update!(attendance_status)
if current_attendance.present?
current_attendance.update!(attendance_status: params[:attendance_status], attendance_mode: "TEACHER")
else
member = attendance.course.students.find_by(user_id: params[:user_id])
tip_exception( "该用户非课堂学生") if member.blank?
attendance.course_member_attendances.create!(course_member_id: member.id, user_id: params[:user_id], course_id: attendance.course_id,
course_group_id: member.course_group_id, attendance_status: params[:attendance_status], attendance_mode: "TEACHER")
end
render_ok
end
end

@ -4,4 +4,9 @@ module Weapps::AttendancesHelper
st_attendance = attendance.course_member_attendances.find_by(user_id: user.id)
st_attendance.present? ? st_attendance.attendance_status : "ABSENCE"
end
def group_attendance_count attendances, group
course_member_ids = group.course_members.pluck(:id)
attendances.select{|attendance| course_member_ids.include?(attendance.course_member_id) && attendance.attendance_status == "NORMAL"}.size
end
end

@ -0,0 +1,26 @@
class CreateStudentAttendanceRecordJob < ApplicationJob
queue_as :default
def perform(attendance_id, group_ids)
attendance = CourseAttendance.find_by(id: attendance_id)
course = attendance.course
return if attendance.blank? || course.blank?
if group_ids.include?(0)
students = course.students
else
students = course.students.where(course_group_id: group_ids)
end
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|
students.each do |student|
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

@ -0,0 +1,28 @@
class StudentJoinAttendanceRecordJob < ApplicationJob
queue_as :default
def perform(member_id)
member = CourseMember.find_by(id: member_id)
course = member&.course
return if member.blank? || course.blank?
current_date = Date.current
current_end_time = Time.current.strftime("%H:%M:%S")
group_ids = member.course_group_id == 0 ? [0] : [member.course_group_id, 0]
current_attendance_ids = course.course_attendances.joins(:course_attendance_groups).where(course_group_id: group_ids).
where("(attendance_date = '#{current_date}' and start_time <= '#{current_end_time}' and end_time > '#{current_end_time}') or (attendance_date > '#{current_date}')").pluck(:id)
attrs = %i[course_attendance_id user_id course_member_id course_id course_group_id created_at updated_at]
same_attrs = {course_member_id: member_id, course_id: course.id, user_id: member.user_id, course_group_id: member.course_group_id}
CourseMemberAttendance.bulk_insert(*attrs) do |worker|
current_attendance_ids.each do |attendance_id|
worker.add same_attrs.merge(course_attendance_id: attendance_id)
end
end
end
end

@ -1,4 +1,5 @@
class CourseAttendance < ApplicationRecord
# status: 0: 未开启1已开启2已截止
# mode: 0 两种签到1 二维码签到2 数字签到
enum mode: { ALL: 0, QRCODE: 1, NUMBER: 2 }
@ -16,6 +17,27 @@ class CourseAttendance < ApplicationRecord
after_create :generate_attendance_code
# 正常签到人数
def normal_count
course_member_attendances.select{|member_attendance| member_attendance.attendance_status == "NORMAL"}.size
end
# 请假人数
def leave_count
course_member_attendances.select{|member_attendance| member_attendance.attendance_status == "LEAVE"}.size
end
# 旷课人数
def absence_count
course_member_attendances.select{|member_attendance| member_attendance.attendance_status == "ABSENCE"}.size
end
def current_attendance?
a_start_time = "#{attendance_date} #{start_time}".to_time
a_end_time = "#{attendance_date} #{end_time}".to_time
a_start_time < Time.current && Time.current < a_end_time
end
# 延迟生成邀请码
def attendance_code
return generate_attendance_code

@ -23,6 +23,12 @@ class CourseMember < ApplicationRecord
# after_destroy :delete_works
# after_create :work_operation
after_create :create_attendance_record
def create_attendance_record
StudentJoinAttendanceRecordJob.perform_later(id)
end
def delete_works
if self.role == "STUDENT"
course = self.course

@ -1,8 +1,8 @@
class CourseMemberAttendance < ApplicationRecord
# attendance_mode 1 二维码签到2 数字签到3 老师签到
enum attendance_mode: { QRCODE: 1, NUMBER: 2, TEACHER: 3 }
# attendance_mode 0 初始数据,1 二维码签到2 数字签到3 老师签到
enum attendance_mode: { DEFAULT: 0, QRCODE: 1, NUMBER: 2, TEACHER: 3}
# attendance_status 1 正常签到2 请假0 旷课
enum attendance_status: { NORMAL: 1, LEAVE: 2, ABSENCE: 3 }
enum attendance_status: { NORMAL: 1, LEAVE: 2, ABSENCE: 0 }
belongs_to :course_member
belongs_to :user
belongs_to :course

@ -0,0 +1,9 @@
json.history_attendances @history_attendances do |attendance|
json.(attendance, :id, :name)
json.created_at attendance.created_at.strftime("%Y/%m/%d %H:%M")
json.normal_count attendance.normal_count
json.leave_count attendance.leave_count
json.absence_count attendance.absence_count
json.edit_auth @user_course_identity < Course::PROFESSOR || attendance.user_id == User.current.id
end
json.all_history_count @all_history_count

@ -0,0 +1,10 @@
json.normal_count @normal_count
json.leave_count @leave_count
json.absence_count @absence_count
json.all_count @all_count
json.code @attendance.attendance_code
json.edit_auth @user_course_identity < Course::PROFESSOR || @attendance.user_id == User.current.id
json.course_groups @groups do |group|
json.(group, :id, :name, :course_members_count)
json.attendance_count group_attendance_count(@all_attendances, group) if @_is_current_attendance
end

@ -0,0 +1,5 @@
json.member_attendances @member_attendances.each do |member|
json.(member, :user_id, :attendance_status)
json.user_name member.user&.real_name
json.student_id member.user&.student_id
end

@ -1061,11 +1061,15 @@ Rails.application.routes.draw do
resources :attendances, only: [:index, :update, :create, :show, :destroy], shallow: true do
collection do
get :student_attendances
get :history_attendances
end
post :end, on: :member
end
end
resources :course_member_attendances, only: [:create]
resources :course_member_attendances, only: [:create, :index] do
post :update_status, on: :collection
end
resources :homework_commons do
post :update_settings, on: :member

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe CreateStudentAttendanceRecordJob, type: :job do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe StudentJoinAttendanceRecordJob, type: :job do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save