题库回复问题

video_log
daiao 5 years ago
parent ba6658bbfc
commit 6f20dc501f

@ -0,0 +1,122 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-user-schools-statistics-index-page').length > 0) {
var $form = $('.user-schools-statistic-list-form');
// ************** 学校选择 *************
var matcherFunc = function(params, data){
if ($.trim(params.term) === '') {
return data;
}
if (typeof data.text === 'undefined') {
return null;
}
if (data.name && data.name.indexOf(params.term) > -1) {
var modifiedData = $.extend({}, data, true);
return modifiedData;
}
// Return `null` if the term should not be displayed
return null;
}
// ************* 省份选择 *****************
var matcherProvinceFunc = function(params, data){
if ($.trim(params.term) === '') {
return data;
}
if (typeof data.text === 'undefined') {
return null;
}
if (data.province && data.province.indexOf(params.term) > -1) {
var modifiedData = $.extend({}, data, true);
return modifiedData;
}
// Return `null` if the term should not be displayed
return null;
}
var defineSchoolSelect = function (schools) {
$form.find('.school-select').select2({
theme: 'bootstrap4',
placeholder: '选择学校/单位',
minimumInputLength: 1,
data: schools,
templateResult: function (item) {
if(!item.id || item.id === '') return item.text;
return item.name;
},
templateSelection: function(item){
if (item.id) {
$form.find('#school_id').val(item.id);
}
return item.name || item.text;
},
matcher: matcherFunc
});
};
var defineProvinceSelect = function (province) {
$form.find('.province-select').select2({
theme: 'bootstrap4',
placeholder: '选择省份',
minimumInputLength: 1,
data: province,
templateResult: function (item) {
if(!item.province || item.province === '') return item.text;
return item.province;
},
templateSelection: function(item){
if (item.province) {
$form.find('#province').val(item.province);
}
return item.province || item.text;
},
matcher: matcherProvinceFunc
});
};
// 初始化学校选择器
$.ajax({
url: '/api/schools/for_option.json',
dataType: 'json',
type: 'GET',
success: function(data) {
defineSchoolSelect(data.schools);
}
});
// 初始化身份选择器
$.ajax({
url: '/api/schools/for_province_option.json',
dataType: 'json',
type: 'GET',
success: function (data) {
console.log(data.province);
defineProvinceSelect(data.province);
}
});
// 清空
$form.on('click', '.clear-btn', function(){
$form.find('select[name="date"]').val('');
$form.find('.school-select').val('').trigger('change');
$form.find('.province-select').val('').trigger('change');
$form.find('input[type="submit"]').trigger('click');
})
// 导出
$('.export-action').on('click', function(){
var form = $(".user-schools-statistic-list-form .search-form")
var exportLink = $(this);
var date = form.find("select[name='date']").val();
var schoolId = form.find('input[name="school_id"]').val();
var url = exportLink.data("url").split('?')[0] + "?date=" + date + "&school_id=" + schoolId;
window.open(url);
});
}
});

@ -6,12 +6,14 @@ class Admins::DashboardsController < Admins::BaseController
@new_user_count = User.where(created_on: current_month).count
shixun_tomcat = edu_setting('cloud_bridge')
uri = "#{shixun_tomcat}/bridge/monitor/getPodsInfo"
res = interface_get uri, 502, "数据接口延迟"
if res['code'] == 0
@pod_num = res['sum'] || 0
unless Rails.env.development?
shixun_tomcat = edu_setting('cloud_bridge')
uri = "#{shixun_tomcat}/bridge/monitor/getPodsInfo"
res = interface_get uri, 502, "数据接口延迟"
if res['code'] == 0
@pod_num = res['sum'] || 0
end
end
end

@ -0,0 +1,18 @@
class Admins::UserSchoolsStatisticsController < Admins::BaseController
def export
params[:per_page] = 10000
_count, @users = Admins::UserSchoolsStatisticQuery.call(params)
filename = ['用户运营情况', Time.zone.now.strftime('%Y%m%d%H%M%S')].join('-') << '.xlsx'
render xlsx: 'export', filename: filename
end
def index
default_sort('finish_challenge_count', 'desc')
total_count, schools = Admins::UserSchoolsStatisticQuery.call(params)
@schools = paginate schools, total_count: total_count
end
end

@ -321,7 +321,7 @@ class ApplicationController < ActionController::Base
end
if !User.current.logged? && Rails.env.development?
User.current = User.find 3117
User.current = User.find 1
end

@ -46,7 +46,7 @@ class DiscussesController < ApplicationController
end
sql = "select d.id from discusses d join shixuns s on d.dis_id = s.id where s.status = 2 and s.hidden = false and d.root_id is null
and d.hidden = false #{sql1} #{sql2} order by d.created_at desc"
and d.hidden = false and d.dis_type = 'Shixun' #{sql1} #{sql2} order by d.created_at desc"
memo_ids = Discuss.find_by_sql(sql).pluck(:id)
@memo_count = memo_ids.size

@ -418,8 +418,8 @@ class ShixunsController < ApplicationController
logger.info("#########service_update_params: #{service_update_params}")
begin
ActiveRecord::Base.transaction do
@shixun.update_attributes(shixun_params)
@shixun.shixun_info.update_attributes(shixun_info_params)
@shixun.update_attributes!(shixun_params)
@shixun.shixun_info.update_attributes!(shixun_info_params)
# 镜像变动
@shixun.shixun_mirror_repositories.where.not(mirror_repository_id: old_mirror_ids).destroy_all
@shixun.shixun_mirror_repositories.create!(new_mirror_id) if new_mirror_id.present?

@ -5,7 +5,7 @@ class ShixunInfo < ApplicationRecord
# validates_presence_of :evaluate_script, message: "实训脚本不能为空"
after_commit :create_diff_record
validates :description, length: { maximum: 5000, too_long: "不能超过5000个字符" }
validates :description, length: { maximum: 10000, too_long: "不能超过10000个字符" }
private

@ -0,0 +1,160 @@
class Admins::UserSchoolsStatisticQuery < ApplicationQuery
include CustomSortable
attr_reader :params
sort_columns :study_challenge_count, :finish_challenge_count, :study_shixun_count, :finish_shixun_count,
default_by: :finish_challenge_count, default_direction: :desc
def initialize(params)
@params = params
end
def call
schools = School.where(nil)
if params[:province]
schools = schools.where("province like ?", "%#{params[:province]}%")
end
if params[:school_id]
schools = schools.where(id: params[:school_id])
end
total = schools.count
# 根据排序字段进行查询
#schools = query_by_sort_column(schools, params[:sort_by])
#schools = custom_sort(schools, params[:sort_by], params[:sort_direction])
#
schools = schools.limit(page_size).offset(offset).to_a
# 查询并组装其它数据
schools = package_other_data(schools)
[total, schools]
end
private
def package_other_data(schools)
ids = schools.map(&:id)
user_e = UserExtension.where(school_id: schools.map(&:id))
#study_myshixun = Myshixun.joins("join user_extensions ue on ue.user_id = myshixuns.user_id").where(ue: {school_id: ids})
#finish_myshixun = Myshixun.joins("join user_extensions ue on ue.user_id = myshixuns.user_id")
# .where(ue: {school_id: ids}, myshixuns: {status: 1})
study_challenge = Game.joins("join user_extensions ue on ue.user_id = games.user_id")
.where(ue: {school_id: ids},).where( games:{status: [0, 1, 2]})
finish_challenge = Game.joins("join user_extensions ue on ue.user_id = games.user_id")
.where(ue: {school_id: ids}).where(games: {status: 2})
reg_teacher = user_e.where(identity: 'teacher')
reg_student = user_e.where.not(identity: 'teacher')
if time_range.present?
#study_myshixun = study_myshixun.where(updated_at: time_range)
#finish_myshixun = finish_myshixun.where(updated_at: time_range)
study_challenge = study_challenge.where(updated_at: time_range)
finish_challenge = finish_challenge.where(updated_at: time_range)
reg_teacher = reg_teacher.where(created_at: time_range)
reg_student = reg_student.where(created_at: time_range)
user_e = t.joins(:user).where(users: {last_login_on: time_range})
end
#study_myshixun_map = study_myshixun.reorder(nil).group(:school_id).count
#finish_myshixun_map = finish_myshixun.reorder(nil).group(:school_id).count
study_challenge_map = study_challenge.reorder(nil).group(:school_id).count
finish_challenge_map = finish_challenge.reorder(nil).group(:school_id).count
evaluate_count_map = study_challenge.reorder(nil).group(:school_id).sum(:evaluate_count)
reg_teacher_map = reg_teacher.reorder(nil).group(:school_id).count
reg_student_map = reg_student.reorder(nil).group(:school_id).count
user_e_map = user_e.reorder(nil).group(:school_id).count
schools.each do |school|
school._extra_data = {
#study_shixun_count: study_myshixun_map.fetch(schools.id, 0),
#finish_shixun_count: finish_myshixun_map.fetch(schools.id, 0),
study_challenge_count: study_challenge_map.fetch(school.id, 0),
finish_challenge_count: finish_challenge_map.fetch(school.id, 0),
evaluate_count: evaluate_count_map.fetch(school.id, 0),
reg_teacher_count: reg_teacher_map.fetch(school.id, 0),
reg_student_count: reg_student_map.fetch(school.id, 0),
user_active_count: user_e_map.fetch(school.id, 0)
}
end
schools
end
def query_by_sort_column(users, sort_by_column)
base_query_column = 'users.*'
case sort_by_column.to_s
when 'study_shixun_count' then
users =
if time_range.present?
users.joins("LEFT JOIN myshixuns ON myshixuns.user_id = users.id "\
"AND myshixuns.updated_at BETWEEN '#{time_range.min}' AND '#{time_range.max}'")
else
users.left_joins(:myshixuns)
end
users.select("#{base_query_column}, COUNT(*) study_shixun_count")
when 'finish_shixun_count' then
users =
if time_range.present?
users.joins("LEFT JOIN myshixuns ON myshixuns.user_id = users.id AND myshixuns.status = 1 AND "\
"myshixuns.updated_at BETWEEN '#{time_range.min}' AND '#{time_range.max}'")
else
users.joins('LEFT JOIN myshixuns ON myshixuns.user_id = users.id AND myshixuns.status = 1')
end
users.select("#{base_query_column}, COUNT(*) finish_shixun_count")
when 'study_challenge_count' then
users =
if time_range.present?
users.joins('LEFT JOIN myshixuns ON myshixuns.user_id = users.id')
.joins("LEFT JOIN games ON games.myshixun_id = myshixuns.id "\
"AND games.status IN (0,1,2) AND games.updated_at BETWEEN '#{time_range.min}' AND '#{time_range.max}'")
else
users.joins('LEFT JOIN myshixuns ON myshixuns.user_id = users.id')
.joins("LEFT JOIN games ON games.myshixun_id = myshixuns.id AND games.status IN (0,1,2)")
end
users.select("#{base_query_column}, COUNT(*) study_challenge_count")
when 'finish_challenge_count' then
users =
if time_range.present?
users#.joins('LEFT JOIN myshixuns ON myshixuns.user_id = users.id')
.joins("LEFT JOIN games ON games.user_id = users.id "\
"AND games.status = 2 AND games.updated_at BETWEEN '#{time_range.min}' AND '#{time_range.max}'")
else
users#.joins('LEFT JOIN myshixuns ON myshixuns.user_id = users.id')
.joins("LEFT JOIN games ON games.user_id = users.id AND games.status = 2")
end
users.select("#{base_query_column}, COUNT(*) finish_challenge_count")
else
users
end
end
def time_range
@_time_range ||= begin
case params[:date]
when 'dayly' then 1.days.ago..Time.now
when 'weekly' then 1.weeks.ago..Time.now
when 'monthly' then 1.months.ago..Time.now
when 'quarterly' then 3.months.ago..Time.now
when 'yearly' then 1.years.ago..Time.now
else ''
end
end
end
def page_size
params[:per_page].to_i.zero? ? 20 : params[:per_page].to_i
end
def offset
(params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * page_size
end
end

@ -62,6 +62,7 @@
<%= sidebar_item_group('#user-submenu', '用户', icon: 'user') do %>
<li><%= sidebar_item(admins_users_path, '用户列表', icon: 'user', controller: 'admins-users') %></li>
<li><%= sidebar_item(admins_user_statistics_path, '用户实训情况', icon: 'area-chart', controller: 'admins-user_statistics') %></li>
<li><%= sidebar_item(admins_user_schools_statistics_path, '用户运营统计', icon: 'user-md', controller: 'admins-user_schools_statistics') %></li>
<% end %>
</li>

@ -0,0 +1,34 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('用户运营情况') %>
<% end %>
<div class="box search-form-container user-schools-statistic-list-form">
<%= form_tag(admins_user_schools_statistics_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<div class="form-group col-12 col-md-auto">
<label for="status">时间范围:</label>
<% data_arrs = [['不限', ''],['最近一天', 'dayly'], ['最近一周', 'weekly'], ['最近一个月', 'monthly'],
['最近三个月', 'quarterly'], ['最近一年', 'yearly']] %>
<%= select_tag(:date, options_for_select(data_arrs, params[:date]), class: 'form-control') %>
</div>
<div class="form-group col-12 col-md-3">
<label for="province">所属省份:</label>
<%= hidden_field_tag(:province, params[:province]) %>
<%= select_tag :province, options_for_select([''], params[:province]), class: 'form-control province-select flex-1' %>
</div>
<div class="form-group col-12 col-md-3">
<label for="school_name">所属单位:</label>
<%= hidden_field_tag(:school_id, params[:school_id]) %>
<%= select_tag :school_name, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %>
</div>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
<%= javascript_void_link '导出', class: 'btn btn-outline-primary export-action', 'data-url': export_admins_user_schools_statistics_path(format: :xlsx) %>
</div>
<div class="box admin-list-container user-schools-statistic-list-container">
<%= render partial: 'admins/user_schools_statistics/shared/list', locals: { schools: @schools } %>
</div>

@ -0,0 +1 @@
$('.user-schools-statistic-list-container').html("<%= j( render partial: 'admins/user_schools_statistics/shared/list', locals: { schools: @schools } ) %>");

@ -0,0 +1,38 @@
<table class="table table-hover text-center user-statistic-list-table">
<thead class="thead-light">
<tr>
<th width="6%">序号</th>
<th width="22%" class="text-left">单位名称</th>
<th width="8%" class="text-left">省份</th>
<th width="10%">注册老师数量<%#= sort_tag('学习关卡数', name: 'study_challenge_count', path: admins_user_statistics_path) %></th>
<th width="10%">注册学生数量<%#= sort_tag('完成关卡数', name: 'finish_challenge_count', path: admins_user_statistics_path) %></th>
<th width="10%">活跃用户<%#= sort_tag('活跃用户', name: 'user_active_count', path: admins_user_schools_statistics_path) %></th>
<th width="10%">学习关卡数<%#= sort_tag('学习关卡数', name: 'finish_shixun_count', path: admins_user_schools_statistics_path) %></th>
<th width="10%">完成关卡数</th>
<th width="14%">评测次数</th>
</tr>
</thead>
<tbody>
<% if schools.present? %>
<% schools.each_with_index do |school, index| %>
<tr class="user-statistic-item-<%= school.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left">
<%= school.name %>
</td>
<td class="text-left"><%= school.province %></td>
<td><%= school.display_extra_data(:reg_teacher_count) %></td>
<td><%= school.display_extra_data(:reg_student_count) %></td>
<td><%= school.display_extra_data(:user_active_count) %></td>
<td><%= school.display_extra_data(:study_challenge_count) %></td>
<td><%= school.display_extra_data(:finish_challenge_count) %></td>
<td><%= school.display_extra_data(:evaluate_count) %></td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: schools } %>

@ -870,6 +870,7 @@ Rails.application.routes.draw do
collection do
get :school_list
get :for_option
get :for_province_option
get :search
end
@ -1163,6 +1164,9 @@ Rails.application.routes.draw do
resources :user_statistics, only: [:index] do
get :export, on: :collection
end
resources :user_schools_statistics, only: [:index] do
get :export, on: :collection
end
resources :library_applies, only: [:index] do
member do
post :agree

Loading…
Cancel
Save