diff --git a/app/controllers/admins/platform_communicates_controller.rb b/app/controllers/admins/platform_communicates_controller.rb
index 15d2c66c3..8bd84059c 100644
--- a/app/controllers/admins/platform_communicates_controller.rb
+++ b/app/controllers/admins/platform_communicates_controller.rb
@@ -1,5 +1,5 @@
class Admins::PlatformCommunicatesController < Admins::BaseController
- before_action :get_communicate, only: [:edit, :update, :destroy, :show, :online_switch]
+ before_action :get_communicate, only: [:edit, :update, :destroy, :show, :online_switch, :new_vote, :create_vote, :edit_vote, :update_vote]
def index
params[:location] = "pc"
@@ -85,6 +85,42 @@ class Admins::PlatformCommunicatesController < Admins::BaseController
# render_ok
end
+ def new_vote
+ @vote = Vote.new(platform_communicate_id: @communicate.id)
+ 2.times { @vote.vote_options.build }
+ end
+
+ def create_vote
+ @vote = Vote.new(platform_communicate_id: @communicate.id)
+ @vote.attributes = vote_params
+
+ if @vote.save
+ redirect_to applet_admins_platform_communicates_path, notice: '投票创建成功'
+ else
+ # 确保至少有2个选项显示在表单中
+ @vote.vote_options.build if @vote.vote_options.empty?
+ @vote.vote_options.build if @vote.vote_options.size == 1
+
+ render :new_vote
+ end
+ end
+
+ def edit_vote
+ @vote = @communicate.vote
+ # 确保至少有2个选项显示在表单中
+ @vote.vote_options.build if @vote.vote_options.empty?
+ @vote.vote_options.build if @vote.vote_options.size == 1
+ end
+
+ def update_vote
+ @vote = @communicate.vote
+ if @vote.update(vote_params)
+ redirect_to applet_admins_platform_communicates_path, notice: '投票更新成功'
+ else
+ render :edit_vote
+ end
+ end
+
private
def get_communicate
@@ -94,4 +130,19 @@ class Admins::PlatformCommunicatesController < Admins::BaseController
def communicate_params
params.require(:platform_communicate).permit!
end
+
+ def vote_params
+ params.require(:vote).permit(
+ :description,
+ :is_multiple_choice,
+ :max_choice_vote_options_count,
+ :due_at,
+ vote_options_attributes: [
+ :id,
+ :title,
+ :order_index,
+ :_destroy
+ ]
+ )
+ end
end
\ No newline at end of file
diff --git a/app/controllers/home/platform_communicates_controller.rb b/app/controllers/home/platform_communicates_controller.rb
index a47fb3729..70f991718 100644
--- a/app/controllers/home/platform_communicates_controller.rb
+++ b/app/controllers/home/platform_communicates_controller.rb
@@ -1,8 +1,110 @@
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)
+ @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
\ No newline at end of file
diff --git a/app/models/platform_communicate.rb b/app/models/platform_communicate.rb
index 8c7cb089f..d327e926e 100644
--- a/app/models/platform_communicate.rb
+++ b/app/models/platform_communicate.rb
@@ -21,6 +21,8 @@ class PlatformCommunicate < ApplicationRecord
before_save :add_fake_id, on: [:create, :update]
has_many :watchers, as: :watchable, dependent: :destroy
+ has_one :vote, dependent: :destroy
+ has_many :vote_options, through: :vote
def watched_ext_info(user_id)
watcher = self.watchers.find_by(user_id: user_id)
diff --git a/app/models/project_actions/pull_request_event.rb b/app/models/project_actions/pull_request_event.rb
index 0864f310c..b7846e723 100644
--- a/app/models/project_actions/pull_request_event.rb
+++ b/app/models/project_actions/pull_request_event.rb
@@ -25,8 +25,8 @@ class ProjectActions::PullRequestEvent < ProjectAction
pull_id: pull_request.id,
pull_number: pull_request.gitea_number,
title: pull_request.title,
- body: pull_request.body,
- git_diff: gitea_pull_request,
+ # body: pull_request.body,
+ # git_diff: gitea_pull_request,
additions: gitea_pull_request['TotalAddition'],
deletions: gitea_pull_request['TotalDeletion'],
changed_files: gitea_pull_request['NumFiles'],
diff --git a/app/models/user.rb b/app/models/user.rb
index 214179993..aa1747ff3 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -192,6 +192,9 @@ class User < Owner
has_one :page, :dependent => :destroy
has_many :home_top_settings, dependent: :destroy
+
+ has_many :user_vote_options, dependent: :destroy
+ has_many :vote_options, through: :user_vote_options
# Groups and active users
scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
diff --git a/app/models/user_vote_option.rb b/app/models/user_vote_option.rb
new file mode 100644
index 000000000..c1e4f3f10
--- /dev/null
+++ b/app/models/user_vote_option.rb
@@ -0,0 +1,17 @@
+class UserVoteOption < ApplicationRecord
+ belongs_to :user
+ belongs_to :vote_option, counter_cache: true
+
+ validates :user_id, uniqueness: { scope: :vote_option_id, message: "您已经投过票了" }
+
+ private
+ def user_can_vote_only_once_per_vote
+ return unless user && vote_option
+
+ existing_vote = UserVoteOption.joins(:vote_option)
+ .where(user_id: user_id, vote_options: { vote_id: vote_option.vote_id })
+ .where.not(id: id) # 排除自身(更新时)
+ .exists?
+ errors.add(:base, '您已经投过票了') if existing_vote
+ end
+end
diff --git a/app/models/vote.rb b/app/models/vote.rb
new file mode 100644
index 000000000..82a639993
--- /dev/null
+++ b/app/models/vote.rb
@@ -0,0 +1,75 @@
+class Vote < ApplicationRecord
+ self.table_name = 'new_votes'
+
+ belongs_to :platform_communicate
+ has_many :vote_options, dependent: :destroy
+ has_many :user_vote_options, through: :vote_options
+
+ accepts_nested_attributes_for :vote_options, allow_destroy: true
+
+ validates :max_choice_vote_options_count,
+ numericality: {
+ greater_than: 1,
+ less_than_or_equal_to: 20,
+ allow_nil: true
+ },
+ if: :is_multiple_choice?
+
+ validate :validate_multiple_choice_settings
+
+
+ def expired?
+ due_at.present? && due_at < Time.current
+ end
+
+ def user_voted?(user)
+ return false unless user
+
+ user_vote_options.where(user_id: user.id).exists?
+ end
+
+ def user_selections(user)
+ return UserVoteOption.none unless user
+
+ user_vote_options.where(user_id: user.id)
+ end
+
+ def total_votes_count
+ # 计算参与投票的总人数(去重)
+ user_vote_options.select(:user_id).distinct.count
+ end
+
+ def total_votes_options_count
+ vote_options.sum(:user_vote_options_count)
+ end
+
+ # 获取投票结果(使用缓存字段,性能更好)
+ def results_with_cache
+ vote_options.select(:id, :title, :user_vote_options_count).map do |option|
+ {
+ id: option.id,
+ title: option.title,
+ vote_count: option.user_vote_options_count,
+ percentage: calculate_percentage_for_option(option.user_vote_options_count)
+ }
+ end
+ end
+
+ private
+
+ def calculate_percentage_for_option(option_votes)
+ total = total_votes_options_count
+ return 0 if total.zero?
+ (option_votes.to_f / total * 100).round(2)
+ end
+
+ def validate_multiple_choice_settings
+ if is_multiple_choice? && max_choice_vote_options_count.nil?
+ errors.add(:max_choice_vote_options_count, '多选投票必须设置最大选择数')
+ end
+
+ if !is_multiple_choice? && max_choice_vote_options_count.present?
+ errors.add(:max_choice_vote_options_count, '单选投票不需要设置最大选择数')
+ end
+ end
+end
diff --git a/app/models/vote_option.rb b/app/models/vote_option.rb
new file mode 100644
index 000000000..a9dafd991
--- /dev/null
+++ b/app/models/vote_option.rb
@@ -0,0 +1,11 @@
+class VoteOption < ApplicationRecord
+
+ belongs_to :vote
+ has_many :user_vote_options, dependent: :destroy
+ has_many :users, through: :user_vote_options
+ validates :title, presence: true
+
+ def self.selected?(option, user)
+ option.user_vote_options.exists?(user_id: user.id)
+ end
+end
diff --git a/app/views/admins/platform_communicates/_list.html.erb b/app/views/admins/platform_communicates/_list.html.erb
index 3ca5c674a..c35c0b674 100644
--- a/app/views/admins/platform_communicates/_list.html.erb
+++ b/app/views/admins/platform_communicates/_list.html.erb
@@ -21,6 +21,11 @@
<%= c.order_index %> |
<%= c.tag_field.to_s.include?("活动") ? link_to(c.watchers_count, "/admins/platform_communicates/#{c.id}") : "--"%> |
+ <% if c.vote.present? %>
+ <%= link_to "编辑投票", edit_vote_admins_platform_communicate_path(c), class: "action" %>
+ <% else %>
+ <%= link_to "新增投票", new_vote_admins_platform_communicate_path(c), class: "action" %>
+ <% end %>
<%= link_to c.status ? "下架" : "上架", "/admins/platform_communicates/#{c.id}/online_switch.js", style: "#{c.status? ? 'color:#FF6800;' : ''}", method: :post, remote: true%>
<%= link_to "编辑", edit_admins_platform_communicate_path(c), remote: true, class: "action" %>
<%= link_to "删除", admins_platform_communicate_path(c), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
diff --git a/app/views/admins/platform_communicates/_vote_form.html.erb b/app/views/admins/platform_communicates/_vote_form.html.erb
new file mode 100644
index 000000000..60a1793ac
--- /dev/null
+++ b/app/views/admins/platform_communicates/_vote_form.html.erb
@@ -0,0 +1,312 @@
+<%= form_for @vote, url: {controller: "platform_communicates", action: "#{type}"} do |form| %>
+ <% if vote.errors.any? %>
+
+ <%= pluralize(vote.errors.count, "error") %> 阻止了此投票的保存:
+
+ <% vote.errors.full_messages.each do |message| %>
+ - <%= message %>
+ <% end %>
+
+
+ <% end %>
+
+
+
+
+
+
+
+ <%= form.label :description, "投票描述", class: "font-weight-bold" %>
+ <%= form.text_area :description, class: "form-control", rows: 3, placeholder: "输入投票描述(可选)" %>
+ 详细描述投票的目的和背景
+
+
+
+
+
+
+
+
+
+
+
+ <%= form.label :max_choice_vote_options_count, "最多选择数", class: "font-weight-bold" %>
+ <%= form.number_field :max_choice_vote_options_count, class: "form-control", min: 2, max: 20, placeholder: "输入最多可选择的数量" %>
+ 设置用户最多可以选择的选项数量(2-20)
+
+
+
+
+
+
+
+
+
+
+
+ <%= form.fields_for :vote_options do |vote_option_fields| %>
+
+
+
+
+
+ <%= vote_option_fields.label :title, "选项名称", class: "font-weight-bold" %>
+ <%= vote_option_fields.text_field :title, class: "form-control", placeholder: "输入选项名称", required: true %>
+
+
+
+
+ <%= vote_option_fields.label :order_index, "排序", class: "font-weight-bold" %>
+ <%= vote_option_fields.number_field :order_index, class: "form-control", min: 1, value: vote_option_fields.object.order_index || 1 %>
+
+
+
+ <% unless vote_option_fields.object.persisted? %>
+
+ <% end %>
+
+
+ <% if vote_option_fields.object.persisted? %>
+
+ <% end %>
+
+
+ <% end %>
+
+
+
+ 提示: 至少需要添加2个投票选项,最多支持50个选项。
+
+
+
+
+
+
+ <%= form.submit vote.persisted? ? "更新投票" : "创建投票", class: "btn btn-primary btn-lg mr-2" %>
+ <%= link_to "取消", applet_admins_platform_communicates_path, class: "btn btn-secondary btn-lg" %>
+
+<% end %>
+
+
+
+
+
+
+<%= javascript_tag nonce: true do %>
+ // 简化的投票表单交互功能
+document.addEventListener('DOMContentLoaded', function() {
+ initVoteForm();
+});
+
+// 如果使用 Turbolinks/Turbo
+document.addEventListener('turbolinks:load', initVoteForm);
+document.addEventListener('turbo:load', initVoteForm);
+
+function initVoteForm() {
+ console.log('初始化投票表单...');
+
+ // 防止重复初始化
+ if (window.voteFormInitialized) {
+ console.log('投票表单已经初始化过,跳过');
+ return;
+ }
+ window.voteFormInitialized = true;
+
+ // 多选切换
+ const multipleChoiceCheckbox = document.getElementById('is_multiple_choice');
+ const maxChoicesField = document.getElementById('max_choices_field');
+
+ if (multipleChoiceCheckbox && maxChoicesField) {
+ function toggleMaxChoices() {
+ maxChoicesField.style.display = multipleChoiceCheckbox.checked ? 'block' : 'none';
+ if (!multipleChoiceCheckbox.checked) {
+ const maxChoiceInput = document.getElementById('vote_max_choice_vote_options_count');
+ if (maxChoiceInput) maxChoiceInput.value = '';
+ }
+ }
+
+ multipleChoiceCheckbox.addEventListener('change', toggleMaxChoices);
+ toggleMaxChoices(); // 初始状态
+ }
+
+ // 清除结束时间
+ const clearEndsAtBtn = document.getElementById('clear_ends_at');
+ if (clearEndsAtBtn) {
+ clearEndsAtBtn.addEventListener('click', function() {
+ const endsAtInput = document.getElementById('vote_ends_at');
+ if (endsAtInput) endsAtInput.value = '';
+ });
+ }
+
+ // 添加选项 - 关键修复:确保只绑定一次
+ const addOptionButton = document.getElementById('add_vote_option');
+ if (addOptionButton && !addOptionButton.hasListener) {
+ addOptionButton.hasListener = true; // 标记已绑定
+
+ addOptionButton.addEventListener('click', function(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ addNewOption();
+ });
+ }
+
+ // 删除选项 - 使用事件委托
+ const optionsContainer = document.getElementById('vote_options');
+ if (optionsContainer) {
+ optionsContainer.addEventListener('click', function(event) {
+ if (event.target.closest('.remove-option')) {
+ event.preventDefault();
+ event.target.closest('.vote-option-item').remove();
+ }
+ });
+ }
+
+ // 表单验证
+ const form = document.querySelector('.vote-form');
+ if (form) {
+ form.addEventListener('submit', validateForm);
+ }
+}
+
+// 添加新选项
+function addNewOption() {
+ console.log('执行添加选项函数');
+
+ const optionsContainer = document.getElementById('vote_options');
+ const optionTemplate = document.getElementById('vote_option_template');
+
+ if (!optionsContainer || !optionTemplate) {
+ console.error('找不到选项容器或模板');
+ return;
+ }
+
+ // 计算新的索引和位置
+ const currentOptions = optionsContainer.querySelectorAll('.vote-option-item');
+ const newIndex = currentOptions.length;
+ const newPosition = getNextPosition();
+
+ const newOption = optionTemplate.content.cloneNode(true);
+ const html = newOption.querySelector('.vote-option-item').outerHTML;
+ let newHtml = html.replace(/INDEX/g, newIndex);
+ newHtml = newHtml.replace(/POSITION_VALUE/g, newPosition);
+
+ optionsContainer.insertAdjacentHTML('beforeend', newHtml);
+
+ console.log(`成功添加选项,索引: ${newIndex}, 位置: ${newPosition}`);
+}
+
+// 获取下一个位置值
+function getNextPosition() {
+ const positionInputs = document.querySelectorAll('input[name*="position"]');
+ let maxPosition = 0;
+
+ positionInputs.forEach(input => {
+ const value = parseInt(input.value) || 0;
+ if (value > maxPosition) maxPosition = value;
+ });
+
+ return maxPosition + 1;
+}
+
+// 表单验证
+function validateForm(event) {
+ const optionsContainer = document.getElementById('vote_options');
+ const optionItems = optionsContainer ? optionsContainer.querySelectorAll('.vote-option-item') : [];
+ let validOptionCount = 0;
+
+ // 计算有效的选项数量
+ optionItems.forEach(item => {
+ const nameInput = item.querySelector('input[type="text"][name*="name"]');
+ if (nameInput && nameInput.value.trim()) {
+ validOptionCount++;
+ }
+ });
+
+ if (validOptionCount < 2) {
+ event.preventDefault();
+ alert('请至少填写2个有效的投票选项!');
+ return false;
+ }
+
+ // 验证选项名称是否重复
+ const optionNames = [];
+ let hasDuplicate = false;
+
+ optionItems.forEach(item => {
+ const nameInput = item.querySelector('input[type="text"][name*="name"]');
+ if (nameInput && nameInput.value.trim()) {
+ const name = nameInput.value.trim().toLowerCase();
+ if (optionNames.includes(name)) {
+ hasDuplicate = true;
+ nameInput.classList.add('is-invalid');
+ } else {
+ optionNames.push(name);
+ nameInput.classList.remove('is-invalid');
+ }
+ }
+ });
+
+ if (hasDuplicate) {
+ event.preventDefault();
+ alert('存在重复的选项名称,请修改后重新提交!');
+ return false;
+ }
+
+ return true;
+}
+<% end %>
\ No newline at end of file
diff --git a/app/views/admins/platform_communicates/edit_vote.html.erb b/app/views/admins/platform_communicates/edit_vote.html.erb
new file mode 100644
index 000000000..592e985b2
--- /dev/null
+++ b/app/views/admins/platform_communicates/edit_vote.html.erb
@@ -0,0 +1,15 @@
+<% content_for :page_title, "编辑投票" %>
+
+
+
+
+
+
+ <%= render 'vote_form', vote: @vote, type: "update_vote" %>
+
+
+
+
+
diff --git a/app/views/admins/platform_communicates/new_vote.html.erb b/app/views/admins/platform_communicates/new_vote.html.erb
new file mode 100644
index 000000000..a8dbe6962
--- /dev/null
+++ b/app/views/admins/platform_communicates/new_vote.html.erb
@@ -0,0 +1,15 @@
+<% content_for :page_title, "创建新投票" %>
+
+
+
+
+
+
+ <%= render 'vote_form', vote: @vote, type: "create_vote" %>
+
+
+
+
+
diff --git a/app/views/api/v1/projects/pipelines/build_pipeline.yaml.erb b/app/views/api/v1/projects/pipelines/build_pipeline.yaml.erb
index 41908c8f5..02b40f71d 100644
--- a/app/views/api/v1/projects/pipelines/build_pipeline.yaml.erb
+++ b/app/views/api/v1/projects/pipelines/build_pipeline.yaml.erb
@@ -19,6 +19,7 @@ on:
<% end %>
<%if node.name.to_s.include?("on-pull_request") %>
pull_request:
+ types: [opened, reopened]
<% end %>
<%if node.name.to_s.include?("on-fork") %>
fork:
diff --git a/app/views/home/platform_communicates/_vote.json.jbuilder b/app/views/home/platform_communicates/_vote.json.jbuilder
new file mode 100644
index 000000000..baaedb5a7
--- /dev/null
+++ b/app/views/home/platform_communicates/_vote.json.jbuilder
@@ -0,0 +1,4 @@
+json.(vote, :id, :description, :is_multiple_choice, :max_choice_vote_options_count)
+json.created_at vote.created_at.to_i
+json.due_at vote.due_at.to_i
+json.total_votes_count vote.total_votes_count # 计算参与投票的总人数(去重)
\ No newline at end of file
diff --git a/app/views/home/platform_communicates/index.json.jbuilder b/app/views/home/platform_communicates/index.json.jbuilder
index 8a2d3d4d1..f88f5e0d1 100644
--- a/app/views/home/platform_communicates/index.json.jbuilder
+++ b/app/views/home/platform_communicates/index.json.jbuilder
@@ -9,5 +9,6 @@ json.communicates do
json.enroll_field communicate.enroll_field.to_s.split(",")
json.enroll_info current_user.watched?(communicate) ? communicate.watched_ext_info(current_user.id) : []
json.url communicate.url_or_uuid
+ json.has_vote communicate.vote.present?
end
end
\ No newline at end of file
diff --git a/app/views/home/platform_communicates/vote_results.json.jbuilder b/app/views/home/platform_communicates/vote_results.json.jbuilder
new file mode 100644
index 000000000..22f3741c4
--- /dev/null
+++ b/app/views/home/platform_communicates/vote_results.json.jbuilder
@@ -0,0 +1,7 @@
+json.vote do
+ json.partial! "home/platform_communicates/vote", locals: {vote: @vote}
+end
+json.selected_option_ids @selected_option_ids
+json.vote_results @vote_results do |result|
+ json.(result, :id, :title, :vote_count, :percentage)
+end
\ No newline at end of file
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 199481259..2591ab8c1 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -15,7 +15,8 @@ Rails.application.configure do
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
- config.cache_store = :file_store, "#{Rails.root }/files/cache_store/"
+ # config.cache_store = :file_store, "#{Rails.root }/files/cache_store/"
+ config.cache_store = :redis_store, { url: 'redis://127.0.0.1:6379/1', namespace: 'cache_store' }
# if Rails.root.join('tmp', 'caching-dev.txt').exist?
# config.action_controller.perform_caching = true
diff --git a/config/routes.rb b/config/routes.rb
index f68039d24..5c76c7482 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -145,7 +145,12 @@ Rails.application.routes.draw do
namespace :home do
resources :platform_statistics, only: [:index]
resources :competitions, only:[:index]
- resources :platform_communicates, only: [:index]
+ resources :platform_communicates, only: [:index] do
+ member do
+ post :submit_vote
+ get :vote_results
+ end
+ end
resources :platform_people, only: [:index]
end
get 'home/index'
@@ -1221,6 +1226,10 @@ Rails.application.routes.draw do
get :applet, on: :collection
member do
post :online_switch
+ get :new_vote
+ post :create_vote
+ get :edit_vote
+ patch :update_vote
end
end
resources :platform_people
diff --git a/db/migrate/20251021015122_create_votes.rb b/db/migrate/20251021015122_create_votes.rb
new file mode 100644
index 000000000..e135946c4
--- /dev/null
+++ b/db/migrate/20251021015122_create_votes.rb
@@ -0,0 +1,13 @@
+class CreateVotes < ActiveRecord::Migration[5.2]
+ def change
+ create_table :new_votes do |t|
+ t.references :platform_communicate
+ t.text :description
+ t.boolean :is_multiple_choice, default: false
+ t.integer :max_choice_vote_options_count, default: 1
+ t.datetime :due_at
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20251021055402_create_vote_options.rb b/db/migrate/20251021055402_create_vote_options.rb
new file mode 100644
index 000000000..0bff1e4dc
--- /dev/null
+++ b/db/migrate/20251021055402_create_vote_options.rb
@@ -0,0 +1,12 @@
+class CreateVoteOptions < ActiveRecord::Migration[5.2]
+ def change
+ create_table :vote_options do |t|
+ t.references :vote
+ t.string :title
+ t.integer :order_index, default: 0
+ t.integer :user_vote_options_count, default: 0
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20251021060115_create_user_vote_options.rb b/db/migrate/20251021060115_create_user_vote_options.rb
new file mode 100644
index 000000000..31aa04c1b
--- /dev/null
+++ b/db/migrate/20251021060115_create_user_vote_options.rb
@@ -0,0 +1,10 @@
+class CreateUserVoteOptions < ActiveRecord::Migration[5.2]
+ def change
+ create_table :user_vote_options do |t|
+ t.references :user, index: true
+ t.references :vote_option, index: true
+
+ t.timestamps
+ end
+ end
+end
|