socialforge/app/controllers/poll_controller.rb

779 lines
27 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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]
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
# 问卷消息状态更新
query_course_poll = @poll.course_messages
query_course_poll.each do |query|
if User.current.id == query.user_id
query.update_attributes(:viewed => true)
end
end
#已提交问卷的用户不能再访问该界面
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 = (!has_commit_poll?(@poll.id,User.current.id)) || User.current.admin?
@percent = get_percent(@poll,User.current)
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
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 create_poll_question
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
}
@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]
@is_insert = true
@poll.poll_questions.where("question_number > #{params[:quest_num].to_i}").update_all(" question_number = question_number + 1")
@poll_question_num = params[:quest_num].to_i
@poll_questions.question_number = params[:quest_num].to_i + 1
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]
################处理选项
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
@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?)
render :json => {:text => "failure"}
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?
#尚未答该题,添加答案
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
else
#pv不为空则当前选项之前已被选择再次点击则是不再选择该项故删除该答案
if pv.delete
@percent = get_percent(@poll,User.current)
render :json => {:text => "false" ,:percent => format("%.2f" ,@percent)}
else
render :json => {:text => "failure"}
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
@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 = paginateHelper @poll.poll_questions,5
@left_nav_type = 7
respond_to do |format|
format.html{render :layout => 'base_courses'}
end
end
#关闭问卷
def close_poll
@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("is_delete = 1 or #{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
@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
end
def get_complete_question(poll,user)
questions = poll.poll_questions
complete_question = []
questions.each do |question|
answers = get_user_answer(question,user)
if question.question_type != 4
if !(answers.nil? || answers.count < 1)
complete_question << question
end
else
if !(answers.nil? || answers.count < 1)
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).count
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(/&nbsp;/," ")
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(/&nbsp;/," ")
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(/&nbsp;/," ")
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(/&nbsp;/," ")
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.poll_answer.answer_text.gsub(/<\/?.*?>/,"").gsub(/&nbsp;/," ") 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(/&nbsp;/," ")}.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