class StudentWorkController < ApplicationController layout "base_courses" include StudentWorkHelper require 'bigdecimal' require "base64" before_filter :find_homework, :only => [:new, :index, :create, :student_work_absence_penalty, :absence_penalty_list, :evaluation_list] before_filter :find_work, :only => [:edit, :update, :show, :destroy, :add_score, :praise_student_work] before_filter :member_of_course, :only => [:index, :new, :create, :show, :add_score, :praise_student_work] before_filter :author_of_work, :only => [:edit, :update, :destroy] before_filter :teacher_of_course, :only => [:student_work_absence_penalty, :absence_penalty_list, :evaluation_list] protect_from_forgery :except => :set_program_score def index #设置作业对应的forge_messages表的viewed字段 query_student_work = @homework.course_messages query_student_work.each do |query| if User.current.id == query.user_id query.update_attributes(:viewed => true) end end @order,@b_sort,@name,@group = params[:order] || "score",params[:sort] || "desc",params[:name] || "",params[:group] @is_teacher = User.current.allowed_to?(:as_teacher,@course) course_group = CourseGroup.find_by_id(@group) if @group if course_group group_students = course_group.users if group_students.empty? student_in_group = '(0)' else student_in_group = '(' + group_students.map{|user| user.id}.join(',') + ')' end #老师 || 非匿评作业 || 匿评结束 显示所有的作品 @show_all = @is_teacher || @homework.homework_type != 1 || @homework.homework_detail_manual.comment_status == 3 || User.current.admin? if @show_all if @homework.homework_type == 1 || @is_teacher || User.current.admin? #超级管理员 || 老师 || 匿评结束 显示所有的作品 if @order == "name" @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("users.lastname #{@b_sort}, users.firstname #{@b_sort}"),@name else @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("#{@order} #{@b_sort}"),@name end else #剩余情况: 学生 && 非匿评作业 如果未提交作品,只能看到自己的,提交了作品,能看到所有作品 my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) if my_work.empty? @stundet_works = [] else if @order == "name" @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("users.lastname #{@b_sort}, users.firstname #{@b_sort}"),@name else @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("#{@order} #{@b_sort}"),@name end end end else #学生 if @homework.homework_detail_manual.comment_status == 1 #未开启匿评,只显示我的作品 @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) elsif @homework.homework_detail_manual.comment_status == 2 #匿评列表,显示匿评作品和我的作品 @is_evaluation = true my_work = @homework.student_works.where(:user_id => User.current.id) @stundet_works = my_work + User.current.student_works_evaluation_distributions.map(&:student_work).select { |work| work.homework_common_id == @homework.id} end end else #老师 || 非匿评作业 || 匿评结束 显示所有的作品 @show_all = @is_teacher || @homework.homework_type != 1 || @homework.homework_detail_manual.comment_status == 3 || User.current.admin? if @show_all if @homework.homework_type == 1 || @is_teacher || User.current.admin? #超级管理员 || 老师 || 匿评结束 显示所有的作品 if @order == "name" @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).order("users.lastname #{@b_sort}, users.firstname #{@b_sort}"),@name else @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").order("#{@order} #{@b_sort}"),@name end else #剩余情况: 学生 && 非匿评作业 如果未提交作品,只能看到自己的,提交了作品,能看到所有作品 my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) if my_work.empty? @stundet_works = [] else if @order == "name" @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).order("users.lastname #{@b_sort}, users.firstname #{@b_sort}"),@name else @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").order("#{@order} #{@b_sort}"),@name end end end else #学生 if @homework.homework_detail_manual.comment_status == 1 #未开启匿评,只显示我的作品 @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) elsif @homework.homework_detail_manual.comment_status == 2 #匿评列表,显示匿评作品和我的作品 @is_evaluation = true my_work = @homework.student_works.where(:user_id => User.current.id) @stundet_works = my_work + User.current.student_works_evaluation_distributions.map(&:student_work).select { |work| work.homework_common_id == @homework.id} end end end @homework_commons = @course.homework_commons.order("created_at desc") @score = @b_sort == "desc" ? "asc" : "desc" respond_to do |format| format.html format.xls { send_data(homework_to_xls(@stundet_works), :type => "text/excel;charset=utf-8; header=present", :filename => "#{@course.teacher.lastname.to_s + @course.teacher.firstname}_#{@course.name}_#{@course.time.to_s + @course.term}_#{@homework.name}#{l(:excel_homework_list)}.xls") } end end def new student_work = @homework.student_works.where("user_id = ?",User.current.id).first if student_work.nil? @stundet_work = StudentWork.new respond_to do |format| format.html end else render_403 end end def create if params[:student_work] stundet_work = StudentWork.new stundet_work.name = params[:student_work][:name] stundet_work.description = params[:student_work][:description] stundet_work.project_id = params[:student_work][:project_id] stundet_work.homework_common_id = @homework.id stundet_work.user_id = User.current.id stundet_work.save_attachments(params[:attachments]) if Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") < Time.parse(Time.now.to_s).strftime("%Y-%m-%d") stundet_work.late_penalty = @homework.late_penalty else stundet_work.late_penalty = 0 end render_attachment_warning_if_needed(stundet_work) if stundet_work.save if @homework.homework_type == 2 && @homework.homework_detail_programing #编程作业,学生提交作品后计算系统得分 url = "http://192.168.80.21:8080/api/questions/#{@homework.homework_detail_programing.question_id}/solutions.json" solutions = { student_work_id:stundet_work.id, src:Base64.encode64(stundet_work.description), language:@homework.homework_detail_programing.language } uri = URI(url) body = solutions.to_json res = Net::HTTP.new(uri.host, uri.port).start do |client| request = Net::HTTP::Post.new(uri.path) request.body = body request["Content-Type"] = "application/json" client.request(request) end end respond_to do |format| format.html { flash[:notice] = l(:notice_successful_create) redirect_to student_work_index_url(:homework => @homework.id) } end return end end respond_to do |format| format.html { flash[:notice] = l(:notice_failed_create) redirect_to new_student_work_url(:homework => @homework.id) } end end def edit if !User.current.admin? && @homework.homework_type == 2 #编程作业不能修改作业 render_403 else respond_to do |format| format.html end end end def update if params[:student_work] @work.name = params[:student_work][:name] @work.description = params[:student_work][:description] @work.project_id = params[:student_work][:project] @work.save_attachments(params[:attachments]) render_attachment_warning_if_needed(@work) if @work.save respond_to do |format| format.html { flash[:notice] = l(:notice_successful_edit) redirect_to student_work_index_url(:homework => @homework.id) } end return end end respond_to do |format| format.html{redirect_to edit_student_work_url(@work)} end end def show @score = student_work_score @work,User.current @is_teacher = User.current.allowed_to?(:as_teacher,@course) respond_to do |format| format.js end end def destroy if @homework.homework_type == 2 #编程作业,作品提交后不可以删除 render_403 elsif @work.destroy respond_to do |format| format.html { redirect_to student_work_index_url(:homework => @homework.id) } end end end #添加评分,已评分则为修改评分 def add_score render_403 and return if User.current == @work.user #不可以匿评自己的作品 @is_teacher = User.current.allowed_to?(:as_teacher,@course) #老师、教辅可以随时评分,学生只能在匿评作业的匿评阶段进行评分 render_403 and return unless @is_teacher || (@homework.homework_type == 1 && @homework.homework_detail_manual.comment_status == 2) @score = student_work_score @work,User.current if @score @score.comment = params[:new_form][:user_message] if params[:new_form] && params[:new_form][:user_message] && params[:new_form][:user_message] != "" @score.score = params[:score] if params[:score] if User.current.admin? @score.reviewer_role = 1 else role = User.current.members.where("course_id = ?",@course.id).first.roles.first.name @score.reviewer_role = get_role_by_name(role) end @is_new = false else @score = StudentWorksScore.new @score.score = params[:score] if params[:score] @score.comment = params[:new_form][:user_message] if params[:new_form] && params[:new_form][:user_message] && params[:new_form][:user_message] != "" @score.user_id = User.current.id @score.student_work_id = @work.id if User.current.admin? @score.reviewer_role = 1 else role = User.current.members.where("course_id = ?",@course.id).first.roles.first.name @score.reviewer_role = get_role_by_name(role) end @is_new = true end @score.save_attachments(params[:attachments]) render_attachment_warning_if_needed(@score) if @score.save case @score.reviewer_role when 1 #教师评分:最后一个教师评分为最终评分 @work.teacher_score = @score.score @work.final_score = @score.score when 2 #教辅评分 教辅评分显示平均分 @work.teaching_asistant_score = @work.student_works_scores.where(:reviewer_role => 2).average(:score).try(:round, 2).to_f if @work.teacher_score.nil? if @work.student_score.nil? @work.final_score = @work.teaching_asistant_score else ta_proportion = @homework.homework_detail_manual.ta_proportion if @homework.homework_detail_manual ta_proportion = @homework.homework_detail_programing.ta_proportion if @homework.homework_detail_programing final_ta_score = BigDecimal.new("#{@work.teaching_asistant_score}") * BigDecimal.new("#{ta_proportion}") final_s_score = BigDecimal.new("#{@work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}")) final_score = final_ta_score + final_s_score @work.final_score = format("%.2f",final_score.to_f) end end when 3 #学生评分 学生评分显示平均分 @work.student_score = @work.student_works_scores.where(:reviewer_role => 3).average(:score).try(:round, 2).to_f if @work.teacher_score.nil? if @work.teaching_asistant_score.nil? @work.final_score = @work.student_score else final_ta_score = BigDecimal.new("#{@work.teaching_asistant_score}") * BigDecimal.new("#{@homework.homework_detail_manual.ta_proportion}") final_s_score = BigDecimal.new("#{@work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{@homework.homework_detail_manual.ta_proportion}")) final_score = final_ta_score + final_s_score @work.final_score = format("%.2f",final_score.to_f) end end end if @work.save respond_to do |format| format.js end end end end #添加评分的回复 def add_score_reply @score = StudentWorksScore.find params[:score_id] @jour = @score.journals_for_messages.new(:user_id => User.current.id,:notes =>params[:message], :reply_id => 0) if @jour.save @status = 1 else @status = 2 end respond_to do |format| format.js end end #删除评分的回复 def destroy_score_reply @jour = JournalsForMessage.find params[:jour_id] if @jour.destroy respond_to do |format| format.js end end end #为作品点赞 def praise_student_work pt = PraiseTread.new pt.user_id = User.current.id pt.praise_tread_object_id = @work.id pt.praise_tread_object_type = "StudentWork" pt.praise_or_tread = 1 if pt.save respond_to do |format| format.js end else render_404 end end #缺评列表显示 def student_work_absence_penalty order = params[:order] || "desc" if @homework.student_works.empty? @stundet_works = [] else work_ids = "(" + @homework.student_works.map(&:id).join(",") + ")" @stundet_works = StudentWork.find_by_sql("SELECT *,(all_count - has_count) AS absence FROM( SELECT * , (SELECT COUNT(*) FROM `student_works_evaluation_distributions` WHERE user_id = student_works.user_id AND student_work_id IN #{work_ids}) AS all_count, (SELECT COUNT(*) FROM `student_works_scores` WHERE user_id = student_works.user_id AND student_work_id IN #{work_ids}) AS has_count FROM `student_works` WHERE homework_common_id = #{@homework.id} ) AS table_1 ORDER BY absence #{order}") end @order = order == "desc" ? "asc" : "desc" respond_to do |format| format.html end end #导出缺评列表 def absence_penalty_list if @homework.student_works.empty? @stundet_works = [] else work_ids = "(" + @homework.student_works.map(&:id).join(",") + ")" @stundet_works = StudentWork.find_by_sql("SELECT * FROM (SELECT *,(all_count - has_count) AS absence FROM( SELECT * , (SELECT COUNT(*) FROM `student_works_evaluation_distributions` WHERE user_id = student_works.user_id AND student_work_id IN #{work_ids}) AS all_count, (SELECT COUNT(*) FROM `student_works_scores` WHERE user_id = student_works.user_id AND student_work_id IN #{work_ids}) AS has_count FROM `student_works` WHERE homework_common_id = #{@homework.id} ) AS table_1) AS table_2 where absence > 0 order by absence") end respond_to do |format| format.xls { send_data(absence_penalty_list_xls(@stundet_works), :type => "text/excel;charset=utf-8; header=present", :filename => "#{@course.teacher.lastname.to_s + @course.teacher.firstname}_#{@course.name}_#{@course.time.to_s + @course.term}_#{@homework.name}#{l(:excel_absence_list)}.xls") } end end #导出匿评列表 def evaluation_list respond_to do |format| format.xls { send_data(evaluation_list_xls(@homework.student_works), :type => "text/excel;charset=utf-8; header=present", :filename => "#{@course.teacher.lastname.to_s + @course.teacher.firstname}_#{@course.name}_#{@course.time.to_s + @course.term}_#{@homework.name}#{l(:excel_evaluation_list)}.xls") } end end #设置编程作业得分 def set_program_score stundet_work = StudentWork.find_by_id params[:student_work_id] @course = stundet_work.homework_common.course student_score_count = 0 if stundet_work && params[:results] && params[:results].class.to_s == "Array" homework_common = stundet_work.homework_common params[:results].each do |result| homework_tests = homework_common.homework_tests.where("input = '#{result[:input]}' AND output = '#{result[:output]}'") homework_tests.each do |homework_test| student_work_test = StudentWorkTest.new student_work_test.student_work = stundet_work student_work_test.homework_test = homework_test student_work_test.result = result[:status] if student_work_test.result == 0 student_score_count += 1 end student_work_test.error_msg = params[:compile_error_msg] student_work_test.save! end end unless homework_common.homework_tests.empty? stundet_work.student_score = student_score_count * 100.0 / homework_common.homework_tests.count if stundet_work.teacher_score.nil? if stundet_work.teaching_asistant_score.nil? stundet_work.final_score = stundet_work.student_score else final_ta_score = BigDecimal.new("#{stundet_work.teaching_asistant_score}") * BigDecimal.new("#{homework_common.homework_detail_programing.ta_proportion}") final_s_score = BigDecimal.new("#{stundet_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{homework_common.homework_detail_programing.ta_proportion}")) final_score = final_ta_score + final_s_score stundet_work.final_score = format("%.1f",final_score.to_f) end end stundet_work.save! end end end private #获取作业 def find_homework @homework = HomeworkCommon.find params[:homework] @course = @homework.course rescue render_404 end #获取作品 def find_work @work = StudentWork.find params[:id] @homework = @work.homework_common @course = @homework.course rescue render_404 end #是不是当前课程的成员 #当前课程成员才可以看到作品列表 def member_of_course render_403 unless User.current.member_of_course?(@course) || User.current.admin? end #判断是不是当前作品的提交者 #提交者 && (非匿评作业 || 未开启匿评) 可以编辑作品 def author_of_work render_403 unless User.current.admin? || (User.current.id == @work.user_id && @homework.homework_type != 1 || @homework.homework_detail_manual.comment_status == 1 ) end def teacher_of_course render_403 unless User.current.allowed_to?(:as_teacher,@course) end #根据条件过滤作业结果 def search_homework_member homeworks,name name = name.downcase select_homework = homeworks.select{ |homework| homework.user[:login].to_s.downcase.include?(name) || homework.user.user_extensions[:student_id].to_s.downcase.include?(name) || (homework.user[:lastname].to_s.downcase + homework.user[:firstname].to_s.downcase).include?(name) } select_homework end #作品列表转换为excel def homework_to_xls items xls_report = StringIO.new book = Spreadsheet::Workbook.new sheet1 = book.create_worksheet :name => "homework" blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10 sheet1.row(0).default_format = blue if @homework.homework_type == 0 #普通作业 sheet1.row(0).concat([l(:excel_user_id),l(:excel_user_name),l(:excel_nickname),l(:excel_student_id),l(:excel_mail),l(:excel_homework_name), l(:excel_t_score),l(:excel_ta_score),l(:excel_f_score),l(:excel_commit_time)]) count_row = 1 items.each do |homework| sheet1[count_row,0]=homework.user.id sheet1[count_row,1] = homework.user.lastname.to_s + homework.user.firstname.to_s sheet1[count_row,2] = homework.user.login sheet1[count_row,3] = homework.user.user_extensions.student_id sheet1[count_row,4] = homework.user.mail sheet1[count_row,5] = homework.name sheet1[count_row,6] = homework.teacher_score.nil? ? l(:label_without_score) : format("%.2f",homework.teacher_score) sheet1[count_row,7] = homework.teaching_asistant_score.nil? ? l(:label_without_score) : format("%.2f",homework.teaching_asistant_score) # sheet1[count_row,8] = homework.student_score.nil? ? l(:label_without_score) : format("%.2f",homework.student_score) sheet1[count_row,8] = homework.respond_to?("score") ? homework.score.nil? ? l(:label_without_score) : format("%.2f",homework.score) : l(:label_without_score) sheet1[count_row,9] = format_time(homework.created_at) count_row += 1 end elsif @homework.homework_type == 1 #匿评作业 sheet1.row(0).concat([l(:excel_user_id),l(:excel_user_name),l(:excel_nickname),l(:excel_student_id),l(:excel_mail),l(:excel_homework_name), l(:excel_t_score),l(:excel_ta_score), l(:excel_n_score),l(:excel_f_score),l(:excel_commit_time)]) count_row = 1 items.each do |homework| sheet1[count_row,0]=homework.user.id sheet1[count_row,1] = homework.user.lastname.to_s + homework.user.firstname.to_s sheet1[count_row,2] = homework.user.login sheet1[count_row,3] = homework.user.user_extensions.student_id sheet1[count_row,4] = homework.user.mail sheet1[count_row,5] = homework.name sheet1[count_row,6] = homework.teacher_score.nil? ? l(:label_without_score) : format("%.2f",homework.teacher_score) sheet1[count_row,7] = homework.teaching_asistant_score.nil? ? l(:label_without_score) : format("%.2f",homework.teaching_asistant_score) sheet1[count_row,8] = homework.student_score.nil? ? l(:label_without_score) : format("%.2f",homework.student_score) sheet1[count_row,9] = homework.respond_to?("score") ? homework.score.nil? ? l(:label_without_score) : format("%.2f",homework.score) : l(:label_without_score) sheet1[count_row,10] = format_time(homework.created_at) count_row += 1 end elsif @homework.homework_type == 2 #编程作业 sheet1.row(0).concat([l(:excel_user_id),l(:excel_user_name),l(:excel_nickname),l(:excel_student_id),l(:excel_mail),l(:excel_homework_name), l(:excel_t_score),l(:excel_ta_score), l(:excel_s_score),l(:excel_f_score),l(:excel_commit_time)]) count_row = 1 items.each do |homework| sheet1[count_row,0]=homework.user.id sheet1[count_row,1] = homework.user.lastname.to_s + homework.user.firstname.to_s sheet1[count_row,2] = homework.user.login sheet1[count_row,3] = homework.user.user_extensions.student_id sheet1[count_row,4] = homework.user.mail sheet1[count_row,5] = homework.name sheet1[count_row,6] = homework.teacher_score.nil? ? l(:label_without_score) : format("%.2f",homework.teacher_score) sheet1[count_row,7] = homework.teaching_asistant_score.nil? ? l(:label_without_score) : format("%.2f",homework.teaching_asistant_score) sheet1[count_row,8] = homework.student_score.nil? ? l(:label_without_score) : format("%.2f",homework.student_score) sheet1[count_row,9] = homework.respond_to?("score") ? homework.score.nil? ? l(:label_without_score) : format("%.2f",homework.score) : l(:label_without_score) sheet1[count_row,10] = format_time(homework.created_at) count_row += 1 end end book.write xls_report xls_report.string end #缺评列表转换为excel def absence_penalty_list_xls items xls_report = StringIO.new book = Spreadsheet::Workbook.new sheet1 = book.create_worksheet :name => "homework" blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10 sheet1.row(0).default_format = blue sheet1.row(0).concat([l(:excel_student_id),l(:excel_nickname),l(:excel_user_name),l(:lable_all_penalty),l(:lable_has_penalty),l(:lable_absence_penalty)]) count_row = 1 items.each do |homework| sheet1[count_row,0] = homework.user.user_extensions.student_id sheet1[count_row,1] = homework.user.login sheet1[count_row,2] = homework.user.lastname.to_s + homework.user.firstname.to_s sheet1[count_row,3] = homework.all_count sheet1[count_row,4] = homework.has_count sheet1[count_row,5] = homework.absence count_row += 1 end book.write xls_report xls_report.string end #匿评列表转换为excel def evaluation_list_xls items xls_report = StringIO.new book = Spreadsheet::Workbook.new sheet1 = book.create_worksheet :name => "homework" blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10 sheet1.row(0).default_format = blue sheet1.row(0).concat([l(:label_work_name),l(:label_work_id),l(:label_work_autor),l(:label_evaluation_id),l(:label_evaluation_name), l(:label_evaluation_score),l(:label_evaluation_common),l(:label_evaluation_time)]) count_row = 1 items.each do |homework| homework.student_works_scores.where(:reviewer_role => 3).each do |score| sheet1[count_row,0] = homework.name sheet1[count_row,1] = homework.user.user_extensions.student_id sheet1[count_row,2] = homework.user.show_name sheet1[count_row,3] = score.user.user_extensions.student_id sheet1[count_row,4] = score.user.show_name sheet1[count_row,5] = score.score sheet1[count_row,6] = score.comment sheet1[count_row,7] = format_time(score.created_at) count_row += 1 end end book.write xls_report xls_report.string end end