|
- 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
- @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_test = homework_common.homework_tests.where("input = '#{result[:input]}' AND output = '#{result[:output]}'").first
- if 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
- 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
- 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
|