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/helpers/export_helper.rb

556 lines
22 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.

module ExportHelper
include ApplicationHelper
require "base64"
require 'zip'
# 附件导出最大值
MAX_DOWN_SIZE = 500 * 1024 * 1024
SAVE_FOLDER = "#{Rails.root}/files"
OUTPUT_FOLDER = "#{Rails.root}/files/archiveZip"
MAX_PATH = 50
# 作业导出为xlsxhomework_type 1普通作业 2编程作业弃用 3分组作业 4实训作业
def student_work_to_xlsx(works,homework)
@work_head_cells = []
@work_cells_column = []
course = homework.course
head_cells_format = %w(序号 登录名 真实姓名 邮箱 学号 分班 提交状态)
allow_late_boolean = homework.allow_late
if allow_late_boolean #允许迟交
allow_late_cell = ["迟交扣分"]
else
allow_late_cell = []
end
if homework.homework_type != "practice" #普通作业/分组作业
homework_type_name = homework.homework_type
if homework_type_name == "group" #分组作业
group_cells = ["关联项目"]
else
group_cells = []
end
normal_head_cells = %w(作品描述 教师评分 教辅评分)
anon_boolean = homework.anonymous_comment
if anon_boolean
head_cells_add = %w(匿名评分 缺评扣分 违规匿评申诉扣分)
else
head_cells_add = []
end
normal_head_b_cells = %w(最终成绩 提交时间 更新时间 评语)
@work_head_cells = (head_cells_format + group_cells + normal_head_cells + head_cells_add + allow_late_cell + normal_head_b_cells).reject(&:blank?)
works.includes(user: :user_extension, student_works_scores: :user).each_with_index do |w, index|
w_user = w.user
w_1 = (index + 1)
if w_user.present?
w_2 = w_user&.login.present? ? w_user&.login : "--"
w_3 = w_user&.real_name.present? ? w_user&.real_name : "--"
w_3_1 = w_user&.mail.present? ? w_user.mail : "--"
w_4 = w_user.student_id.present? ? w_user.student_id : "--"
else
w_2 = "--"
w_3 = "--"
w_3_1 = "--"
w_4 = "--"
end
course_name = course.students.find_by(user_id: w.user_id).try(:course_group_name)
w_5 = course_name.present? ? course_name : "--"
#0 未提交, 1 按时提交, 2 延迟提交
if w.work_status == 0
w_6 = "未提交"
elsif w.work_status == 1
w_6 = "按时提交"
elsif w.work_status == 2
w_6 = "延迟提交"
else
w_6 = "--"
end
if homework_type_name == "group"
project_name = w.project
if project_name.present?
w_7 = w.project.name
else
w_7 = "--"
end
else
w_7 = nil
end
w_8 = w.description.present? ? strip_html(w.description) : "--"
w_9 = w.teacher_score.nil? ? "未评分" : w.teacher_score.round(1)
w_10 = w.teaching_asistant_score.nil? ? "未评分" : w.teaching_asistant_score.round(1)
if anon_boolean
w_11 = w.student_score.nil? ? "未评分" : w.student_score.round(1)
w_12 = (homework.teacher_priority == 1 && !w.teacher_score.nil?) ? 0 : w.absence_penalty #缺评扣分
home_work_de = homework.homework_detail_manual
w_13 = home_work_de.present? ? home_work_de.appeal_penalty : "--" #违规匿评申诉扣分
else
w_11,w_12,w_13 = nil
end
if allow_late_boolean #允许迟交
w_14 = (homework.teacher_priority == 1 && !w.teacher_score.nil?) ? 0 : w.late_penalty #迟交扣分
else
w_14 = nil
end
w_15 = w.work_score.nil? ? "未评分" : w.work_score.round(1)
w_16 = w.commit_time ? format_time(w.commit_time) : "--"
w_17 = w.update_time ? format_time(w.update_time) : "--"
teacher_comments = w.student_works_scores
if teacher_comments.present?
w_18 = ""
teacher_comments.each do |t|
user_name = t.user&.real_name
user_time = format_time(t.updated_at)
user_score = t&.score
user_comment = t.comment.present? ? t.comment : "--"
comment_title = "#{user_name} #{user_time.to_s} #{user_score.to_s}\n#{user_comment}\n\n"
w_18 = w_18 + comment_title
end
else
w_18 = "--"
end
row_cells_column = [w_1,w_2,w_3,w_3_1,w_4,w_5,w_6,w_7,w_8,w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16,w_17,w_18]
row_cells_column = row_cells_column.reject(&:blank?)
@work_cells_column.push(row_cells_column)
end
else #实训题
shixun = homework.shixuns.first
shixun_head_cells = %w(完成情况 通关时间 总耗时 总评测次数 获得经验值 关卡得分)
eff_boolean = homework.work_efficiency
if eff_boolean
eff_score_cell = ["效率分"]
else
eff_score_cell = []
end
if allow_late_boolean #允许迟交
eff_score_cell.push("迟交扣分")
end
shixun_time_cells = %w(最终成绩 更新时间 提交耗时 评语)
@work_head_cells = (head_cells_format + shixun_head_cells + eff_score_cell + shixun_time_cells).reject(&:blank?)
works.includes(:student_works_scores, user: :user_extension, myshixun: :games).each_with_index do |w, index|
myshixun = w.try(:myshixun)
w_user = w.user
w_1 = (index + 1)
w_2 = w_user&.login.present? ? w_user&.login : "--"
w_3 = w_user&.real_name.present? ? w_user&.real_name : "--"
w_3_1 = w_user&.mail.present? ? w_user.mail : "--"
w_4 = w_user.student_id.present? ? w_user.student_id : "--"
course_name = course.students.find_by(user_id: w.user_id).try(:course_group_name)
w_5 = course_name.present? ? course_name : "--"
#0 未提交, 1 按时提交, 2 延迟提交
if w.work_status == 0
w_6 = "未提交"
elsif w.work_status == 1
w_6 = "按时提交"
elsif w.work_status == 2
w_6 = "延迟提交"
else
w_6 = "--"
end
w_7 = w.work_status == 0 ? '--' : myshixun.try(:passed_count).to_s+"/"+shixun.challenges_count.to_s
w_8 = myshixun ? myshixun.try(:passed_time) == "--" ? "--" : format_time(myshixun.try(:passed_time)) : "--" # 通关时间
w_9 = myshixun ? (myshixun.try(:passed_count) > 0 ? myshixun.total_spend_time : '--') : "--" #总耗时
w_10 = myshixun ? myshixun.output_times : 0 #评测次数
w_11 = myshixun ? myshixun.total_score : "--" #获得经验值
w_12 = w.final_score.present? ? w.final_score : 0
if eff_boolean
w_13 = w.eff_score
else
w_13 = nil
end
if allow_late_boolean #允许迟交
w_14 = w.late_penalty #迟交扣分
else
w_14 = nil
end
w_15 = w.work_score.nil? ? "--" : w.work_score.round(1)
w_16 = w.update_time ? format_time(w.update_time) : "--" "更新时间"
w_17 = (game_spend_time w.cost_time)
teacher_comments = w.student_works_scores
if teacher_comments.present?
w_18 = ""
teacher_comments.each do |t|
user_name = t.user&.real_name
user_time = format_time(t.updated_at)
user_score = t&.score
user_comment = t.comment.present? ? t.comment : "--"
comment_title = "#{user_name} #{user_time.to_s} #{user_score.to_s}\n#{user_comment}\n\n"
w_18 = w_18 + comment_title
end
else
w_18 = "--"
end
row_cells_column = [w_1,w_2,w_3,w_3_1,w_4,w_5,w_6,w_7,w_8,w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16,w_17,w_18]
row_cells_column = row_cells_column.reject(&:blank?)
@work_cells_column.push(row_cells_column)
end
end
end
#毕设任务的导出
def graduation_work_to_xlsx(items,task,current_user)
head_cells_format = %w(序号 登录名 真实姓名 邮箱 学号 分班)
task_type_boolean = task.task_type == 2
if task_type_boolean #是否分组
head_cells_format = head_cells_format + ["分组"]
end
head_cells_format = head_cells_format + ["提交状态"]
task_project_boolean = task.base_on_project
if task_project_boolean #关联项目
head_cells_format = head_cells_format + ["关联项目"]
end
head_cells_format = head_cells_format + %w(作品描述 教师评分)
task_comment_boolean = task.cross_comment
if task_comment_boolean #是否交叉评阅
head_cells_format = head_cells_format + ["交叉评分"]
end
head_cells_format = head_cells_format + %w(迟交扣分 最终成绩 提交时间 更新时间 评语)
@head_cells_column = head_cells_format
@task_cells_column = []
items.includes(user: :user_extension).each_with_index do |work,index|
w_1 = (index+1)
w_user = work.user
w_2 = w_user&.login.present? ? w_user&.login : "--"
w_3 = w_user&.real_name.present? ? w_user&.real_name : "--"
w_3_1 = w_user&.mail.present? ? w_user.mail : "--"
w_4 = w_user.student_id.present? ? w_user.student_id : "--"
w_5 = work.class_grouping_name
if task_type_boolean #是否分组
w_6 = work.grouping_name
else
w_6 = nil
end
w_status = work.work_status.to_i
if w_status == 0
w_7 = "未提交"
elsif w_status == 1
w_7 = "按时提交"
elsif w_status == 2
w_7 = "延时提交"
else
w_7 = "--"
end
if task_project_boolean #关联项目
w_project = project_info work, current_user, @user_course_identity #因为课堂引用了export_helper
w_8 = w_project[:name]
else
w_8 = nil
end
if work.description
w_9 = strip_html work.description
else
w_9 = "--"
end
w_10 = work.teacher_score.nil? ? "未评分" : work.teacher_score.round(1)
if task_comment_boolean #是否交叉评阅
w_11 = work.cross_score.nil? ? "未评分" : work.cross_score.round(1)
else
w_11 = nil
end
w_12 = work.late_penalty
w_13 = work.work_score.nil? ? "未评分" : work.work_score.round(1)
w_14 = work.commit_time.present? ? format_time(work.commit_time) : "--"
w_15 = work.update_time.present? ? format_time(work.update_time) : "--"
teacher_comments = work.graduation_work_scores
if teacher_comments.present?
w_16 = ""
teacher_comments.each do |t|
user_name = t.user&.real_name
user_time = format_time(t.updated_at)
user_score = t&.score
user_comment = t.comment.present? ? t.comment : "--"
comment_title = "#{user_name} #{user_time.to_s} #{user_score.to_s}\n#{user_comment}\n\n"
# ("教师:" + user_name + "\n" + "时间:" + user_time.to_s + "\n" + "分数:" + user_score.to_s + "分" + "\n" + "评语:" + user_comment + "\n\n")
w_16 = w_16 + comment_title
end
else
w_16 = "--"
end
row_cells_column = [w_1,w_2,w_3,w_3_1,w_4,w_5,w_6,w_7,w_8,w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16]
row_cells_column = row_cells_column.reject(&:blank?)
@task_cells_column.push(row_cells_column)
end
end
#试卷的导出
def get_export_users(exercise,course,export_ex_users)
question_types = exercise.exercise_questions.pluck(:question_type).uniq
@table_columns = %w(序号 登录名 真实姓名 邮箱 学号 分班 提交状态)
@user_columns = []
ques_type_boolean = question_types.include?(4)
if ques_type_boolean #仅存在主观题或客观题的时候
@table_columns = @table_columns + %w(客观题成绩 主观题成绩 最终成绩 开始答题时间 提交时间)
else
@table_columns = @table_columns + %w(最终成绩 开始答题时间 提交时间)
end
export_ex_users.includes(user: :user_extension).each_with_index do |e_user,index|
user_info = e_user.user
member = course.students.find_by_user_id(e_user.user_id)
user_course = member.try(:course_group_name)
user_obj_score = e_user.objective_score < 0.0 ? 0.0 : e_user.objective_score.round(1).to_s
user_suj_score = e_user.subjective_score < 0.0 ? 0.0 : e_user.subjective_score.round(1).to_s
user_score = e_user.score.present? ? e_user.score.round(1).to_s : 0.0
if e_user.commit_status.present? && e_user.commit_status == 1
user_commit_stu = "按时提交"
else
user_commit_stu = "未提交"
end
user_start_time = e_user.start_at.present? ? e_user.start_at.strftime('%Y-%m-%d %H:%M') : "--"
user_end_time = e_user.end_at.present? ? e_user.end_at.strftime('%Y-%m-%d %H:%M') : "--"
user_student_id = user_info.student_id.present? ? user_info.student_id : "--"
user_login = user_info&.login.present? ? user_info.login : "--"
user_real_name = user_info.real_name.present? ? user_info.real_name : "--"
user_mail = user_info&.mail.present? ? user_info.mail : "--"
user_option = [index+1,user_login,user_real_name, user_mail,
user_student_id,user_course,user_commit_stu]
if ques_type_boolean
other_user_option = [user_obj_score,user_suj_score,user_score,user_start_time,user_end_time]
else
other_user_option = [user_score,user_start_time,user_end_time]
end
user_option = user_option + other_user_option
@user_columns.push(user_option)
end
end
#毕设选题的导出
def graduation_topic_to_xlsx(students,course)
@topic_head_cells = %w(序号 登录名 真实姓名 邮箱 学号 分班 课题名称 指导教师 教师职位 设计 论文 创作 生产/社会实际 结合科研 其它 真题 模拟题 纵向课题 横向课题 自选 新题 往届题,有新要求
往届题,无新要求 课题来源单位 调研或实习地点 确认结果)
@topic_body_cells = []
if students.count > 0
students.includes(user: :user_extension).each_with_index do |student, index|
user = student.user
student_topic = course.student_graduation_topics.user_topics_accept(user.id).first
if student_topic.present?
topic = student_topic.graduation_topic
else
student_topic = nil
topic = nil
end
w_1 = (index+1)
w_2 = user&.login.present? ? user&.login : "--"
w_3 = user&.real_name.present? ? user&.real_name : "--"
w_3_1 = user&.mail.present? ? user.mail : "--"
w_4 = user.student_id.present? ? user.student_id : "--"
w_5 = student&.course_group_name.present? ? student.course_group_name : "--"
w_6 = topic.present? ? topic.name : "--"
w_7 = topic.present? ? topic.teacher.full_name : "--"
w_8 = topic.present? ? topic.teacher.identity : "--"
if topic.present?
w_9 = topic.topic_type == 1 ? "" : ""
w_10 = topic.topic_type == 2 ? "" : ""
w_11 = topic.topic_type == 3 ? "" : ""
w_12 = topic.topic_source == 1 ? "" : ""
w_13 = topic.topic_source == 2 ? "" : ""
w_14 = topic.topic_source == 3 ? "" : ""
w_15 = topic.topic_property_first == 1 ? "" : ""
w_16 = topic.topic_property_first == 2 ? "" : ""
w_17 = topic.topic_property_second == 1 ? "" : ""
w_18 = topic.topic_property_second == 2 ? "" : ""
w_19 = topic.topic_property_second == 3 ? "" : ""
w_20 = topic.topic_repeat == 1 ? "" : ""
w_21 = topic.topic_repeat == 2 ? "" : ""
w_22 = topic.topic_repeat == 3 ? "" : ""
w_23 = topic.source_unit
w_24 = "#{topic.province}#{topic.city}"
else
w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16,w_17,w_18,w_19,w_20,w_21,w_22,w_23,w_24 = "--"
end
if student_topic.present?
w_25 = student_topic.status == 0 ? "待确认" : "已同意"
else
w_25 = "--"
end
student_info_array = [w_1,w_2,w_3,w_3_1,w_4,w_5,w_6,w_7,w_8,w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16,w_17,w_18,w_19,w_20,w_21,w_22,w_23,w_24,w_25]
@topic_body_cells.push(student_info_array)
end
end
end
def encode64(str)
Base64.urlsafe_encode64(str)
end
def decode64(str)
Base64.urlsafe_decode64(str)
end
# 检测文件大小是否超过500m
def checkfileSize(works)
file_count = 0
file_size = 0
works.each do |work|
file_count += work.attachments.count
work.attachments.each do |attach|
file_size += attach.filesize
end
end
if file_size > MAX_DOWN_SIZE
status = -2
elsif file_count > 0
status = 0
else
status = -1
end
status
end
def zip_homework_common homework_common, student_works
bid_homework_path = []
digests = []
student_works.each do |work|
unless work.attachments.empty?
out_file = zip_student_work_by_user(work, homework_common)
bid_homework_path << out_file.file_path
digests << out_file.file_digest
end
end
out_file_name = "#{Time.now.to_i}_#{homework_common.name}.zip"
out_file_name.gsub!(" ", "-")
out_file_name.gsub!("/", "_")
out_file = find_or_pack(homework_common, homework_common.user_id, digests.sort){
zipping(out_file_name, bid_homework_path, OUTPUT_FOLDER)
}
[{files:[out_file.file_path], count: 1, index: 1,
real_file: out_file.file_path,
file: File.basename(out_file.file_path),
base64file: encode64(File.basename(out_file.file_path)),
size:(out_file.pack_size / 1024.0 / 1024.0).round(2)
}]
end
def zip_student_work_by_user(work, object)
homeworks_attach_path = []
not_exist_file = []
filename = []
# 需要将所有homework.attachments遍历加入zip
digests = []
work.attachments.each do |attach|
if File.exist?(attach.diskfile)
homeworks_attach_path << attach.diskfile
digests << attach.digest
filename << attach.filename
else
not_exist_file << attach.filename
digests << 'not_exist_file'
filename << attach.filename
end
end
#单个文件的话,不需要压缩,只改名
if homeworks_attach_path.size == 1
out_file = find_or_pack(object, work.user_id, digests.sort){
des_path = "#{OUTPUT_FOLDER}/#{make_zip_name(work, filename.first)}_#{File.basename(homeworks_attach_path.first)}"
FileUtils.cp homeworks_attach_path.first, des_path
des_path
}
else
out_file = find_or_pack(object, work.user_id, digests.sort){
zipping("#{make_zip_name(work)}.zip",
homeworks_attach_path, OUTPUT_FOLDER, true, not_exist_file)
}
end
out_file
end
def find_or_pack(homework, user_id, digests)
raise "please given a pack block" unless block_given?
out_file = ZipPack.packed?(homework, user_id, digests.sort)
unless out_file && out_file.file_valid?
file = yield
ZipPack.where(container_id: homework.id, container_type: homework.class.to_s, user_id: user_id).delete_all
out_file = ZipPack.create(container_id: homework.id,
container_type: homework.class.to_s,
user_id: user_id,
file_digest: Educoder::Utils.digest(file),
file_path: file,
pack_size: File.size(file),
file_digests: digests.join(',')
)
else
out_file.pack_times = out_file.pack_times + 1
out_file.save
end
out_file
end
def make_zip_name(work, file_name="")
Rails.logger.info("######################file_name: #{file_name}")
name = file_name === "" ? "" : (file_name[0, file_name.rindex('.')]+"_")
"#{name}#{work.user.real_name}_#{((work.user.student_id.nil?) ? "" : work.user.student_id)}"
end
def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[])
rename_zipfile = zip_name_refer ||= "#{Time.now.to_i.to_s}.zip"
# 文件名过长
if rename_zipfile.size > MAX_PATH
rename_zipfile = rename_zipfile[0,rename_zipfile.size-4][0,MAX_PATH-4] + rename_zipfile[-4,4]
end
zipfile_name = "#{output_path}/#{rename_zipfile}"
# 同名文件重命名时用
index = 1
Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name))
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
files_paths.each do |filename|
rename_file = File.basename(filename)
rename_file = filename_to_real( File.basename(filename)) if is_attachment
begin
zipfile.add(rename_file, filename)
rescue Exception => e
rename_file = rename_same_file(rename_file, index)
index += 1
zipfile.add(rename_file, filename)
# zipfile.get_output_stream('FILE_NOTICE.txt'){|os| os.write "该作品中有重复命名文件,请通过文件名学号和姓名信息进入该作业详细界面手动下载"}
next
end
end
unless not_exist_file.empty?
zipfile.get_output_stream('FILE_LOST.txt'){|os| os.write "以下文件无法成功下载,请联系相关人员重新上传:" +
not_exist_file.join(',').to_s}
end
end
zipfile_name
end
def filename_to_real(name)
attach = Attachment.find_by_disk_filename(name)
attach.filename
end
def format_sheet_name name
name = name.gsub(":", "-")
end
def rename_same_file(name, index)
basename = File.basename(name, ".*")
new_basename = basename + "_" + index.to_s
extname = File.extname(name)
new_basename + extname
end
end