| @@ -0,0 +1,49 @@ | |||||
| class Admins::FeedbacksController < Admins::BaseController | |||||
| before_action :get_feedback, only: [:new_history, :create_history, :destroy] | |||||
| def index | |||||
| sort_by = Feedback.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at' | |||||
| sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc' | |||||
| feedbacks = Feedback.order("#{sort_by} #{sort_direction}") | |||||
| @feedbacks = paginate(feedbacks) | |||||
| end | |||||
| def destroy | |||||
| if @feedback.destroy | |||||
| redirect_to admins_feedbacks_path | |||||
| flash[:success] = "反馈意见删除成功" | |||||
| else | |||||
| redirect_to admins_feedbacks_path | |||||
| flash[:danger] = "反馈意见删除失败" | |||||
| end | |||||
| end | |||||
| def new_history | |||||
| @feedback_message_history = FeedbackMessageHistory.new | |||||
| end | |||||
| def create_history | |||||
| @feedback_message_history = @feedback.feedback_message_histories.new(feedback_message_history_params) | |||||
| @feedback_message_history.user = current_user | |||||
| if @feedback_message_history.save | |||||
| redirect_to admins_feedbacks_path | |||||
| flash[:success] = "发送通知成功" | |||||
| else | |||||
| redirect_to admins_feedbacks_path | |||||
| flash[:danger] = @feedback_message_history.errors.full_messages.join(", ") | |||||
| end | |||||
| end | |||||
| private | |||||
| def feedback_params | |||||
| params.require(:feedback).permit! | |||||
| end | |||||
| def feedback_message_history_params | |||||
| params.require(:feedback_message_history).permit(:title, :content) | |||||
| end | |||||
| def get_feedback | |||||
| @feedback = Feedback.find_by_id(params[:id]) | |||||
| end | |||||
| end | |||||
| @@ -7,7 +7,7 @@ class IssueTagsController < ApplicationController | |||||
| def index | def index | ||||
| issue_tags = @project.issue_tags.reorder("#{order_name} #{order_type}") | |||||
| issue_tags = @project.issue_tags.includes(:issues).reorder("issue_tags.#{order_name} #{order_type}") | |||||
| @user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user)) | @user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user)) | ||||
| @page = params[:page] || 1 | @page = params[:page] || 1 | ||||
| @limit = params[:limit] || 15 | @limit = params[:limit] || 15 | ||||
| @@ -100,20 +100,6 @@ class PullRequestsController < ApplicationController | |||||
| Issues::UpdateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate! | Issues::UpdateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate! | ||||
| merge_params | merge_params | ||||
| @issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank? | |||||
| if params[:issue_tag_ids].present? && !@issue&.issue_tags_relates.where(issue_tag_id: params[:issue_tag_ids]).exists? | |||||
| if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1 | |||||
| return normal_status(-1, "最多只能创建一个标记。") | |||||
| elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1 | |||||
| @issue&.issue_tags_relates&.destroy_all | |||||
| params[:issue_tag_ids].each do |tag| | |||||
| IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag) | |||||
| end | |||||
| else | |||||
| return normal_status(-1, "请输入正确的标记。") | |||||
| end | |||||
| end | |||||
| reviewers = User.where(id: params[:reviewer_ids]) | reviewers = User.where(id: params[:reviewer_ids]) | ||||
| @pull_request.reviewers = reviewers | @pull_request.reviewers = reviewers | ||||
| @@ -165,6 +151,8 @@ class PullRequestsController < ApplicationController | |||||
| colsed = PullRequests::CloseService.call(@owner, @repository, @pull_request, current_user) | colsed = PullRequests::CloseService.call(@owner, @repository, @pull_request, current_user) | ||||
| if colsed === true | if colsed === true | ||||
| @pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::CLOSE) | @pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::CLOSE) | ||||
| # 合并请求下issue处理为关闭 | |||||
| @issue&.update_attributes!({status_id:5}) | |||||
| SendTemplateMessageJob.perform_later('PullRequestClosed', current_user.id, @pull_request.id) if Site.has_notice_menu? | SendTemplateMessageJob.perform_later('PullRequestClosed', current_user.id, @pull_request.id) if Site.has_notice_menu? | ||||
| normal_status(1, "已拒绝") | normal_status(1, "已拒绝") | ||||
| else | else | ||||
| @@ -210,6 +198,8 @@ class PullRequestsController < ApplicationController | |||||
| # @pull_request.project_trend_status! | # @pull_request.project_trend_status! | ||||
| @pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::MERGE) | @pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::MERGE) | ||||
| @issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id) | @issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id) | ||||
| # 合并请求下issue处理为关闭 | |||||
| @issue&.update_attributes!({status_id:5}) | |||||
| SendTemplateMessageJob.perform_later('PullRequestMerged', current_user.id, @pull_request.id) if Site.has_notice_menu? | SendTemplateMessageJob.perform_later('PullRequestMerged', current_user.id, @pull_request.id) if Site.has_notice_menu? | ||||
| normal_status(1, "合并成功") | normal_status(1, "合并成功") | ||||
| else | else | ||||
| @@ -13,4 +13,8 @@ class UserMailer < ApplicationMailer | |||||
| @code = code | @code = code | ||||
| mail(to: mail, subject: 'Gitink | 更改邮箱验证码') | mail(to: mail, subject: 'Gitink | 更改邮箱验证码') | ||||
| end | end | ||||
| def feedback_email(mail, title, content) | |||||
| mail(to: mail, subject: title, content_type: "text/html", body: content) | |||||
| end | |||||
| end | end | ||||
| @@ -16,5 +16,6 @@ | |||||
| class Feedback < ApplicationRecord | class Feedback < ApplicationRecord | ||||
| belongs_to :user | belongs_to :user | ||||
| has_many :feedback_message_histories, dependent: :destroy | |||||
| end | end | ||||
| @@ -0,0 +1,36 @@ | |||||
| # == Schema Information | |||||
| # | |||||
| # Table name: feedback_message_histories | |||||
| # | |||||
| # id :integer not null, primary key | |||||
| # feedback_id :integer | |||||
| # user_id :integer | |||||
| # title :string(255) | |||||
| # content :text(65535) | |||||
| # created_at :datetime not null | |||||
| # updated_at :datetime not null | |||||
| # | |||||
| # Indexes | |||||
| # | |||||
| # index_feedback_message_histories_on_feedback_id (feedback_id) | |||||
| # index_feedback_message_histories_on_user_id (user_id) | |||||
| # | |||||
| class FeedbackMessageHistory < ApplicationRecord | |||||
| belongs_to :feedback | |||||
| belongs_to :user | |||||
| before_validation :send_meessage_email, on: :create | |||||
| private | |||||
| def send_meessage_email | |||||
| unless UserMailer.feedback_email(feedback&.user&.mail, title, content).deliver_now | |||||
| errors[:title] << '邮件发送失败!' | |||||
| end | |||||
| rescue | |||||
| errors[:title] << '邮件发送失败!' | |||||
| end | |||||
| end | |||||
| @@ -177,6 +177,7 @@ class User < Owner | |||||
| has_one :trace_user, dependent: :destroy | has_one :trace_user, dependent: :destroy | ||||
| has_many :user_trace_tasks, dependent: :destroy | has_many :user_trace_tasks, dependent: :destroy | ||||
| has_many :feedbacks, dependent: :destroy | |||||
| # Groups and active users | # Groups and active users | ||||
| scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) } | scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) } | ||||
| scope :like, lambda { |keywords| | scope :like, lambda { |keywords| | ||||
| @@ -17,7 +17,7 @@ class Projects::ListQuery < ApplicationQuery | |||||
| sort = params[:sort_by] || "updated_on" | sort = params[:sort_by] || "updated_on" | ||||
| sort_direction = params[:sort_direction] || "desc" | sort_direction = params[:sort_direction] || "desc" | ||||
| collection = optimize_sorting(collection, sort) if params[:category_id].present? | |||||
| # collection = optimize_sorting(collection, sort) if params[:category_id].present? | |||||
| custom_sort(collection, sort, sort_direction) | custom_sort(collection, sort, sort_direction) | ||||
| # scope = scope.reorder("projects.#{sort} #{sort_direction}") | # scope = scope.reorder("projects.#{sort} #{sort_direction}") | ||||
| @@ -0,0 +1,39 @@ | |||||
| <div class="modal fade feedback-history-change-modal" tabindex="-1" role="dialog" aria-hidden="true"> | |||||
| <div class="modal-dialog modal-dialog-centered" role="document" style="max-width: 800px"> | |||||
| <div class="modal-content"> | |||||
| <div class="modal-header"> | |||||
| <h5 class="modal-title">发送邮件给<%= @feedback&.user&.mail%></h5> | |||||
| <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | |||||
| <span aria-hidden="true">×</span> | |||||
| </button> | |||||
| </div> | |||||
| <%= form_for @feedback_message_history, url: {controller: "feedbacks", action: "create_history"} do |p| %> | |||||
| <div class="modal-body"> | |||||
| <div class="form-group"> | |||||
| <label> | |||||
| 邮件标题 <span class="ml10 color-orange mr20">*</span> | |||||
| </label> | |||||
| <%= p.text_field :title,class: "form-control input-lg", placeholder: "邮件标题", value: "您提交的意见反馈有新回复",required: true, maxlength: 64, readonly: true%> | |||||
| </div> | |||||
| <div class="form-group"> | |||||
| <label> | |||||
| <span class="color-grey-6 pt10"> | |||||
| 邮件正文 | |||||
| <span class="ml10 color-orange mr20">*</span> | |||||
| </span> | |||||
| </label> | |||||
| <div class="mt-10"> | |||||
| <div class="pl-0 my-3 setting-item-body" id="feedback-history-email-editor"> | |||||
| <%= p.text_area :content, class:"form-control", style: 'display: none;', rows: "10", cols: "20", placeholer: "请输入邮件正文" %> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="modal-footer"> | |||||
| <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> | |||||
| <%= p.submit "确认", class: "btn btn-primary submit-btn" %> | |||||
| </div> | |||||
| <% end %> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| @@ -0,0 +1,46 @@ | |||||
| <table class="table table-hover text-center subject-list-table"> | |||||
| <thead class="thead-light"> | |||||
| <tr> | |||||
| <th width="5%">序号</th> | |||||
| <th width="10%">用户名</th> | |||||
| <th width="20%">用户邮箱</th> | |||||
| <th width="20%"><%= sort_tag('创建时间', name: 'created_at', path: admins_feedbacks_path) %></th> | |||||
| <th width="25%">反馈意见</th> | |||||
| <th width="15%">操作</th> | |||||
| </tr> | |||||
| </thead> | |||||
| <tbody> | |||||
| <% if feedbacks.present? %> | |||||
| <% feedbacks.each_with_index do |feedback, index| %> | |||||
| <tr class="feedback-item-<%= feedback.id %>"> | |||||
| <td><%= list_index_no((params[:page] || 1).to_i, index) %></td> | |||||
| <td><%= feedback&.user&.login%></td> | |||||
| <td><%= feedback&.user&.mail%></td> | |||||
| <td><%= feedback.created_at&.strftime('%Y-%m-%d %H:%M') %></td> | |||||
| <td> | |||||
| <span class="d-inline-block" tabindex="0" data-toggle="tooltip" data-placement="left" title="<%= feedback.content%>"> | |||||
| <a href="javascript:"> | |||||
| <%= feedback.content.truncate(20) %> | |||||
| </a> | |||||
| </span> | |||||
| </td> | |||||
| <td class="action-container"> | |||||
| <%= link_to "发送邮件", new_history_admins_feedback_path(feedback), remote: true, class: "action" %> | |||||
| <%#= link_to "删除", admins_feedback_path(feedback), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %> | |||||
| </td> | |||||
| </tr> | |||||
| <% end %> | |||||
| <% else %> | |||||
| <%= render 'admins/shared/no_data_for_table' %> | |||||
| <% end %> | |||||
| </tbody> | |||||
| </table> | |||||
| <%= render partial: 'admins/shared/paginate', locals: { objects: feedbacks } %> | |||||
| <style> | |||||
| .tooltip-inner { | |||||
| max-width: 800px; | |||||
| /* width: inherit; will take up least amount of space */ | |||||
| } | |||||
| </style> | |||||
| @@ -0,0 +1,9 @@ | |||||
| <% define_admin_breadcrumbs do %> | |||||
| <% add_admin_breadcrumb('反馈意见') %> | |||||
| <% end %> | |||||
| <div class="box admin-list-container feedback-list-container" style="min-height: 400px"> | |||||
| <%= render partial: 'admins/feedbacks/list', locals: { feedbacks: @feedbacks } %> | |||||
| </div> | |||||
| <div id="feedback-modals"> | |||||
| </div> | |||||
| @@ -0,0 +1 @@ | |||||
| $('.feedback-list-container').html("<%= j( render partial: 'admins/feedbacks/list', locals: { feedbacks: @feedbacks } ) %>"); | |||||
| @@ -0,0 +1,3 @@ | |||||
| $("#feedback-modals").html("<%= j render(partial: 'admins/feedbacks/history_form_modal', locals: {type: 'new_history'}) %>") | |||||
| $(".feedback-history-change-modal").modal('show'); | |||||
| createMDEditor('feedback-history-email-editor', {width: 750, height: 300, placeholder: '请输入邮件正文',watch: false, imageUpload: false }); | |||||
| @@ -56,6 +56,7 @@ | |||||
| <%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %> | <%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %> | ||||
| <li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li> | <li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li> | ||||
| <li><%= sidebar_item(admins_nps_path, 'NPS用户调研', icon: 'question-circle', controller: 'admins-nps') %></li> | <li><%= sidebar_item(admins_nps_path, 'NPS用户调研', icon: 'question-circle', controller: 'admins-nps') %></li> | ||||
| <li><%= sidebar_item(admins_feedbacks_path, '用户反馈', icon: 'question-circle', controller: 'admins-feedbacks') %></li> | |||||
| <% end %> | <% end %> | ||||
| </li> | </li> | ||||
| <li> | <li> | ||||
| @@ -4,6 +4,7 @@ json.user_admin_or_member @user_admin_or_member | |||||
| json.issue_tags do | json.issue_tags do | ||||
| json.array! @issue_tags.each.to_a do |tag| | json.array! @issue_tags.each.to_a do |tag| | ||||
| json.extract! tag, :id, :name, :description, :color, :issues_count, :project_id, :gid, :gitea_url | |||||
| json.extract! tag, :id, :name, :description, :color, :project_id, :gid, :gitea_url | |||||
| json.issues_count tag.issues_count - tag.issues.closed.size | |||||
| end | end | ||||
| end | end | ||||
| @@ -231,6 +231,8 @@ zh-CN: | |||||
| ignore: | ignore: | ||||
| name: 'git忽略文件名称' | name: 'git忽略文件名称' | ||||
| content: 'git忽略文件内容' | content: 'git忽略文件内容' | ||||
| feedback_message_history: | |||||
| title: '' | |||||
| close_pr: 合并请求 | close_pr: 合并请求 | ||||
| roles: | roles: | ||||
| Developer: 开发者 | Developer: 开发者 | ||||
| @@ -943,6 +943,10 @@ Rails.application.routes.draw do | |||||
| resources :nps do | resources :nps do | ||||
| post :switch_change, on: :collection | post :switch_change, on: :collection | ||||
| end | end | ||||
| resources :feedbacks, only: [:index, :destroy] do | |||||
| get :new_history, on: :member | |||||
| post :create_history, on: :member | |||||
| end | |||||
| resources :laboratories, only: [:index, :create, :destroy, :update] do | resources :laboratories, only: [:index, :create, :destroy, :update] do | ||||
| member do | member do | ||||
| get :shixuns_for_select | get :shixuns_for_select | ||||
| @@ -0,0 +1,12 @@ | |||||
| class CreateFeedbackMessageHistories < ActiveRecord::Migration[5.2] | |||||
| def change | |||||
| create_table :feedback_message_histories do |t| | |||||
| t.references :feedback | |||||
| t.references :user | |||||
| t.string :title | |||||
| t.text :content | |||||
| t.timestamps | |||||
| end | |||||
| end | |||||
| end | |||||