#encoding utf-8 class PollController < ApplicationController before_filter :find_poll_and_course, :only => [:edit,:update,:destroy,:show,:statistics_result,:create_poll_question,:commit_poll,:commit_answer,:publish_poll,:republish_poll,:poll_result,:close_poll,:export_poll,:save_poll,:update_question_num] before_filter :find_container, :only => [:new,:create, :index] before_filter :is_logged, :only => [:index, :show, :poll_result,:new,:create,:edit,:update,:destroy,:publish_poll,:republish_poll,:close_poll,:export_poll,:commit_answer,:commit_poll,:statistics_result,:save_poll] before_filter :is_member_of_course, :only => [:index,:show,:poll_result] before_filter :is_course_teacher, :only => [:new,:create,:edit,:update,:destroy,:publish_poll,:republish_poll,:close_poll,:export_poll,:save_poll] include PollHelper def index if @course @is_teacher = User.current.allowed_to?(:as_teacher,@course) if @is_teacher remove_invalid_poll(@course) polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id}") else polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id} and polls_status = 2") end @polls = paginateHelper polls,20 #分页 @left_nav_type = 7 respond_to do |format| format.html{render :layout => 'base_courses'} end elsif @project #项目的问卷调查相关代码 end end def show @poll = Poll.find params[:id] if @poll.polls_status != 2 && !(User.current.allowed_to?(:as_teacher,@course) || User.current.admin?) render_403 return end # 问卷消息状态更新 @poll.course_messages.where(:user_id => User.current.id, :viewed => 0).update_all(:viewed => true) #已提交问卷的用户不能再访问该界面 # if has_commit_poll?(@poll.id,User.current.id) && (!User.current.admin?) # redirect_to poll_index_url(:polls_type => "Course", :polls_group_id => @course.id) # else @can_edit_poll = @poll.user != User.current @percent = get_percent(@poll,User.current) @poll_questions = @poll.poll_questions.includes(:poll_answers) @left_nav_type = 7 respond_to do |format| format.html {render :layout => 'base_courses'} end #end end def new if @course option = { :polls_name => "", :polls_type => @course.class.to_s, :polls_group_id => @course.id, :polls_status => 1, :user_id => User.current.id, :published_at => Time.now, :closed_at => Time.now, :show_result => 1, :polls_description => "" } @poll = Poll.create option if @poll redirect_to edit_poll_url @poll.id end elsif @project #项目的问卷调查相关代码 end end def create end def edit respond_to do |format| @left_nav_type = 7 format.html{render :layout => 'base_courses'} end end def update @poll.polls_name = params[:polls_name] @poll.polls_description = params[:polls_description] if @poll.save respond_to do |format| format.js end else render_404 end end def destroy if @poll && @poll.destroy if @is_teacher polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id}") else polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id} and polls_status = 2") end @polls = paginateHelper polls,20 #分页 if params[:is_redirect] redirect_to poll_index_url(:polls_type => "Course", :polls_group_id => @course.id) else respond_to do |format| format.js end end end end def statistics_result @poll = Poll.find(params[:id]) poll_questions = @poll.poll_questions @poll_questions = paginateHelper poll_questions, 5 @left_nav_type = 7 respond_to do |format| format.html{render :layout => 'base_courses'} end end def get_poll_totalcount poll_question @total_questions_count = poll_question.poll_votes.count end def get_poll_everycount poll_answer @every_answer_count = poll_answer.poll_votes.count end def update_question_num @poll_question = PollQuestion.find params[:ques_id] poll_questions = @poll.poll_questions if @poll_question if params[:opr] == 'up' && @poll_question.question_number > 1 @before_que = poll_questions.where("question_number = #{@poll_question.question_number - 1}").first if @before_que && @poll_question.update_attribute('question_number', @poll_question.question_number - 1) @before_que.update_attribute('question_number', @before_que.question_number + 1) end elsif params[:opr] == 'down' && @poll_question.question_number < poll_questions.count @after_que = poll_questions.where("question_number = #{@poll_question.question_number + 1}").first if @after_que && @poll_question.update_attribute('question_number', @poll_question.question_number + 1) @after_que.update_attribute('question_number', @after_que.question_number - 1) end end respond_to do |format| format.js end end end #添加题目 def create_poll_question @last_question = @poll.poll_questions.last question_title = params[:poll_questions_title].nil? || params[:poll_questions_title].empty? ? l(:label_enter_single_title) : params[:poll_questions_title] option = { :is_necessary => (params[:is_necessary]=="true" ? 1 : 0), :question_title => question_title, :question_type => params[:question_type] || 1, :question_number => @poll.poll_questions.count + 1, :max_choices => params[:max_choices].to_i || 0, :min_choices => params[:min_choices].to_i || 0, } @poll_questions = @poll.poll_questions.new option if params[:question_answer] for i in 1..params[:question_answer].count answer = (params[:question_answer].values[i-1].nil? || params[:question_answer].values[i-1].empty?) ? l(:label_new_answer) : params[:question_answer].values[i-1] question_option = { :answer_position => i, :answer_text => answer } @poll_questions.poll_answers.new question_option end end if params[:question_other_answer] question_option = { :answer_position => params[:question_answer].count + 1, :answer_text => '' } @poll_questions.poll_answers.new question_option end # 如果是插入的话,那么从插入的这个id以后的question_num都将要+1 if params[:quest_id] insert_poll = PollQuestion.find params[:quest_id] if insert_poll @is_insert = true ques_num = insert_poll.question_number @poll.poll_questions.where("question_number > #{ques_num}").update_all(" question_number = question_number + 1") @poll_question_num = ques_num @poll_questions.question_number = ques_num + 1 end end if @poll_questions.save respond_to do |format| format.js end end end #修改题目 def update_poll_question @poll_question = PollQuestion.find params[:poll_question] #@poll = @poll_question.poll @poll_question.is_necessary = params[:is_necessary]=="true" ? 1 : 0 @poll_question.question_title = params[:poll_questions_title].nil? || params[:poll_questions_title].empty? ? l(:label_enter_single_title) : params[:poll_questions_title] @poll_question.max_choices = params[:max_choices].to_i || 0 @poll_question.min_choices = params[:min_choices].to_i || 0 ################处理选项 if params[:question_answer] @poll_question.poll_answers.each do |answer| answer.destroy unless params[:question_answer].keys.include? answer.id.to_s end for i in 1..params[:question_answer].count question = @poll_question.poll_answers.find_by_id params[:question_answer].keys[i-1] answer = (params[:question_answer].values[i-1].nil? || params[:question_answer].values[i-1].empty?) ? l(:label_new_answer) : params[:question_answer].values[i-1] if question question.answer_position = i question.answer_text = answer question.save else question_option = { :answer_position => i, :answer_text => answer } @poll_question.poll_answers.new question_option end end if params[:question_other_answer] question = @poll_question.poll_answers.where("answer_text = ''").first unless question question_option = { :answer_position => params[:question_answer].count + 1, :answer_text => '' } @poll_question.poll_answers.new question_option end else question = @poll_question.poll_answers.where("answer_text = ''").first if question question.destroy end end end @poll_question.save respond_to do |format| format.js end end #删除题目 def delete_poll_question @poll_question = PollQuestion.find params[:poll_question] @poll = @poll_question.poll poll_questions = @poll.poll_questions.where("question_number > #{@poll_question.question_number}") poll_questions.each do |question| question.question_number -= 1 question.save end if @poll_question && @poll_question.destroy respond_to do |format| format.js end end end #发布问卷 def publish_poll @index = params[:index] @poll.polls_status = 2 @poll.published_at = Time.now @poll.show_result = params[:show_result].to_i if params[:show_result] if @poll.save if params[:is_remote] redirect_to poll_index_url(:polls_type => "Course", :polls_group_id => @course.id) else respond_to do |format| format.js end end end end #保存问卷 def save_poll @poll.show_result = params[:show_result].to_i if @poll.save respond_to do |format| format.js end end end #提交答案 def commit_answer pq = PollQuestion.find(params[:poll_question_id]) # if has_commit_poll?(@poll.id,User.current.id) && (!User.current.admin?) # @percent = get_percent(@poll,User.current) # render :json => {:text => "ok" ,:percent => format("%.2f" ,@percent)} # return # end if pq.question_type == 1 #单选题 pv = PollVote.find_by_poll_question_id_and_user_id(params[:poll_question_id],User.current.id) if pv.nil? #尚未答该题,添加答案 pv = PollVote.new pv.user_id = User.current.id pv.poll_question_id = params[:poll_question_id] end #修改该题对应答案 pv.poll_answer_id = params[:poll_answer_id] pv.vote_text = params[:vote_text] if params[:vote_text] if pv.save #保存成功返回成功信息及当前以答题百分比 @percent = get_percent(@poll,User.current) render :json => {:text => "ok" ,:percent => format("%.2f" ,@percent)} else #返回失败信息 render :json => {:text => "failure"} end elsif pq.question_type == 2 #多选题 pv = PollVote.find_by_poll_answer_id_and_user_id(params[:poll_answer_id],User.current.id) if pv.nil? #尚未答该题,添加答案 count = PollVote.where("poll_question_id = #{params[:poll_question_id].to_i} and user_id = #{User.current.id}").count if pq.max_choices != 0 && count >= pq.max_choices render :json => {:text => "over"} else pv = PollVote.new pv.user_id = User.current.id pv.poll_question_id = params[:poll_question_id] pv.poll_answer_id = params[:poll_answer_id] pv.vote_text = params[:vote_text] if params[:vote_text] if pv.save @percent = get_percent(@poll,User.current) render :json => {:text => "ok",:percent => format("%.2f" ,@percent)} else render :json => {:text => "failure"} end end else #pv不为空,则当前选项之前已被选择,再次点击则是不再选择该项,故删除该答案 if params[:vote_text] pv.vote_text = params[:vote_text] if pv.save @percent = get_percent(@poll,User.current) render :json => {:text => "ok",:percent => format("%.2f" ,@percent)} else render :json => {:text => "failure"} end else if pv.delete @percent = get_percent(@poll,User.current) render :json => {:text => "false" ,:percent => format("%.2f" ,@percent)} else render :json => {:text => "failure"} end end end elsif pq.question_type == 3 #单行文本 pv = PollVote.find_by_poll_question_id_and_user_id(params[:poll_question_id],User.current.id) if pv.nil? #pv为空之前尚未答题,添加答案 if params[:vote_text].nil? || params[:vote_text].blank? #用户提交空答案,视作不作答 @percent = get_percent(@poll,User.current) render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} else #添加答案 pv = PollVote.new pv.user_id = User.current.id pv.poll_question_id = params[:poll_question_id] pv.vote_text = params[:vote_text] if pv.save @percent = get_percent(@poll,User.current) render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} else render :json => {:text => "failure"} end end else #pv不为空说明用户之前已作答 if params[:vote_text].nil? || params[:vote_text].blank? #用户提交空答案,视为删除答案 if pv.delete @percent = get_percent(@poll,User.current) render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} else render :json => {:text => "failure"} end else #用户修改答案 pv.vote_text = params[:vote_text] if pv.save @percent = get_percent(@poll,User.current) render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} else render :json => {:text => "failure"} end end end elsif pq.question_type == 4 #多行文本题 pv = PollVote.find_by_poll_question_id_and_poll_answer_id_and_user_id(params[:poll_question_id],params[:poll_answer_id],User.current.id) if pv.nil? #pv为空之前尚未答题,添加答案 if params[:vote_text].nil? || params[:vote_text].blank? #用户提交空答案,视作不作答 @percent = get_percent(@poll,User.current) render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} else #添加答案 pv = PollVote.new pv.user_id = User.current.id pv.poll_question_id = params[:poll_question_id] pv.poll_answer_id = params[:poll_answer_id] pv.vote_text = params[:vote_text] if pv.save @percent = get_percent(@poll,User.current) render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} else render :json => {:text => "failure"} end end else #pv不为空说明用户之前已作答 if params[:vote_text].nil? || params[:vote_text].blank? #用户提交空答案,视为删除答案 if pv.delete @percent = get_percent(@poll,User.current) render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} else render :json => {:text => "failure"} end else #用户修改答案 pv.vote_text = params[:vote_text] if pv.save @percent = get_percent(@poll,User.current) render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} else render :json => {:text => "failure"} end end end else render :json => {:text => "failure"} end end #提交问卷 def commit_poll @uncomplete_question = get_uncomplete_question(@poll,User.current) if @uncomplete_question.count < 1 pu = get_poll_user(@poll.id,User.current.id) pu.user_id = User.current.id pu.poll_id = @poll.id if pu.save #redirect_to poll_index_path(:polls_group_id => @course.id,:polls_type => 'Course') @status = 0 #提交成功 else @status = 2 #未知错误 end else @status = 1 #有未做得必答题 end respond_to do |format| format.js end end def import_poll @poll = Poll.find(params[:to_id]) question_num = @poll.poll_questions.select("max(question_number) question_number").first.question_number import_poll = Poll.find(params[:import_id]) import_poll.poll_questions.each_with_index do |question,index| option = { :is_necessary => question.is_necessary, :question_title => question.question_title, :question_type => question.question_type, :question_number => question_num + index+1 } poll_questions = @poll.poll_questions.new option for i in 1..question.poll_answers.count answer = question.poll_answers[i-1][:answer_text] question_option = { :answer_position => i, :answer_text => answer } poll_questions.poll_answers.new question_option end @poll.poll_questions << poll_questions end if @poll.save @poll = Poll.find(params[:to_id]) respond_to do |format| format.js end end end #重新发布问卷 def republish_poll @index = params[:index] @poll.poll_questions.each do |poll_question| poll_question.poll_votes.destroy_all end @poll.poll_users.destroy_all @poll.polls_status = 1 @poll.save respond_to do |format| format.js end end #显示某个学生某份问卷的填写结果 def poll_result @poll_questions = @poll.poll_questions @left_nav_type = 7 respond_to do |format| format.html{render :layout => 'base_courses'} end end #关闭问卷 def close_poll @index = params[:index] @poll.polls_status = 3 @poll.closed_at = Time.now if @poll.save respond_to do |format| format.js end end end #导出问卷 def export_poll poll_questions = @poll.poll_questions respond_to do |format| format.xls { send_data(poll_to_xls(poll_questions), :type => "text/excel;charset=utf-8; header=present", :filename => filename_for_content_disposition("#{@poll.polls_name}.xls") ) } end end # 将其他地方的问卷导出来 def other_poll # 查作者是我,或者作者是当前课程的老师,且不在当前课程内的问卷 进行导入 courses = User.current.courses.select { |course| User.current.allowed_to?(:as_teacher,course)} course_ids = courses.empty? ? "(-1)" : "(" + courses.map { |course| course.id}.join(',') + ")" none_courses = User.current.courses.where("#{Course.table_name}.id = #{params[:polls_group_id].to_i}") none_course_ids = none_courses.empty? ? "(-1)" : "(" + none_courses.map { |course| course.id}.join(',') + ")" #tea_ids = '(' #tea_ids << Course.find(params[:polls_group_id]).tea_id.to_s << ','<< User.current.id.to_s << ')' @polls = Poll.where("(user_id = #{User.current.id} or polls_group_id in #{course_ids}) and polls_type = 'course' and polls_group_id not in #{none_course_ids}") @polls_group_id = params[:polls_group_id] respond_to do |format| format.js end end # 将问卷导入本课程 def import_other_poll course_id = params[:course_id] @course = Course.find(course_id) params[:polls].each_with_index do |p,i| poll = Poll.find(p) option = { :polls_name => poll.polls_name || l(:label_poll_new), :polls_type => 'Course', :polls_group_id => course_id, :polls_status => 1, :user_id => User.current.id, :published_at => Time.now, :closed_at => Time.now, :show_result => 1, :polls_description => poll.polls_description } @poll = Poll.create option poll.poll_questions.each do | q| #question_title = params[:poll_questions_title].nil? || params[:poll_questions_title].empty? ? l(:label_enter_single_title) : params[:poll_questions_title] option = { :is_necessary => q[:is_necessary], :question_title => q[:question_title], :question_type => q[:question_type] || 1, :question_number => q[:question_number] } @poll_questions = @poll.poll_questions.new option for i in 1..q.poll_answers.count answer = q.poll_answers[i-1].nil? ? l(:label_new_answer) : q.poll_answers[i-1][:answer_text] question_option = { :answer_position => i, :answer_text => answer } @poll_questions.poll_answers.new question_option end end @poll.save end redirect_to poll_index_path(:polls_type => "Course", :polls_group_id => @course.id) # @is_teacher = User.current.allowed_to?(:as_teacher,@course) # if @is_teacher # polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id}") # else # polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id} and polls_status = 2") # end # @polls = paginateHelper polls,20 #分页 # respond_to do |format| # format.js # end end private def remove_invalid_poll(course) polls = Poll.where("polls_type = 'Course' and polls_group_id = #{course.id} and polls_name = ''") unless polls.empty? polls.each do |poll| if poll.poll_questions.empty? poll.destroy end end end end def find_poll_and_course @poll = Poll.find params[:id] @course = Course.find @poll.polls_group_id rescue Exception => e render_404 end def find_container if params[:polls_type] && params[:polls_group_id] case params[:polls_type] when "Course" @course = Course.find_by_id params[:polls_group_id] when "Project" @project = Project.find_by_id params[:polls_group_id] end else render_404 end end def is_logged redirect_to signin_path unless User.current.logged? end def is_member_of_course render_403 unless(@course && (User.current.member_of_course?(@course) || User.current.admin?)) end def is_course_teacher @is_teacher = User.current.allowed_to?(:as_teacher,@course) render_403 unless(@course && @is_teacher) end #获取未完成的题目 def get_uncomplete_question poll,user necessary_questions = poll.poll_questions.where("#{PollQuestion.table_name}.is_necessary = 1") uncomplete_question = [] necessary_questions.each do |question| answers = get_user_answer(question,user) if question.question_type != 4 if answers.nil? || answers.count < 1 uncomplete_question << question end else if answers.nil? || answers.count < question.poll_answers.count uncomplete_question << question end end # if answers.nil? || answers.count < 1 # uncomplete_question << question # end end uncomplete_question end #获取用户对某个问题的答案 def get_user_answer(question,user) # user_answer = question.poll_votes.where("#{PollVote.table_name}.user_id = #{user.id}") user_answer = question.poll_votes.select{|e| e.user_id == user.id} user_answer end def get_complete_question(poll,user) questions = poll.poll_questions.includes(:poll_votes) complete_question = [] questions.each do |question| answers = question.poll_votes.select{|e| e.user_id == user.id} if !(answers.empty? || answers.count < 1) if question.question_type != 4 complete_question << question else answers.each do |ans| complete_question << ans end end end end complete_question end def get_percent poll,user if poll.poll_questions.count == 0 return 0 else complete_count = get_complete_question(poll,user).size all_count = poll.poll_questions.where("question_type != 4").count poll.poll_questions.where("question_type = 4").each do |pq| all_count += pq.poll_answers.count end return (complete_count.to_f / all_count.to_f)*100 end end #PollUser记录用户是否已提交问卷有对应的记录则已提交,没有则新建一个 def get_poll_user poll_id,user_id pu = PollUser.find_by_poll_id_and_user_id(poll_id,user_id) if pu.nil? pu = PollUser.new end pu end #将poll中题目转换为Excel def poll_to_xls poll_questions xls_report = StringIO.new book = Spreadsheet::Workbook.new sheet1 = book.create_worksheet :name => "poll" blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10 count_row = 0 poll_questions.each do |poll_question| if poll_question.question_type == 1 || poll_question.question_type == 2 sheet1.row(count_row).default_format = blue sheet1[count_row,0]= l(:label_poll_question_num,:num => poll_question.question_number) sheet1[count_row + 1,0] = l(:label_poll_subtotal) sheet1[count_row + 2,0] = l(:label_poll_proportion) poll_question.poll_answers.each_with_index do |poll_answer,i| sheet1[count_row, i + 1] = poll_answer.answer_text == "" ? l(:label_poll_other) : poll_answer.answer_text.gsub(/<\/?.*?>/,"").gsub(/ /," ") sheet1[count_row + 1, i + 1] = poll_answer.poll_votes.count sheet1[count_row + 2, i + 1] = statistics_result_percentage(poll_answer.poll_votes.count, total_answer(poll_question.id)).to_s + "%" end sheet1[count_row + 3,0] = l(:label_poll_valid_commit) sheet1[count_row + 3,1] = total_answer(poll_question.id) count_row += 5 else sheet1.row(count_row).default_format = blue sheet1[count_row,0] = l(:label_poll_question_num,:num => poll_question.question_number) sheet1[count_row,1] = poll_question.question_title count_row += 1 if poll_question.question_type == 3 poll_question.poll_votes.each do |poll_vote| sheet1[count_row,0] = poll_vote.vote_text.gsub(/<\/?.*?>/,"").gsub(/ /," ") count_row += 1 end count_row += 1 else count = 0 poll_question.poll_answers.reorder("answer_position asc").each_with_index do |poll_answer,i| sheet1.row(count_row).default_format = blue sheet1[count_row, i] = poll_answer.answer_text.gsub(/<\/?.*?>/,"").gsub(/ /," ") count = poll_question.poll_votes.where("poll_answer_id = #{poll_answer.id}").count > count ? poll_question.poll_votes.where("poll_answer_id = #{poll_answer.id}").count : count poll_question.poll_votes.where("poll_answer_id = #{poll_answer.id}").each_with_index do |poll_vote, j| sheet1[count_row + j + 1,i] = poll_vote.vote_text.gsub(/<\/?.*?>/,"").gsub(/ /," ") end end count_row = count_row + count + 2 end end end sheet1.row(count_row).default_format = blue sheet1[count_row ,0] = l(:label_bidding_user_studentname) current_index = 1 poll_questions.each do |poll_question| if poll_question.question_type == 4 poll_question.poll_answers.reorder("answer_position asc").each do |ans| sheet1[count_row ,current_index] = poll_question.question_title + "(#{ans.answer_text})" current_index += 1 end else sheet1[count_row ,current_index] = poll_question.question_title current_index += 1 end end count_row += 1 @poll.users.each do |user| sheet1[count_row ,0] = user.show_name current_index = 1 poll_questions.each_with_index do |poll_question, i| if poll_question.question_type == 1 || poll_question.question_type == 2 sheet1[count_row ,current_index] = user.poll_votes.where(:poll_question_id => poll_question.id).map{|poll_vote| (poll_vote.vote_text.nil? ? poll_vote.poll_answer.answer_text.gsub(/<\/?.*?>/,"").gsub(/ /," ") : l(:label_other_answer) + " (" + poll_vote.vote_text.to_s + ") ") if poll_vote.poll_answer}.join(";") current_index += 1 elsif poll_question.question_type == 3 sheet1[count_row ,current_index] = user.poll_votes.where(:poll_question_id => poll_question.id).map{|poll_vote| poll_vote.vote_text.gsub(/<\/?.*?>/,"").gsub(/ /," ")}.join(";") current_index += 1 else poll_question.poll_answers.reorder("answer_position asc").each do |ans| poll_vote = user.poll_votes.where(:poll_question_id => poll_question.id, :poll_answer_id => ans.id).first sheet1[count_row ,current_index] = poll_vote.nil? ? "" : poll_vote.vote_text current_index += 1 end end end count_row += 1 end book.write xls_report xls_report.string end end