parent
bba5f20ffe
commit
dc8f291d9d
@ -0,0 +1,12 @@
|
||||
$(document).on('turbolinks:load', function(){
|
||||
if ($('body.admins-daily-school-statistics-index-page').length > 0) {
|
||||
$('.export-action').on('click', function(){
|
||||
var form = $(".daily-school-statistic-list-form .search-form")
|
||||
var exportLink = $(this);
|
||||
var keyword = form.find("input[name='keyword']").val();
|
||||
|
||||
var url = exportLink.data("url").split('?')[0] + "?keyword=" + keyword;
|
||||
window.open(url);
|
||||
});
|
||||
}
|
||||
})
|
@ -0,0 +1,135 @@
|
||||
$(document).on('turbolinks:load', function(){
|
||||
if ($('body.admins-school-statistics-index-page').length > 0) {
|
||||
var searchForm = $(".school-statistic-list-form .search-form");
|
||||
var growFormUrl = searchForm.data('grow-form-url');
|
||||
var contrastFormUrl = searchForm.data('contrast-form-url');
|
||||
|
||||
var dataTypeInput = searchForm.find("input[name='data_type']");
|
||||
var keywordInput = searchForm.find("input[name='keyword']");
|
||||
var contrastBtn = searchForm.find(".contrast-btn");
|
||||
var growBtn = searchForm.find(".grow-btn");
|
||||
var contrastDateContainer = searchForm.find('.contrast-date-container');
|
||||
var growDateContainer = searchForm.find('.grow-date-container');
|
||||
|
||||
// 数据对比日期输入框
|
||||
var beginDateInput = searchForm.find("input[name='begin_date']");
|
||||
var endDateInput = searchForm.find("input[name='end_date']");
|
||||
var otherBeginDateInput = searchForm.find("input[name='other_begin_date']");
|
||||
var otherEndDateInput = searchForm.find("input[name='other_end_date']");
|
||||
|
||||
// 新增数据日期输入框
|
||||
var growBeginDateInput = searchForm.find("input[name='grow_begin_date']");
|
||||
var growEndDateInput = searchForm.find("input[name='grow_end_date']");
|
||||
|
||||
// 数据展示切换: 数据对比、新增数据
|
||||
searchForm.on('click', ".contrast-btn", function(){
|
||||
if(contrastBtn.hasClass("active")) { return }
|
||||
changeDataType("contrast");
|
||||
submitForm();
|
||||
});
|
||||
searchForm.on('click', ".grow-btn", function(){
|
||||
if(growBtn.hasClass("active")) { return }
|
||||
changeDataType("grow");
|
||||
submitForm();
|
||||
});
|
||||
|
||||
// 搜索按钮
|
||||
searchForm.on('click', ".search-btn", function(){
|
||||
console.log('submit');
|
||||
submitForm();
|
||||
});
|
||||
|
||||
$('.school-statistic-list-container').on('change', '.contrast-column-select', function() {
|
||||
searchForm.find("input[name='contrast_column']").val($('.contrast-column-select').val());
|
||||
submitForm();
|
||||
});
|
||||
|
||||
var submitForm = function(){
|
||||
if(!validateFrom()) { return }
|
||||
|
||||
var form = searchForm;
|
||||
var url = dataTypeInput.val() == "contrast" ? contrastFormUrl : growFormUrl;
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
data: form.serialize(),
|
||||
dataType: "script"
|
||||
})
|
||||
};
|
||||
|
||||
var validateFrom = function(){
|
||||
if (dataTypeInput.val() != "contrast") { return true; }
|
||||
|
||||
// 全部为空时,需要展示空数据页
|
||||
if (beginDateInput.val() == "" && endDateInput.val() == "" &&
|
||||
otherBeginDateInput.val() == "" && otherBeginDateInput.val() == "") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (beginDateInput.val() != "" && endDateInput.val() != "" &&
|
||||
otherBeginDateInput.val() != "" && otherBeginDateInput.val() != "") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
var changeDataType = function(dataType){
|
||||
if (dataTypeInput.val() == dataType) { return }
|
||||
|
||||
if (dataType == "contrast") {
|
||||
contrastBtn.addClass("active");
|
||||
growBtn.removeClass("active");
|
||||
dataTypeInput.val('contrast');
|
||||
growDateContainer.hide();
|
||||
contrastDateContainer.show();
|
||||
|
||||
clearGrowDateInput();
|
||||
} else {
|
||||
contrastBtn.removeClass("active");
|
||||
growBtn.addClass("active");
|
||||
dataTypeInput.val('grow');
|
||||
growDateContainer.show();
|
||||
contrastDateContainer.hide();
|
||||
|
||||
clearContrastDateInput();
|
||||
}
|
||||
};
|
||||
|
||||
var clearGrowDateInput = function() {
|
||||
searchForm.find("input[name='grow_begin_date']").val('');
|
||||
searchForm.find("input[name='grow_end_date']").val('');
|
||||
searchForm.find("input[name='grow_date_input']").val('');
|
||||
};
|
||||
|
||||
var clearContrastDateInput = function(){
|
||||
searchForm.find("input[name='begin_date']").val('');
|
||||
searchForm.find("input[name='end_date']").val('');
|
||||
searchForm.find("input[name='other_begin_date']").val('');
|
||||
searchForm.find("input[name='other_end_date']").val('');
|
||||
searchForm.find("input[name='date_input']").val('');
|
||||
searchForm.find("input[name='other_date_input']").val('');
|
||||
};
|
||||
|
||||
var baseOptions = {
|
||||
autoclose: true,
|
||||
language: 'zh-CN',
|
||||
format: 'yyyy-mm-dd',
|
||||
startDate: '2017-04-01',
|
||||
endDate: '-1d'
|
||||
}
|
||||
|
||||
var defineDateRangeSelect = function(element){
|
||||
var options = $.extend({inputs: $(element).find('.start-date, .end-date')}, baseOptions);
|
||||
$(element).datepicker(options);
|
||||
|
||||
$(element).find('.start-date').datepicker().on('changeDate', function(e){
|
||||
$(element).find('.end-date').datepicker('setStartDate', e.date);
|
||||
})
|
||||
};
|
||||
|
||||
defineDateRangeSelect('.grow-date-input-daterange');
|
||||
defineDateRangeSelect('.date-input-daterange');
|
||||
defineDateRangeSelect('.other-date-input-daterange');
|
||||
}
|
||||
})
|
@ -0,0 +1,16 @@
|
||||
$(document).on('turbolinks:load', function(){
|
||||
$('#sidebarCollapse').on('click', function () {
|
||||
$(this).toggleClass('active');
|
||||
$('#sidebar').toggleClass('active');
|
||||
$.cookie('admin_sidebar_collapse', $(this).hasClass('active'), {path: '/admins'});
|
||||
});
|
||||
|
||||
var sidebarController = $('#sidebar').data('current-controller');
|
||||
if (sidebarController.length > 0) {
|
||||
$('#sidebar a.active').removeClass('active');
|
||||
$('#sidebar ul.collapse.show').removeClass('show');
|
||||
var activeLi = $('#sidebar a[data-controller="' + sidebarController + '"]');
|
||||
activeLi.addClass('active');
|
||||
activeLi.parent().parent('ul.collapse').addClass('show');
|
||||
}
|
||||
});
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@
|
||||
!function(a){a.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1}}(jQuery);
|
@ -0,0 +1,5 @@
|
||||
.admins-daily-school-statistics-index-page {
|
||||
.daily-school-statistic-list-container {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
.admins-school-statistics-index-page {
|
||||
.school-statistic-list-form {
|
||||
.time-select {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.type-box {
|
||||
.btn { margin: 0 5px; }
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.contrast-date-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.school-statistic-list-container {
|
||||
.contrast-column-select {
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 15px;
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.right-border::after {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 0;
|
||||
content: '';
|
||||
width: 0;
|
||||
height: 20px;
|
||||
border-right: 1px solid #000;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,477 @@
|
||||
/*!
|
||||
* Datepicker for Bootstrap v1.9.0 (https://github.com/uxsolutions/bootstrap-datepicker)
|
||||
*
|
||||
* Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
*/
|
||||
|
||||
.datepicker {
|
||||
padding: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
direction: ltr;
|
||||
}
|
||||
.datepicker-inline {
|
||||
width: 220px;
|
||||
}
|
||||
.datepicker-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
.datepicker-rtl.dropdown-menu {
|
||||
left: auto;
|
||||
}
|
||||
.datepicker-rtl table tr td span {
|
||||
float: right;
|
||||
}
|
||||
.datepicker-dropdown {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.datepicker-dropdown:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #999;
|
||||
border-top: 0;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
}
|
||||
.datepicker-dropdown:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #fff;
|
||||
border-top: 0;
|
||||
position: absolute;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-left:before {
|
||||
left: 6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-left:after {
|
||||
left: 7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-right:before {
|
||||
right: 6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-right:after {
|
||||
right: 7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-bottom:before {
|
||||
top: -7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-bottom:after {
|
||||
top: -6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-top:before {
|
||||
bottom: -7px;
|
||||
border-bottom: 0;
|
||||
border-top: 7px solid #999;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-top:after {
|
||||
bottom: -6px;
|
||||
border-bottom: 0;
|
||||
border-top: 6px solid #fff;
|
||||
}
|
||||
.datepicker table {
|
||||
margin: 0;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.datepicker td,
|
||||
.datepicker th {
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
.table-striped .datepicker table tr td,
|
||||
.table-striped .datepicker table tr th {
|
||||
background-color: transparent;
|
||||
}
|
||||
.datepicker table tr td.day:hover,
|
||||
.datepicker table tr td.day.focused {
|
||||
background: #eee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker table tr td.old,
|
||||
.datepicker table tr td.new {
|
||||
color: #999;
|
||||
}
|
||||
.datepicker table tr td.disabled,
|
||||
.datepicker table tr td.disabled:hover {
|
||||
background: none;
|
||||
color: #999;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td.highlighted {
|
||||
background: #d9edf7;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.today,
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today.disabled:hover {
|
||||
background-color: #fde19a;
|
||||
background-image: -moz-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: -ms-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
|
||||
background-image: -webkit-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: -o-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
|
||||
border-color: #fdf59a #fdf59a #fbed50;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #000;
|
||||
}
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today:hover:hover,
|
||||
.datepicker table tr td.today.disabled:hover,
|
||||
.datepicker table tr td.today.disabled:hover:hover,
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active,
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today:hover.disabled,
|
||||
.datepicker table tr td.today.disabled.disabled,
|
||||
.datepicker table tr td.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.today[disabled],
|
||||
.datepicker table tr td.today:hover[disabled],
|
||||
.datepicker table tr td.today.disabled[disabled],
|
||||
.datepicker table tr td.today.disabled:hover[disabled] {
|
||||
background-color: #fdf59a;
|
||||
}
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active {
|
||||
background-color: #fbf069 \9;
|
||||
}
|
||||
.datepicker table tr td.today:hover:hover {
|
||||
color: #000;
|
||||
}
|
||||
.datepicker table tr td.today.active:hover {
|
||||
color: #fff;
|
||||
}
|
||||
.datepicker table tr td.range,
|
||||
.datepicker table tr td.range:hover,
|
||||
.datepicker table tr td.range.disabled,
|
||||
.datepicker table tr td.range.disabled:hover {
|
||||
background: #eee;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today,
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover {
|
||||
background-color: #f3d17a;
|
||||
background-image: -moz-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: -ms-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
|
||||
background-image: -webkit-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: -o-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
|
||||
border-color: #f3e97a #f3e97a #edde34;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today:hover:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover:hover,
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active,
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today:hover.disabled,
|
||||
.datepicker table tr td.range.today.disabled.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.range.today[disabled],
|
||||
.datepicker table tr td.range.today:hover[disabled],
|
||||
.datepicker table tr td.range.today.disabled[disabled],
|
||||
.datepicker table tr td.range.today.disabled:hover[disabled] {
|
||||
background-color: #f3e97a;
|
||||
}
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active {
|
||||
background-color: #efe24b \9;
|
||||
}
|
||||
.datepicker table tr td.selected,
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover {
|
||||
background-color: #9e9e9e;
|
||||
background-image: -moz-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: -ms-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
|
||||
background-image: -webkit-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: -o-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
|
||||
border-color: #808080 #808080 #595959;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected:hover:hover,
|
||||
.datepicker table tr td.selected.disabled:hover,
|
||||
.datepicker table tr td.selected.disabled:hover:hover,
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active,
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected:hover.disabled,
|
||||
.datepicker table tr td.selected.disabled.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover.disabled,
|
||||
.datepicker table tr td.selected[disabled],
|
||||
.datepicker table tr td.selected:hover[disabled],
|
||||
.datepicker table tr td.selected.disabled[disabled],
|
||||
.datepicker table tr td.selected.disabled:hover[disabled] {
|
||||
background-color: #808080;
|
||||
}
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active {
|
||||
background-color: #666666 \9;
|
||||
}
|
||||
.datepicker table tr td.active,
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -o-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active:hover:hover,
|
||||
.datepicker table tr td.active.disabled:hover,
|
||||
.datepicker table tr td.active.disabled:hover:hover,
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active,
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active:hover.disabled,
|
||||
.datepicker table tr td.active.disabled.disabled,
|
||||
.datepicker table tr td.active.disabled:hover.disabled,
|
||||
.datepicker table tr td.active[disabled],
|
||||
.datepicker table tr td.active:hover[disabled],
|
||||
.datepicker table tr td.active.disabled[disabled],
|
||||
.datepicker table tr td.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker table tr td span {
|
||||
display: block;
|
||||
width: 23%;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
float: left;
|
||||
margin: 1%;
|
||||
cursor: pointer;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.datepicker table tr td span:hover,
|
||||
.datepicker table tr td span.focused {
|
||||
background: #eee;
|
||||
}
|
||||
.datepicker table tr td span.disabled,
|
||||
.datepicker table tr td span.disabled:hover {
|
||||
background: none;
|
||||
color: #999;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td span.active,
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -o-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active:hover:hover,
|
||||
.datepicker table tr td span.active.disabled:hover,
|
||||
.datepicker table tr td span.active.disabled:hover:hover,
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active,
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active:hover.disabled,
|
||||
.datepicker table tr td span.active.disabled.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover.disabled,
|
||||
.datepicker table tr td span.active[disabled],
|
||||
.datepicker table tr td span.active:hover[disabled],
|
||||
.datepicker table tr td span.active.disabled[disabled],
|
||||
.datepicker table tr td span.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker table tr td span.old,
|
||||
.datepicker table tr td span.new {
|
||||
color: #999;
|
||||
}
|
||||
.datepicker .datepicker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
.datepicker .datepicker-switch,
|
||||
.datepicker .prev,
|
||||
.datepicker .next,
|
||||
.datepicker tfoot tr th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker .datepicker-switch:hover,
|
||||
.datepicker .prev:hover,
|
||||
.datepicker .next:hover,
|
||||
.datepicker tfoot tr th:hover {
|
||||
background: #eee;
|
||||
}
|
||||
.datepicker .prev.disabled,
|
||||
.datepicker .next.disabled {
|
||||
visibility: hidden;
|
||||
}
|
||||
.datepicker .cw {
|
||||
font-size: 10px;
|
||||
width: 12px;
|
||||
padding: 0 2px 0 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.input-append.date .add-on,
|
||||
.input-prepend.date .add-on {
|
||||
cursor: pointer;
|
||||
}
|
||||
.input-append.date .add-on i,
|
||||
.input-prepend.date .add-on i {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.input-daterange input {
|
||||
text-align: center;
|
||||
}
|
||||
.input-daterange input:first-child {
|
||||
-webkit-border-radius: 3px 0 0 3px;
|
||||
-moz-border-radius: 3px 0 0 3px;
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
.input-daterange input:last-child {
|
||||
-webkit-border-radius: 0 3px 3px 0;
|
||||
-moz-border-radius: 0 3px 3px 0;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.input-daterange .add-on {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
min-width: 16px;
|
||||
height: 18px;
|
||||
padding: 4px 5px;
|
||||
font-weight: normal;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
vertical-align: middle;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
margin-left: -5px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-datepicker.css.map */
|
@ -0,0 +1,510 @@
|
||||
/*!
|
||||
* Datepicker for Bootstrap v1.9.0 (https://github.com/uxsolutions/bootstrap-datepicker)
|
||||
*
|
||||
* Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
*/
|
||||
|
||||
.datepicker {
|
||||
padding: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
direction: ltr;
|
||||
}
|
||||
.datepicker-inline {
|
||||
width: 220px;
|
||||
}
|
||||
.datepicker-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
.datepicker-rtl.dropdown-menu {
|
||||
left: auto;
|
||||
}
|
||||
.datepicker-rtl table tr td span {
|
||||
float: right;
|
||||
}
|
||||
.datepicker-dropdown {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.datepicker-dropdown:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #999;
|
||||
border-top: 0;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
}
|
||||
.datepicker-dropdown:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #fff;
|
||||
border-top: 0;
|
||||
position: absolute;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-left:before {
|
||||
left: 6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-left:after {
|
||||
left: 7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-right:before {
|
||||
right: 6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-right:after {
|
||||
right: 7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-bottom:before {
|
||||
top: -7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-bottom:after {
|
||||
top: -6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-top:before {
|
||||
bottom: -7px;
|
||||
border-bottom: 0;
|
||||
border-top: 7px solid #999;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-top:after {
|
||||
bottom: -6px;
|
||||
border-bottom: 0;
|
||||
border-top: 6px solid #fff;
|
||||
}
|
||||
.datepicker table {
|
||||
margin: 0;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.datepicker td,
|
||||
.datepicker th {
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
.table-striped .datepicker table tr td,
|
||||
.table-striped .datepicker table tr th {
|
||||
background-color: transparent;
|
||||
}
|
||||
.datepicker table tr td.day:hover,
|
||||
.datepicker table tr td.day.focused {
|
||||
background: #eee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker table tr td.old,
|
||||
.datepicker table tr td.new {
|
||||
color: #999;
|
||||
}
|
||||
.datepicker table tr td.disabled,
|
||||
.datepicker table tr td.disabled:hover {
|
||||
background: none;
|
||||
color: #999;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td.highlighted {
|
||||
background: #d9edf7;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.today,
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today.disabled:hover {
|
||||
background-color: #fde19a;
|
||||
background-image: -moz-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: -ms-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
|
||||
background-image: -webkit-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: -o-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
|
||||
border-color: #fdf59a #fdf59a #fbed50;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #000;
|
||||
}
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today:hover:hover,
|
||||
.datepicker table tr td.today.disabled:hover,
|
||||
.datepicker table tr td.today.disabled:hover:hover,
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active,
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today:hover.disabled,
|
||||
.datepicker table tr td.today.disabled.disabled,
|
||||
.datepicker table tr td.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.today[disabled],
|
||||
.datepicker table tr td.today:hover[disabled],
|
||||
.datepicker table tr td.today.disabled[disabled],
|
||||
.datepicker table tr td.today.disabled:hover[disabled] {
|
||||
background-color: #fdf59a;
|
||||
}
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active {
|
||||
background-color: #fbf069 \9;
|
||||
}
|
||||
.datepicker table tr td.today:hover:hover {
|
||||
color: #000;
|
||||
}
|
||||
.datepicker table tr td.today.active:hover {
|
||||
color: #fff;
|
||||
}
|
||||
.datepicker table tr td.range,
|
||||
.datepicker table tr td.range:hover,
|
||||
.datepicker table tr td.range.disabled,
|
||||
.datepicker table tr td.range.disabled:hover {
|
||||
background: #eee;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today,
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover {
|
||||
background-color: #f3d17a;
|
||||
background-image: -moz-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: -ms-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
|
||||
background-image: -webkit-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: -o-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
|
||||
border-color: #f3e97a #f3e97a #edde34;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today:hover:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover:hover,
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active,
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today:hover.disabled,
|
||||
.datepicker table tr td.range.today.disabled.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.range.today[disabled],
|
||||
.datepicker table tr td.range.today:hover[disabled],
|
||||
.datepicker table tr td.range.today.disabled[disabled],
|
||||
.datepicker table tr td.range.today.disabled:hover[disabled] {
|
||||
background-color: #f3e97a;
|
||||
}
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active {
|
||||
background-color: #efe24b \9;
|
||||
}
|
||||
.datepicker table tr td.selected,
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover {
|
||||
background-color: #9e9e9e;
|
||||
background-image: -moz-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: -ms-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
|
||||
background-image: -webkit-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: -o-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
|
||||
border-color: #808080 #808080 #595959;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected:hover:hover,
|
||||
.datepicker table tr td.selected.disabled:hover,
|
||||
.datepicker table tr td.selected.disabled:hover:hover,
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active,
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected:hover.disabled,
|
||||
.datepicker table tr td.selected.disabled.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover.disabled,
|
||||
.datepicker table tr td.selected[disabled],
|
||||
.datepicker table tr td.selected:hover[disabled],
|
||||
.datepicker table tr td.selected.disabled[disabled],
|
||||
.datepicker table tr td.selected.disabled:hover[disabled] {
|
||||
background-color: #808080;
|
||||
}
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active {
|
||||
background-color: #666666 \9;
|
||||
}
|
||||
.datepicker table tr td.active,
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -o-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active:hover:hover,
|
||||
.datepicker table tr td.active.disabled:hover,
|
||||
.datepicker table tr td.active.disabled:hover:hover,
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active,
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active:hover.disabled,
|
||||
.datepicker table tr td.active.disabled.disabled,
|
||||
.datepicker table tr td.active.disabled:hover.disabled,
|
||||
.datepicker table tr td.active[disabled],
|
||||
.datepicker table tr td.active:hover[disabled],
|
||||
.datepicker table tr td.active.disabled[disabled],
|
||||
.datepicker table tr td.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker table tr td span {
|
||||
display: block;
|
||||
width: 23%;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
float: left;
|
||||
margin: 1%;
|
||||
cursor: pointer;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.datepicker table tr td span:hover,
|
||||
.datepicker table tr td span.focused {
|
||||
background: #eee;
|
||||
}
|
||||
.datepicker table tr td span.disabled,
|
||||
.datepicker table tr td span.disabled:hover {
|
||||
background: none;
|
||||
color: #999;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td span.active,
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -o-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active:hover:hover,
|
||||
.datepicker table tr td span.active.disabled:hover,
|
||||
.datepicker table tr td span.active.disabled:hover:hover,
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active,
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active:hover.disabled,
|
||||
.datepicker table tr td span.active.disabled.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover.disabled,
|
||||
.datepicker table tr td span.active[disabled],
|
||||
.datepicker table tr td span.active:hover[disabled],
|
||||
.datepicker table tr td span.active.disabled[disabled],
|
||||
.datepicker table tr td span.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker table tr td span.old,
|
||||
.datepicker table tr td span.new {
|
||||
color: #999;
|
||||
}
|
||||
.datepicker .datepicker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
.datepicker .datepicker-switch,
|
||||
.datepicker .prev,
|
||||
.datepicker .next,
|
||||
.datepicker tfoot tr th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker .datepicker-switch:hover,
|
||||
.datepicker .prev:hover,
|
||||
.datepicker .next:hover,
|
||||
.datepicker tfoot tr th:hover {
|
||||
background: #eee;
|
||||
}
|
||||
.datepicker .prev.disabled,
|
||||
.datepicker .next.disabled {
|
||||
visibility: hidden;
|
||||
}
|
||||
.datepicker .cw {
|
||||
font-size: 10px;
|
||||
width: 12px;
|
||||
padding: 0 2px 0 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.input-append.date .add-on,
|
||||
.input-prepend.date .add-on {
|
||||
cursor: pointer;
|
||||
}
|
||||
.input-append.date .add-on i,
|
||||
.input-prepend.date .add-on i {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.input-daterange input {
|
||||
text-align: center;
|
||||
}
|
||||
.input-daterange input:first-child {
|
||||
-webkit-border-radius: 3px 0 0 3px;
|
||||
-moz-border-radius: 3px 0 0 3px;
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
.input-daterange input:last-child {
|
||||
-webkit-border-radius: 0 3px 3px 0;
|
||||
-moz-border-radius: 0 3px 3px 0;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.input-daterange .add-on {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
min-width: 16px;
|
||||
height: 20px;
|
||||
padding: 4px 5px;
|
||||
font-weight: normal;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
vertical-align: middle;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
margin-left: -5px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
.datepicker.dropdown-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
float: left;
|
||||
display: none;
|
||||
min-width: 160px;
|
||||
list-style: none;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
||||
-webkit-background-clip: padding-box;
|
||||
-moz-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
*border-right-width: 2px;
|
||||
*border-bottom-width: 2px;
|
||||
color: #333333;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.datepicker.dropdown-menu th,
|
||||
.datepicker.datepicker-inline th,
|
||||
.datepicker.dropdown-menu td,
|
||||
.datepicker.datepicker-inline td {
|
||||
padding: 4px 5px;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-datepicker.standalone.css.map */
|
@ -0,0 +1,36 @@
|
||||
class Admins::DailySchoolStatisticsController < Admins::BaseController
|
||||
def index
|
||||
params[:sort_by] = params[:sort_by].presence || :teacher_count
|
||||
params[:sort_direction] = params[:sort_direction].presence || :desc
|
||||
|
||||
total_count, statistics = Admins::SchoolDailyStatisticService.call(params)
|
||||
|
||||
@statistics = paginate statistics, total_count: total_count
|
||||
|
||||
respond_to do |format|
|
||||
format.html { load_statistic_total }
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def export
|
||||
params[:per_page] = 10000
|
||||
_count, @schools = Admins::SchoolDailyStatisticService.call(params)
|
||||
|
||||
filename = ['学校统计总表', params[:keyword], Time.zone.now.strftime('%Y%m%d%H%M%S')].join('-') << '.xlsx'
|
||||
render xlsx: 'export', filename: filename
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_statistic_total
|
||||
@teacher_total = User.joins(:user_extension).where(user_extensions: { identity: :teacher }).count
|
||||
@student_total = User.joins(:user_extension).where(user_extensions: { identity: :student }).count
|
||||
@course_total = Course.count
|
||||
@active_course_total = Course.where(is_end: false).count
|
||||
@shixun_homework_total = HomeworkCommon.where(homework_type: 4).count
|
||||
@other_homework_total = HomeworkCommon.where(homework_type: [1, 3]).count
|
||||
@shixun_total = Shixun.count
|
||||
@shixun_evaluate_total = SchoolReport.sum(:shixun_evaluate_count)
|
||||
end
|
||||
end
|
@ -0,0 +1,49 @@
|
||||
class Admins::SchoolStatisticsController < Admins::BaseController
|
||||
before_action :contrast_column_select_options, only: [:contrast]
|
||||
|
||||
def index
|
||||
params[:data_type] ||= 'grow'
|
||||
params[:sort_by] = params[:sort_by].presence || :teacher_increase_count
|
||||
params[:sort_direction] = params[:sort_direction].presence || :desc
|
||||
|
||||
service = Admins::StatisticSchoolDataGrowService.new(params)
|
||||
@grow_summary = service.grow_summary
|
||||
|
||||
total_count, statistics = service.call
|
||||
|
||||
@statistics = paginate statistics, total_count: total_count
|
||||
end
|
||||
|
||||
def contrast
|
||||
params[:contrast_column] = params[:contrast_column].presence || :teacher_increase_count
|
||||
params[:sort_direction] ||= :desc
|
||||
params[:sort_by] = :percentage
|
||||
|
||||
# 无对比日期时直接返回无数据页面
|
||||
if useless_contrast_date_parameter?
|
||||
@total_count = 0
|
||||
@statistics = paginate([])
|
||||
return
|
||||
end
|
||||
|
||||
total_count, statistics = Admins::StatisticSchoolContrastDataService.call(params)
|
||||
|
||||
@statistics = paginate statistics, total_count: total_count
|
||||
rescue Admins::StatisticSchoolContrastDataService::ParameterError
|
||||
render_unprocessable_entity('参数错误')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def useless_contrast_date_parameter?
|
||||
params[:begin_date].blank? && params[:end_date].blank? &&
|
||||
params[:other_begin_date].blank? &¶ms[:other_end_date].blank?
|
||||
end
|
||||
|
||||
def contrast_column_select_options
|
||||
@select_options =
|
||||
Admins::StatisticSchoolContrastDataService::CONTRAST_COLUMN_LIST.map do |column|
|
||||
[I18n.t("school_daily_report.#{column}"), column]
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
class SchoolDailyActiveUser < ApplicationRecord
|
||||
belongs_to :school_daily_report
|
||||
end
|
@ -0,0 +1,5 @@
|
||||
class SchoolDailyReport < ApplicationRecord
|
||||
belongs_to :school
|
||||
|
||||
has_many :school_daily_active_users, dependent: :delete_all
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
class SchoolReport < ApplicationRecord
|
||||
belongs_to :school
|
||||
end
|
@ -0,0 +1,123 @@
|
||||
class Admins::SchoolDailyStatisticService < ApplicationService
|
||||
include CustomSortable
|
||||
|
||||
attr_reader :params
|
||||
|
||||
sort_columns :student_count, :teacher_count, :homework_count, :other_homework_count,
|
||||
:course_count, :active_course_count, :nearly_course_time, :shixun_count, :shixun_evaluate_count,
|
||||
default_by: :teacher_count, default_direction: :desc
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
schools = School.group('schools.id')
|
||||
|
||||
keyword = params[:keyword].try(:to_s).try(:strip)
|
||||
if keyword.present?
|
||||
schools = schools.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
count = schools.count.count
|
||||
|
||||
# 根据排序字段进行查询
|
||||
schools = query_by_sort_column(schools, params[:sort_by])
|
||||
schools = custom_sort(schools, params[:sort_by], params[:sort_direction])
|
||||
|
||||
schools = schools.limit(page_size).offset(offset)
|
||||
# 查询并组装其它数据
|
||||
schools = package_other_data(schools)
|
||||
|
||||
[count, schools]
|
||||
end
|
||||
|
||||
def package_other_data(schools)
|
||||
ids = schools.map(&:id)
|
||||
|
||||
student_map = UserExtension.where(school_id: ids, identity: :student).group(:school_id).count
|
||||
teacher_map = UserExtension.where(school_id: ids, identity: :teacher).group(:school_id).count
|
||||
|
||||
homeworks = HomeworkCommon.joins(:course)
|
||||
shixun_homework_map = homeworks.where(homework_type: 4, courses: { school_id: ids }).group('school_id').count
|
||||
other_homework_map = homeworks.where(homework_type: [1, 3], courses: { school_id: ids }).group('school_id').count
|
||||
|
||||
courses = Course.where(is_delete: 0, school_id: ids).group('school_id')
|
||||
course_map = courses.count
|
||||
nearly_course_time_map = courses.joins(:course_acts).maximum('course_activities.updated_at')
|
||||
active_course_map = courses.where(is_end: false).count
|
||||
|
||||
shixun_map = Shixun.joins(user: :user_extension).where(user_extensions: { identity: :teacher, school_id: ids })
|
||||
.where(fork_from: nil).group('school_id').count
|
||||
|
||||
reports = SchoolReport.where(school_id: ids)
|
||||
evaluate_count_map = reports.each_with_object({}) { |report, obj| obj[report.school_id] = report.shixun_evaluate_count }
|
||||
|
||||
schools.map do |school|
|
||||
{
|
||||
id: school.id,
|
||||
name: school.name,
|
||||
teacher_count: teacher_map[school.id],
|
||||
student_count: student_map[school.id],
|
||||
homework_count: shixun_homework_map[school.id],
|
||||
other_homework_count: other_homework_map[school.id],
|
||||
course_count: course_map[school.id],
|
||||
nearly_course_time: nearly_course_time_map[school.id],
|
||||
active_course_count: active_course_map[school.id],
|
||||
shixun_count: shixun_map.fetch(school.id, 0),
|
||||
shixun_evaluate_count: evaluate_count_map.fetch(school.id, 0)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def query_by_sort_column(schools, sort_by_column)
|
||||
base_query_column = 'schools.id, schools.name'
|
||||
|
||||
case sort_by_column.to_s
|
||||
when 'teacher_count' then
|
||||
schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0')
|
||||
.select("#{base_query_column}, COUNT(*) teacher_count")
|
||||
when 'student_count' then
|
||||
schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 1')
|
||||
.select("#{base_query_column}, COUNT(*) student_count")
|
||||
when 'homework_count' then
|
||||
schools.joins('LEFT JOIN courses ON courses.school_id = schools.id')
|
||||
.joins('LEFT JOIN homework_commons hc ON hc.course_id = courses.id AND hc.homework_type = 4')
|
||||
.select("#{base_query_column}, COUNT(*) homework_count")
|
||||
when 'other_homework_count' then
|
||||
schools.joins('LEFT JOIN courses ON courses.school_id = schools.id')
|
||||
.joins('LEFT JOIN homework_commons hc ON hc.course_id = courses.id AND hc.homework_type IN (1, 3)')
|
||||
.select("#{base_query_column}, COUNT(*) other_homework_count")
|
||||
when 'course_count' then
|
||||
schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0')
|
||||
.select("#{base_query_column}, COUNT(*) course_count")
|
||||
when 'shixun_count' then
|
||||
schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0')
|
||||
.joins('LEFT JOIN users ON users.id = ue.user_id')
|
||||
.joins('LEFT JOIN shixuns sx ON sx.user_id = users.id AND sx.fork_from IS NULL')
|
||||
.select("#{base_query_column}, COUNT(*) shixun_count")
|
||||
when 'shixun_evaluate_count' then
|
||||
schools.joins('LEFT JOIN school_reports ON school_reports.school_id = schools.id')
|
||||
.select("#{base_query_column}, shixun_evaluate_count")
|
||||
when 'nearly_course_time' then
|
||||
schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0')
|
||||
.joins('LEFT JOIN course_activities acs ON acs.course_id = cs.id')
|
||||
.select("#{base_query_column}, MAX(acs.updated_at) nearly_course_time")
|
||||
when 'active_course_count' then
|
||||
schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0 AND cs.is_end = false')
|
||||
.select("#{base_query_column}, COUNT(*) active_course_count")
|
||||
else
|
||||
schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0')
|
||||
.select("#{base_query_column}, COUNT(*) teacher_count")
|
||||
end
|
||||
end
|
||||
|
||||
def page_size
|
||||
params[:per_page] || 20
|
||||
end
|
||||
|
||||
def offset
|
||||
(params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * page_size
|
||||
end
|
||||
end
|
@ -0,0 +1,80 @@
|
||||
class Admins::StatisticSchoolContrastDataService < ApplicationService
|
||||
ParameterError = Class.new(StandardError)
|
||||
|
||||
PAGE_SIZE = 20
|
||||
CONTRAST_COLUMN_LIST = %w(
|
||||
teacher_increase_count student_increase_count course_increase_count
|
||||
shixun_increase_count active_user_count shixun_homework_count shixun_evaluate_count
|
||||
).freeze
|
||||
|
||||
attr_reader :params, :sort_direction, :contrast_column
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
@sort_direction = params[:sort_direction].to_s
|
||||
@contrast_column = params[:contrast_column].to_s
|
||||
end
|
||||
|
||||
def call
|
||||
validate_parameter!
|
||||
reports = School.joins(:school_daily_reports).select(select_columns)
|
||||
|
||||
keyword = params[:keyword].try(:to_s).try(:strip)
|
||||
if keyword.present?
|
||||
reports = reports.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
count = reports.count('distinct(schools.id)')
|
||||
|
||||
sql = query_report_sql(reports.group('schools.id').to_sql)
|
||||
reports = SchoolDailyReport.find_by_sql(sql)
|
||||
|
||||
[count, reports]
|
||||
end
|
||||
|
||||
private
|
||||
def validate_parameter!
|
||||
if %i[begin_date end_date other_begin_date other_end_date].any? { |key| params[key].blank? }
|
||||
raise ParameterError
|
||||
end
|
||||
|
||||
unless %w(desc asc).include?(sort_direction)
|
||||
raise ParameterError
|
||||
end
|
||||
|
||||
unless CONTRAST_COLUMN_LIST.include?(contrast_column)
|
||||
raise ParameterError
|
||||
end
|
||||
end
|
||||
|
||||
def format_date(date)
|
||||
Time.zone.parse(date).strftime("%Y-%m-%d")
|
||||
end
|
||||
|
||||
def offset
|
||||
(params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * PAGE_SIZE
|
||||
end
|
||||
|
||||
def select_columns
|
||||
if contrast_column != 'active_user_count'
|
||||
"schools.id school_id, schools.name school_name,"\
|
||||
"(SUM(IF(date BETWEEN '#{format_date(params[:begin_date])}' AND '#{format_date(params[:end_date])}', #{contrast_column}, 0))) total,"\
|
||||
"(SUM(IF(date BETWEEN '#{format_date(params[:other_begin_date])}' AND '#{format_date(params[:other_end_date])}', #{contrast_column}, 0))) other_total"
|
||||
else
|
||||
# 活跃用户对比时处理方法不同
|
||||
relations = SchoolDailyActiveUser.select('COUNT(distinct user_id)').joins(:school_daily_report)
|
||||
.where('school_id = schools.id')
|
||||
total_subquery = relations.where("date BETWEEN '#{format_date(params[:begin_date])}' AND '#{format_date(params[:end_date])}'").to_sql
|
||||
other_total_subquery = relations.where("date BETWEEN '#{format_date(params[:other_begin_date])}' AND '#{format_date(params[:other_end_date])}'").to_sql
|
||||
|
||||
"schools.id school_id, schools.name school_name, (#{total_subquery}) AS total, (#{other_total_subquery}) AS other_total"
|
||||
end
|
||||
end
|
||||
|
||||
def query_report_sql(from_sql)
|
||||
order_by = "(total = 0 AND other_total != 0) #{sort_direction}, (percentage != 0) #{sort_direction}, percentage #{sort_direction}"
|
||||
|
||||
"SELECT reports.*, (other_total - total) increase, (IF(other_total - total = 0, 0.0, round((other_total - total) / IF(total = 0, 1, total), 5))) percentage "\
|
||||
"FROM (#{from_sql}) reports ORDER BY #{order_by} LIMIT #{PAGE_SIZE} OFFSET #{offset}"
|
||||
end
|
||||
end
|
@ -0,0 +1,69 @@
|
||||
class StatisticSchoolDailyReportTask
|
||||
def call
|
||||
School.find_each do |school|
|
||||
# 新增教师和学生
|
||||
users = User.joins(:user_extension)
|
||||
.where(user_extensions: { school_id: school.id })
|
||||
|
||||
teacher_count = users.where(created_on: yesterday, user_extensions: { identity: :teacher }).count
|
||||
student_count = users.where(created_on: yesterday, user_extensions: { identity: :student }).count
|
||||
|
||||
# 活跃用户
|
||||
active_user_ids = users.where(last_login_on: yesterday).pluck(:id)
|
||||
active_user_count = active_user_ids.size
|
||||
|
||||
|
||||
# 新增课堂
|
||||
course_count = school.courses.where(created_at: yesterday).count
|
||||
|
||||
# 新增实训
|
||||
shixun_count = Shixun.joins(user: :user_extension)
|
||||
.where(user_extensions: { identity: :teacher, school_id: school.id })
|
||||
.where(created_at: yesterday).count
|
||||
# 新增实训作业数
|
||||
shixun_homework_count = HomeworkCommon.joins(:course).where(courses: { school_id: school.id })
|
||||
.where(homework_type: 4, created_at: yesterday).count
|
||||
|
||||
# 新增实训评测数量
|
||||
shixun_evaluate_count = EvaluateRecord.joins('LEFT JOIN homework_commons_shixuns hcs ON hcs.shixun_id = evaluate_records.shixun_id')
|
||||
.joins('LEFT JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4')
|
||||
.joins('LEFT JOIN members ON members.user_id = evaluate_records.user_id')
|
||||
.joins('LEFT JOIN courses ON members.course_id = courses.id AND hc.course_id = courses.id')
|
||||
.where(courses: { school_id: school.id })
|
||||
.where(created_at: yesterday).reorder(nil).count
|
||||
|
||||
# 无有效数据时不记录
|
||||
data = [teacher_count, student_count, course_count, shixun_count, active_user_count,
|
||||
shixun_homework_count, shixun_evaluate_count]
|
||||
next if data.all?(&:zero?)
|
||||
|
||||
create_params = {
|
||||
school_id: school.id, school_name: school.name, teacher_increase_count: teacher_count,
|
||||
student_increase_count: student_count, course_increase_count: course_count,
|
||||
shixun_homework_count: shixun_homework_count, shixun_evaluate_count: shixun_evaluate_count,
|
||||
shixun_increase_count: shixun_count, active_user_count: active_user_count, date: current_date
|
||||
}
|
||||
report = SchoolDailyReport.create!(create_params)
|
||||
|
||||
if active_user_ids.present?
|
||||
values = '(' + active_user_ids.join(", #{report.id}),(") + ", #{report.id})"
|
||||
user_sql = "INSERT INTO school_daily_active_users(user_id, school_daily_report_id) VALUES#{values}"
|
||||
SchoolDailyActiveUser.connection.execute(user_sql)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def current_date
|
||||
@_current_date ||= Time.zone.now.beginning_of_day - 1.day
|
||||
end
|
||||
|
||||
def yesterday
|
||||
@_yesterday ||= begin
|
||||
# 每日凌晨5点为节点
|
||||
end_time = Time.zone.now.beginning_of_day + 5.hour
|
||||
begin_time = end_time - 1.day
|
||||
begin_time..end_time
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,20 @@
|
||||
class StatisticSchoolReportTask
|
||||
def call
|
||||
School.find_each do |school|
|
||||
evaluate_count = Game.joins(:challenge)
|
||||
.joins('LEFT JOIN members ON members.user_id = games.user_id')
|
||||
.joins('LEFT JOIN homework_commons_shixuns hcs ON hcs.shixun_id = challenges.shixun_id')
|
||||
.joins('LEFT JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4')
|
||||
.joins('LEFT JOIN courses ON hc.course_id = courses.id AND members.course_id = courses.id')
|
||||
.where(courses: { school_id: school.id })
|
||||
.sum(:evaluate_count)
|
||||
|
||||
report = SchoolReport.find_or_initialize_by(school_id: school.id)
|
||||
|
||||
report.school_name = school.name
|
||||
report.shixun_evaluate_count = evaluate_count
|
||||
|
||||
report.save
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,13 @@
|
||||
wb = xlsx_package.workbook
|
||||
wb.add_worksheet(name: '统计总表') do |sheet|
|
||||
sheet.add_row %w(ID 单位名称 教师总人数 学生总人数 课堂总数 正在进行课堂数 总实训数 实训评测总数 实训作业总数 其它作业总数 动态时间)
|
||||
|
||||
@schools.each do |school|
|
||||
sheet.add_row([
|
||||
school[:id].to_s, school[:name].to_s, (school[:teacher_count] || 0).to_s, (school[:student_count] || 0).to_s,
|
||||
(school[:course_count] || 0).to_s, (school[:active_course_count] || 0).to_s,
|
||||
(school[:shixun_count] || 0).to_s,(school[:shixun_evaluate_count] || 0).to_s, (school[:homework_count] || 0).to_s,
|
||||
(school[:other_homework_count] || 0).to_s, format_time(school[:nearly_course_time])
|
||||
])
|
||||
end
|
||||
end
|
@ -0,0 +1,29 @@
|
||||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('统计总表', admins_daily_school_statistics_path) %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container daily-school-statistic-list-form">
|
||||
<%= form_tag(admins_daily_school_statistics_path, method: :get, class: 'form-inline search-form', remote: true) do %>
|
||||
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: 'ID/单位名称搜索') %>
|
||||
<%= submit_tag('搜索', class: 'btn btn-primary ml-3') %>
|
||||
<% end %>
|
||||
|
||||
<%#= link_to '导出Excel', export_admins_daily_school_statistics_path(format: :xlsx), class: 'btn btn-outline-primary export-action' %>
|
||||
<%= javascript_void_link '导出Excel', class: 'btn btn-outline-primary export-action', 'data-url': export_admins_daily_school_statistics_path(format: :xlsx) %>
|
||||
</div>
|
||||
|
||||
<div class="box py-0 pt-4 pl-4">
|
||||
统计总计:
|
||||
教师总人数<span class="text-danger"><%= @teacher_total %></span>人,
|
||||
学生总人数<span class="text-danger"><%= @student_total %></span>人,
|
||||
课堂总数<span class="text-danger"><%= @course_total %></span>个,
|
||||
正在进行课堂总数<span class="text-danger"><%= @active_course_total %></span>个,
|
||||
实训总数<span class="text-danger"><%= @shixun_total %></span>个,
|
||||
实训评测总数<span class="text-danger"><%= @shixun_evaluate_total %></span>个,
|
||||
实训作业总数<span class="text-danger"><%= @shixun_homework_total %></span>个,
|
||||
其它作业总数<span class="text-danger"><%= @other_homework_total %></span>个
|
||||
</div>
|
||||
|
||||
<div class="box daily-school-statistic-list-container">
|
||||
<%= render partial: 'admins/daily_school_statistics/shared/list', locals: { statistics: @statistics } %>
|
||||
</div>
|
@ -0,0 +1 @@
|
||||
$(".daily-school-statistic-list-container").html("<%= j(render partial: 'admins/daily_school_statistics/shared/list', locals: { statistics: @statistics }) %>")
|
@ -0,0 +1,46 @@
|
||||
<table class="table table-hover daily-school-statistic-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="18%" class="edu-txt-left">单位名称</th>
|
||||
|
||||
<th width="10%"><%= sort_tag('教师总人数', name: 'teacher_count', path: admins_daily_school_statistics_path) %></th>
|
||||
<th width="10%"><%= sort_tag('学生总人数', name: 'student_count', path: admins_daily_school_statistics_path) %></th>
|
||||
<th width="10%"><%= sort_tag('课堂总数', name: 'course_count', path: admins_daily_school_statistics_path) %></th>
|
||||
<th width="10%"><%= sort_tag('正在进行课堂数', name: 'active_course_count', path: admins_daily_school_statistics_path) %></th>
|
||||
<th width="10%"><%= sort_tag('实训总数', name: 'shixun_count', path: admins_daily_school_statistics_path) %></th>
|
||||
<th width="12%">
|
||||
<%= sort_tag('实训评测总数', name: 'shixun_evaluate_count', path: admins_daily_school_statistics_path) %>
|
||||
<i class="fa fa-question-circle" data-toggle="tooltip" data-html="true" data-placement="top" title="数据更新时间为<br/>当日6点、12点、18点、24点"></i>
|
||||
</th>
|
||||
<th width="10%"><%= sort_tag('实训作业总数', name: 'homework_count', path: admins_daily_school_statistics_path) %></th>
|
||||
<th width="10%"><%= sort_tag('其它作业总数', name: 'other_homework_count', path: admins_daily_school_statistics_path) %></th>
|
||||
<th width="14%"><%= sort_tag('动态时间', name: 'nearly_course_time', path: admins_daily_school_statistics_path) %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if statistics.present? %>
|
||||
<% statistics.each do |statistic| %>
|
||||
<tr>
|
||||
<td class="edu-txt-left">
|
||||
<%= link_to '#' do %>
|
||||
<%= overflow_hidden_span statistic[:name], width: '200px' %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= statistic[:teacher_count].to_i %></td>
|
||||
<td><%= statistic[:student_count].to_i %></td>
|
||||
<td><%= statistic[:course_count].to_i %></td>
|
||||
<td><%= statistic[:active_course_count].to_i %></td>
|
||||
<td><%= statistic[:shixun_count].to_i %></td>
|
||||
<td><%= statistic[:shixun_evaluate_count].to_i %></td>
|
||||
<td><%= statistic[:homework_count].to_i %></td>
|
||||
<td><%= statistic[:other_homework_count].to_i %></td>
|
||||
<td><%= statistic[:nearly_course_time]&.strftime('%Y-%m-%d %H:%M') %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= render 'admins/shared/no_data_for_table' %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= render partial: 'admins/shared/paginate', locals: { objects: statistics } %>
|
@ -0,0 +1 @@
|
||||
$(".school-statistic-list-container").html("<%= j(render partial: 'admins/school_statistics/shared/contrast_list', locals: { statistics: @statistics, select_options: @select_options }) %>")
|
@ -0,0 +1 @@
|
||||
$(".school-statistic-list-container").html("<%= j(render partial: 'admins/school_statistics/shared/list', locals: { statistics: @statistics }) %>")
|
@ -1 +0,0 @@
|
||||
<h3>403</h3>
|
@ -1,6 +1,6 @@
|
||||
<div class="d-flex flex-column align-items-center justify-content-center not-found">
|
||||
<div class="not-found-img">
|
||||
<div class="d-flex flex-column align-items-center justify-content-center global-error">
|
||||
<div class="global-error-code">
|
||||
<span>404</span>
|
||||
</div>
|
||||
<div class="not-found-text">资源未找到</div>
|
||||
<div class="global-error-text">资源未找到</div>
|
||||
</div>
|
@ -1,6 +1,6 @@
|
||||
<div class="d-flex flex-column align-items-center justify-content-center not-found">
|
||||
<div class="not-found-img">
|
||||
<div class="d-flex flex-column align-items-center justify-content-center global-error">
|
||||
<div class="global-error-code">
|
||||
<span>422</span>
|
||||
</div>
|
||||
<div class="not-found-text"><%= @message %></div>
|
||||
<div class="global-error-text"><%= @message %></div>
|
||||
</div>
|
@ -1,6 +1,6 @@
|
||||
<div class="d-flex flex-column align-items-center justify-content-center not-found">
|
||||
<div class="not-found-img">
|
||||
<div class="d-flex flex-column align-items-center justify-content-center global-error">
|
||||
<div class="global-error-code">
|
||||
<span>500</span>
|
||||
</div>
|
||||
<div class="not-found-text">系统错误</div>
|
||||
<div class="global-error-text">系统错误</div>
|
||||
</div>
|
@ -0,0 +1,9 @@
|
||||
zh-CN:
|
||||
school_daily_report:
|
||||
teacher_increase_count: 新增教师
|
||||
student_increase_count: 新增学生
|
||||
course_increase_count: 新增课堂
|
||||
shixun_increase_count: 新增实训
|
||||
shixun_homework_count: 新增实训作业
|
||||
shixun_evaluate_count: 新增实训评测
|
||||
active_user_count: 活跃用户
|
Loading…
Reference in new issue