diff --git a/app/controllers/admins/feedbacks_controller.rb b/app/controllers/admins/feedbacks_controller.rb new file mode 100644 index 000000000..ff64ae5a1 --- /dev/null +++ b/app/controllers/admins/feedbacks_controller.rb @@ -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 \ No newline at end of file diff --git a/app/controllers/api/v1/users/feedbacks_controller.rb b/app/controllers/api/v1/users/feedbacks_controller.rb new file mode 100644 index 000000000..4e79de7bd --- /dev/null +++ b/app/controllers/api/v1/users/feedbacks_controller.rb @@ -0,0 +1,16 @@ +class Api::V1::Users::FeedbacksController < Api::V1::BaseController + + before_action :load_observe_user + before_action :check_auth_for_observe_user + + def create + @result = Api::V1::Users::Feedbacks::CreateService.call(@observe_user, feedback_params) + return render_error("反馈意见创建失败.") if @result.nil? + return render_ok + end + + private + def feedback_params + params.permit(:content) + end +end \ No newline at end of file diff --git a/app/controllers/issue_tags_controller.rb b/app/controllers/issue_tags_controller.rb index 011735ff7..da9f16f71 100644 --- a/app/controllers/issue_tags_controller.rb +++ b/app/controllers/issue_tags_controller.rb @@ -7,7 +7,7 @@ class IssueTagsController < ApplicationController 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)) @page = params[:page] || 1 @limit = params[:limit] || 15 diff --git a/app/controllers/pull_requests_controller.rb b/app/controllers/pull_requests_controller.rb index e81b68807..2b9bbbe6f 100644 --- a/app/controllers/pull_requests_controller.rb +++ b/app/controllers/pull_requests_controller.rb @@ -100,20 +100,6 @@ class PullRequestsController < ApplicationController Issues::UpdateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate! 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]) @pull_request.reviewers = reviewers @@ -165,6 +151,8 @@ class PullRequestsController < ApplicationController colsed = PullRequests::CloseService.call(@owner, @repository, @pull_request, current_user) if colsed === true @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? normal_status(1, "已拒绝") else @@ -210,6 +198,8 @@ class PullRequestsController < ApplicationController # @pull_request.project_trend_status! @pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::MERGE) @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? normal_status(1, "合并成功") else diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index c70f053f6..33fd93f83 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -57,6 +57,13 @@ class UsersController < ApplicationController Cache::V2::OwnerCommonService.new(@user.id).read end + def action + if params[:action_id].present? && params[:action_type].present? + UserAction.create(:action_id => params[:action_id], :action_type => "#{params[:action_type]}", :user_id => User.current.id, :ip => request.remote_ip) + end + render_ok + end + def watch_users watchers = Watcher.watching_users(@user.id).includes(:user).order("watchers.created_at desc") if params[:search].present? diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 19f565183..13cf2ac54 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -13,4 +13,8 @@ class UserMailer < ApplicationMailer @code = code mail(to: mail, subject: 'Gitink | 更改邮箱验证码') end + + def feedback_email(mail, title, content) + mail(to: mail, subject: title, content_type: "text/html", body: content) + end end diff --git a/app/models/feedback.rb b/app/models/feedback.rb new file mode 100644 index 000000000..2528d4022 --- /dev/null +++ b/app/models/feedback.rb @@ -0,0 +1,21 @@ +# == Schema Information +# +# Table name: feedbacks +# +# id :integer not null, primary key +# user_id :integer +# content :text(65535) +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_feedbacks_on_user_id (user_id) +# + +class Feedback < ApplicationRecord + + belongs_to :user + has_many :feedback_message_histories, dependent: :destroy + +end diff --git a/app/models/feedback_message_history.rb b/app/models/feedback_message_history.rb new file mode 100644 index 000000000..90ae185e0 --- /dev/null +++ b/app/models/feedback_message_history.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 5ed2550b8..b8b6b0066 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -177,6 +177,7 @@ class User < Owner has_one :trace_user, dependent: :destroy has_many :user_trace_tasks, dependent: :destroy + has_many :feedbacks, dependent: :destroy # Groups and active users scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) } scope :like, lambda { |keywords| diff --git a/app/services/api/v1/users/feedbacks/create_service.rb b/app/services/api/v1/users/feedbacks/create_service.rb new file mode 100644 index 000000000..2db4baac2 --- /dev/null +++ b/app/services/api/v1/users/feedbacks/create_service.rb @@ -0,0 +1,26 @@ +class Api::V1::Users::Feedbacks::CreateService < ApplicationService + include ActiveModel::Model + + attr_reader :user, :content + attr_accessor :feedback + + validates :content, presence: true + + def initialize(user, params) + @user = user + @content = params[:content] + end + + def call + raise Error, errors.full_messages.join(",") unless valid? + + begin + @feedback = Feedback.new(user: user, content: content) + @feedback.save! + + return @feedback.valid? ? @feedback : nil + rescue + raise Error, "服务器错误,请联系系统管理员!" + end + end +end \ No newline at end of file diff --git a/app/views/admins/feedbacks/_history_form_modal.html.erb b/app/views/admins/feedbacks/_history_form_modal.html.erb new file mode 100644 index 000000000..df12a73d3 --- /dev/null +++ b/app/views/admins/feedbacks/_history_form_modal.html.erb @@ -0,0 +1,39 @@ + \ No newline at end of file diff --git a/app/views/admins/feedbacks/_list.html.erb b/app/views/admins/feedbacks/_list.html.erb new file mode 100644 index 000000000..1b7b045ed --- /dev/null +++ b/app/views/admins/feedbacks/_list.html.erb @@ -0,0 +1,46 @@ + + + + + + + + + + + + + <% if feedbacks.present? %> + <% feedbacks.each_with_index do |feedback, index| %> + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
序号用户名用户邮箱<%= sort_tag('创建时间', name: 'created_at', path: admins_feedbacks_path) %>反馈意见操作
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: feedbacks } %> + + \ No newline at end of file diff --git a/app/views/admins/feedbacks/index.html.erb b/app/views/admins/feedbacks/index.html.erb new file mode 100644 index 000000000..391c83ca6 --- /dev/null +++ b/app/views/admins/feedbacks/index.html.erb @@ -0,0 +1,9 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('反馈意见') %> +<% end %> + +
+ <%= render partial: 'admins/feedbacks/list', locals: { feedbacks: @feedbacks } %> +
+
+
diff --git a/app/views/admins/feedbacks/index.js.erb b/app/views/admins/feedbacks/index.js.erb new file mode 100644 index 000000000..daaa24cc7 --- /dev/null +++ b/app/views/admins/feedbacks/index.js.erb @@ -0,0 +1 @@ +$('.feedback-list-container').html("<%= j( render partial: 'admins/feedbacks/list', locals: { feedbacks: @feedbacks } ) %>"); \ No newline at end of file diff --git a/app/views/admins/feedbacks/new_history.js.erb b/app/views/admins/feedbacks/new_history.js.erb new file mode 100644 index 000000000..c795b0f5b --- /dev/null +++ b/app/views/admins/feedbacks/new_history.js.erb @@ -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 }); diff --git a/app/views/admins/projects/shared/_list.html.erb b/app/views/admins/projects/shared/_list.html.erb index 720b08dac..eb0e61255 100644 --- a/app/views/admins/projects/shared/_list.html.erb +++ b/app/views/admins/projects/shared/_list.html.erb @@ -5,7 +5,6 @@ ID 项目名称 公开 - 精选 推荐 Issues 资源 @@ -27,7 +26,6 @@ <%= link_to(project.name, "/#{project&.owner&.login}/#{project.identifier}", target: '_blank') %> <%= project.is_public ? '√' : '' %> - <%= project.is_pinned ? '√' : '' %> <%= project.recommend ? '√' : '' %> <%= project.issues.size %> <%= project.attachments.size %> @@ -40,8 +38,6 @@ <%= project.created_on&.strftime('%Y-%m-%d %H:%M') %> <% if project.is_public %> - <%= javascript_void_link '精选', class: 'action pinned-action', data: { id: project.id }, style: project.is_pinned ? 'display: none;' : '' %> - <%= javascript_void_link '取消精选', class: 'action unpinned-action', data: { id: project.id }, style: project.is_pinned ? '' : 'display: none;' %> <%= javascript_void_link '推荐', class: 'action recommend-action', data: { id: project.id }, style: project.recommend ? 'display: none;' : '' %> <%= javascript_void_link '取消推荐', class: 'action unrecommend-action', data: { id: project.id }, style: project.recommend ? '' : 'display: none;' %> <%= link_to "设置推荐等级", edit_admins_project_path(project.id), remote: true, class: "action edit-recommend-action", style: project.recommend ? '' : 'display: none;' %> diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index 9a87980b0..afd0dad68 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -56,6 +56,7 @@ <%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %>
  • <%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %>
  • <%= sidebar_item(admins_nps_path, 'NPS用户调研', icon: 'question-circle', controller: 'admins-nps') %>
  • +
  • <%= sidebar_item(admins_feedbacks_path, '用户反馈', icon: 'question-circle', controller: 'admins-feedbacks') %>
  • <% end %>
  • diff --git a/app/views/issue_tags/index.json.jbuilder b/app/views/issue_tags/index.json.jbuilder index 7f20a4374..37bd51608 100644 --- a/app/views/issue_tags/index.json.jbuilder +++ b/app/views/issue_tags/index.json.jbuilder @@ -4,6 +4,7 @@ json.user_admin_or_member @user_admin_or_member json.issue_tags do 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 \ No newline at end of file diff --git a/config/locales/forms/api_v1_service.zh-CN.yml b/config/locales/forms/api_v1_service.zh-CN.yml new file mode 100644 index 000000000..268cdc5c4 --- /dev/null +++ b/config/locales/forms/api_v1_service.zh-CN.yml @@ -0,0 +1,5 @@ +'zh-CN': + activemodel: + attributes: + api/v1/users/feedbacks/create_service: + content: "反馈意见" \ No newline at end of file diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 623a4d1c9..e7c586417 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -231,6 +231,8 @@ zh-CN: ignore: name: 'git忽略文件名称' content: 'git忽略文件内容' + feedback_message_history: + title: '' close_pr: 合并请求 roles: Developer: 开发者 diff --git a/config/routes.rb b/config/routes.rb index 1185abd86..f47bd5aba 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -267,6 +267,7 @@ Rails.application.routes.draw do get :trustie_related_projects post :sync_user_info get :email_search + post :action scope '/ci', module: :ci do scope do @@ -942,6 +943,10 @@ Rails.application.routes.draw do resources :nps do post :switch_change, on: :collection 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 member do get :shixuns_for_select diff --git a/config/routes/api.rb b/config/routes/api.rb index ab098b1dc..1c55d59d9 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -13,6 +13,7 @@ defaults format: :json do end scope module: :users do resources :projects, only: [:index] + resources :feedbacks, only: [:create] end scope ':repo' do diff --git a/db/migrate/20221108024322_create_feedbacks.rb b/db/migrate/20221108024322_create_feedbacks.rb new file mode 100644 index 000000000..316df6b05 --- /dev/null +++ b/db/migrate/20221108024322_create_feedbacks.rb @@ -0,0 +1,10 @@ +class CreateFeedbacks < ActiveRecord::Migration[5.2] + def change + create_table :feedbacks do |t| + t.references :user + t.text :content + + t.timestamps + end + end +end diff --git a/db/migrate/20221108100538_create_feedback_message_histories.rb b/db/migrate/20221108100538_create_feedback_message_histories.rb new file mode 100644 index 000000000..cd5f236df --- /dev/null +++ b/db/migrate/20221108100538_create_feedback_message_histories.rb @@ -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