You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
educoder/app/services/ecs/import_course_student_achie...

82 lines
3.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

class Ecs::ImportCourseStudentAchievementService < ApplicationService
Error = Class.new(StandardError)
attr_reader :ec_year, :course_evaluation, :attachment
def initialize(course_evaluation, attachment_id)
@course_evaluation = course_evaluation
@ec_year = course_evaluation.ec_course.ec_year
@attachment = Attachment.find_by(id: attachment_id)
end
def call
raise Error, '文件不存在' if attachment.blank?
raise Error, '请先导入学生数据' if ec_year.ec_year_students.count.zero?
path = attachment.diskfile
excel = Ecs::ImportAchievementExcel.new(path)
ActiveRecord::Base.transaction do
course_evaluation.ec_student_achievements.delete_all
handler = excel.average_score_template? ? :average_score_handler : :detail_score_handler
EcStudentAchievement.bulk_insert(*achievement_columns) do |worker|
excel.read_each do |arr|
send(handler, worker, arr)
end
end
score_type = excel.average_score_template? ? :average : :detail
current_course_evaluation.update!(import_status: true, score_type: score_type)
end
rescue BaseImportExcel::Error => ex
raise Error, ex.message
end
private
def achievement_columns
%i[
score student_name student_number position ec_year_student_id
ec_course_evaluation_id ec_course_evaluation_subitem_id created_at updated_at
]
end
def average_score_handler(worker, arr)
items_size = course_evaluation.ec_course_evaluation_subitems.size
ec_year.ec_year_students.find_each do |student|
course_evaluation.ec_course_evaluation_subitems.each_with_index do |evaluation_subitem, index|
course_evaluation.evaluation_count.times do |times|
score = arr[times * items_size + index].to_i # 共4个分项第一次考核的第三项下标为 0 * 4 + 2即 2
attrs = {
score: score, student_name: student.name, student_number: student.student_id,
position: times + 1, ec_year_student_id: student.id, ec_course_evaluation_id: course_evaluation.id,
ec_course_evaluation_subitem_id: evaluation_subitem.id
}
worker.add(attrs)
end
end
end
end
def detail_score_handler(worker, arr)
student = ec_year_students.find_by(student_id: arr[0].is_a?(Float) ? arr[0].to_i : arr[0].to_s.strip)
return if student.blank?
items_size = course_evaluation.ec_course_evaluation_subitems.size
course_evaluation.ec_course_evaluation_subitems.each_with_index do |evaluation_subitem, index|
course_evaluation.evaluation_count.times do |times|
# 因为0和1是学号和姓名所以下标要 + 2
score = arr[times * items_size + 2 + index].to_i # 共4个分项第一次考核的第三项下标为 0 * 4 + 2 + 2即 arr[4]
attrs = {
score: score, student_name: student.name, student_number: student.student_id,
position: times + 1, ec_year_student_id: student.id, ec_course_evaluation_id: course_evaluation.id,
ec_course_evaluation_subitem_id: evaluation_subitem.id
}
worker.add(attrs)
end
end
end
end