parent
84d4d70ad9
commit
bb2f4cf438
@ -1,28 +0,0 @@
|
||||
$(document).on('turbolinks:load', function() {
|
||||
if ($('body.partners-customers-page').length > 0) {
|
||||
var $customerContainer = $('.customer-list-container');
|
||||
var partnerId = $customerContainer.find('.customer-list-body').data('id');
|
||||
|
||||
$customerContainer.on('change', '.manager-group-select', function(){
|
||||
console.log('manager-group-select change', $(this).val());
|
||||
var $select = $(this);
|
||||
var customerId = $select.data('id');
|
||||
var managerGroupId = $select.val();
|
||||
|
||||
$.ajax({
|
||||
url: '/partners/' + partnerId + '/customer_manager_group.json',
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
data: { customer_id: customerId, manager_group_id: managerGroupId },
|
||||
success: function(){
|
||||
showSuccessFlash();
|
||||
$select.data('last', managerGroupId);
|
||||
},
|
||||
error: function(res){
|
||||
showErrorNotify(res.responseJSON.message);
|
||||
$select.val($select.data('last'));
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
@ -1,125 +0,0 @@
|
||||
$(document).on('turbolinks:load', function() {
|
||||
if ($('body.partners-partner-manager-groups-page').length > 0) {
|
||||
var $container = $('.manager-group-list-container');
|
||||
var partnerId = $container.find('.manager-group-list-body').data('id');
|
||||
|
||||
// ------- 新建编辑权限组弹窗 --------
|
||||
var $managerGroupModal = $('.modal.partner-save-manager-group-modal');
|
||||
var $managerGroupForm = $managerGroupModal.find('form.partner-save-manager-group-form');
|
||||
var $managerGroupIdInput = $managerGroupForm.find('input[name="manager_group_id"]');
|
||||
var $managerGroupNameInput = $managerGroupForm.find('input[name="manager_group_name"]');
|
||||
|
||||
$managerGroupForm.validate({
|
||||
errorElement: 'span',
|
||||
errorClass: 'danger text-danger',
|
||||
rules: {
|
||||
manager_group_name: {
|
||||
required: true,
|
||||
maxlength: 20
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
$managerGroupModal.on('show.bs.modal', function(event){
|
||||
var $link = $(event.relatedTarget);
|
||||
var managerGroupId = $link.data('id');
|
||||
var managerGroupName = $link.data('name');
|
||||
|
||||
if(managerGroupId && managerGroupId !== ''){
|
||||
$managerGroupModal.find('.modal-title').html('重命名');
|
||||
$managerGroupIdInput.val(managerGroupId);
|
||||
$managerGroupNameInput.val(managerGroupName)
|
||||
} else {
|
||||
$managerGroupModal.find('.modal-title').html('新建');
|
||||
$managerGroupIdInput.val('');
|
||||
$managerGroupNameInput.val('');
|
||||
}
|
||||
});
|
||||
|
||||
$managerGroupModal.on('hide.bs.modal', function(){
|
||||
$managerGroupIdInput.val('');
|
||||
$managerGroupNameInput.val('');
|
||||
});
|
||||
|
||||
$managerGroupModal.on('click', '.submit-btn', function(){
|
||||
$managerGroupForm.find('.error').html('');
|
||||
var url = $managerGroupForm.data('url');
|
||||
|
||||
if ($managerGroupForm.valid()) {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
dataType: 'script',
|
||||
url: url,
|
||||
data: $managerGroupForm.serialize()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ---------- 添加管理员弹窗 ------------
|
||||
var $partnerManagerModal = $('.modal.partner-add-partner-manager-modal');
|
||||
var $partnerManagerForm = $partnerManagerModal.find('form.partner-add-partner-manager-form');
|
||||
var $managerGroupIdInput = $partnerManagerForm.find('input[name="manager_group_id"]');
|
||||
var $userSelect = $partnerManagerForm.find('.partner-manager-select');
|
||||
|
||||
$userSelect.select2({
|
||||
theme: 'bootstrap4',
|
||||
placeholder: '请输入要添加的管理员姓名',
|
||||
multiple: true,
|
||||
closeOnSelect: false,
|
||||
minimumInputLength: 1,
|
||||
ajax: {
|
||||
delay: 500,
|
||||
url: '/api/users_for_partners',
|
||||
dataType: 'json',
|
||||
data: function(params){
|
||||
return { name: params.term, partner_id: partnerId, page: params.page || 1, per_page: 20 };
|
||||
},
|
||||
processResults: function(data, params){
|
||||
params.page = params.page || 1;
|
||||
|
||||
return {
|
||||
results: data.users,
|
||||
pagination: {
|
||||
more: (params.page * 20) < data.count
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
templateResult: function (item) {
|
||||
if(!item.id || item.id === '') return item.text;
|
||||
return $("<span>" + item.real_name + " <span class='font-12'>" + item.school_name + ' ' + item.identity + "</span></span>");
|
||||
},
|
||||
templateSelection: function(item){
|
||||
if (item.id) {
|
||||
}
|
||||
return item.real_name || item.text;
|
||||
}
|
||||
});
|
||||
|
||||
$partnerManagerModal.on('show.bs.modal', function(event){
|
||||
var $link = $(event.relatedTarget);
|
||||
var managerGroupId = $link.data('id');
|
||||
|
||||
$managerGroupIdInput.val(managerGroupId);
|
||||
$userSelect.select2('val', ' ');
|
||||
$partnerManagerModal.find('.error').html('');
|
||||
});
|
||||
|
||||
$partnerManagerModal.on('click', '.submit-btn', function(){
|
||||
$partnerManagerModal.find('.error').html('');
|
||||
var managerGroupId = $managerGroupIdInput.val();
|
||||
|
||||
var userIds = $userSelect.val();
|
||||
if (userIds && userIds.length > 0) {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
dataType: 'script',
|
||||
url: '/partners/' + partnerId + '/partner_managers',
|
||||
data: { user_ids: userIds, manager_group_id: managerGroupId }
|
||||
});
|
||||
} else {
|
||||
$partnerManagerModal.modal('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
@ -1,156 +0,0 @@
|
||||
$(document).on('turbolinks:load', function() {
|
||||
if($('body.colleges-statistics-page').length > 0) {
|
||||
var $statisticBody = $('.statistics-body');
|
||||
var $statisticBase = $('.statistic-base');
|
||||
var schoolId = $statisticBody.data('id');
|
||||
var $statisticCourse = $statisticBody.find('.statistic-course')
|
||||
var $shixunChart = $statisticBody.find('.shixun-chart');
|
||||
|
||||
$.get('/colleges/' + schoolId + '/shixun_time', function(data){
|
||||
$statisticBase.find('.shixun-time').html("<span>" + data.shixun_time + "</span>天");
|
||||
});
|
||||
$.get('/colleges/' + schoolId + '/shixun_report_count', function(data){
|
||||
$statisticBase.find('.shixun-report-count').html("<span>" + data.shixun_report_count + "</span>个");
|
||||
});
|
||||
|
||||
$.ajax({ url: '/colleges/' + schoolId + '/course_statistics', method: 'GET', dataType: 'script' });
|
||||
$.ajax({ url: '/colleges/' + schoolId + '/teachers', method: 'GET', dataType: 'script' });
|
||||
|
||||
var initShixunChart = function(names, data){
|
||||
var shixunChart = echarts.init(document.getElementById('shixun-chart'));
|
||||
var options = {
|
||||
series : [
|
||||
{
|
||||
name: '访问来源',
|
||||
type: 'pie',
|
||||
radius: '55%',
|
||||
data: data
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
shixunChart.setOption(options);
|
||||
};
|
||||
$.get('/colleges/' + schoolId + '/shixun_chart_data', function(data){
|
||||
$statisticBody.find('.shixun-chart-loading').hide();
|
||||
if (data.data.length > 0) {
|
||||
$shixunChart.css('height', '400px').css('width', '100%');
|
||||
initShixunChart(data.names, data.data);
|
||||
} else {
|
||||
$statisticBody.find('.shixun-chart-empty').show();
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({ url: '/colleges/' + schoolId + '/student_shixun', method: 'GET', dataType: 'script' });
|
||||
|
||||
var initHotEvaluating = function(names, values){
|
||||
var Color = ['#962e66', '#623363', '#CCCCCC', '#9A9A9A', '#FF8080', '#FF80C2', '#B980FF', '#80B9FF', '#6FE9FF', '#4DE8B4', '#F8EF63', '#FFB967'];
|
||||
|
||||
var option = {
|
||||
backgroundColor: '#fff',
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '10%',
|
||||
containLabel: true
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
show: "true",
|
||||
trigger: 'item',
|
||||
formatter: '{c0}',
|
||||
backgroundColor: 'rgba(0,0,0,0.7)', // 背景
|
||||
padding: [8, 10], //内边距
|
||||
extraCssText: 'box-shadow: 0 0 3px rgba(255, 255, 255, 0.4);', //添加阴影
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#CCCCCC'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#CCCCCC'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#656565',
|
||||
fontWeight: 'normal',
|
||||
fontSize: '12'
|
||||
},
|
||||
formatter: '{value}'
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#cccccc'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitArea: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
inside: false,
|
||||
textStyle: {
|
||||
color: '#656565',
|
||||
fontWeight: 'normal',
|
||||
fontSize: '12'
|
||||
}
|
||||
},
|
||||
data: names
|
||||
},
|
||||
series: [{
|
||||
name: '',
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
normal: {
|
||||
show: true,
|
||||
color: function(params) {
|
||||
return Color[params.dataIndex]
|
||||
},
|
||||
barBorderRadius: 50,
|
||||
borderWidth: 0,
|
||||
borderColor: '#333'
|
||||
}
|
||||
},
|
||||
barGap: '0%',
|
||||
barCategoryGap: '50%',
|
||||
data: values
|
||||
}
|
||||
|
||||
]
|
||||
};
|
||||
var myChart = echarts.init(document.getElementById('hot-chart'));
|
||||
myChart.setOption(option);
|
||||
}
|
||||
|
||||
$.get('/colleges/' + schoolId + '/student_hot_evaluations', function(data){
|
||||
$statisticBody.find('.hot-chart-loading').hide();
|
||||
if (data.names.length > 0) {
|
||||
$statisticBody.find('.hot-chart').css('height', '400px').css('width', '100%');
|
||||
initHotEvaluating(data.names.reverse(), data.values.reverse());
|
||||
} else {
|
||||
$statisticBody.find('.hot-chart-empty').show();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
@ -1,131 +0,0 @@
|
||||
.college-body-container {
|
||||
padding: 20px;
|
||||
flex: 1;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: scroll;
|
||||
|
||||
& > .content {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
|
||||
.box {
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
/* 面包屑 */
|
||||
.breadcrumb {
|
||||
padding-left: 5px;
|
||||
font-size: 20px;
|
||||
background: unset;
|
||||
}
|
||||
|
||||
/* 内容表格 */
|
||||
table {
|
||||
table-layout: fixed;
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
tr {
|
||||
&.no-data {
|
||||
&:hover {
|
||||
color: darkgrey;
|
||||
background: unset;
|
||||
}
|
||||
|
||||
& > td {
|
||||
text-align: center;
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action-container {
|
||||
& > .action {
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
.more-action-dropdown {
|
||||
.dropdown-item {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 分页 */
|
||||
.paginate-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.paginate-total {
|
||||
margin-bottom: 10px;
|
||||
color: darkgrey;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 搜索表单 */
|
||||
.search-form-container {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.search-form {
|
||||
flex: 1;
|
||||
|
||||
* { font-size: 14px; }
|
||||
|
||||
select, input {
|
||||
margin-right: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.global-error {
|
||||
color: grey;
|
||||
min-height: 300px;
|
||||
|
||||
&-code {
|
||||
font-size: 80px;
|
||||
}
|
||||
|
||||
&-text {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
.nav-link {
|
||||
padding: 0.5rem 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
border: 1px solid #ced4da;
|
||||
}
|
||||
|
||||
.batch-action-container {
|
||||
padding: 10px 20px 0;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
.partners-customers-page {
|
||||
.customer-list-body {
|
||||
min-height: 300px;
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
.partners-partner-manager-groups-page {
|
||||
.customer-list-form {
|
||||
padding: 10px 20px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.manager-group-item {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&-left {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-right {
|
||||
.action {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.partner-manager {
|
||||
&-body {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
&-item {
|
||||
padding: 5px 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.remove-partner-manager-action {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
right: 10px;
|
||||
top: 0;
|
||||
font-size: 24px;
|
||||
|
||||
& > i {
|
||||
color: #dc3545;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.remove-partner-manager-action {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&-avatar {
|
||||
cursor: pointer;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
|
||||
& > img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
&.add-partner-manager-item {
|
||||
.partner-manager-item-avatar {
|
||||
background: #E4E4E4;
|
||||
|
||||
&:hover {
|
||||
background: #D0D0D0;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 39px;
|
||||
left: 20px;
|
||||
width: 40px;
|
||||
height: 2px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 39px;
|
||||
width: 2px;
|
||||
height: 40px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
.colleges-statistics-page {
|
||||
.college-body-container {
|
||||
padding: 0;
|
||||
|
||||
.statistic-header {
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
background-image: url('/images/educoder/statistics.jpg');
|
||||
background-size: 100% 100%;
|
||||
|
||||
&-container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&-title {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #4CACFF;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
&-content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
&-item {
|
||||
margin-bottom: 22px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
|
||||
&-label {
|
||||
color: #989898;
|
||||
}
|
||||
|
||||
&-content {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.statistic-box {
|
||||
border: unset;
|
||||
box-shadow: 0px 0px 9px rgba(174, 175, 177, 0.2);
|
||||
}
|
||||
|
||||
.statistic-base {
|
||||
&-title {
|
||||
padding: 2rem 1.25rem;
|
||||
background: #fff;
|
||||
border-bottom: unset;
|
||||
}
|
||||
|
||||
&-table {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&-item {
|
||||
padding: 0;
|
||||
|
||||
&-label {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
color: #686868;
|
||||
background: #F5F5F5;
|
||||
border-top: 1px solid #EBEBEB;
|
||||
border-bottom: 1px solid #EBEBEB;
|
||||
}
|
||||
|
||||
&-content {
|
||||
height: 100px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
line-height: 100px;
|
||||
|
||||
span {
|
||||
margin-right: 5px;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.statistic-container {
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0px 0px 9px rgba(174, 175, 177, 0.2);
|
||||
|
||||
.statistic-label {
|
||||
padding: 2rem 1.25rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.statistic-table {
|
||||
overflow-x: scroll;
|
||||
table.course-table { min-width: 1100px; }
|
||||
table.teacher-rank-table { min-width: 640px; }
|
||||
}
|
||||
|
||||
table th {
|
||||
background: #F5F5F5;
|
||||
border-color: #EBEBEB;
|
||||
}
|
||||
|
||||
&.statistic-course {
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
&.statistic-teacher-rank, &.statistic-student-rank {
|
||||
min-height: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
.statistic-chart {
|
||||
padding: 0 20px;
|
||||
height: 400px;
|
||||
|
||||
.shixun-chart-loading, .shixun-chart-empty, .hot-chart-loading, .hot-chart-empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
class CollegesController < ApplicationController
|
||||
include PaginateHelper
|
||||
|
||||
layout 'college'
|
||||
|
||||
before_action :require_login
|
||||
before_action :check_college_present!
|
||||
before_action :check_manage_permission!
|
||||
|
||||
helper_method :current_school, :current_college
|
||||
|
||||
def statistics
|
||||
# 教师、学生总数
|
||||
count_statistic = UserExtension.where(school_id: current_school.id)
|
||||
.select('SUM(IF(identity=0, 1, 0)) AS teachers_count, SUM(IF(identity=1, 1, 0)) AS students_count').first
|
||||
@teachers_count = count_statistic['teachers_count']
|
||||
@students_count = count_statistic['students_count']
|
||||
|
||||
# 课堂总数
|
||||
@courses_count = Course.where(school_id: current_school.id, is_delete: 0).where.not(id: 1309).count
|
||||
# 实训总数
|
||||
@shixuns_count = Shixun.visible.joins('left join user_extensions on user_extensions.user_id = shixuns.user_id')
|
||||
.where(user_extensions: { school_id: current_school.id }).count
|
||||
end
|
||||
|
||||
def shixun_time
|
||||
time_sum = Game.joins('left join user_extensions on user_extensions.user_id = games.user_id')
|
||||
.where(user_extensions: { school_id: current_school.id }).sum(:cost_time)
|
||||
shixun_time_sum = (time_sum / (24 * 60 * 60.0)).ceil
|
||||
|
||||
render json: { shixun_time: shixun_time_sum }
|
||||
end
|
||||
|
||||
def shixun_report_count
|
||||
shixun_report_count = StudentWork.where(work_status: [1, 2]).where('myshixun_id != 0')
|
||||
.joins('left join user_extensions on user_extensions.user_id = student_works.user_id')
|
||||
.where(user_extensions: { school_id: current_school.id }).count
|
||||
render json: { shixun_report_count: shixun_report_count }
|
||||
end
|
||||
|
||||
def teachers
|
||||
@teachers = User.find_by_sql("SELECT users.id, users.login, users.lastname, users.firstname, users.nickname, IFNULL((SELECT count(shixuns.id) FROM shixuns where shixuns.user_id =users.id group by shixuns.user_id), 0) AS publish_shixun_count,
|
||||
(SELECT count(c.id) FROM courses c, course_members m WHERE c.id != 1309 and m.course_id = c.id AND m.user_id=users.id AND m.role in (1,2,3) and c.school_id = #{current_school.id} AND c.is_delete = 0) as course_count
|
||||
FROM `users`, user_extensions ue where ue.school_id=#{current_school.id} and users.id=ue.user_id and ue.identity=0 ORDER BY publish_shixun_count desc, course_count desc, id desc LIMIT 10")
|
||||
# ).order("publish_shixun_count desc, experience desc").limit(10)
|
||||
@teachers =
|
||||
@teachers.map do |teacher|
|
||||
course_ids = Course.find_by_sql("SELECT c.id FROM courses c, course_members m WHERE c.id != 1309 and m.course_id = c.id AND m.role in (1,2,3) AND m.user_id=#{teacher.id} AND c.is_delete = 0 and c.school_id = #{current_school.id}")
|
||||
course_count = course_ids.size
|
||||
homeworks = HomeworkCommon.where(:homework_type => 4, :course_id => course_ids.map(&:id))
|
||||
un_shixun_work_count = homeworks.where("publish_time > '#{Time.now}' or publish_time is null").count
|
||||
shixun_work_count = homeworks.size - un_shixun_work_count
|
||||
student_count = StudentsForCourse.where(:course_id => course_ids.map(&:id)).count
|
||||
myshixun_ids = StudentWork.select("myshixun_id").where("homework_common_id in (#{homeworks.map(&:id).join(',').strip == "" ? -1 : homeworks.map(&:id).join(',')}) and myshixun_id is not null")
|
||||
complete_myshixun = Myshixun.select("id").where(:status => 1, :id => myshixun_ids.map(&:myshixun_id)).size
|
||||
all_myshixun = Myshixun.select("id").where(:id => myshixun_ids.map(&:myshixun_id)).size
|
||||
complete_rate = all_myshixun == 0 ? 0 : ((complete_myshixun * 100) / all_myshixun).try(:round, 2).to_f
|
||||
real_name = teacher.show_real_name
|
||||
teacher = teacher.attributes.dup.merge({
|
||||
real_name: real_name,
|
||||
course_count: course_count,
|
||||
shixun_work_count: shixun_work_count,
|
||||
un_shixun_work_count: un_shixun_work_count,
|
||||
student_count: student_count,
|
||||
complete_rate: complete_rate
|
||||
}).to_json
|
||||
JSON.parse(teacher)
|
||||
end
|
||||
end
|
||||
|
||||
def shixun_chart_data
|
||||
shixun_ids = HomeworkCommonsShixun.joins(homework_common: :course).where(courses: {school_id: current_school.id, is_delete: 0}).where('courses.id != 1309').pluck('distinct shixun_id')
|
||||
shixun_count_map = ShixunTagRepertoire.joins(:tag_repertoire).where(shixun_id: shixun_ids).group('tag_repertoires.name').order('count_shixun_id desc').count(:shixun_id)
|
||||
|
||||
names = []
|
||||
data = []
|
||||
shixun_count_map.each do |name, count|
|
||||
break if names.size == 9
|
||||
|
||||
names << name
|
||||
data << { value: count, name: name }
|
||||
end
|
||||
|
||||
if shixun_count_map.keys.size > 9
|
||||
other_count = shixun_count_map.values[9..-1].reduce(:+)
|
||||
names << 'Others'
|
||||
data << { name: 'Others', value: other_count }
|
||||
end
|
||||
|
||||
render json: { names: names, data: data }
|
||||
end
|
||||
|
||||
# 在线课堂
|
||||
def course_statistics
|
||||
courses = Course.where(school_id: current_school.id, is_delete: 0).where.not(id: 1309)
|
||||
|
||||
courses = courses.left_joins(practice_homeworks: { student_works: { myshixun: :games } })
|
||||
.select('courses.id, courses.name, courses.is_end, sum(games.evaluate_count) evaluating_count')
|
||||
.group('courses.id').order('is_end asc, evaluating_count desc')
|
||||
|
||||
params[:per_page] = 8
|
||||
@courses = paginate courses
|
||||
|
||||
course_ids = @courses.map(&:id)
|
||||
@student_count = StudentsForCourse.where(course_id: course_ids).group(:course_id).count
|
||||
@shixun_work_count = HomeworkCommon.where(homework_type: 4, course_id: course_ids).group(:course_id).count
|
||||
@attachment_count = Attachment.where(container_id: course_ids, container_type: 'Course').group(:container_id).count
|
||||
@message_count = Message.joins(:board).where(boards: { parent_id: 0, course_id: course_ids }).group('boards.course_id').count
|
||||
@active_time = CourseActivity.where(course_id: course_ids).group(:course_id).maximum(:created_at)
|
||||
@exercise_count = Exercise.where(course_id: course_ids).group(:course_id).count
|
||||
@poll_count = Poll.where(course_id: course_ids).group(:course_id).count
|
||||
@other_work_count = HomeworkCommon.where(homework_type: [1,3], course_id: course_ids).group(:course_id).count
|
||||
end
|
||||
|
||||
# 学生实训
|
||||
def student_shixun
|
||||
@students = User.joins(:user_extension).where(user_extensions: { school_id: current_school.id, identity: 1 }).includes(:user_extension).order('experience desc').limit(10)
|
||||
|
||||
student_ids = @students.map(&:id)
|
||||
@shixun_count = Myshixun.where(user_id: student_ids).group(:user_id).count
|
||||
@study_shixun_count = Myshixun.where(user_id: student_ids, status: 0).group(:user_id).count
|
||||
end
|
||||
|
||||
def student_hot_evaluations
|
||||
games = Game.joins(:myshixun).joins('join shixun_tag_repertoires str on str.shixun_id = myshixuns.shixun_id')
|
||||
games = games.joins('join tag_repertoires tr on tr.id = str.tag_repertoire_id')
|
||||
games = games.joins("join user_extensions ue on ue.user_id = myshixuns.user_id and ue.school_id = #{current_school.id}")
|
||||
evaluate_count_map = games.group('tr.name').reorder('sum_games_evaluate_count desc').limit(10).sum('games.evaluate_count')
|
||||
|
||||
render json: { names: evaluate_count_map.keys, values: evaluate_count_map.values }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_login
|
||||
return if User.current.logged?
|
||||
|
||||
redirect_to "/login?back_url=#{CGI::escape(request.fullpath)}"
|
||||
end
|
||||
|
||||
def check_college_present!
|
||||
return if current_college.present?
|
||||
|
||||
redirect_to '/404'
|
||||
end
|
||||
|
||||
def check_manage_permission!
|
||||
return if can_manage_college?
|
||||
|
||||
redirect_to '/403'
|
||||
end
|
||||
|
||||
def can_manage_college?
|
||||
return true if current_user.admin_or_business? # 超级管理员|运营
|
||||
return true if current_college.is_a?(Department) && current_college.member?(current_user) # 部门管理员
|
||||
return true if current_user.is_teacher? && current_user.school_id == current_school.id # 学校老师
|
||||
return true if current_school.customers.exists? && current_user.partner&.partner_customers&.exists?(customer_id: current_school.customer_id)
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def current_school
|
||||
current_college.is_a?(School) ? current_college : current_college.school
|
||||
end
|
||||
|
||||
def current_college
|
||||
@_current_college ||= begin
|
||||
Department.find_by(identifier: params[:id]) || School.find_by(id: params[:id])
|
||||
end
|
||||
end
|
||||
end
|
@ -1,45 +0,0 @@
|
||||
<table class="table text-center course-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th class="text-left">名称</th>
|
||||
<th class="text-left">管理教师</th>
|
||||
<th>评测次数</th>
|
||||
<th>学生</th>
|
||||
<th>实训作业</th>
|
||||
<th>资源</th>
|
||||
<th>帖子</th>
|
||||
<th>其它任务</th>
|
||||
<th>状态</th>
|
||||
<th>时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if @courses.present? %>
|
||||
<% @courses.each do |course| %>
|
||||
<tr>
|
||||
<td class="text-left"><a href="/courses/<%= course.id %>/students" target="_blank" class="d-inline-block text-truncate" style="max-width: 220px"><%= course.name %></a></td>
|
||||
<% teacher_names = course.teacher_users.map(&:real_name).join('、') %>
|
||||
<td class="text-left">
|
||||
<span class="d-inline-block text-truncate" style="max-width: 150px" data-toggle="tooltip" title="<%= teacher_names %>">
|
||||
<%= teacher_names || '--' %>
|
||||
</span>
|
||||
</td>
|
||||
<td><%= course.evaluating_count.to_i %></td>
|
||||
<td><%= @student_count.fetch(course.id, 0) %></td>
|
||||
<td><%= @shixun_work_count.fetch(course.id, 0) %></td>
|
||||
<td><%= @attachment_count.fetch(course.id, 0) %></td>
|
||||
<td><%= @message_count.fetch(course.id, 0) %></td>
|
||||
<td><%= @exercise_count.fetch(course.id, 0) + @poll_count.fetch(course.id, 0) + @other_work_count.fetch(course.id, 0) %></td>
|
||||
<td class="<%= course.is_end ? 'text-secondary' : 'text-warning' %>"><%= course.is_end ? "已结束" : "正在进行" %></td>
|
||||
<td class="text-secondary"><%= @active_time[course.id]&.strftime('%Y-%m-%d %H:%M') %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<tr><td colspan="100">暂无数据</td></tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex justify-content-center text-center">
|
||||
<%= render partial: 'admins/shared/paginate', locals: { objects: @courses } %>
|
||||
</div>
|
@ -1,23 +0,0 @@
|
||||
<% if @students.present? %>
|
||||
<% @students.each_with_index do |student, index| %>
|
||||
<tr>
|
||||
<td>
|
||||
<% if index < 3 %>
|
||||
<img src="/images/educoder/competition/<%= index + 1 %>.png" width="18px" height="22px" class="mt8"/></td>
|
||||
<% else %>
|
||||
<%= index + 1 %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="color-dark">
|
||||
<a href="/users/<%= student.login %>" target="_blank" class="d-inline-block text-truncate" style="max-width: 84px;"><%= student.real_name %></a>
|
||||
</td>
|
||||
<td><%= student.student_id %></td>
|
||||
<td><%= @shixun_count.fetch(student.id, 0) %></td>
|
||||
<td><%= @study_shixun_count.fetch(student.id, 0) %></td>
|
||||
<td><%= student.grade %></td>
|
||||
<td class="text-info"><%= student.experience %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<tr><td colspan="100">暂无数据</td></tr>
|
||||
<% end %>
|
@ -1,16 +0,0 @@
|
||||
<% if @teachers.present? %>
|
||||
<% @teachers.each_with_index do |teacher, index| %>
|
||||
<tr>
|
||||
<td class="pl20 pr20"><%= index + 1 %></td>
|
||||
<td class="color-dark"><a href="<%= user_path(teacher['login']) %>" target="_blank" class="task-hide" style="max-width: 84px;"><%= teacher['real_name'] %></a></td>
|
||||
<td><%= teacher['course_count'] %></td>
|
||||
<td><%= teacher['shixun_work_count'] %></td>
|
||||
<td><%= teacher['un_shixun_work_count'] %></td>
|
||||
<td><%= teacher['student_count'] %></td>
|
||||
<td><%= teacher['complete_rate'] %>%</td>
|
||||
<td class="color-blue"><%= teacher['publish_shixun_count'].to_i %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<tr><td colspan="100">暂无数据</td></tr>
|
||||
<% end %>
|
@ -1 +0,0 @@
|
||||
$(".statistic-course .statistic-table").html("<%= j(render 'colleges/course_statistics') %>");
|
@ -1,21 +0,0 @@
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="/images/educoder/headNavLogo.png" width="40" height="40" alt="">
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item"><a class="nav-link" href="/paths">实践课程</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/courses">翻转课堂</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/shixuns">实训项目</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/competitions">在线竞赛</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/moop_cases">教学案例</a></li>
|
||||
<!-- <li class="nav-item"><a class="nav-link" href="/crowdsourcing">众包创新</a></li>-->
|
||||
<li class="nav-item"><a class="nav-link" href="/forums">交流问答</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
@ -1,164 +0,0 @@
|
||||
<div class="statistic-header">
|
||||
<div class="container statistic-header-container">
|
||||
<div class="statistic-header-title"><%= current_school.name %></div>
|
||||
<div class="statistic-header-content">
|
||||
<div class="statistic-header-item">
|
||||
<div class="statistic-header-item-label">教师</div>
|
||||
<div class="statistic-header-item-content"><%= @teachers_count %></div>
|
||||
</div>
|
||||
<div class="statistic-header-item">
|
||||
<div class="statistic-header-item-label">学生</div>
|
||||
<div class="statistic-header-item-content"><%= @students_count %></div>
|
||||
</div>
|
||||
<div class="statistic-header-item">
|
||||
<div class="statistic-header-item-label">课堂</div>
|
||||
<div class="statistic-header-item-content"><%= @courses_count %></div>
|
||||
</div>
|
||||
<div class="statistic-header-item">
|
||||
<div class="statistic-header-item-label">共建实训</div>
|
||||
<div class="statistic-header-item-content"><%= @shixuns_count %></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container statistics-body my-4" data-id="<%= current_school.id %>">
|
||||
<div class="card statistic-box statistic-base">
|
||||
<h4 class="card-header statistic-base-title">基本情况</h4>
|
||||
<div class="card-body statistic-base-table row">
|
||||
<div class="col-4 col-md-2 statistic-base-item">
|
||||
<div class="statistic-base-item-label">教师</div>
|
||||
<div class="statistic-base-item-content">
|
||||
<span><%= @teachers_count %></span>人
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-md-2 statistic-base-item">
|
||||
<div class="statistic-base-item-label">学生</div>
|
||||
<div class="statistic-base-item-content">
|
||||
<span><%= @students_count %></span>人
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-md-2 statistic-base-item">
|
||||
<div class="statistic-base-item-label">课堂</div>
|
||||
<div class="statistic-base-item-content">
|
||||
<span><%= @courses_count %></span>个
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-md-2 statistic-base-item">
|
||||
<div class="statistic-base-item-label">共建实训</div>
|
||||
<div class="statistic-base-item-content">
|
||||
<span><%= @shixuns_count %></span>个
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-md-2 statistic-base-item">
|
||||
<div class="statistic-base-item-label">实习报告</div>
|
||||
<div class="statistic-base-item-content shixun-report-count">
|
||||
加载中...
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-md-2 statistic-base-item">
|
||||
<div class="statistic-base-item-label">学员实战时间</div>
|
||||
<div class="statistic-base-item-content shixun-time">
|
||||
加载中...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="statistic-container my-4 statistic-course">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="statistic-label">课堂</div>
|
||||
<div class="statistic-table">
|
||||
<table class="table text-center course-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th class="text-left">名称</th>
|
||||
<th class="text-left">管理教师</th>
|
||||
<th>评测次数</th>
|
||||
<th>学生</th>
|
||||
<th>实训作业</th>
|
||||
<th>资源</th>
|
||||
<th>帖子</th>
|
||||
<th>其它任务</th>
|
||||
<th>状态</th>
|
||||
<th>时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td colspan="100">加载中...</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-4 mx-0 row">
|
||||
<div class="col-12 col-md-7 statistic-container statistic-teacher-rank">
|
||||
<div class="statistic-label">教师排名</div>
|
||||
<div class="statistic-table">
|
||||
<table class="table text-center teacher-rank-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>排名</th>
|
||||
<th>姓名</th>
|
||||
<th>管理课堂</th>
|
||||
<th width="15%">已发布实训作业</th>
|
||||
<th width="15%">未发布实训作业</th>
|
||||
<th>学生数</th>
|
||||
<th>完成率</th>
|
||||
<th>发布实训</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td colspan="100">加载中...</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-5 statistic-container">
|
||||
<div class="statistic-label">在线实训情况</div>
|
||||
<div class="statistic-chart">
|
||||
<div class="shixun-chart-loading">加载中...</div>
|
||||
<div class="shixun-chart-empty" style="display: none;">无数据</div>
|
||||
<div class="shixun-chart" id="shixun-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-4 mx-0 row">
|
||||
<div class="col-12 col-md-7 statistic-container statistic-student-rank">
|
||||
<div class="statistic-label">学生排名</div>
|
||||
<div class="statistic-table">
|
||||
<table class="table text-center student-rank-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>排名</th>
|
||||
<th>姓名</th>
|
||||
<th>学号</th>
|
||||
<th>完成实训</th>
|
||||
<th>在学实训</th>
|
||||
<th>金币</th>
|
||||
<th>经验值</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td colspan="100">加载中...</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-5 statistic-container">
|
||||
<div class="statistic-label">最热评测</div>
|
||||
<div class="statistic-chart">
|
||||
<div class="hot-chart-loading">加载中...</div>
|
||||
<div class="hot-chart-empty" style="display: none;">无数据</div>
|
||||
<div class="hot-chart" id="hot-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
@ -1 +0,0 @@
|
||||
$('.statistic-student-rank table.student-rank-table tbody').html("<%= j(render :partial => 'colleges/student_rank') %>")
|
@ -1 +0,0 @@
|
||||
$('.statistic-teacher-rank table.teacher-rank-table tbody').html("<%= j(render :partial => 'colleges/teacher_rank') %>")
|
Loading…
Reference in new issue