forgeplus/app/controllers/home/platform_communicates_contr...

110 lines
3.5 KiB
Ruby

class Home::PlatformCommunicatesController < ApplicationController
before_action :require_login, only: [:submit_vote, :vote_results]
before_action :load_vote, only: [:submit_vote, :vote_results]
def index
location = params[:location] || "pc"
scope = PlatformCommunicate.where(status:true).where(location: location).order(order_index: :desc)
@communicates = kaminari_paginate(scope.includes(:vote))
end
def submit_vote
return render_error("投票已结束!") if @vote.expired?
# 处理投票选项
selected_option_ids = vote_params[:vote_option_ids] || []
# 验证选择数量
validation_result = validate_vote_selections(selected_option_ids)
return render_error(validation_result[:message]) unless validation_result[:valid]
# 保存投票
result = save_user_votes(selected_option_ids)
if result[:success]
render_ok
else
render_error(result[:errors].join(', '))
end
end
def vote_results
@vote_results = @vote.results_with_cache
@selected_option_ids = current_user.user_vote_options.where(vote_option: @vote.vote_options).pluck(:vote_option_id)
end
private
def load_vote
@communicate = PlatformCommunicate.find_by_id(params[:id])
@vote = @communicate.vote
return render_error("投票不存在!") unless @vote.present?
end
def vote_params
params.require(:vote).permit(vote_option_ids: [])
end
def validate_vote_selections(selected_option_ids)
selected_option_ids = Array(selected_option_ids).map(&:to_i).uniq
# 检查是否选择了选项
if selected_option_ids.empty?
return { valid: false, message: '请至少选择一个投票选项' }
end
# 检查选项是否属于该投票
valid_option_ids = @vote.vote_options.pluck(:id)
invalid_options = selected_option_ids - valid_option_ids
unless invalid_options.empty?
return { valid: false, message: '包含无效的投票选项' }
end
# 检查选择数量限制
if @vote.is_multiple_choice
max_choices = @vote.max_choice_vote_options_count || selected_option_ids.length
if selected_option_ids.length > max_choices
return {
valid: false,
message: "最多只能选择 #{max_choices} 个选项"
}
end
else
if selected_option_ids.length > 1
return { valid: false, message: '只能选择一个选项' }
end
end
{ valid: true }
end
def save_user_votes(selected_option_ids)
selected_option_ids = Array(selected_option_ids).map(&:to_i)
saved_selections = []
errors = []
ActiveRecord::Base.transaction do
# 如果是多选,先删除用户之前的投票记录(重新投票)
if @vote.is_multiple_choice
@vote.user_vote_options.where(user_id: current_user.id).destroy_all
end
selected_option_ids.each do |option_id|
vote_option = @vote.vote_options.find(option_id)
user_vote_option = current_user.user_vote_options.new(
vote_option: vote_option
)
if user_vote_option.save
saved_selections << user_vote_option
else
errors << user_vote_option.errors.full_messages
raise ActiveRecord::Rollback
end
end
end
if errors.empty?
{ success: true, selections: saved_selections }
else
{ success: false, errors: errors.flatten }
end
end
end