操作记录后台查询

This commit is contained in:
xxq250 2024-09-27 09:35:40 +08:00
parent 20543c6bc2
commit 47f8ce478c
7 changed files with 183 additions and 3 deletions

View File

@ -0,0 +1,14 @@
class Admins::UserActionsController < Admins::BaseController
before_action :require_admin
def index
@user_actions = UserAction.order(created_at: :desc)
@user_actions = @user_actions.where(action_type: params[:action_type]) if params[:action_type].present?
keyword = params[:keyword].to_s.strip.presence
if keyword
sql = 'login LIKE :keyword OR phone LIKE :keyword OR mail LIKE :keyword'
@user_actions = @user_actions.where(sql, keyword: "%#{keyword}%")
end
@user_actions = paginate @user_actions
end
end

View File

@ -10,6 +10,10 @@
# updated_at :datetime not null
# ip :string(255)
# data_bank :text(65535)
# login :string(255)
# phone :string(255)
# email :string(255)
# memo :text(65535)
#
# Indexes
#
@ -19,5 +23,51 @@
# index_user_actions_on_user_id (user_id)
#
class UserAction < ApplicationRecord
end
class UserAction < ApplicationRecord
before_create :add_user_info
serialize :data_bank, JSON
def action_name
case action_type
when "DestroyUser" then "删除用户"
when "DestroyProject" then "删除项目"
when "Login" then "登录"
when "Logout" then "退出登录"
else self.action_type
end
end
def action_data
case action_type
when "DestroyUser" then build_mode("User")
when "DestroyProject" then build_mode("Project")
else nil
end
end
def user
action_user = User.find_by(id: self.user_id)
if action_user.blank?
action_user = self.action_data
end
action_user
end
def build_mode(model_name)
model = model_name.constantize.new
model_name.constantize.column_names.each do |col|
model[col] = self.data_bank[col]
end
model
end
private
def add_user_info
if user.present?
self.login = user.login
self.email = user.mail
self.phone = user.phone
end
end
end

View File

@ -0,0 +1,44 @@
<table class="table table-hover users-list-table">
<thead class="thead-light">
<tr>
<th width="5%" class="text-center">序号</th>
<th width="10%">操作类型</th>
<th width="10%" class="text-left">账号</th>
<th width="15%" class="text-left">邮箱</th>
<th width="10%" class="text-left">手机号</th>
<th width="10%" class="text-left">姓名</th>
<th width="15%">操作时间</th>
<th width="35%">原因/备注</th>
</tr>
</thead>
<tbody>
<% if user_actions.present? %>
<% user_actions.each_with_index do |action, index| %>
<tr class="user-item-<%= action.user.id %>">
<td class="text-center"><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td><%= action.action_name %></td>
<td>
<%= link_to "/#{action.user&.login}", target: '_blank' do %>
<%= overflow_hidden_span action.user&.login, width: 100 %>
<% end %>
</td>
<td class="text-left">
<%= overflow_hidden_span action.user&.mail, width: 150 %>
</td>
<td><%= action.user&.phone %></td>
<td class="text-left">
<%= link_to "/#{action.user&.login}", target: '_blank' do %>
<%= overflow_hidden_span action.user&.real_name, width: 100 %>
<% end %>
</td>
<td><%= display_text(action.created_at&.strftime('%Y-%m-%d %H:%M')) %></td>
<td><%= action.memo %></td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: user_actions } %>

View File

@ -0,0 +1,50 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('操作记录', admins_user_actions_path) %>
<% end %>
<div class="box search-form-container user-list-form">
<%= form_tag(admins_user_actions_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
操作类型:
<% action_type_options = [['自定义',''],['删除用户','DestroyUser'], ['删除项目', 'DestroyProject']] %>
<%= select_tag(:action_type_select, options_for_select(action_type_options), class: 'form-control') %>
<%= text_field_tag(:action_type, params[:action_type], class: 'form-control col-sm-2 ml-3',style: 'display:none;', placeholder: '自定义操作类型检索') %>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '用户名/邮箱/手机号检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %>
</div>
<!--<div class="box py-0 pt-4 pl-4 daily-school-statistic-title" >-->
<!-- <p style="font-weight: bold">数据统计:</p>-->
<!-- <p>-->
<!-- 评分用户数/用户总数:<span class="text-danger"><%#= @score_total_count %>/<%#= UserNp.count %></span>-->
<!-- 平均评分:<span class="text-danger"><%#= UserNp.where("action_type !='close'").average(:score).to_f.round(1) %></span>-->
<%# @user_nps_mid = @score_total_count % 2 == 0 ? @score_total_count / 2 : (@score_total_count + 1) / 2 %>
<!-- 评分中位数:<span class="text-danger"><%#= UserNp.where("action_type !='close'").order("score").pluck(:score)[@user_nps_mid - 1].to_i %></span>-->
<!-- 最低评分/评分人数:<span class="text-danger"><%#=@min_score.to_i %>/<%#= UserNp.where("action_type !='close'").where(score: @min_score).count %></span>-->
<!-- 最高评分/评分人数:<span class="text-danger"><%#=@max_score.to_i %>/<%#= UserNp.where("action_type !='close'").where(score: @max_score).count %></span>-->
<!-- </p>-->
<!-- <p style="padding-bottom: 10px !important;">-->
<!-- 填写意见用户数/用户总数:<span class="text-danger"><%#= UserNp.where("LENGTH(memo) >0").count %>/<%#= UserNp.count %></span>-->
<!-- 期待更加丰富的功能:<span class="text-danger"><%#= UserNp.where("memo like '%期待更加丰富的功能%'").count %></span>-->
<!-- 希望有新手引导:<span class="text-danger"><%#= UserNp.where("memo like '%希望有新手引导%'").count %></span>-->
<!-- 提升用户体验:<span class="text-danger"><%#= UserNp.where("memo like '%用户体验需进一步提升%'").count %></span>-->
<!-- 其他:<span class="text-danger"><%#= UserNp.where("action_type !='close'").where("LENGTH(memo) >0").where.not(id: UserNp.where("memo like '%期待更加丰富的功能%' or memo like '%希望有新手引导%' or memo like '%用户体验需进一步提升%' ").ids).count %></span>-->
<!-- </p>-->
<!--</div>-->
<div class="box admin-list-container users-list-container">
<%= render partial: 'admins/user_actions/user_action_list', locals: { user_actions: @user_actions } %>
</div>
<script>
$(function () {
$('#action_type_select').change(function () {
var switch_value = $(this).val();
$('#action_type').val(switch_value);
if (switch_value == ''){
$('#action_type').show();
}else{
$('#action_type').hide();
}
})
})
</script>

View File

@ -0,0 +1 @@
$('.users-list-container').html("<%= j( render partial: 'admins/user_actions/user_action_list', locals: { user_actions: @user_actions } ) %>");

View File

@ -92,7 +92,7 @@ Rails.application.routes.draw do
resources :project_rank, only: [:index]
resources :user_rank, only: [:index]
resources :nps, only: [:create]
resources :statistic, only: [:index] do
collection do
get :platform_profile
@ -1025,6 +1025,7 @@ Rails.application.routes.draw do
post :drag, on: :collection
post :replace_image_url, on: :member
end
resources :user_actions , only:[:index]
resources :faqs
resources :nps do
post :switch_change, on: :collection

View File

@ -0,0 +1,20 @@
class AddUserInfoToUserActions < ActiveRecord::Migration[5.2]
def change
add_column :user_actions, :login, :string
add_column :user_actions, :phone, :string
add_column :user_actions, :email, :string
add_column :user_actions, :memo, :text
UserAction.find_in_batches(batch_size: 1000) do |sw|
Parallel.each(sw, in_threads: 5) do |user_action|
next if user_action.user_id.blank?
user = User.find_by(id: user_action.user_id)
next if user.blank?
user_action.login = user.login
user_action.email = user.mail
user_action.phone = user.phone
user_action.save
end
end
end
end