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

6 years ago
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