parent
8e4bc5bffa
commit
e15e24b369
@ -0,0 +1,66 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.admins-dashboards-index-page').length > 0) {
|
||||||
|
// 月新增用户
|
||||||
|
var monthChart = echarts.init(document.getElementById('month-active-user'));
|
||||||
|
monthChart.setOption({
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series : [
|
||||||
|
{
|
||||||
|
name: '访问来源',
|
||||||
|
type: 'pie',
|
||||||
|
radius: '55%',
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
monthChart.showLoading();
|
||||||
|
$.get('/admins/dashboards/month_active_user.json').done(function(data){
|
||||||
|
monthChart.setOption({
|
||||||
|
series: [
|
||||||
|
{ data: data.data }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
monthChart.hideLoading();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 近七天评测次数
|
||||||
|
// var evaluateChart = echarts.init(document.getElementById('evaluate-pie'));
|
||||||
|
// evaluateChart.setOption({
|
||||||
|
// 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: 'category', boundaryGap: false, data: [] },
|
||||||
|
// yAxis: { type: 'value' },
|
||||||
|
// series: [{ data: [], type: 'line', areaStyle: {} }]
|
||||||
|
// });
|
||||||
|
// evaluateChart.showLoading();
|
||||||
|
// $.get('/admins/dashboards/evaluate.json').done(function(data){
|
||||||
|
// evaluateChart.setOption({
|
||||||
|
// xAxis: { data: data.names },
|
||||||
|
// series: [{ data: data.data }]
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// evaluateChart.hideLoading();
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,173 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.admins-departments-index-page').length > 0) {
|
||||||
|
var $searchContainer = $('.department-list-form');
|
||||||
|
var $searchForm = $searchContainer.find('form.search-form');
|
||||||
|
var $list = $('.department-list-container');
|
||||||
|
|
||||||
|
$searchContainer.on('change', '.form-check-input', function(){
|
||||||
|
$searchForm.find('input[type="submit"]').trigger('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============== 新建部门 ===============
|
||||||
|
var $modal = $('.modal.admin-create-department-modal');
|
||||||
|
var $form = $modal.find('form.admin-create-department-form');
|
||||||
|
var $departmentNameInput = $form.find('input[name="department_name"]');
|
||||||
|
var $schoolSelect = $modal.find('.school-select');
|
||||||
|
|
||||||
|
$form.validate({
|
||||||
|
errorElement: 'span',
|
||||||
|
errorClass: 'danger text-danger',
|
||||||
|
rules: {
|
||||||
|
school_id: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
department_name: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
school_id: {
|
||||||
|
required: '请选择所属单位'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// modal ready fire
|
||||||
|
$modal.on('show.bs.modal', function () {
|
||||||
|
$departmentNameInput.val('');
|
||||||
|
$schoolSelect.select2('val', ' ');
|
||||||
|
});
|
||||||
|
|
||||||
|
// ************** 学校选择 *************
|
||||||
|
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 defineSchoolSelect = function(schools) {
|
||||||
|
$schoolSelect.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) {
|
||||||
|
$('#school_id').val(item.id);
|
||||||
|
}
|
||||||
|
return item.name || item.text;
|
||||||
|
},
|
||||||
|
matcher: matcherFunc
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/schools/for_option.json',
|
||||||
|
dataType: 'json',
|
||||||
|
type: 'GET',
|
||||||
|
success: function(data) {
|
||||||
|
defineSchoolSelect(data.schools);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$modal.on('click', '.submit-btn', function(){
|
||||||
|
$form.find('.error').html('');
|
||||||
|
|
||||||
|
if ($form.valid()) {
|
||||||
|
var url = $form.data('url');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
url: url,
|
||||||
|
data: $form.serialize(),
|
||||||
|
success: function(){
|
||||||
|
$.notify({ message: '创建成功' });
|
||||||
|
$modal.modal('hide');
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
window.location.reload();
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
error: function(res){
|
||||||
|
var data = res.responseJSON;
|
||||||
|
$form.find('.error').html(data.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============= 添加部门管理员 ==============
|
||||||
|
var $addMemberModal = $('.admin-add-department-member-modal');
|
||||||
|
var $addMemberForm = $addMemberModal.find('.admin-add-department-member-form');
|
||||||
|
var $memberSelect = $addMemberModal.find('.department-member-select');
|
||||||
|
var $departmentIdInput = $addMemberForm.find('input[name="department_id"]')
|
||||||
|
|
||||||
|
$addMemberModal.on('show.bs.modal', function(event){
|
||||||
|
var $link = $(event.relatedTarget);
|
||||||
|
var departmentId = $link.data('department-id');
|
||||||
|
$departmentIdInput.val(departmentId);
|
||||||
|
|
||||||
|
$memberSelect.select2('val', ' ');
|
||||||
|
});
|
||||||
|
|
||||||
|
$memberSelect.select2({
|
||||||
|
theme: 'bootstrap4',
|
||||||
|
placeholder: '请输入要添加的管理员姓名',
|
||||||
|
multiple: true,
|
||||||
|
minimumInputLength: 1,
|
||||||
|
ajax: {
|
||||||
|
delay: 500,
|
||||||
|
url: '/admins/users',
|
||||||
|
dataType: 'json',
|
||||||
|
data: function(params){
|
||||||
|
return { name: params.term };
|
||||||
|
},
|
||||||
|
processResults: function(data){
|
||||||
|
return { results: data.users }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
templateResult: function (item) {
|
||||||
|
if(!item.id || item.id === '') return item.text;
|
||||||
|
return item.real_name;
|
||||||
|
},
|
||||||
|
templateSelection: function(item){
|
||||||
|
if (item.id) {
|
||||||
|
}
|
||||||
|
return item.real_name || item.text;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$addMemberModal.on('click', '.submit-btn', function(){
|
||||||
|
$addMemberForm.find('.error').html('');
|
||||||
|
|
||||||
|
var departmentId = $departmentIdInput.val();
|
||||||
|
var memberIds = $memberSelect.val();
|
||||||
|
if (departmentId && memberIds && memberIds.length > 0) {
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'script',
|
||||||
|
url: '/admins/departments/' + departmentId + '/department_member',
|
||||||
|
data: { user_ids: memberIds }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$addMemberModal.modal('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,20 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.admins-library-applies-index-page').length > 0) {
|
||||||
|
var $searchFrom = $('.library-applies-list-form');
|
||||||
|
$searchFrom.find('select[name="status"]').val('pending');
|
||||||
|
|
||||||
|
$searchFrom.on('click', '.search-form-tab', function(){
|
||||||
|
var $link = $(this);
|
||||||
|
|
||||||
|
$searchFrom.find('input[name="keyword"]').val('');
|
||||||
|
$searchFrom.find('select[name="status"]').val('processed');
|
||||||
|
|
||||||
|
if($link.data('value') === 'processed'){
|
||||||
|
$searchFrom.find('.status-filter').show();
|
||||||
|
} else {
|
||||||
|
$searchFrom.find('.status-filter').hide();
|
||||||
|
$searchFrom.find('select[name="status"]').val('pending');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,19 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.admins-mirror-repositories-edit-page, body.admins-mirror-repositories-update-page').length > 0) {
|
||||||
|
var $form = $('form.edit-mirror');
|
||||||
|
|
||||||
|
$form.validate({
|
||||||
|
errorElement: 'span',
|
||||||
|
errorClass: 'danger text-danger',
|
||||||
|
rules: {
|
||||||
|
"mirror_repository[type_name]": {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$form.submit(function(e){
|
||||||
|
if(!$form.valid()){ e.preventDefault(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,4 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.admins-mirror-repositories-index-page').length > 0) {
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,33 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.admins-mirror-scripts-edit-page, body.admins-mirror-scripts-update-page, body.admins-mirror-scripts-new-page, body.admins-mirror-scripts-create-page').length > 0) {
|
||||||
|
var $form = $('form.script-form');
|
||||||
|
|
||||||
|
// codemirror编辑器
|
||||||
|
var scriptEditor = CodeMirror.fromTextArea(document.getElementById('mirror_script_script'), {
|
||||||
|
lineNumbers: true,
|
||||||
|
mode: 'shell',
|
||||||
|
theme: "default",
|
||||||
|
indentUnit: 4, //代码缩进为一个tab的距离
|
||||||
|
matchBrackets: true,
|
||||||
|
autoRefresh: true,
|
||||||
|
smartIndent: true,//智能换行
|
||||||
|
styleActiveLine: true,
|
||||||
|
lint: true
|
||||||
|
});
|
||||||
|
scriptEditor.setSize('auto', '600px');
|
||||||
|
|
||||||
|
$form.validate({
|
||||||
|
errorElement: 'span',
|
||||||
|
errorClass: 'danger text-danger',
|
||||||
|
rules: {
|
||||||
|
"mirror_script[script_type]": {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$form.submit(function(e){
|
||||||
|
if(!$form.valid()){ e.preventDefault(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,32 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
$('.admin-modal-container').on('show.bs.modal', '.modal.admin-choose-mirror-modal', function(){
|
||||||
|
var $modal = $('.modal.admin-choose-mirror-modal');
|
||||||
|
var $form = $modal.find('form.admin-choose-mirror-form');
|
||||||
|
|
||||||
|
var validateForm = function(){
|
||||||
|
var checkedValue = $form.find('input[name="mirror_number"]:checked').val();
|
||||||
|
|
||||||
|
if(checkedValue == undefined){
|
||||||
|
$modal.find('.error').html('必须选择一种镜像保存!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$modal.on('click', '.submit-btn', function(){
|
||||||
|
$form.find('.error').html('');
|
||||||
|
var url = $form.attr('action');
|
||||||
|
|
||||||
|
if (validateForm()) {
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'script',
|
||||||
|
url: url,
|
||||||
|
data: $form.serialize(),
|
||||||
|
}).done(function(){
|
||||||
|
$modal.modal('hide');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
@ -0,0 +1,34 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
$('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-department-modal', function(){
|
||||||
|
var $modal = $('.modal.admin-edit-department-modal');
|
||||||
|
var $form = $modal.find('form.admin-edit-department-form');
|
||||||
|
|
||||||
|
$form.validate({
|
||||||
|
errorElement: 'span',
|
||||||
|
errorClass: 'danger text-danger',
|
||||||
|
rules: {
|
||||||
|
'department[name]': {
|
||||||
|
required: true,
|
||||||
|
maxlength: 20
|
||||||
|
},
|
||||||
|
'department[host_count]': {
|
||||||
|
digits: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$modal.on('click', '.submit-btn', function(){
|
||||||
|
$form.find('.error').html('');
|
||||||
|
var url = $form.attr('action');
|
||||||
|
|
||||||
|
if ($form.valid()) {
|
||||||
|
$.ajax({
|
||||||
|
method: 'PATCH',
|
||||||
|
dataType: 'script',
|
||||||
|
url: url,
|
||||||
|
data: $form.serialize()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
@ -0,0 +1,110 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
var $modal = $('.modal.admin-merge-department-modal');
|
||||||
|
if ($modal.length > 0) {
|
||||||
|
var $form = $modal.find('form.admin-merge-department-form');
|
||||||
|
var $schoolIdInput = $form.find('input[name="school_id"]');
|
||||||
|
var $originDepartmentIdInput = $form.find('input[name="origin_department_id"]');
|
||||||
|
var $departmentSelect = $modal.find('.department-select');
|
||||||
|
|
||||||
|
$form.validate({
|
||||||
|
errorElement: 'span',
|
||||||
|
errorClass: 'danger text-danger',
|
||||||
|
rules: {
|
||||||
|
department_id: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
department_id: {
|
||||||
|
required: '请选择部门'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ************** 学校选择 *************
|
||||||
|
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 defineDepartmentSelect = function(departments) {
|
||||||
|
$departmentSelect.empty();
|
||||||
|
|
||||||
|
$departmentSelect.select2({
|
||||||
|
theme: 'bootstrap4',
|
||||||
|
placeholder: '请选择所属部门',
|
||||||
|
data: departments,
|
||||||
|
templateResult: function (item) {
|
||||||
|
if(!item.id || item.id === '') return item.text;
|
||||||
|
return item.name;
|
||||||
|
},
|
||||||
|
templateSelection: function(item){
|
||||||
|
if (item.id) {
|
||||||
|
$form.find('#department_id').val(item.id);
|
||||||
|
}
|
||||||
|
return item.name || item.text;
|
||||||
|
},
|
||||||
|
matcher: matcherFunc
|
||||||
|
});
|
||||||
|
$departmentSelect.select2('val', ' ');
|
||||||
|
};
|
||||||
|
|
||||||
|
// modal ready fire
|
||||||
|
$modal.on('show.bs.modal', function (event) {
|
||||||
|
var $link = $(event.relatedTarget);
|
||||||
|
|
||||||
|
var schoolId = $link.data('schoolId');
|
||||||
|
|
||||||
|
$schoolIdInput.val(schoolId);
|
||||||
|
$originDepartmentIdInput.val($link.data('departmentId'));
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/schools/' + schoolId + '/departments/for_option.json',
|
||||||
|
dataType: 'json',
|
||||||
|
type: 'GET',
|
||||||
|
success: function(data) {
|
||||||
|
defineDepartmentSelect(data.departments);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$modal.on('click', '.submit-btn', function(){
|
||||||
|
$form.find('.error').html('');
|
||||||
|
|
||||||
|
if ($form.valid()) {
|
||||||
|
var url = $form.data('url');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
url: url,
|
||||||
|
data: $form.serialize(),
|
||||||
|
success: function(){
|
||||||
|
$.notify({ message: '操作成功' });
|
||||||
|
$modal.modal('hide');
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
window.location.reload();
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
error: function(res){
|
||||||
|
var data = res.responseJSON;
|
||||||
|
$form.find('.error').html(data.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,89 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
var $modal = $('.modal.admin-replace-mirror-modal');
|
||||||
|
if ($modal.length > 0) {
|
||||||
|
var $form = $modal.find('form.admin-replace-mirror-form');
|
||||||
|
var $mirrorIdInput = $modal.find('.modal-body input[name="mirror_id"]');
|
||||||
|
var $mirrorSelect = $modal.find('.new-mirror-select');
|
||||||
|
|
||||||
|
var setMirror = function(id, name){
|
||||||
|
$mirrorIdInput.val(id);
|
||||||
|
$form.find('.mirror-id-container').html(id);
|
||||||
|
$form.find('.mirror-name-container').html(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
$form.validate({
|
||||||
|
errorElement: 'span',
|
||||||
|
errorClass: 'danger text-danger',
|
||||||
|
rules: {
|
||||||
|
new_mirror_id: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
new_mirror_id: {
|
||||||
|
required: '请选择新镜像'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// modal ready fire
|
||||||
|
$modal.on('show.bs.modal', function (event) {
|
||||||
|
var $link = $(event.relatedTarget);
|
||||||
|
|
||||||
|
var mirrorId = $link.data('id');
|
||||||
|
var mirrorName = $link.data('name');
|
||||||
|
|
||||||
|
setMirror(mirrorId, mirrorName);
|
||||||
|
$mirrorSelect.select2('val', ' ');
|
||||||
|
});
|
||||||
|
$modal.on('hide.bs.modal', function () {
|
||||||
|
setMirror('', '');
|
||||||
|
$mirrorSelect.select2('val', ' ');
|
||||||
|
$('#new_mirror_id-error').remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$mirrorSelect.select2({
|
||||||
|
theme: 'bootstrap4',
|
||||||
|
placeholder: '输入要合并的镜像名',
|
||||||
|
minimumInputLength: 1,
|
||||||
|
ajax: {
|
||||||
|
url: '/admins/mirror_repositories/for_select',
|
||||||
|
dataType: 'json',
|
||||||
|
data: function(params){
|
||||||
|
return { keyword: params.term };
|
||||||
|
},
|
||||||
|
processResults: function(data){
|
||||||
|
return { results: data.mirrors }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
templateResult: function (item) {
|
||||||
|
if(!item.id || item.id === '') return item.text;
|
||||||
|
return item.name;
|
||||||
|
},
|
||||||
|
templateSelection: function(item){
|
||||||
|
if (item.id) {
|
||||||
|
$('#new_mirror_id-error').remove();
|
||||||
|
$('#new_mirror_id').val(item.id);
|
||||||
|
}
|
||||||
|
return item.name || item.text;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$modal.on('click', '.submit-btn', function(){
|
||||||
|
$form.find('.error').html('');
|
||||||
|
|
||||||
|
if ($form.valid()) {
|
||||||
|
var url = $form.data('url');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'script',
|
||||||
|
url: url,
|
||||||
|
data: $form.serialize(),
|
||||||
|
}).done(function(){
|
||||||
|
$modal.modal('hide');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,62 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
var $modal = $('.modal.admin-upload-file-modal');
|
||||||
|
if ($modal.length > 0) {
|
||||||
|
var $form = $modal.find('form.admin-upload-file-form')
|
||||||
|
var $sourceIdInput = $modal.find('input[name="source_id"]');
|
||||||
|
var $sourceTypeInput = $modal.find('input[name="source_type"]');
|
||||||
|
|
||||||
|
$modal.on('show.bs.modal', function(event){
|
||||||
|
var $link = $(event.relatedTarget);
|
||||||
|
var sourceId = $link.data('sourceId');
|
||||||
|
var sourceType = $link.data('sourceType');
|
||||||
|
|
||||||
|
$sourceIdInput.val(sourceId);
|
||||||
|
$sourceTypeInput.val(sourceType);
|
||||||
|
|
||||||
|
$modal.find('.upload-file-input').trigger('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
$modal.find('.upload-file-input').on('change', function(e){
|
||||||
|
var file = $(this)[0].files[0];
|
||||||
|
|
||||||
|
if(file){
|
||||||
|
$modal.find('.file-names').html(file.name);
|
||||||
|
$modal.find('.submit-btn').trigger('click');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var formValid = function(){
|
||||||
|
if($form.find('input[name="file"]').val() == undefined || $form.find('input[name="file"]').val().length == 0){
|
||||||
|
$form.find('.error').html('请选择文件');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
$modal.on('click', '.submit-btn', function(){
|
||||||
|
$form.find('.error').html('');
|
||||||
|
|
||||||
|
if (formValid()) {
|
||||||
|
var formDataString = $form.serialize();
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
url: '/admins/files?' + formDataString,
|
||||||
|
data: new FormData($form[0]),
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: function(data){
|
||||||
|
$.notify({ message: '上传成功' });
|
||||||
|
$modal.trigger('upload:success', data);
|
||||||
|
$modal.modal('hide');
|
||||||
|
},
|
||||||
|
error: function(res){
|
||||||
|
var data = res.responseJSON;
|
||||||
|
$form.find('.error').html(data.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,20 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.admins-project-package-applies-index-page').length > 0) {
|
||||||
|
var $searchFrom = $('.project-package-applies-form');
|
||||||
|
$searchFrom.find('select[name="status"]').val('pending');
|
||||||
|
|
||||||
|
$searchFrom.on('click', '.search-form-tab', function(){
|
||||||
|
var $link = $(this);
|
||||||
|
|
||||||
|
$searchFrom.find('input[name="keyword"]').val('');
|
||||||
|
$searchFrom.find('select[name="status"]').val('all');
|
||||||
|
|
||||||
|
if($link.data('value') === 'all'){
|
||||||
|
$searchFrom.find('.status-filter').show();
|
||||||
|
} else {
|
||||||
|
$searchFrom.find('.status-filter').hide();
|
||||||
|
$searchFrom.find('select[name="status"]').val('pending');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,44 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.admins-shixun-settings-index-page').length > 0) {
|
||||||
|
let searchContainer = $(".shixun-settings-list-form");
|
||||||
|
let searchForm = $("form.search-form",searchContainer);
|
||||||
|
|
||||||
|
searchContainer.on('change', '.shixun-settings-select', function(){
|
||||||
|
searchForm.find('input[type="submit"]').trigger('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
//导出
|
||||||
|
searchContainer.on('click',"#shixun-settings-export",function () {
|
||||||
|
window.location.href = "/admins/shixun_settings.xls?" + searchForm.serialize();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".shixun-settings-list-container").on("change", '.shixun-setting-form', function () {
|
||||||
|
var s_id = $(this).attr("data-id");
|
||||||
|
var s_value = $(this).val();
|
||||||
|
var s_name = $(this).attr("name");
|
||||||
|
var json = {};
|
||||||
|
var s_index = $(this).parent("td").siblings(".shixun-line-no").text();
|
||||||
|
json[s_name] = s_value;
|
||||||
|
json["page_no"] = s_index;
|
||||||
|
$.ajax({
|
||||||
|
url: "/admins/shixun_settings/" + s_id,
|
||||||
|
type: "PUT",
|
||||||
|
dataType:'script',
|
||||||
|
data: json
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
$("select#settings-tag-choosed").select2({
|
||||||
|
placeholder: "请选择分类",
|
||||||
|
allowClear: true
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.modal.admin-upload-file-modal').on('upload:success', function(e, data){
|
||||||
|
var $imageElement = $('.shixun-image-' + data.source_id);
|
||||||
|
$imageElement.attr('src', data.url);
|
||||||
|
$imageElement.show();
|
||||||
|
$imageElement.next().html('重新上传');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,14 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if($('body.admins-shixuns-index-page').length > 0){
|
||||||
|
$('select#tag-choosed').select2({
|
||||||
|
placeholder: "请选择分类",
|
||||||
|
allowClear: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let search_form = $(".search-form");
|
||||||
|
//导出
|
||||||
|
$(".shixuns-list-form").on("click","#shixuns-export",function () {
|
||||||
|
window.location.href = "/admins/shixuns.xls?" + search_form.serialize();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,20 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.admins-video-applies-index-page').length > 0) {
|
||||||
|
var $searchFrom = $('.video-applies-form');
|
||||||
|
$searchFrom.find('select[name="status"]').val('pending');
|
||||||
|
|
||||||
|
$searchFrom.on('click', '.search-form-tab', function(){
|
||||||
|
var $link = $(this);
|
||||||
|
|
||||||
|
$searchFrom.find('input[name="keyword"]').val('');
|
||||||
|
$searchFrom.find('select[name="status"]').val('all');
|
||||||
|
|
||||||
|
if($link.data('value') === 'all'){
|
||||||
|
$searchFrom.find('.status-filter').show();
|
||||||
|
} else {
|
||||||
|
$searchFrom.find('.status-filter').hide();
|
||||||
|
$searchFrom.find('select[name="status"]').val('pending');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,21 @@
|
|||||||
|
//= require rails-ujs
|
||||||
|
//= require turbolinks
|
||||||
|
//= require jquery3
|
||||||
|
//= require popper
|
||||||
|
//= require bootstrap-sprockets
|
||||||
|
|
||||||
|
//= require echarts
|
||||||
|
|
||||||
|
//= require_tree ./colleges
|
||||||
|
|
||||||
|
Turbolinks.setProgressBarDelay(200);
|
||||||
|
|
||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
$('[data-toggle="popover"]').popover();
|
||||||
|
})
|
||||||
|
|
||||||
|
$(document).on("turbolinks:before-cache", function () {
|
||||||
|
$('[data-toggle="tooltip"]').tooltip('hide');
|
||||||
|
$('[data-toggle="popover"]').popover('hide');
|
||||||
|
});
|
@ -0,0 +1,156 @@
|
|||||||
|
$(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();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,2 @@
|
|||||||
|
// Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
// All this logic will automatically be available in application.js.
|
@ -0,0 +1,7 @@
|
|||||||
|
.admins-dashboards-index-page {
|
||||||
|
.pie-statistic {
|
||||||
|
.pie {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
.admins-departments-index-page {
|
||||||
|
.department-list-table {
|
||||||
|
.member-container {
|
||||||
|
.member-user {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.member-user-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 22px;
|
||||||
|
line-height: 22px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
margin: 2px 2px;
|
||||||
|
border: 1px solid #91D5FF;
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
color: #91D5FF;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
.admins-library-applies-index-page {
|
||||||
|
.library-applies-list-container {
|
||||||
|
span {
|
||||||
|
&.apply-status-agreed { color: #28a745; }
|
||||||
|
&.apply-status-refused { color: #dc3545; }
|
||||||
|
&.apply-status-processed { color: #6c757d; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
.admins-project-package-applies-index-page {
|
||||||
|
.project-package-applies-list-container {
|
||||||
|
span {
|
||||||
|
&.apply-status-agreed { color: #28a745; }
|
||||||
|
&.apply-status-refused { color: #dc3545; }
|
||||||
|
&.apply-status-processed { color: #6c757d; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
.admins-shixuns-index-page{
|
||||||
|
.shixuns-list-container{
|
||||||
|
.shixuns-status-1 { color: #6c757d; }
|
||||||
|
.shixuns-status-2 { color: #28a745; }
|
||||||
|
.shixuns-status-3 { color: #dc3545; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
.admins-shixun-settings-index-page {
|
||||||
|
input[type="checkbox"]{
|
||||||
|
font-size:18px;
|
||||||
|
}
|
||||||
|
.select2 input::-webkit-input-placeholder{
|
||||||
|
color:#ccc;
|
||||||
|
}
|
||||||
|
.select2 .select2-selection__choice{
|
||||||
|
border: 1px solid #eee !important;
|
||||||
|
}
|
||||||
|
.setting-chosen{
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 10px;
|
||||||
|
color:#333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shixun-setting-image {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
.admins-video-applies-index-page {
|
||||||
|
.video-applies-list-container {
|
||||||
|
span {
|
||||||
|
&.apply-status-agreed { color: #28a745; }
|
||||||
|
&.apply-status-refused { color: #dc3545; }
|
||||||
|
&.apply-status-processed { color: #6c757d; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
@import "bootstrap";
|
||||||
|
@import "font-awesome-sprockets";
|
||||||
|
@import "font-awesome";
|
||||||
|
|
||||||
|
@import "common";
|
||||||
|
|
||||||
|
@import "colleges/*";
|
||||||
|
|
||||||
|
|
||||||
|
.navbar-dark .navbar-nav .nav-link {
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
@ -0,0 +1,135 @@
|
|||||||
|
.colleges-statistics-page {
|
||||||
|
.college-body-container {
|
||||||
|
.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%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
body {
|
||||||
|
font-size: 14px;
|
||||||
|
background: #efefef;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
&:hover {
|
||||||
|
text-decoration: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.danger, input.danger {
|
||||||
|
border-color: #dc3545!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.error {
|
||||||
|
color: #dc3545!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.form-control {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.input-group-prepend {
|
||||||
|
.input-group-text {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-1 {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-12 { font-size: 12px !important; }
|
||||||
|
.font-14 { font-size: 14px !important; }
|
||||||
|
.font-16 { font-size: 16px !important; }
|
||||||
|
.font-18 { font-size: 18px !important; }
|
@ -0,0 +1,3 @@
|
|||||||
|
// Place all the styles related to the homework_banks controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -1 +1 @@
|
|||||||
.select2-container--bootstrap4 .select2-selection--single{height:calc(1.5em + .75rem + 2px)!important}.select2-container--bootstrap4 .select2-selection--single .select2-selection__placeholder{color:#757575;line-height:calc(1.5em + .75rem)}.select2-container--bootstrap4 .select2-selection--single .select2-selection__arrow{position:absolute;top:50%;right:3px;width:20px}.select2-container--bootstrap4 .select2-selection--single .select2-selection__arrow b{top:60%;border-color:#343a40 transparent transparent;border-style:solid;border-width:5px 4px 0;width:0;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute}.select2-container--bootstrap4 .select2-selection--single .select2-selection__rendered{line-height:calc(1.5em + .75rem)}.select2-search--dropdown .select2-search__field{border:1px solid #ced4da;border-radius:.25rem}.select2-results__message{color:#6c757d}.select2-container--bootstrap4 .select2-selection--multiple{min-height:calc(1.5em + .75rem + 2px)!important}.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__rendered{-webkit-box-sizing:border-box;box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice{color:#343a40;border:1px solid #bdc6d0;border-radius:.2rem;padding:0 5px 0 0;cursor:pointer;float:left;margin-top:.3em;margin-right:5px}.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice__remove{color:#bdc6d0;font-weight:700;margin-left:3px;margin-right:1px;padding-right:3px;padding-left:3px;float:left}.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice__remove:hover{color:#343a40}.select2-container{display:block}.select2-container :focus{outline:0}.input-group .select2-container--bootstrap4{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.input-group-prepend~.select2-container--bootstrap4 .select2-selection{border-top-left-radius:0;border-bottom-left-radius:0}.select2-container--bootstrap4 .select2-selection{border:1px solid #ced4da;border-radius:.25rem;width:100%}.select2-container--bootstrap4.select2-container--focus .select2-selection{border-color:#17a2b8;-webkit-box-shadow:0 0 0 .2rem rgba(0,123,255,.25);box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.select2-container--bootstrap4.select2-container--focus.select2-container--open .select2-selection{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--bootstrap4.select2-container--disabled.select2-container--focus .select2-selection,.select2-container--bootstrap4.select2-container--disabled .select2-selection{background-color:#e9ecef;cursor:not-allowed;border-color:#ced4da;-webkit-box-shadow:none;box-shadow:none}.select2-container--bootstrap4.select2-container--disabled.select2-container--focus .select2-search__field,.select2-container--bootstrap4.select2-container--disabled .select2-search__field{background-color:transparent}form.was-validated select:invalid~.select2-container--bootstrap4 .select2-selection,select.is-invalid~.select2-container--bootstrap4 .select2-selection{border-color:#dc3545}form.was-validated select:valid~.select2-container--bootstrap4 .select2-selection,select.is-valid~.select2-container--bootstrap4 .select2-selection{border-color:#28a745}.select2-container--bootstrap4 .select2-dropdown{border-color:#ced4da;border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--bootstrap4 .select2-dropdown.select2-dropdown--above{border-top:1px solid #ced4da;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.select2-container--bootstrap4 .select2-dropdown .select2-results__option[aria-selected=true]{background-color:#e9ecef}.select2-container--bootstrap4 .select2-results__option--highlighted,.select2-container--bootstrap4 .select2-results__option--highlighted.select2-results__option[aria-selected=true]{background-color:#007bff;color:#f8f9fa}.select2-container--bootstrap4 .select2-results__option[role=group]{padding:0}.select2-container--bootstrap4 .select2-results>.select2-results__options{max-height:15em;overflow-y:auto}.select2-container--bootstrap4 .select2-results__group{padding:6px;display:list-item;color:#6c757d}.select2-container--bootstrap4 .select2-selection__clear{width:1.2em;height:1.2em;line-height:1.15em;padding-left:.3em;margin-top:.5em;border-radius:100%;background-color:#6c757d;color:#f8f9fa;float:right;margin-right:.3em}.select2-container--bootstrap4 .select2-selection__clear:hover{background-color:#343a40}
|
.select2-container--bootstrap4 .select2-selection--single{height:calc(1.5em + .75rem + 2px)!important}.select2-container--bootstrap4 .select2-selection--single .select2-selection__placeholder{color:#757575;line-height:calc(1.5em + .75rem)}.select2-container--bootstrap4 .select2-selection--single .select2-selection__arrow{position:absolute;top:50%;right:3px;width:20px}.select2-container--bootstrap4 .select2-selection--single .select2-selection__arrow b{top:60%;border-color:#343a40 transparent transparent;border-style:solid;border-width:5px 4px 0;width:0;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute}.select2-container--bootstrap4 .select2-selection--single .select2-selection__rendered{line-height:calc(1.5em + .75rem)}.select2-search--dropdown .select2-search__field{border:1px solid #ced4da;border-radius:.25rem}.select2-results__message{color:#6c757d}.select2-container--bootstrap4 .select2-selection--multiple{min-height:calc(1.5em + .75rem + 2px)!important}.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__rendered{-webkit-box-sizing:border-box;box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice{color:#343a40;border:1px solid #bdc6d0;border-radius:.2rem;padding:0 5px 0 0;cursor:pointer;float:left;margin-top:.3em;margin-right:5px}.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice__remove{color:#bdc6d0;font-weight:700;margin-left:3px;margin-right:1px;padding-right:3px;padding-left:3px;float:left}.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice__remove:hover{color:#343a40}.select2-container{display:block}.select2-container :focus{outline:0}.input-group .select2-container--bootstrap4{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.input-group-prepend~.select2-container--bootstrap4 .select2-selection{border-top-left-radius:0;border-bottom-left-radius:0}.select2-container--bootstrap4 .select2-selection{border:1px solid #ced4da;border-radius:.25rem;width:100%}.select2-container--bootstrap4.select2-container--focus .select2-selection{border-color:#17a2b8;-webkit-box-shadow:0 0 0 .2rem rgba(0,123,255,.25);box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.select2-container--bootstrap4.select2-container--focus.select2-container--open .select2-selection{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--bootstrap4.select2-container--disabled.select2-container--focus .select2-selection,.select2-container--bootstrap4.select2-container--disabled .select2-selection{background-color:#e9ecef;cursor:not-allowed;border-color:#ced4da;-webkit-box-shadow:none;box-shadow:none}.select2-container--bootstrap4.select2-container--disabled.select2-container--focus .select2-search__field,.select2-container--bootstrap4.select2-container--disabled .select2-search__field{background-color:transparent}form.was-validated select:invalid~.select2-container--bootstrap4 .select2-selection,select.is-invalid~.select2-container--bootstrap4 .select2-selection{border-color:#dc3545}form.was-validated select:valid~.select2-container--bootstrap4 .select2-selection,select.is-valid~.select2-container--bootstrap4 .select2-selection{border-color:#28a745}.select2-container--bootstrap4 .select2-dropdown{border-color:#ced4da;border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--bootstrap4 .select2-dropdown.select2-dropdown--above{border-top:1px solid #ced4da;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.select2-container--bootstrap4 .select2-dropdown .select2-results__option[aria-selected=true]{background-color:#e9ecef}.select2-container--bootstrap4 .select2-results__option--highlighted,.select2-container--bootstrap4 .select2-results__option--highlighted.select2-results__option[aria-selected=true]{background-color:#007bff;color:#f8f9fa}.select2-container--bootstrap4 .select2-results__option[role=group]{padding:0}.select2-container--bootstrap4 .select2-results>.select2-results__options{max-height:15em;overflow-y:auto}.select2-container--bootstrap4 .select2-results__group{padding:6px;display:list-item;color:#6c757d}.select2-container--bootstrap4 .select2-selection__clear{width:1.2em;height:1.2em;line-height:1.15em;padding-left:.3em;margin-top:.5em;border-radius:100%;background-color:#ccc;color:#f8f9fa;float:right;margin-right:.3em}.select2-container--bootstrap4 .select2-selection__clear:hover{background-color:#343a40}
|
@ -0,0 +1,11 @@
|
|||||||
|
class Admins::ChooseMirrorRepositoriesController < Admins::BaseController
|
||||||
|
def new
|
||||||
|
@mirror = MirrorRepository.find(params[:mirror_id])
|
||||||
|
@new_mirror = MirrorOperationRecord.where(mirror_repository_id: @mirror.id, status: 1, user_id: -1).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
mirror = MirrorRepository.find(params[:mirror_id])
|
||||||
|
Admins::ChooseMirrorService.call(mirror, current_user, params[:mirror_number])
|
||||||
|
end
|
||||||
|
end
|
@ -1,4 +1,51 @@
|
|||||||
class Admins::DashboardsController < Admins::BaseController
|
class Admins::DashboardsController < Admins::BaseController
|
||||||
def index
|
def index
|
||||||
|
@active_user_count = User.where(last_login_on: today).count
|
||||||
|
@weekly_active_user_count = User.where(last_login_on: current_week).count
|
||||||
|
@month_active_user_count = User.where(last_login_on: current_month).count
|
||||||
|
|
||||||
|
@new_user_count = User.where(created_on: current_month).count
|
||||||
|
end
|
||||||
|
|
||||||
|
def month_active_user
|
||||||
|
count = UserExtension.where(created_at: current_month).group(:identity).count
|
||||||
|
|
||||||
|
data = [
|
||||||
|
{ value: count['teacher'].to_i, name: '老师' },
|
||||||
|
{ value: count['student'].to_i, name: '学生' },
|
||||||
|
{ value: count['professional'].to_i, name: '专业人士' },
|
||||||
|
{ value: count[nil].to_i, name: '未选职业' },
|
||||||
|
]
|
||||||
|
|
||||||
|
render_ok(data: data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def evaluate
|
||||||
|
names = []
|
||||||
|
data = []
|
||||||
|
|
||||||
|
1.upto(7) do |i|
|
||||||
|
date = i.days.ago
|
||||||
|
names.unshift(date.strftime('%Y-%m-%d'))
|
||||||
|
|
||||||
|
count = Output.where(created_at: date.beginning_of_day..date.end_of_day).count
|
||||||
|
data.unshift(count)
|
||||||
|
end
|
||||||
|
|
||||||
|
render_ok(names: names, data: data)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def today
|
||||||
|
Time.now.beginning_of_day..Time.now.end_of_day
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_week
|
||||||
|
7.days.ago.beginning_of_day..Time.now.end_of_day
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_month
|
||||||
|
30.days.ago.beginning_of_day..Time.now.end_of_day
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -0,0 +1,20 @@
|
|||||||
|
class Admins::DepartmentMembersController < Admins::BaseController
|
||||||
|
|
||||||
|
helper_method :current_department
|
||||||
|
|
||||||
|
def create
|
||||||
|
Admins::AddDepartmentMemberService.call(current_department, params)
|
||||||
|
current_department.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@member = current_department.department_members.find_by(user_id: params[:user_id])
|
||||||
|
@member.destroy! if @member.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_department
|
||||||
|
@_current_department ||= Department.find(params[:department_id])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,95 @@
|
|||||||
|
class Admins::DepartmentsController < Admins::BaseController
|
||||||
|
|
||||||
|
helper_method :current_department
|
||||||
|
|
||||||
|
def index
|
||||||
|
params[:sort_by] ||= 'created_at'
|
||||||
|
params[:sort_direction] ||= 'desc'
|
||||||
|
|
||||||
|
departments = Admins::DepartmentQuery.call(params)
|
||||||
|
|
||||||
|
@departments = paginate departments.preload(:school, :member_users)
|
||||||
|
|
||||||
|
department_ids = @departments.map(&:id)
|
||||||
|
@users_count = UserExtension.where(department_id: department_ids).group(:department_id).count
|
||||||
|
@professional_auth_count = UserExtension.where(department_id: department_ids)
|
||||||
|
.joins(:user).where(users: { professional_certification: true })
|
||||||
|
.group(:department_id).count
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
department_name = params[:department_name].to_s.strip
|
||||||
|
school = School.find(params[:school_id])
|
||||||
|
|
||||||
|
return render_error('部门名称重复') if school.departments.exists?(name: department_name)
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
department = school.departments.create!(name: department_name, is_auth: 1)
|
||||||
|
ApplyAddDepartment.create!(school_id: school.id, status: 1, name: department.name,
|
||||||
|
department_id: department.id, user_id: current_user.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
identifier = update_params.delete(:identifier).presence
|
||||||
|
if identifier && Department.where.not(id: current_department.id).exists?(identifier: identifier)
|
||||||
|
return render_error('统计链接重复', type: :notify)
|
||||||
|
end
|
||||||
|
|
||||||
|
current_department.update!(update_params.merge(identifier: identifier))
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
current_department.apply_add_departments.update_all(status: 2)
|
||||||
|
|
||||||
|
user_ids = current_department.user_extensions.pluck(:user_id)
|
||||||
|
if user_ids.present?
|
||||||
|
DeleteDepartmentNotifyJob.perform_later(current_department.id, 0, user_ids)
|
||||||
|
current_department.soft_delete!
|
||||||
|
else
|
||||||
|
current_department.destroy!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
render_delete_success
|
||||||
|
end
|
||||||
|
|
||||||
|
def merge
|
||||||
|
return render_error('请选择其它部门') if params[:origin_department_id].to_s == params[:department_id].to_s
|
||||||
|
|
||||||
|
origin_department = Department.find(params[:origin_department_id])
|
||||||
|
to_department = Department.find(params[:department_id])
|
||||||
|
|
||||||
|
return render_error('部门所属单位不相同') if origin_department.school_id != to_department.school_id
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
origin_department.apply_add_departments.delete_all
|
||||||
|
|
||||||
|
origin_department.user_extensions.update_all(department_id: to_department.id)
|
||||||
|
|
||||||
|
if to_department.identifier.blank? && origin_department.identifier.present?
|
||||||
|
to_department.update!(identifier: origin_department.identifier)
|
||||||
|
end
|
||||||
|
|
||||||
|
origin_department.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_department
|
||||||
|
@_current_department ||= Department.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_params
|
||||||
|
params.require(:department).permit(:name, :identifier, :host_count)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,54 @@
|
|||||||
|
class Admins::FilesController < Admins::BaseController
|
||||||
|
before_action :convert_file!, only: [:create]
|
||||||
|
|
||||||
|
def create
|
||||||
|
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||||
|
|
||||||
|
Util.write_file(@file, file_path)
|
||||||
|
|
||||||
|
render_ok(source_id: params[:source_id], source_type: params[:source_type].to_s, url: file_url)
|
||||||
|
rescue StandardError => ex
|
||||||
|
logger_error(ex)
|
||||||
|
render_error('上传失败')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def convert_file!
|
||||||
|
max_size = 10 * 1024 * 1024 # 10M
|
||||||
|
if params[:file].class == ActionDispatch::Http::UploadedFile
|
||||||
|
@file = params[:file]
|
||||||
|
render_error('请上传文件') if @file.size.zero?
|
||||||
|
render_error('文件大小超过限制') if @file.size > max_size
|
||||||
|
else
|
||||||
|
file = params[:file].to_s.strip
|
||||||
|
return render_error('请上传正确的图片') if file.blank?
|
||||||
|
@file = Util.convert_base64_image(file, max_size: max_size)
|
||||||
|
end
|
||||||
|
rescue Base64ImageConverter::Error => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_path
|
||||||
|
@_file_path ||= begin
|
||||||
|
case params[:source_type].to_s
|
||||||
|
when 'Shixun' then
|
||||||
|
disk_filename('Shixun', params[:source_id])
|
||||||
|
else
|
||||||
|
disk_filename(params[:source_type].to_s, params[:source_id].to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def disk_filename(type, id)
|
||||||
|
File.join(storage_path, type.to_s, id.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
def storage_path
|
||||||
|
@_storage_path ||= File.join(Rails.root, 'public', 'images', 'avatars')
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_url
|
||||||
|
File.join('/images/avatars/', params[:source_type].to_s, params[:source_id].to_s)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,25 @@
|
|||||||
|
class Admins::LibraryAppliesController < Admins::BaseController
|
||||||
|
def index
|
||||||
|
params[:status] ||= 'pending'
|
||||||
|
applies = Admins::LibraryApplyQuery.call(params)
|
||||||
|
|
||||||
|
@library_applies = paginate applies.preload(library: :user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def agree
|
||||||
|
Libraries::AgreeApplyService.new(current_library_apply, current_user).call
|
||||||
|
render_success_js
|
||||||
|
end
|
||||||
|
|
||||||
|
def refuse
|
||||||
|
Libraries::RefuseApplyService.new(current_library_apply, current_user, reason: params[:reason]).call
|
||||||
|
|
||||||
|
render_success_js
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_library_apply
|
||||||
|
@_current_library_apply ||= LibraryApply.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,97 @@
|
|||||||
|
class Admins::MirrorRepositoriesController < Admins::BaseController
|
||||||
|
before_action :check_shixun_mirrors!, only: [:index]
|
||||||
|
|
||||||
|
def index
|
||||||
|
mirrors = MirrorRepository.all
|
||||||
|
mirrors = mirrors.reorder(status: :desc, main_type: :desc, type_name: :asc)
|
||||||
|
|
||||||
|
@mirrors = paginate mirrors.includes(:mirror_scripts)
|
||||||
|
@error_mirror_names = MirrorRepository.where(status: 5).pluck(:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@mirror = MirrorRepository.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@mirror = MirrorRepository.new
|
||||||
|
Admins::SaveMirrorRepositoryService.call(@mirror, current_user, form_params)
|
||||||
|
|
||||||
|
flash[:success] = '保存成功'
|
||||||
|
redirect_to edit_admins_mirror_repository_path(@mirror)
|
||||||
|
rescue ActiveRecord::RecordInvalid
|
||||||
|
flash.now[:danger] = '保存失败'
|
||||||
|
render 'new'
|
||||||
|
rescue Admins::SaveMirrorRepositoryService::Error => ex
|
||||||
|
flash.now[:danger] = ex.message
|
||||||
|
render 'new'
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@mirror = current_mirror
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@mirror = current_mirror
|
||||||
|
|
||||||
|
Admins::SaveMirrorRepositoryService.call(current_mirror, current_user, form_params)
|
||||||
|
|
||||||
|
flash[:success] = '保存成功'
|
||||||
|
redirect_to edit_admins_mirror_repository_path(current_mirror)
|
||||||
|
rescue ActiveRecord::RecordInvalid
|
||||||
|
flash.now[:danger] = '保存失败'
|
||||||
|
render 'edit'
|
||||||
|
rescue Admins::SaveMirrorRepositoryService::Error => ex
|
||||||
|
flash.now[:danger] = ex.message
|
||||||
|
render 'edit'
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
return render_js_error('该状态下不允许删除') unless current_mirror.deletable?
|
||||||
|
|
||||||
|
current_mirror.destroy!
|
||||||
|
|
||||||
|
render_delete_success
|
||||||
|
end
|
||||||
|
|
||||||
|
def for_select
|
||||||
|
mirrors = MirrorRepository.all
|
||||||
|
|
||||||
|
keyword = params[:keyword].to_s.strip
|
||||||
|
mirrors = mirrors.where('name LIKE ?', "%#{keyword}%") if keyword.present?
|
||||||
|
|
||||||
|
@mirrors = paginate mirrors
|
||||||
|
|
||||||
|
render_ok(count: @mirrors.total_count, mirrors: @mirrors.as_json(only: %i[id name]))
|
||||||
|
end
|
||||||
|
|
||||||
|
def merge
|
||||||
|
origin_mirror = MirrorRepository.find(params[:mirror_id])
|
||||||
|
mirror = MirrorRepository.find(params[:new_mirror_id])
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
origin_mirror.update!(name: mirror.name, mirrorID: mirror.mirrorID)
|
||||||
|
mirror.destroy!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_mirror
|
||||||
|
@_current_mirror ||= MirrorRepository.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_params
|
||||||
|
columns = %i[type_name main_type time_limit resource_limit cpu_limit memory_limit description status]
|
||||||
|
params.require(:mirror_repository).permit(*columns)
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_shixun_mirrors!
|
||||||
|
return
|
||||||
|
return unless request.format.html?
|
||||||
|
|
||||||
|
Admins::CheckShixunMirrorsService.call
|
||||||
|
rescue Admins::CheckShixunMirrorsService::Error => e
|
||||||
|
internal_server_error(e.message)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,59 @@
|
|||||||
|
class Admins::MirrorScriptsController < Admins::BaseController
|
||||||
|
helper_method :current_mirror
|
||||||
|
|
||||||
|
def index
|
||||||
|
scripts = current_mirror.mirror_scripts.order(updated_at: :desc)
|
||||||
|
@scripts = paginate scripts
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@script = current_mirror.mirror_scripts.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@script = current_mirror.mirror_scripts.new(form_params)
|
||||||
|
|
||||||
|
if @script.save
|
||||||
|
flash[:success] = '保存成功'
|
||||||
|
redirect_to edit_admins_mirror_repository_mirror_script_path(current_mirror, @script)
|
||||||
|
else
|
||||||
|
flash[:danger] = '保存失败'
|
||||||
|
render 'new'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@script = current_script
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@script = current_script
|
||||||
|
|
||||||
|
if @script.update(form_params)
|
||||||
|
flash[:success] = '保存成功'
|
||||||
|
redirect_to edit_admins_mirror_repository_mirror_script_path(current_mirror, @script)
|
||||||
|
else
|
||||||
|
flash[:danger] = '保存失败'
|
||||||
|
render 'edit'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
current_script.destroy!
|
||||||
|
render_delete_success
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_script
|
||||||
|
@_current_script ||= current_mirror.mirror_scripts.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_mirror
|
||||||
|
@_current_mirror ||= MirrorRepository.find(params[:mirror_repository_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_params
|
||||||
|
params.require(:mirror_script).permit(:script_type, :description, :script)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,14 @@
|
|||||||
|
class Admins::MyshixunsController < Admins::BaseController
|
||||||
|
def index
|
||||||
|
params[:sort_by] = params[:sort_by].presence || 'created_at'
|
||||||
|
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||||
|
|
||||||
|
myshixuns = Admins::MyshixunQuery.call(params)
|
||||||
|
|
||||||
|
@myshixuns = paginate myshixuns.includes(:last_executable_task, :last_task, shixun: :user, user: { user_extension: :school })
|
||||||
|
|
||||||
|
myshixun_ids = @myshixuns.map(&:id)
|
||||||
|
@finish_game_count = Game.where(myshixun_id: myshixun_ids, status: 2).group(:myshixun_id).count
|
||||||
|
@total_score = Game.where(myshixun_id: myshixun_ids, status: 2).where('final_score > 0').group(:myshixun_id).sum(:final_score)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,37 @@
|
|||||||
|
class Admins::ProjectPackageAppliesController < Admins::BaseController
|
||||||
|
before_action :current_apply,only: [:agree,:refuse]
|
||||||
|
|
||||||
|
def index
|
||||||
|
params[:status] ||= 'pending'
|
||||||
|
status = params[:status]
|
||||||
|
if status == 'all'
|
||||||
|
status = %w(agreed refused)
|
||||||
|
end
|
||||||
|
package_applies = ProjectPackageApply.where(status: status)
|
||||||
|
keyword = params[:keyword].to_s.strip || ""
|
||||||
|
if keyword.present?
|
||||||
|
package_applies = package_applies.joins(:project_package).where("project_packages.title like ?","%#{keyword}%")
|
||||||
|
end
|
||||||
|
@package_applies = paginate package_applies.includes(project_package: { creator: :user_extension })
|
||||||
|
end
|
||||||
|
|
||||||
|
def agree
|
||||||
|
ProjectPackages::AgreeApplyService.new(current_apply).call
|
||||||
|
render_success_js
|
||||||
|
rescue ProjectPackages::AgreeApplyService::Error => e
|
||||||
|
render json: { status: -1, message: e.message }
|
||||||
|
end
|
||||||
|
|
||||||
|
def refuse
|
||||||
|
ProjectPackages::RefuseApplyService.new(current_apply, reason: params[:reason]).call
|
||||||
|
render_success_js
|
||||||
|
rescue ProjectPackages::RefuseApplyService::Error => e
|
||||||
|
render json: { status: -1, message: e.message }
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_apply
|
||||||
|
@_current_apply ||= ProjectPackageApply.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,97 @@
|
|||||||
|
class Admins::ShixunSettingsController < Admins::BaseController
|
||||||
|
|
||||||
|
def index
|
||||||
|
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||||
|
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||||
|
|
||||||
|
shixun_settings = Admins::ShixunSettingsQuery.call(params)
|
||||||
|
@editing_shixuns = shixun_settings.where(status:0).size
|
||||||
|
@pending_shixuns = shixun_settings.where(status:1).size
|
||||||
|
@processed_shixuns = shixun_settings.where(status:2).size
|
||||||
|
@closed_shixuns = shixun_settings.where(status:3).size
|
||||||
|
|
||||||
|
@sort_json = {
|
||||||
|
can_copy: params[:can_copy].present? ? params[:can_copy] : false,
|
||||||
|
webssh: params[:webssh].present? ? params[:webssh] : "0",
|
||||||
|
hidden: params[:hidden].present? ? params[:hidden] : false,
|
||||||
|
homepage_show: params[:homepage_show].present? ? params[:homepage_show] : false,
|
||||||
|
task_pass: params[:task_pass].present? ? params[:task_pass] : false,
|
||||||
|
code_hidden: params[:code_hidden].present? ? params[:code_hidden] : false
|
||||||
|
}
|
||||||
|
|
||||||
|
@shixuns_type_check = MirrorRepository.pluck(:type_name,:id)
|
||||||
|
@shixun_tags = TagRepertoire.order("name asc").pluck(:name,:id)
|
||||||
|
@params_page = params[:page] || 1
|
||||||
|
@shixun_settings = paginate shixun_settings.preload(:user,:tag_repertoires)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
format.html
|
||||||
|
format.xls{
|
||||||
|
filename = "实训详情_#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}.xls"
|
||||||
|
send_data(shixun_list_xls(shixun_settings), :type => 'application/octet-stream', :filename => filename_for_content_disposition(filename))
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@shixun = Shixun.find_by(id:params[:id])
|
||||||
|
@page_no = params[:page_no] || "1"
|
||||||
|
@shixun_tags = TagRepertoire.order("name asc").pluck(:name,:id)
|
||||||
|
tag_ids = params[:tag_repertoires]
|
||||||
|
if tag_ids.present?
|
||||||
|
@shixun&.shixun_tag_repertoires.delete_all
|
||||||
|
tag_repertoire_ids = @shixun&.tag_repertoires&.pluck(:id)
|
||||||
|
tag_ids.each do |id|
|
||||||
|
unless tag_repertoire_ids.include?(id)
|
||||||
|
tag_repertoire = @shixun.shixun_tag_repertoires.new(shixun_id:@shixun.id,tag_repertoire_id:id)
|
||||||
|
tag_repertoire.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
unless @shixun.update_attributes(setting_params)
|
||||||
|
redirect_to admins_shixun_settings_path
|
||||||
|
flash[:danger] = "更新失败"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def shixun_list_xls shixuns
|
||||||
|
xls_report = StringIO.new
|
||||||
|
book = Spreadsheet::Workbook.new
|
||||||
|
sheet1 = book.create_worksheet :name => "sheet"
|
||||||
|
blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10
|
||||||
|
sheet1.row(0).default_format = blue
|
||||||
|
sheet1.row(0).concat(["实训ID","实训名称","技术平台", "Fork源", "实践任务","选择题任务","挑战人数", "通关人数", "状态","创建者", "单位", "职业", "关卡序号","关卡名称","技能标签"])
|
||||||
|
count_row = 1
|
||||||
|
shixuns.find_each do |shixun|
|
||||||
|
sheet1[count_row, 0] = shixun.identifier
|
||||||
|
sheet1[count_row, 1] = shixun.name
|
||||||
|
sheet1[count_row, 2] = shixun.shixun_main_name
|
||||||
|
sheet1[count_row, 3] = shixun.fork_identifier
|
||||||
|
sheet1[count_row, 4] = shixun.challenges.practice_type.count
|
||||||
|
sheet1[count_row, 5] = shixun.challenges.choose_type.count
|
||||||
|
sheet1[count_row, 6] = shixun.myshixuns.count
|
||||||
|
sheet1[count_row, 7] = shixun.myshixuns.finished.count
|
||||||
|
sheet1[count_row, 8] = shixun.shixun_status
|
||||||
|
sheet1[count_row, 9] = shixun.owner.show_real_name
|
||||||
|
sheet1[count_row, 10] = shixun.owner.school_name
|
||||||
|
sheet1[count_row, 11] = shixun.owner.identity
|
||||||
|
shixun.challenges.each do |challenge|
|
||||||
|
sheet1[count_row, 12] = "第#{challenge.position}关"
|
||||||
|
sheet1[count_row, 13] = challenge.subject
|
||||||
|
sheet1[count_row, 14] = challenge.tags_show
|
||||||
|
count_row += 1
|
||||||
|
end
|
||||||
|
count_row += 1
|
||||||
|
end
|
||||||
|
book.write xls_report
|
||||||
|
xls_report.string
|
||||||
|
end
|
||||||
|
|
||||||
|
def setting_params
|
||||||
|
params.permit(:use_scope,:excute_time,:close,:status,:can_copy,:webssh,:hidden,:homepage_show,:task_pass,:code_hidden,:id,tag_repertoires:[])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,64 @@
|
|||||||
|
class Admins::ShixunsController < Admins::BaseController
|
||||||
|
|
||||||
|
def index
|
||||||
|
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||||
|
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||||
|
shixuns = Admins::ShixunQuery.call(params)
|
||||||
|
@editing_shixuns = shixuns.where(status:0).size
|
||||||
|
@pending_shixuns = shixuns.where(status:1).size
|
||||||
|
@processed_shixuns = shixuns.where(status:2).size
|
||||||
|
@closed_shixuns = shixuns.where(status:3).size
|
||||||
|
@shixuns_type_check = MirrorRepository.pluck(:type_name,:id)
|
||||||
|
@params_page = params[:page] || 1
|
||||||
|
@shixuns = paginate shixuns.preload(:user,:challenges)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
format.html
|
||||||
|
format.xls{
|
||||||
|
filename = "实训详情_#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}.xls"
|
||||||
|
send_data(shixun_list_xls(shixuns), :type => 'application/octet-stream', :filename => filename_for_content_disposition(filename))
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
Shixun.find(params[:id]).destroy!
|
||||||
|
|
||||||
|
render_delete_success
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def shixun_list_xls shixuns
|
||||||
|
xls_report = StringIO.new
|
||||||
|
book = Spreadsheet::Workbook.new
|
||||||
|
sheet1 = book.create_worksheet :name => "sheet"
|
||||||
|
blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10
|
||||||
|
sheet1.row(0).default_format = blue
|
||||||
|
sheet1.row(0).concat(["实训ID","实训名称","技术平台", "Fork源", "实践任务","选择题任务","挑战人数", "通关人数", "状态","创建者", "单位", "职业", "关卡序号","关卡名称","技能标签"])
|
||||||
|
count_row = 1
|
||||||
|
shixuns.find_each do |shixun|
|
||||||
|
sheet1[count_row, 0] = shixun.identifier
|
||||||
|
sheet1[count_row, 1] = shixun.name
|
||||||
|
sheet1[count_row, 2] = shixun.shixun_main_name
|
||||||
|
sheet1[count_row, 3] = shixun.fork_identifier
|
||||||
|
sheet1[count_row, 4] = shixun.challenges.practice_type.count
|
||||||
|
sheet1[count_row, 5] = shixun.challenges.choose_type.count
|
||||||
|
sheet1[count_row, 6] = shixun.myshixuns.count
|
||||||
|
sheet1[count_row, 7] = shixun.myshixuns.finished.count
|
||||||
|
sheet1[count_row, 8] = shixun.shixun_status
|
||||||
|
sheet1[count_row, 9] = shixun.owner.show_real_name
|
||||||
|
sheet1[count_row, 10] = shixun.owner.school_name
|
||||||
|
sheet1[count_row, 11] = shixun.owner.identity
|
||||||
|
shixun.challenges.each do |challenge|
|
||||||
|
sheet1[count_row, 12] = "第#{challenge.position}关"
|
||||||
|
sheet1[count_row, 13] = challenge.subject
|
||||||
|
sheet1[count_row, 14] = challenge.tags_show
|
||||||
|
count_row += 1
|
||||||
|
end
|
||||||
|
count_row += 1
|
||||||
|
end
|
||||||
|
book.write xls_report
|
||||||
|
xls_report.string
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,41 @@
|
|||||||
|
class Admins::VideoAppliesController < Admins::BaseController
|
||||||
|
|
||||||
|
def index
|
||||||
|
params[:status] ||= 'pending'
|
||||||
|
status = params[:status]
|
||||||
|
if status == 'all'
|
||||||
|
status = %w(agreed refused)
|
||||||
|
end
|
||||||
|
|
||||||
|
applies = VideoApply.where(status: status).order('video_applies.updated_at desc')
|
||||||
|
|
||||||
|
search = params[:keyword].to_s.strip
|
||||||
|
if search.present?
|
||||||
|
applies = applies.joins(:video)
|
||||||
|
.where('videos.title like :search', search: "%#{search}%")
|
||||||
|
end
|
||||||
|
|
||||||
|
@video_applies = paginate applies.includes(video: { user: :user_extension })
|
||||||
|
end
|
||||||
|
|
||||||
|
def agree
|
||||||
|
Videos::AgreeApplyService.new(current_video_apply, current_user).call
|
||||||
|
render_success_js
|
||||||
|
rescue Videos::AgreeApplyService::Error => e
|
||||||
|
render json: { status: -1, message: e.message }
|
||||||
|
end
|
||||||
|
|
||||||
|
def refuse
|
||||||
|
Videos::RefuseApplyService.new(current_video_apply, current_user, reason: params[:reason]).call
|
||||||
|
render_success_js
|
||||||
|
rescue Videos::RefuseApplyService::Error => e
|
||||||
|
render json: { status: -1, message: e.message }
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_video_apply
|
||||||
|
@_current_video_apply ||= VideoApply.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,171 @@
|
|||||||
|
class CollegesController < ApplicationController
|
||||||
|
include Admins::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.role in (1,2,3) and c.school_id = #{current_school.id} AND m.user_id=users.id AND c.is_delete = 0) as course_count
|
||||||
|
FROM `users`, user_extensions ue where users.id=ue.user_id and ue.identity=0 and ue.school_id=#{current_school.id} 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.customer_id && 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
|
@ -0,0 +1,129 @@
|
|||||||
|
#encoding: UTF-8
|
||||||
|
class ExerciseBanksController < ApplicationController
|
||||||
|
before_action :require_login
|
||||||
|
before_action :find_bank, except: [:choose_shixun]
|
||||||
|
before_action :bank_admin, only: [:update]
|
||||||
|
before_action :commit_shixun_present, only: [:commit_shixun]
|
||||||
|
|
||||||
|
def show
|
||||||
|
@exercise_questions = @bank.exercise_bank_questions&.includes(:exercise_bank_choices, :exercise_bank_shixun_challenges,
|
||||||
|
:exercise_bank_standard_answers).order("question_number ASC")
|
||||||
|
|
||||||
|
if @bank.container_type == "Exercise"
|
||||||
|
get_exercise_question_count
|
||||||
|
else
|
||||||
|
get_poll_question_count
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
tip_exception("标题不能为空!") if params[:exercise_name].blank?
|
||||||
|
@bank.update_attributes!(name: params[:exercise_name], description: params[:exercise_description])
|
||||||
|
normal_status(0,"更新成功")
|
||||||
|
end
|
||||||
|
|
||||||
|
def choose_shixun
|
||||||
|
search = params[:search]
|
||||||
|
type = params[:type]
|
||||||
|
# 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭)
|
||||||
|
if current_user.admin?
|
||||||
|
@shixuns = Shixun.unhidden
|
||||||
|
else
|
||||||
|
none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id)
|
||||||
|
|
||||||
|
@shixuns = Shixun.where.not(id: none_shixun_ids).unhidden
|
||||||
|
end
|
||||||
|
|
||||||
|
# 实训的所有标签
|
||||||
|
@tags = TagRepertoire.select([:id, :name]).joins(:shixuns).where(shixuns: {id: @shixuns}).distinct
|
||||||
|
|
||||||
|
if params[:search] && params[:search].strip != ""
|
||||||
|
@shixuns = @shixuns.joins(:user).where("shixuns.name like ? or concat(users.lastname, users.firstname) like ?",
|
||||||
|
"%#{search}%", "%#{search}%").distinct
|
||||||
|
end
|
||||||
|
|
||||||
|
unless type.blank? || type == "all"
|
||||||
|
@shixuns = @shixuns.joins(:shixun_tag_repertoires).where(shixun_tag_repertoires: {tag_repertoire_id: type}).distinct
|
||||||
|
end
|
||||||
|
|
||||||
|
@shixuns = @shixuns.select([:id, :name, :status, :myshixuns_count, :identifier, :user_id, :trainee])
|
||||||
|
@total_count = @shixuns.size
|
||||||
|
|
||||||
|
## 分页参数
|
||||||
|
page = params[:page] || 1
|
||||||
|
@shixuns = @shixuns.reorder("shixuns.created_at desc").includes(:challenges, user: [user_extension: :school]).page(page).per(10)
|
||||||
|
end
|
||||||
|
|
||||||
|
#确认实训的选择
|
||||||
|
def commit_shixun
|
||||||
|
@shixun_challenges = @shixun.challenges
|
||||||
|
@shixun_challenges_count = @shixun_challenges.size
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def find_bank
|
||||||
|
@bank = ExerciseBank.find_by!(id: params[:id])
|
||||||
|
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin? ||
|
||||||
|
(current_user.certification_teacher? && @bank.is_public)
|
||||||
|
end
|
||||||
|
|
||||||
|
def bank_admin
|
||||||
|
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin?
|
||||||
|
end
|
||||||
|
|
||||||
|
#判断实训是否已选择
|
||||||
|
def commit_shixun_present
|
||||||
|
question_shixun_ids = @exercise.exercise_bank_questions.pluck(:shixun_id).reject(&:blank?)
|
||||||
|
shixun_id = params[:shixun_id]
|
||||||
|
@shixun = Shixun.find_by(id: shixun_id)
|
||||||
|
if shixun_id.present? && question_shixun_ids.include?(shixun_id)
|
||||||
|
normal_status(-1,"该实训已选择!")
|
||||||
|
elsif @shixun.blank?
|
||||||
|
normal_status(-1,"该实训不存在!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_exercise_question_count
|
||||||
|
@exercise_ques_count = @exercise_questions.size # 全部的题目数
|
||||||
|
@exercise_ques_scores = @exercise_questions.pluck(:question_score).sum
|
||||||
|
|
||||||
|
#单选题的数量及分数
|
||||||
|
exercise_single_ques = @exercise_questions.find_by_custom("question_type", Exercise::SINGLE)
|
||||||
|
@exercise_single_ques_count = exercise_single_ques.size
|
||||||
|
@exercise_single_ques_scores = exercise_single_ques.pluck(:question_score).sum
|
||||||
|
|
||||||
|
#多选题的数量及分数
|
||||||
|
exercise_double_ques = @exercise_questions.find_by_custom("question_type", Exercise::MULTIPLE)
|
||||||
|
@exercise_double_ques_count = exercise_double_ques.size
|
||||||
|
@exercise_double_ques_scores = exercise_double_ques.pluck(:question_score).sum
|
||||||
|
|
||||||
|
# 判断题数量及分数
|
||||||
|
exercise_ques_judge = @exercise_questions.find_by_custom("question_type", Exercise::JUDGMENT)
|
||||||
|
@exercise_ques_judge_count = exercise_ques_judge.size
|
||||||
|
@exercise_ques_judge_scores = exercise_ques_judge.pluck(:question_score).sum
|
||||||
|
|
||||||
|
#填空题数量及分数
|
||||||
|
exercise_ques_null = @exercise_questions.find_by_custom("question_type", Exercise::COMPLETION)
|
||||||
|
@exercise_ques_null_count = exercise_ques_null.size
|
||||||
|
@exercise_ques_null_scores = exercise_ques_null.pluck(:question_score).sum
|
||||||
|
|
||||||
|
#简答题数量及分数
|
||||||
|
exercise_ques_main = @exercise_questions.find_by_custom("question_type", Exercise::SUBJECTIVE)
|
||||||
|
@exercise_ques_main_count = exercise_ques_main.size
|
||||||
|
@exercise_ques_main_scores = exercise_ques_main.pluck(:question_score).sum
|
||||||
|
|
||||||
|
#实训题数量及分数
|
||||||
|
exercise_ques_shixun = @exercise_questions.find_by_custom("question_type", Exercise::PRACTICAL)
|
||||||
|
@exercise_ques_shixun_count = exercise_ques_shixun.size
|
||||||
|
@exercise_ques_shixun_scores = exercise_ques_shixun.pluck(:question_score).sum
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_poll_question_count
|
||||||
|
@poll_questions_count = @exercise_questions&.size # 全部的题目数
|
||||||
|
@poll_question_singles = @exercise_questions.find_by_custom("question_type", 1).size # 单选题
|
||||||
|
@poll_question_doubles = @exercise_questions.find_by_custom("question_type", 2).size # 多选题
|
||||||
|
@poll_question_mains = @exercise_questions.find_by_custom("question_type", 3).size #主观题
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -0,0 +1,40 @@
|
|||||||
|
class GtopicBanksController < ApplicationController
|
||||||
|
before_action :require_login
|
||||||
|
before_action :find_bank
|
||||||
|
before_action :bank_admin, only: [:edit, :update]
|
||||||
|
|
||||||
|
def show
|
||||||
|
@bank_attachments = @bank.attachments
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@attachments = @bank.attachments
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
@bank.update_attributes(gtopic_bank_params)
|
||||||
|
Attachment.associate_container(params[:attachment_ids], @bank.id, @bank.class) if params[:attachment_ids]
|
||||||
|
normal_status(0, "更新成功")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def find_bank
|
||||||
|
@bank = GtopicBank.find_by!(id: params[:id])
|
||||||
|
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin? ||
|
||||||
|
(current_user.certification_teacher? && @bank.is_public)
|
||||||
|
end
|
||||||
|
|
||||||
|
def bank_admin
|
||||||
|
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin?
|
||||||
|
end
|
||||||
|
|
||||||
|
def gtopic_bank_params
|
||||||
|
tip_exception("name参数不能为空") if params[:gtopic_bank][:name].blank?
|
||||||
|
tip_exception("description参数不能为空") if params[:gtopic_bank][:description].blank?
|
||||||
|
params.require(:gtopic_bank).permit(:name, :topic_type, :topic_source, :topic_property_first, :description,
|
||||||
|
:topic_property_second, :source_unit, :topic_repeat, :province, :city)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,69 @@
|
|||||||
|
class HomeworkBanksController < ApplicationController
|
||||||
|
before_action :require_login
|
||||||
|
before_action :find_bank
|
||||||
|
before_action :bank_params, only: [:update]
|
||||||
|
before_action :bank_admin, only: [:update, :destroy, :set_public]
|
||||||
|
|
||||||
|
def show
|
||||||
|
@bank_attachments = @bank.attachments.where(attachtype: 1)
|
||||||
|
@reference_attachments = @bank.attachments.where(attachtype: 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
if @bank.homework_type == 1
|
||||||
|
@bank.update_attributes(name: params[:name], description: params[:description], reference_answer: params[:reference_answer])
|
||||||
|
elsif @bank.homework_type == 3
|
||||||
|
@bank.update_attributes(name: params[:name], description: params[:description], reference_answer: params[:reference_answer],
|
||||||
|
base_on_project: params[:base_on_project], min_num: params[:min_num], max_num: params[:max_num])
|
||||||
|
end
|
||||||
|
|
||||||
|
# 作业描述的附件
|
||||||
|
Attachment.associate_container(params[:attachment_ids], @bank.id, @bank.class) if params[:attachment_ids]
|
||||||
|
# 作业参考答案的附件
|
||||||
|
Attachment.associate_container(params[:reference_attachment_ids], @bank.id, @bank.class, 2) if params[:reference_attachment_ids]
|
||||||
|
|
||||||
|
normal_status(0, "更新成功")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
@bank.homework_commons.update_all(homework_bank_id: nil)
|
||||||
|
@bank.destroy!
|
||||||
|
normal_status("删除成功")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_public
|
||||||
|
@bank.update_attributes(is_public: 1)
|
||||||
|
normal_status("更新成功")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def find_bank
|
||||||
|
@bank = HomeworkBank.find_by!(id: params[:id])
|
||||||
|
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin? ||
|
||||||
|
(current_user.certification_teacher? && @bank.is_public)
|
||||||
|
end
|
||||||
|
|
||||||
|
def bank_admin
|
||||||
|
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin?
|
||||||
|
end
|
||||||
|
|
||||||
|
def bank_params
|
||||||
|
tip_exception("name参数不能为空") if params[:homework_bank][:name].blank?
|
||||||
|
tip_exception("description参数不能为空") if params[:homework_bank][:description].blank?
|
||||||
|
if @bank.homework_type == 3
|
||||||
|
tip_exception("base_on_project参数不能为空") if params[:homework_bank][:base_on_project].nil?
|
||||||
|
tip_exception("min_num参数不能为空") if params[:homework_bank][:min_num].blank?
|
||||||
|
tip_exception("max_num参数不能为空") if params[:homework_bank][:max_num].blank?
|
||||||
|
tip_exception("最小人数不能小于1") if params[:homework_bank][:min_num].to_i < 1
|
||||||
|
tip_exception("最大人数不能小于最小人数") if params[:homework_bank][:max_num].to_i < params[:homework_bank][:min_num].to_i
|
||||||
|
end
|
||||||
|
params.require(:homework_bank).permit(:name, :description, :reference_answer) if @bank.homework_type == 1
|
||||||
|
params.require(:homework_bank).permit(:name, :description, :reference_answer, :min_num, :max_num, :base_on_project) if @bank.homework_type == 3
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -0,0 +1,49 @@
|
|||||||
|
class TaskBanksController < ApplicationController
|
||||||
|
before_action :require_login
|
||||||
|
before_action :find_bank
|
||||||
|
before_action :bank_admin, only: [:update]
|
||||||
|
|
||||||
|
def show
|
||||||
|
@bank_attachments = @bank.attachments
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
begin
|
||||||
|
@bank.update_attributes(gtask_bank_params)
|
||||||
|
Attachment.associate_container(params[:attachment_ids], @bank.id, @bank.class) if params[:attachment_ids]
|
||||||
|
normal_status(0, "更新成功")
|
||||||
|
rescue Exception => e
|
||||||
|
uid_logger(e.message)
|
||||||
|
tip_exception(e.message)
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def find_bank
|
||||||
|
@bank = GtaskBank.find_by!(id: params[:id])
|
||||||
|
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin? ||
|
||||||
|
(current_user.certification_teacher? && @bank.is_public)
|
||||||
|
end
|
||||||
|
|
||||||
|
def bank_admin
|
||||||
|
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin?
|
||||||
|
end
|
||||||
|
|
||||||
|
def gtask_bank_params
|
||||||
|
tip_exception("name参数不能为空") if params[:gtask_bank][:name].blank?
|
||||||
|
tip_exception("description参数不能为空") if params[:gtask_bank][:description].blank?
|
||||||
|
if @bank.homework_type == 3
|
||||||
|
tip_exception("base_on_project参数不能为空") if params[:gtask_bank][:base_on_project].nil?
|
||||||
|
tip_exception("min_num参数不能为空") if params[:gtask_bank][:min_num].blank?
|
||||||
|
tip_exception("max_num参数不能为空") if params[:gtask_bank][:max_num].blank?
|
||||||
|
tip_exception("最小人数不能小于1") if params[:gtask_bank][:min_num].to_i < 1
|
||||||
|
tip_exception("最大人数不能小于最小人数") if params[:gtask_bank][:max_num].to_i < params[:gtask_bank][:min_num].to_i
|
||||||
|
end
|
||||||
|
params.require(:gtask_bank).permit(:name, :description) if @bank.task_type == 1
|
||||||
|
params.require(:gtask_bank).permit(:name, :description, :min_num, :max_num, :base_on_project) if @bank.task_type == 2
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,23 @@
|
|||||||
|
module Admins::MirrorRepositoriesHelper
|
||||||
|
def mirror_type_tag(mirror)
|
||||||
|
case mirror.main_type
|
||||||
|
when '1' then '<i class="fa fa-star text-success font-16" aria-hidden="true" data-toggle="tooltip" data-title="主类别"></i>'.html_safe
|
||||||
|
when '0' then '<i class="fa fa-star text-secondary font-16" aria-hidden="true" data-toggle="tooltip" data-title="子类别"></i>'.html_safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def mirror_status_tag(mirror)
|
||||||
|
case mirror.status
|
||||||
|
when 0
|
||||||
|
'<i class="fa fa-check-circle text-secondary font-16" data-toggle="tooltip" data-title="未发布"></i>'.html_safe
|
||||||
|
when 1
|
||||||
|
'<i class="fa fa-check-circle text-success font-16" data-toggle="tooltip" data-title="已发布"></i>'.html_safe
|
||||||
|
when 2, 3
|
||||||
|
'<i class="fa fa-exclamation-circle text-danger font-16" data-toggle="tooltip" data-title="被修改"></i>'.html_safe
|
||||||
|
when 4
|
||||||
|
'<i class="fa fa-times-circle text-danger font-18" data-toggle="tooltip" data-title="被删除"></i>'.html_safe
|
||||||
|
when 5
|
||||||
|
'<i class="fa fa-exclamation-circle text-warning font-16" data-toggle="tooltip" data-title="子节点异常"></i>'.html_safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,2 @@
|
|||||||
|
module ExerciseBankQuestionsHelper
|
||||||
|
end
|
@ -0,0 +1,2 @@
|
|||||||
|
module HomeworkBanksHelper
|
||||||
|
end
|
@ -0,0 +1,21 @@
|
|||||||
|
# 删除部门 消息通知
|
||||||
|
class DeleteDepartmentNotifyJob < ApplicationJob
|
||||||
|
queue_as :notify
|
||||||
|
|
||||||
|
def perform(department_id, operator_id, user_ids)
|
||||||
|
department = Department.unscoped.find_by(id: department_id)
|
||||||
|
return if department.blank? || user_ids.blank?
|
||||||
|
|
||||||
|
attrs = %i[ user_id trigger_user_id container_id container_type tiding_type status created_at updated_at]
|
||||||
|
|
||||||
|
same_attrs = {
|
||||||
|
trigger_user_id: operator_id, container_id: department.id, container_type: 'Department',
|
||||||
|
status: 4, tiding_type: 'System'
|
||||||
|
}
|
||||||
|
Tiding.bulk_insert(*attrs) do |worker|
|
||||||
|
user_ids.each do |user_id|
|
||||||
|
worker.add same_attrs.merge(user_id: user_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,10 @@
|
|||||||
|
class Customer < ApplicationRecord
|
||||||
|
default_scope { order(created_at: :desc) }
|
||||||
|
|
||||||
|
belongs_to :school
|
||||||
|
|
||||||
|
has_many :partner_customers, dependent: :destroy
|
||||||
|
has_many :partners, through: :partner_customers
|
||||||
|
|
||||||
|
has_many :users
|
||||||
|
end
|
@ -1,4 +1,7 @@
|
|||||||
class ExerciseBankChoice < ApplicationRecord
|
class ExerciseBankChoice < ApplicationRecord
|
||||||
belongs_to :exercise_bank_question
|
belongs_to :exercise_bank_question
|
||||||
has_many :exercise_bank_standard_answers
|
has_many :exercise_bank_standard_answers
|
||||||
|
|
||||||
|
scope :find_choice_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题
|
||||||
|
scope :left_choice_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题
|
||||||
end
|
end
|
@ -1,3 +1,5 @@
|
|||||||
class Partner < ApplicationRecord
|
class Partner < ApplicationRecord
|
||||||
|
belongs_to :school, optional: true
|
||||||
|
|
||||||
has_many :users
|
has_many :users
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
class PartnerCustomer < ApplicationRecord
|
||||||
|
belongs_to :partner
|
||||||
|
belongs_to :customer
|
||||||
|
end
|
@ -0,0 +1,32 @@
|
|||||||
|
class Admins::DepartmentQuery < ApplicationQuery
|
||||||
|
include CustomSortable
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
sort_columns :created_at, default_by: :created_at, default_direction: :desc
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
departments = Department.where(is_auth: true).without_deleted
|
||||||
|
|
||||||
|
keyword = params[:keyword].to_s.strip
|
||||||
|
if keyword.present?
|
||||||
|
departments = departments.joins(:school)
|
||||||
|
.where('schools.name LIKE :keyword OR departments.name LIKE :keyword', keyword: "%#{keyword}%")
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:with_member].to_s == 'true'
|
||||||
|
subquery = DepartmentMember.where('department_id = departments.id').select('1 AS one').to_sql
|
||||||
|
departments = departments.where("EXISTS(#{subquery})")
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:with_identifier].to_s == 'true'
|
||||||
|
departments = departments.where.not(identifier: nil).where.not(identifier: '')
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_sort(departments, params[:sort_by], params[:sort_direction])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,29 @@
|
|||||||
|
class Admins::LibraryApplyQuery < ApplicationQuery
|
||||||
|
include CustomSortable
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
sort_columns :updated_at, default_by: :updated_at, default_direction: :desc
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
status =
|
||||||
|
case params[:status]
|
||||||
|
when 'processed' then %w(agreed refused)
|
||||||
|
else params[:status]
|
||||||
|
end
|
||||||
|
applies = LibraryApply.where(status: status) if status.present?
|
||||||
|
|
||||||
|
# 关键字模糊查询
|
||||||
|
keyword = params[:keyword].to_s.strip
|
||||||
|
if keyword.present?
|
||||||
|
applies = applies.joins(:library)
|
||||||
|
.where('title LIKE :keyword OR uuid LIKE :keyword', keyword: "%#{keyword}%")
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_sort(applies, params[:sort_by], params[:sort_direction])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,26 @@
|
|||||||
|
class Admins::MyshixunQuery < ApplicationQuery
|
||||||
|
include CustomSortable
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
sort_columns :created_at, default_by: :created_at, default_direction: :desc
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
objs = Myshixun.all
|
||||||
|
|
||||||
|
keyword = params[:keyword].to_s.strip
|
||||||
|
if keyword.present?
|
||||||
|
like_sql = 'users.login LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword OR '\
|
||||||
|
'schools.name LIKE :keyword OR shixuns.name LIKE :keyword OR CONCAT(teacher.lastname, teacher.firstname) Like :keyword'
|
||||||
|
objs = objs.joins(:shixun, user: { user_extension: :school })
|
||||||
|
.joins('JOIN users teacher ON teacher.id = shixuns.user_id')
|
||||||
|
.where(like_sql, keyword: "%#{keyword}%")
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_sort(objs, params[:sort_by], params[:sort_direction])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,48 @@
|
|||||||
|
class Admins::ShixunQuery < ApplicationQuery
|
||||||
|
include CustomSortable
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
sort_columns :created_at, default_by: :created_at, default_direction: :desc
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
all_shixuns = Shixun.all
|
||||||
|
status =
|
||||||
|
case params[:status]
|
||||||
|
when "editing" then [0]
|
||||||
|
when "pending" then [1]
|
||||||
|
when "processed" then [2]
|
||||||
|
when "closed" then [3]
|
||||||
|
else
|
||||||
|
[0,1,2,3]
|
||||||
|
end
|
||||||
|
|
||||||
|
all_shixuns = all_shixuns.where(status: status) if status.present?
|
||||||
|
|
||||||
|
if params[:tag].present?
|
||||||
|
all_shixuns = all_shixuns.joins(:mirror_repositories).where("mirror_repositories.id = ?",params[:tag].to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 关键字模糊查询
|
||||||
|
keyword = params[:keyword].to_s.strip
|
||||||
|
if keyword.present?
|
||||||
|
search_type = params[:search_type] || "0"
|
||||||
|
case search_type
|
||||||
|
when "0"
|
||||||
|
all_shixuns = all_shixuns.joins(:user)
|
||||||
|
.where('CONCAT(lastname, firstname) like :keyword', keyword: "%#{keyword}%")
|
||||||
|
when "1"
|
||||||
|
all_shixuns = all_shixuns.where('name like :keyword', keyword: "%#{keyword}%")
|
||||||
|
else
|
||||||
|
all_shixuns = all_shixuns.joins(user: {user_extension: :school}).where('schools.name LIKE ?', "%#{keyword}%")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_sort(all_shixuns, params[:sort_by], params[:sort_direction])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,54 @@
|
|||||||
|
class Admins::ShixunSettingsQuery < ApplicationQuery
|
||||||
|
include CustomSortable
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
sort_columns :created_at, default_by: :created_at, default_direction: :desc
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
all_shixuns = Shixun.all
|
||||||
|
status =
|
||||||
|
case params[:status]
|
||||||
|
when "editing" then [0]
|
||||||
|
when "pending" then [1]
|
||||||
|
when "processed" then [2]
|
||||||
|
when "closed" then [3]
|
||||||
|
else
|
||||||
|
[0,1,2,3]
|
||||||
|
end
|
||||||
|
|
||||||
|
all_shixuns = all_shixuns.where(status: status) if status.present?
|
||||||
|
|
||||||
|
if params[:tag].present?
|
||||||
|
all_shixuns = all_shixuns.joins(:mirror_repositories).where("mirror_repositories.id = ?",params[:tag].to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 关键字模糊查询
|
||||||
|
keyword = params[:keyword].to_s.strip
|
||||||
|
if keyword.present?
|
||||||
|
search_type = params[:search_type] || "0"
|
||||||
|
case search_type
|
||||||
|
when "0"
|
||||||
|
all_shixuns = all_shixuns.joins(:user)
|
||||||
|
.where('CONCAT(lastname, firstname) like :keyword', keyword: "%#{keyword}%")
|
||||||
|
when "1"
|
||||||
|
all_shixuns = all_shixuns.where('name like :keyword', keyword: "%#{keyword}%")
|
||||||
|
else
|
||||||
|
all_shixuns = all_shixuns.joins(user: {user_extension: :school}).where('schools.name LIKE ?', "%#{keyword}%")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
all_shixuns = all_shixuns.where(can_copy: params[:can_copy]) if params[:can_copy]
|
||||||
|
all_shixuns = all_shixuns.where(webssh: params[:webssh]) if params[:webssh]
|
||||||
|
all_shixuns = all_shixuns.where(hidden: params[:hidden]) if params[:hidden]
|
||||||
|
all_shixuns = all_shixuns.where(homepage_show: params[:homepage_show]) if params[:homepage_show]
|
||||||
|
all_shixuns = all_shixuns.where(task_pass: params[:task_pass]) if params[:task_pass]
|
||||||
|
all_shixuns = all_shixuns.where(code_hidden: params[:code_hidden]) if params[:code_hidden]
|
||||||
|
|
||||||
|
custom_sort(all_shixuns, params[:sort_by], params[:sort_direction])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,20 @@
|
|||||||
|
class Admins::AddDepartmentMemberService < ApplicationService
|
||||||
|
|
||||||
|
attr_reader :department, :params
|
||||||
|
|
||||||
|
def initialize(department, params)
|
||||||
|
@department = department
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
columns = %i[]
|
||||||
|
DepartmentMember.bulk_insert(*columns) do |worker|
|
||||||
|
Array.wrap(params[:user_ids]).compact.each do |user_id|
|
||||||
|
next if department.department_members.exists?(user_id: user_id)
|
||||||
|
|
||||||
|
worker.add(department_id: department.id, user_id: user_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue