dev_partners
Alec Zhou 6 years ago
commit 0486340146

@ -62,6 +62,9 @@ gem 'elasticsearch-rails'
gem 'oauth2'
# cronjob
gem 'whenever', require: false
#Ruby 2.2+ has removed test/unit from the core library.
if RUBY_VERSION>='2.2'
gem 'test-unit', '~> 3.0'

@ -362,6 +362,13 @@ class ApplicationController < ActionController::Base
true
end
# 运营人员
def require_business
unless (User.current.business? || User.current.admin?)
render_403
end
end
def deny_access
User.current.logged? ? render_403 : require_login
end

@ -1635,7 +1635,7 @@ class CoursesController < ApplicationController
@course_modules = @course.course_modules.where(:hidden => 0)
course_module_type = @course_modules.map(&:module_type)
@is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
@is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin? || User.current.business?
if User.current.member_of_course?(@course) && !@is_teacher
member = @course.members.where(:user_id => User.current.id).first
if member.try(:course_group_id).to_i == 0

@ -1,20 +1,44 @@
class Managements::SchoolsController < Managements::BaseController
before_filter :set_navigation_bar
before_filter :set_default_sort_params, only: :statistics
before_filter :contrast_column_select_options, only: [:data_contrast]
def statistics
@sub_type = 1
params[:sort_by] ||= :teacher_count
params[:sort_direction] ||= :desc
schools = Management::SchoolReportService.new(params).call
@schools = paginateHelper schools
end
def yesterday_data
@sub_type = 2
params[:sort_by] ||= :teacher_increase_count
params[:sort_direction] ||= :desc
reports = Management::SchoolYesterdayDataService.new(params).call
@reports = paginateHelper reports
end
def data_contrast
params[:contrast_column] = :teacher_increase_count if params[:contrast_column].blank?
params[:sort_direction] ||= :desc
params[:sort_by] ||= :percentage
@obj_count, @reports = Management::SchoolDataContrastService.new(params).call
@obj_pages = Paginator.new(@obj_count, Management::SchoolDataContrastService::PAGE_SIZE, params[:page])
rescue Management::SchoolDataContrastService::ParameterError
raise '参数错误'
end
private
def set_navigation_bar
@menu_type = 1
end
def set_default_sort_params
params[:sort_by] ||= :teacher_count
params[:sort_direction] ||= :desc
def contrast_column_select_options
@select_options = Management::SchoolDataContrastService::CONTRAST_COLUMN_LIST.map do |column|
[I18n.t("school_daily_report.#{column}"), column]
end
end
end
end

@ -1,6 +1,6 @@
# encoding: utf-8
class ManagementsController < ApplicationController
before_filter :require_admin
before_filter :require_business
layout 'base_management'
include ManagementsHelper
include SortHelper
@ -63,7 +63,6 @@ class ManagementsController < ApplicationController
# 工程认证视频导入模板
def ec_template
@template = EcTemplate.where(nil)
end
def add_template
@ -197,6 +196,7 @@ class ManagementsController < ApplicationController
if request.post?
@user.nickname = params[:nickname]
@user.lastname = params[:lastname]
@user.business = params[:business].to_i
@user.firstname = ""
@user.mail = params[:mail].strip == "" ? nil : params[:mail]
@user.phone = params[:phone].strip == "" ? nil : params[:phone]
@ -3350,7 +3350,7 @@ end
end
@users = User.where(:id => user_id).where("#{sql}").includes(:apply_actions, user_extensions: [:department, :school]).order("last_login_on desc")
@xls_users = @users.reorder("created_on desc").limit(1000) #导出excel用户
@xls_users = @users.reorder("created_on desc").limit(3000) #导出excel用户
@page = (params['page'] || 1).to_i
@users_count = @users.count
@limit = 20
@ -4181,7 +4181,7 @@ end
sheet1 = book.create_worksheet :name => "course"
blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10
sheet1.row(0).default_format = blue
sheet1.row(0).concat(["ID","课堂名称","成员","资源","普通作业"," 实训作业","试卷","私有","状态","创建者单位","创建者","动态时间"])
sheet1.row(0).concat(["ID","课堂名称","成员","资源","普通作业"," 实训作业","试卷","私有","状态","创建者单位","创建者","动态时间","创建时间"])
count_row = 1
courses.each do |course|
school = course.teacher.try(:user_extensions).try(:school).try(:name).blank? ? "--" : course.teacher.school_name
@ -4198,6 +4198,7 @@ end
sheet1[count_row,9] = school
sheet1[count_row,10] = teacher_name
sheet1[count_row,11] = format_time(course.updatetime)
sheet1[count_row,12] = format_time(course.created_at)
count_row += 1
end
book.write xls_report

@ -12,6 +12,7 @@ class ShixunsController < ApplicationController
before_filter :view_allow, :only => [:collaborators, :propaedeutics, :shixun_discuss, :ranking_list]
before_filter :require_manager, :only => [ :settings, :add_script, :publish, :collaborators_delete, :shixun_members_added, :add_collaborators, :update, :destroy]
before_filter :validation_email, :only => [:new]
before_filter :require_admin, :only => [:destroy]
# 移动云ToC模式权限控制
# before_filter :ecloud_auth, :except => [:show, :index]

@ -274,7 +274,7 @@ class UsersController < ApplicationController
# 私信
def private_messages
if User.current == @user || User.current.admin?
if User.current == @user || User.current.admin? || User.current.business?
@onclick_time = User.current.onclick_time.onclick_time
User.current.onclick_time.update_attribute(:onclick_time, Time.now)
@messages = PrivateMessage.find_by_sql("SELECT ui.* FROM (SELECT * FROM private_messages WHERE STATUS != 2 AND user_id = #{@user.id} ORDER BY id DESC) ui GROUP BY ui.target_id ORDER BY ui.send_time DESC")

@ -30,6 +30,17 @@ class WelcomeController < ApplicationController
require 'simple_xlsx_reader'
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
def local_init
LocalShixun.delete_all
LocalMirrorRepository.delete_all
LocalShixunTagRepertoire.delete_all
LocalChallenge.delete_all
LocalTestSet.delete_all
LocalChallengeTag.delete_all
render :json => {status: 0, message: "success"}
end
def shixun_to_local
identifiers = params[:identifiers].split(",")
shixuns = Shixun.where(identifier: identifiers)
@ -62,7 +73,7 @@ class WelcomeController < ApplicationController
if shixun.challenges.present?
shixun.challenges.each do |challenge|
new_challenge = LocalChallenge.new
new_challenge.attributes = challenge.attributes.dup.except("id","shixun_id","user_id")
new_challenge.attributes = challenge.attributes.dup.except("id","shixun_id","user_id", "test_set_score")
new_challenge.local_shixun_id = local_shixun.id
new_challenge.save!
# 评测题,选择题暂时不考虑
@ -98,6 +109,7 @@ class WelcomeController < ApplicationController
def local_to_shixun
ActiveRecord::Base.transaction do
shixun_list = []
LocalShixun.find_each do |local_shixun|
identifier = generate_identifier
shixun = Shixun.create!(name: local_shixun.name, description: local_shixun.description, user_id: User.current.id,
@ -141,7 +153,7 @@ class WelcomeController < ApplicationController
if local_challenges.present?
local_challenges.each do |local_challenge|
new_challenge = Challenge.new
new_challenge.attributes = local_challenge.attributes.dup.except("id","local_shixun_id","user_id")
new_challenge.attributes = local_challenge.attributes.dup.except("id","local_shixun_id","user_id", "test_set_score")
new_challenge.user_id = User.current.id
new_challenge.shixun_id = shixun.id
new_challenge.save!
@ -166,8 +178,9 @@ class WelcomeController < ApplicationController
end
end
end
render :json => {status: 0, message: "success", identifier: shixun.identifier}
shixun_list << shixun.identifier
end
render :json => {status: 0, message: "success", identifier: shixun_list}
end
end
@ -205,7 +218,7 @@ class WelcomeController < ApplicationController
@tea_users = User.where(homepage_teacher: 1).includes(:user_extensions).limit(10).order("experience desc")
@stu_users = User.includes(:user_extensions).where(user_extensions: {identity: 1}).limit(10).order("experience desc")
render :layout => 'educoder'
render :layout => 'base_local'
end
# 自动导入用户

@ -671,7 +671,7 @@ module ApplicationHelper
when 1
case sub_type
when 1 then "统计总表"
when 2 then "变化报表"
when 2 then "数据变化报表"
end
when 2
sub_type == 1 ? "课程列表" : (sub_type == 2? "课堂列表" : (sub_type == 3? "实训作业" : "项目列表"))
@ -3995,7 +3995,7 @@ module ApplicationHelper
# Returns the javascript tags that are included in the html layout head
def javascript_heads
tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application', 'jquery.colorbox-min', 'baiduTemplate')
tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'jquery.colorbox-min', 'baiduTemplate')
unless User.current.pref.warn_on_leaving_unsaved == '0'
tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
end
@ -4009,6 +4009,15 @@ module ApplicationHelper
tags
end
# 临时本地版
def javascript_heads_local
tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'jquery.colorbox-min')
unless User.current.pref.warn_on_leaving_unsaved == '0'
tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
end
tags
end
def hubspot_head
tags = javascript_include_tag('hubspot/messenger.min', 'hubspot/messenger-theme-future')
tags << stylesheet_link_tag('hubspot/messenger', 'hubspot/messenger-theme-future', 'hubspot/messenger-theme-flat')

@ -11,7 +11,7 @@ module CustomSortable
sort_by ||= self.class.sort_options[:default_by]
sort_direction ||= self.class.sort_options[:default_direction]
return relations unless self.class.check_sort_parameter_validate(sort_by, sort_direction)
return relations unless self.class.check_sort_parameter_validate(sort_by.to_s, sort_direction.to_s)
order_method = self.class.sort_options[:reorder] ? :reorder : :order
relations.send(order_method, "#{sort_by} #{sort_direction}")

@ -121,13 +121,6 @@ class OpenSourceProject < ActiveRecord::Base
ApplyProjectMaster.delete_all "apply_type = '#{self.class}' AND apply_id = #{self.id} AND user_id = #{user.id}"
end
def admin?(user)
if user.admin? or ApplyProjectMaster.find(:all, :conditions => ["user_id = ? and apply_type = 'OpenSourceProject' and apply_id = ? and status = ?", user.id, self.id, 2]).present?
return true
else
return false
end
end
def reset_counters!
self.class.reset_counters!(id)

@ -0,0 +1,3 @@
class SchoolDailyReport < ActiveRecord::Base
belongs_to :school
end

@ -28,6 +28,7 @@ class Shixun < ActiveRecord::Base
:propaedeutics, :trainee, :major_id, :homepage_show, :webssh, :hidden, :fork_from, :can_copy, :modify_time, :reset_time, :git_url, :use_scope,
:vnc, :evaluate_script, :image_text, :exec_time, :test_set_permission, :hide_code, :excute_time, :forbid_copy
belongs_to :creator, foreign_key: :user_id, class_name: 'User'
has_many :users, :through => :shixun_members
has_many :shixun_members, :dependent => :destroy
has_one :repository, :dependent => :destroy

@ -17,7 +17,7 @@ class GamesService
myshixun = Myshixun.min.find(game.myshixun_id)
shixun = Shixun.min.find(myshixun.shixun_id)
unless (myshixun.user_id == current_user.id || current_user.admin? || current_user.id == shixun.try(:user_id) || current_user.is_certification_teacher)
unless (myshixun.user_id == current_user.id || current_user.admin? || current_user.business? || current_user.id == shixun.try(:user_id) || current_user.is_certification_teacher)
return{:status => 403}
end
game_challenge = Challenge.min.find(game.challenge_id)

@ -0,0 +1,66 @@
class Management::SchoolDataContrastService
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
).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 = SchoolDailyReport.select(select_columns)
keyword = params[:keyword].try(:to_s).try(:strip)
if keyword.present?
reports = reports.where("school_name LIKE :keyword OR school_id LIKE :keyword", keyword: "%#{keyword}%")
end
reports = reports.group(:school_id)
count = reports.count.count
[count, SchoolDailyReport.find_by_sql(query_report_sql(reports.to_sql))]
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
"school_id, 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"
end
def query_report_sql(from_sql)
"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 percentage #{sort_direction} LIMIT #{PAGE_SIZE} OFFSET #{offset}"
end
end

@ -29,16 +29,12 @@ class Management::SchoolReportService
<<-SQL
schools.id, schools.name,
(
SELECT COUNT(*) FROM users u
LEFT JOIN user_extensions ue ON ue.user_id = u.id
LEFT JOIN ec_school_users esu ON esu.user_id = u.id
WHERE esu.school_id = schools.id AND ue.identity = #{User::STUDENT}
SELECT COUNT(*) FROM user_extensions ue
WHERE ue.school_id = schools.id AND ue.identity = #{User::STUDENT}
) student_count,
(
SELECT COUNT(*) FROM users u
LEFT JOIN user_extensions ue ON ue.user_id = u.id
LEFT JOIN ec_school_users esu ON esu.user_id = u.id
WHERE esu.school_id = schools.id AND ue.identity = #{User::TEACHER}
SELECT COUNT(*) FROM user_extensions ue
WHERE ue.school_id = schools.id AND ue.identity = #{User::TEACHER}
) teacher_count,
(
SELECT COUNT(*) FROM homework_commons hc

@ -0,0 +1,32 @@
class Management::SchoolYesterdayDataService
include CustomSortable
attr_reader :params
sort_columns :student_increase_count, :teacher_increase_count,
:course_increase_count, :shixun_increase_count, :active_user_count,
default_by: :teacher_increase_count, default_direction: :desc
def initialize(params)
@params = params
end
def call
reports = SchoolDailyReport.where(date: yesterday)
keyword = params[:keyword].try(:to_s).try(:strip)
if keyword.present?
reports = reports.where("school_name LIKE :keyword OR school_id LIKE :keyword", keyword: "%#{keyword}%")
end
reports = custom_sort(reports, params[:sort_by], params[:sort_direction])
reports
end
private
def yesterday
# 每日凌晨5点为节点, 25日凌晨4点、3点、2点等等未到更新数据时间点看到的数据是23日-24日的统计数据
(Time.zone.now - 5.hours).beginning_of_day - 1.days
end
end

@ -0,0 +1,44 @@
class StatisticSchoolDailyReportTask
def call
School.find_each do |school|
# 新增教师和学生
users = User.joins(:user_extensions)
.where(user_extensions: { school_id: school.id })
teacher_count = users.where(created_on: yesterday, user_extensions: { identity: User::TEACHER }).count
student_count = users.where(created_on: yesterday, user_extensions: { identity: User::STUDENT }).count
# 活跃用户
active_user_count = users.where(last_login_on: yesterday).count
# 新增课堂
course_count = school.courses.where(created_at: yesterday).count
# 新增实训
shixun_count = Shixun.joins(creator: :user_extensions)
.where('user_extensions.school_id = ?', school.id)
.where(created_at: yesterday).count
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_increase_count: shixun_count, active_user_count: active_user_count, date: current_date
}
SchoolDailyReport.create!(create_params)
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

@ -73,15 +73,6 @@
<% end %>
</div>
</div>
<!--第三方账号登录-->
<!--<div class="mt10 edu-txt-center">
<p class="color-grey-9">第三方账号登录</p>
<div class="mt15">
<a href="javascript:void(0)" class="margin15"><img src="/images/educoder/weixin.png" class="radius"/></a>
<a href="javascript:void(0)" class="margin15"><img src="/images/educoder/QQ.png" class="radius"/></a>
<a href="javascript:void(0)" class="margin15"><img src="/images/educoder/weibo.png" class="radius"/></a>
</div>
</div>-->
</div>
</div>
<%= render :partial => "account/copyright_info" %>

@ -6,25 +6,8 @@
<li class="<%= course_controller.include?(params[:controller]) ? " active" : "" %>"><%= link_to "翻转课堂", courses_path %></li>
<!-- 精选实训 -->
<li class="pr <%= shixuns_controller.include?(params[:controller]) ? " active" : "" %>"><%= link_to "开发社区", shixuns_path %><img src="/images/educoder/hot-h.png" class="nav-img" /></li>
<% careers = Career.published.order("created_at asc") %>
<% if careers.present? %>
<li class="fl edu-menu-panel headIcon careershover <%= params[:action] == "index" && params[:controller] == "careers" ? " active" : "" %>" style="cursor: auto;">
<p>职业路径</p>
<ul class="edu-menu-list edu-menu-listnew" style="top:60px">
<% careers.each do |career| %>
<li><a href="<%= introduction_career_path(career) %>"><%= career.name %></a></li>
<% end %>
</ul>
</li>
<% end %>
<li class="<%= params[:controller] == "competitions" ? " active" : "" %>"><%= link_to "竞赛", competitions_path %></li>
<li class="<%= params[:controller] == "forums" ? " active" : "" %>"><%= link_to "问答", forums_path %></li>
<% if User.current.ec_school.present? %>
<li class="<%= ecs_controller.include?(params[:controller]) ? " active" : "" %>" id="ec_banner">
<%= link_to "认证", department_ecs_path(:school_id => User.current.ec_school) %>
</li>
<% end %>
</ul>
<div class="posi-search" id="posi-search" style="display: none">
<div class="search-all clearfix">
@ -45,25 +28,27 @@
</div>
</div>
</div>
<div class="fr edu-menu-panel ml15" style="height:60px;">
<%= link_to (image_tag(url_to_avatar(User.current), :width =>"34", :height => "34", :class => "radius mt13", :nhname => "avatar_image", :alt=>"头像", :id => "nh_user_logo")), user_path(User.current),:class => "fl" %>
<ul class="edu-menu-list" style="top:60px;">
<span class="bor-bottom-greyE currentName task-hide"><%= User.current.show_name %></span>
<li><%= link_to '我的课堂', user_path(User.current) %></li>
<li><%= link_to '我的实训', user_path(User.current, :type => 'a_shixun') %></li>
<li><%= link_to '我的实训课程', user_path(User.current, :type => 'a_path') %></li>
<% if User.current.partner.present? %>
<li><%= link_to '客户管理', partner_list_cooperate_path(User.current.partner) %></li>
<% end %>
<li><%= link_to '我的项目', user_path(User.current, :type => 'a_project') %></li>
<% if User.current.logged? %>
<div class="fr edu-menu-panel ml15" style="height:60px;">
<%= link_to (image_tag(url_to_avatar(User.current), :width =>"34", :height => "34", :class => "radius mt13", :nhname => "avatar_image", :alt=>"头像", :id => "nh_user_logo")), user_path(User.current),:class => "fl" %>
<ul class="edu-menu-list" style="top:60px;">
<span class="bor-bottom-greyE currentName task-hide"><%= User.current.show_name %></span>
<li><%= link_to '我的课堂', user_path(User.current) %></li>
<li><%= link_to '我的实训', user_path(User.current, :type => 'a_shixun') %></li>
<li><%= link_to '我的实训课程', user_path(User.current, :type => 'a_path') %></li>
<li><%= link_to '我的项目', user_path(User.current, :type => 'a_project') %></li>
<li><%= link_to '账号管理', my_account_path %></li>
<li class="bor-top-greyE"><%= link_to '退出', signout_path %></li>
</ul>
</div>
<% else %>
<span class="font-15 fr mt15 ml15">
<%= link_to '登录', signin_path, :class => "mr5 color-white" %>
<em class="vertical-line"></em>
<%= link_to '注册', user_join_path, :class => "ml5 color-white" %>
</span>
<% end %>
<% if User.current.department_members.count > 0 %>
<li><%= link_to '学院统计', statistics_college_path(User.current.department_members.first.try(:department)) %></li>
<% end %>
<li><%= link_to '账号管理', my_account_path %></li>
<li class="bor-top-greyE"><%= link_to '退出', signout_path %></li>
</ul>
</div>
<div class="fr head-right">
<a href="javascript:void(0)" id="search-open" class="fl headIcon pointer">
<i class="iconfont icon-sousuo color-white"></i>
@ -81,28 +66,12 @@
<li><%= link_to '新建项目', new_project_path() %></li>
</ul>
<ul class="fl with50 edu-txt-center">
<li><%= link_to "加入课堂", join_private_courses_courses_path, :remote => true %></li>
<li><%= link_to "加入项目", applied_join_project_path, :remote => true %></li>
<li><%= link_to "加入课堂", join_private_courses_courses_path, :remote => true %></li>
<li><%= link_to "加入项目", applied_join_project_path, :remote => true %></li>
</ul>
</div>
</div>
<div class="fl edu-menu-panel headIcon">
<a href="<%= user_tidings_user_path(User.current) %>">
<i class="iconfont icon-xiaoxilingdang color-white"></i>
</a>
<!--新消息提醒-->
<% new_tidings_count = User.current.tidings.where("created_at > '#{User.current.onclick_time.onclick_time}'").count %>
<% new_pri_message_count = User.current.private_messages.where("created_at > '#{User.current.onclick_time.onclick_time}'").count %>
<% count = new_tidings_count + new_pri_message_count %>
<% if count > 0 %>
<a href="<%= user_tidings_user_path(User.current) %>"><span class="newslight"><%= count > 99 ? "99+" : count %></span> </a>
<div class="edu-menu-list edu-txt-center" style="width:220px;top:60px">
<a class="font-14 padding10" style="line-height: 35px;" href="<%= user_tidings_user_path(User.current) %>">您有<span class="color-orange"><%= count %></span>条新消息,点击查看</a>
</div>
<% end %>
</div>
</div>
</div>
@ -128,11 +97,11 @@
<% notice = SystemUpdateNotice.last %>
<% if @noticed_update || ((User.current.certification == 1 || params[:controller] != "welcome") && notice.present? && notice.end_time > Time.now && notice.start_time >= (Time.now - 21600) && User.current.user_system_notices.where(:notice_type => notice.notice_type).count == 0) %>
var htmlvalue = "<%= escape_javascript(render :partial => 'account/user_update_notice', :locals => {:notice => notice})%>";
pop_box_new(htmlvalue, 500, 380);
<% UserSystemNotice.create(:user_id => User.current.id, :notice_type => notice.notice_type) %>
var htmlvalue = "<%= escape_javascript(render :partial => 'account/user_update_notice', :locals => {:notice => notice})%>";
pop_box_new(htmlvalue, 500, 380);
<% UserSystemNotice.create(:user_id => User.current.id, :notice_type => notice.notice_type) %>
<%# elsif notice.present? && notice.end_time < Time.now %>
<%# notice.destroy %>
<%# notice.destroy %>
<% end %>
});

@ -8,17 +8,6 @@
<li class="pr <%= shixuns_controller.include?(params[:controller]) ? " active" : "" %>"><%= link_to "开发社区", shixuns_path %><img src="/images/educoder/hot-h.png" class="nav-img" /></li>
<% careers = Career.published.order("created_at asc") %>
<% if careers.present? %>
<li class="fl edu-menu-panel headIcon careershover <%= params[:action] == "index" && params[:controller] == "careers" ? " active" : "" %>" style="cursor: auto;">
<p>职业路径</p>
<ul class="edu-menu-list edu-menu-listnew" style="top:60px">
<% careers.each do |career| %>
<li><a href="<%= introduction_career_path(career) %>"><%= career.name %></a></li>
<% end %>
</ul>
</li>
<% end %>
<li class="<%= params[:controller] == "competitions" ? " active" : "" %>"><%= link_to "竞赛", competitions_path %></li>
<li class="<%= params[:controller] == "forums" ? " active" : "" %>"><%= link_to "问答", forums_path %></li>
<!--<li><%#= link_to "活动竞赛", competitions_path %></li>-->

@ -7,43 +7,23 @@
<meta name="keywords" content="智能课堂,实训项目" />
<%= csrf_meta_tag %>
<%= favicon %>
<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2','css/font-awesome','educoder/edu-main','educoder/edu-all','educoder/magic-check.css','/assets/iconfont/iconfont.css', :media => 'all' %> <%= javascript_heads %>
<%= javascript_include_tag 'edu/application', 'educoder/edu_application','educoder/edu_account',"educoder/edu_user" %>
<%= yield :header_tags -%>
<!-- MathJax的配置 -->
<script type="text/javascript"
src="/javascripts/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<!-- 配置 在生成的公式图片上去掉Math定义的右键菜单$$ $$ \( \) \[ \] 中的公式给予显示-->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
showMathMenu: false,
showMathMenuMSIE: false,
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<%= stylesheet_link_tag 'css/font-awesome','educoder/edu-main','educoder/edu-all','/assets/iconfont/iconfont.css', :media => 'all' %>
</head>
<body onload="prettyPrint();">
<div class="newContainer"> <!-- 页面全部内容 -->
<div class="newHeader" id="nHeader"> <!-- 头部 -->
<% if User.current.logged? %>
<%= render :partial => 'layouts/logined_header' %>
<% else%>
<%= render :partial => 'layouts/unlogin_header' %>
<% end%>
<div class="newContainer">
<div class="newHeader" id="nHeader">
<%= render :partial => 'layouts/logined_header' %>
<div class="cl"></div>
</div>
<div class="newMain clearfix"> <!-- 主提部分 -->
<div class="newMain clearfix">
<div id="Container">
<%= yield %>
</div>
<div class="cl"></div>
<!-------------------侧边提示区域-------------------------->
<%= render :partial => 'users/returnTop_btn' %>
</div>
<!----------------------左侧导航栏 ------------------------->
<%#= render :partial => 'layouts/public_left_info' %>
<%= render :partial => 'layouts/footer' %>
<div class="cl"></div>
<div id="ajax-modal" style="display:none;"></div>
@ -55,4 +35,6 @@
</div>
</div>
</body>
<%= javascript_heads_local %>
<%= javascript_include_tag 'edu/application', 'educoder/edu_application',"educoder/edu_user" %>
</html>

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title><%= h html_title %></title>
<meta name="description" content="高校智能课堂与综合实训平台" />
<meta name="keywords" content="智能课堂,实训项目" />
<%= csrf_meta_tag %>
<%= favicon %>
<%= javascript_edu_index_heads %>
<%= stylesheet_link_tag 'educoder/edu-main', 'educoder/edu-all', 'educoder/magic-check' %>
</head>
<div class="newContainer">
<div class="newHeader" id="nHeader">
<%= render 'layouts/logined_header' %>
</div>
<div class="newMain clearfix">
<%= yield %>
</div>
<%= render :partial => 'layouts/footer' %>
</div>
<div id="ajax-indicator" style="display:none;">
<span><%= l(:label_loading) %></span>
</div>
</body>
<%= javascript_include_tag 'educoder/edu_application','educoder/jquery.raty' %>
</html>

@ -35,6 +35,7 @@
<li class="fl edu-admin-nav-li edu-position <%= 'active' if @menu_type == 1 %>"><a href="javascript:void(0);" class="edu-admin-nav-a">学校+</a>
<ul class="edu-admin-nav-inner edu-absolute">
<li><%= link_to '统计总表', school_report_managements_path %></li>
<li><%= link_to '数据变化报表', school_yesterday_data_managements_path %></li>
</ul>
</li>
<li class="fl edu-admin-nav-li edu-position <%= 'active' if @menu_type == 2 %>"><a href="javascript:void(0);" class="edu-admin-nav-a">课堂+</a>

@ -7,23 +7,9 @@
<meta name="keywords" content="智能课堂,实训项目" />
<%= csrf_meta_tag %>
<%= favicon %>
<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2','educoder/edu-main','educoder/edu-all', 'css/font-awesome','educoder/magic-check.css' %>
<%#= javascript_heads %>
<%= javascript_include_tag 'jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'jquery.colorbox-min', 'edu/application', 'educoder/edu_application','educoder/edu_account','educoder/avatars' %>
<%#= stylesheet_link_tag 'css/edu-showpage','css/edu-index', 'css/font-awesome', 'css/edu-common', 'css/edu-login', 'css/edu-public', 'css/edu-popup' %>
<%#= javascript_include_tag 'edu/application', "bigdata" %>
<!-- MathJax的配置 -->
<script type="text/javascript"
src="/javascripts/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
<%= stylesheet_link_tag 'educoder/edu-main','educoder/edu-all' %>
<%= javascript_include_tag 'jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'educoder/edu_application', 'educoder/edu_account' %>
showMathMenu: false,
showMathMenuMSIE: false,
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
</head>
<body>
<div class="newContainer">

@ -0,0 +1,223 @@
<form class="management-school-data-form">
<div style="float: left; margin: 10px 10px 10px 25px;">
<%= hidden_field_tag :contrast_column, params[:contrast_column] %>
<%= hidden_field_tag :begin_date, params[:begin_date] %>
<%= hidden_field_tag :end_date, params[:end_date] %>
<%= hidden_field_tag :other_begin_date, params[:other_begin_date] %>
<%= hidden_field_tag :other_end_date, params[:other_end_date] %>
<%= text_field_tag :date_input, params[:date_input],
class: 'date-input winput-200-30', placeholder: '请选择时间段一' %>
<span>VS</span>
<%= text_field_tag :other_date_input, params[:other_date_input],
class: 'other-date-input winput-200-30', placeholder: '请选择时间段二' %>
</div>
<div style="float: left;">
<%= hidden_field_tag :data_type, params[:data_type] || 'yesterday' %>
<% if params[:data_type] == 'contrast' %>
<a href="javascript:void(0)" class="fl task-btn ml5 mt10 contrast-btn task-btn-orange">时间对比</a>
<a href="javascript:void(0)" class="fl task-btn ml5 mt10 yesterday-btn">日新增</a>
<% else %>
<a href="javascript:void(0)" class="fl task-btn ml5 mt10 contrast-btn">时间对比</a>
<a href="javascript:void(0)" class="fl task-btn ml5 mt10 yesterday-btn task-btn-orange">日新增</a>
<% end %>
</div>
<%= text_field_tag :keyword, params[:keyword], placeholder: '请输入单位名称或者ID关键字进行搜索',
class: 'fl task-form-30 task-height-30 mt10', style: 'margin: 10px 10px 10px 25px;' %>
<%= link_to '搜索', 'javascript:void(0)', class: 'fl task-btn task-btn-orange ml5 mt10 search-btn' %>
<%= link_to '清除', 'javascript:void(0)', class: 'fl task-btn ml5 mt2 mt10 reset-btn' %>
</form>
<script>
$(function(){
var yesterdayFormUrl = "<%= school_yesterday_data_managements_path %>";
var contrastFormUrl = "<%= school_data_contrast_managements_path %>";
var searchForm = $(".management-school-data-form");
var dataTypeInput = searchForm.find("input[name='data_type']");
var keywordInput = searchForm.find("input[name='keyword']");
var contrastBtn = searchForm.find(".contrast-btn");
var yesterdayBtn = searchForm.find(".yesterday-btn");
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']");
// 数据展示切换: 数据对比、日新增
searchForm.on('click', ".contrast-btn", function(){
if(contrastBtn.hasClass("task-btn-orange")) { return }
changeDataType("contrast");
});
searchForm.on('click', ".yesterday-btn", function(){
if(yesterdayBtn.hasClass("task-btn-orange")) { return }
changeDataType("yesterday");
submitForm();
});
// 搜索按钮
searchForm.on('click', ".search-btn", function(){
submitForm();
});
searchForm.on("click", ".reset-btn", function(){
keywordInput.val("");
submitForm();
});
$('.contrast-column-select').on('change', 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 : yesterdayFormUrl;
$.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 false;
}
return true;
};
var changeDataType = function(dataType){
if (dataTypeInput.val() == dataType) { return }
if (dataType == "contrast") {
contrastBtn.addClass("task-btn-orange");
yesterdayBtn.removeClass("task-btn-orange");
dataTypeInput.val('contrast');
} else {
contrastBtn.removeClass("task-btn-orange");
yesterdayBtn.addClass("task-btn-orange");
dataTypeInput.val('yesterday');
clearContrastDateInput();
}
};
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 locale = {
clearText: '清除',
clearStatus: '清除已选日期',
closeText: '关闭',
closeStatus: '不改变当前选择',
prevText: '< 上月',
prevStatus: '显示上月',
prevBigText: '<<',
prevBigStatus: '显示上一年',
nextText: '下月>',
nextStatus: '显示下月',
nextBigText: '>>',
nextBigStatus: '显示下一年',
currentText: '今天',
currentStatus: '显示本月',
monthNames: ['一月','二月','三月','四月','五月','六月', '七月','八月','九月','十月','十一月','十二月'],
monthNamesShort: ['一月','二月','三月','四月','五月','六月', '七月','八月','九月','十月','十一月','十二月'],
monthStatus: '选择月份',
yearStatus: '选择年份',
weekHeader: '周',
weekStatus: '年内周次',
dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
dayNamesMin: ['日','一','二','三','四','五','六'],
dayStatus: '设置 DD 为一周起始',
dateStatus: '选择 m月 d日, DD',
dateFormat: 'yy-mm-dd',
firstDay: 1,
initStatus: '请选择日期',
isRTL: false
};
var options = {
dateFormat: 'yy-mm-dd',
minDate: new Date('2017-04-01'),
maxDate: -1,
onSelect: function(selectedDate) {
if(!$(this).data().datepicker.first){
$(this).data().datepicker.inline = true;
$(this).data().datepicker.first = selectedDate;
if($(this).hasClass("date-input")){
beginDateInput.val("");
endDateInput.val("");
} else {
otherBeginDateInput.val("");
otherEndDateInput.val("");
}
}else{
// 计算时间先后顺序
var begin_date = null;
var end_date = null;
if(selectedDate > $(this).data().datepicker.first){
begin_date = $(this).data().datepicker.first;
end_date = selectedDate;
}else{
begin_date = selectedDate;
end_date = $(this).data().datepicker.first;
}
// 记录所选时间
if($(this).hasClass("date-input")){
beginDateInput.val(begin_date);
endDateInput.val(end_date);
} else {
otherBeginDateInput.val(begin_date);
otherEndDateInput.val(end_date);
}
// 展示所选时间
$(this).val(begin_date + " 至 " + end_date);
$(this).data().datepicker.inline = false;
// 切换数据类型
changeDataType("contrast");
}
},
onClose:function(){
var date = $(this).data().datepicker.first;
if (date) {
if($(this).hasClass("date-input") && beginDateInput.val() == ""){
beginDateInput.val(date);
endDateInput.val(date);
} else if ($(this).hasClass("other-date-input") && otherBeginDateInput.val() == "") {
otherBeginDateInput.val(date);
otherEndDateInput.val(date);
}
}
delete $(this).data().datepicker.first;
$(this).data().datepicker.inline = false;
submitForm();
}
};
options = $.extend({}, locale, options);
searchForm.find(".date-input").datepicker(options);
searchForm.find(".other-date-input").datepicker(options);
});
</script>

@ -0,0 +1,72 @@
<div style="position: relative;">
<div style="padding: 15px 0; text-align: center; font-size: 18px; font-weight: bold; border: 1px solid #eee; border-bottom: unset;">
学校数据统计(<%= I18n.t("school_daily_report.#{params[:contrast_column]}") %>变化统计情况)
</div>
<%= select_tag :contrast_column,
options_for_select(@select_options, params[:contrast_column]),
class: 'fl task-height-30 contrast-column-select',
style: 'position: absolute; right: 30px; top: 15px;' %>
</div>
<table class="edu-pop-table edu-txt-center" cellpadding="0" cellspacing="0" style="table-layout: fixed">
<thead>
<tr>
<th width="6%">序号</th>
<th width="10%">ID</th>
<th width="20%" class="edu-txt-left">单位名称</th>
<th width="24%">时段一<br><%= "#{params[:begin_date]}至#{params[:end_date]}" %></th>
<th width="24%">时段二<br><%= "#{params[:other_begin_date]}至#{params[:other_end_date]}" %></th>
<th width="16%" colspan="2">
<%= sort_tag('变化情况', name: 'percentage', path: school_data_contrast_managements_path) %>
<br> 新 增 数 | 新增百分比)
</th>
</tr>
</thead>
<tbody>
<% @reports.each_with_index do |report, index| %>
<tr>
<td><%= (@obj_pages.page - 1) * @obj_pages.per_page + index + 1 %></td>
<td><%= report.school_id %></td>
<td class="edu-txt-left"><%= report.school_name %></td>
<td><%= report['total'] %></td>
<td><%= report['other_total'] %></td>
<% if report['increase'] > 0 %>
<td class="edu-txt-right pr20 right-border" style="position: relative; color: red;">
+<%= report['increase'] %>
</td>
<td class="edu-txt-left pl20 c_red" style="color: red;">+<%= report['percentage'] %>%</td>
<% elsif report['increase'].zero? %>
<td class="edu-txt-right pr20 right-border" style="position: relative;">
<%= report['increase'] %>
</td>
<td class="edu-txt-left pl20"><%= report['percentage'] %></td>
<% else %>
<td class="edu-txt-right pr20 right-border c_green" style="position: relative; color: green;">
<%= report['increase'] %>
</td>
<td class="edu-txt-left pl20" style="color: green;"><%= report['percentage'] %>%</td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<div style="text-align:center;" class="new_expand">
<div class="pages_user_show" style="width:auto; display:inline-block;margin: 18px 0;">
<ul id="school_data_contrast_ref_pages">
<%= pagination_links_full @obj_pages, @obj_count, per_page_links: false, remote: true, flag: true, is_new: true, path: school_data_contrast_managements_path(params.except(:page)) %>
</ul>
<div class="cl"></div>
</div>
</div>
<style>
.right-border::after {
position: absolute;
top: 10px;
right: 0;
content: '';
width: 0;
height: 20px;
border-right: 1px solid #000;
}
</style>

@ -15,10 +15,9 @@
</tr>
</thead>
<tbody>
<% @schools.as_json.each_with_index do |data, index| %>
<% @schools.each_with_index do |school, index| %>
<tr>
<% school = data["school"] %>
<td><%= (@obj_pages.page - 1) * @obj_pages.per_page + index + 1 %></td>
<td><% p school %><%= (@obj_pages.page - 1) * @obj_pages.per_page + index + 1 %></td>
<td><%= school['id'] %></td>
<td class="edu-txt-left"><%= school['name'] %></td>
<td><%= school['teacher_count'] %></td>

@ -0,0 +1,38 @@
<table class="edu-pop-table edu-txt-center" cellpadding="0" cellspacing="0" style="table-layout: fixed">
<thead>
<tr>
<th width="6%">序号</th>
<th width="10%">ID</th>
<th width="24%" class="edu-txt-left">单位名称</th>
<th width="12%"><%= sort_tag('新增教师', name: 'teacher_increase_count', path: school_yesterday_data_managements_path) %></th>
<th width="12%"><%= sort_tag('新增学生', name: 'student_increase_count', path: school_yesterday_data_managements_path) %></th>
<th width="12%"><%= sort_tag('新增课堂', name: 'course_increase_count', path: school_yesterday_data_managements_path) %></th>
<th width="12%"><%= sort_tag('新增实训', name: 'shixun_increase_count', path: school_yesterday_data_managements_path) %></th>
<th width="12%"><%= sort_tag('活跃用户', name: 'active_user_count', path: school_yesterday_data_managements_path) %></th>
</tr>
</thead>
<tbody>
<% @reports.each_with_index do |report, index| %>
<tr>
<td><%= (@obj_pages.page - 1) * @obj_pages.per_page + index + 1 %></td>
<td><%= report.school_id %></td>
<td class="edu-txt-left"><%= report.school_name %></td>
<td><%= report.teacher_increase_count %></td>
<td><%= report.student_increase_count %></td>
<td><%= report.course_increase_count %></td>
<td><%= report.shixun_increase_count %></td>
<td><%= report.active_user_count %></td>
</tr>
<% end %>
</tbody>
</table>
<div style="text-align:center;" class="new_expand">
<div class="pages_user_show" style="width:auto; display:inline-block;margin: 18px 0;">
<ul id="school_yesterday_data_ref_pages">
<%= pagination_links_full @obj_pages, @obj_count, per_page_links: false, remote: true, flag: true, is_new: true, path: school_yesterday_data_managements_path(params.except(:page)) %>
</ul>
<div class="cl"></div>
</div>
</div>

@ -0,0 +1,2 @@
$("#managements-school-data").html("<%= j(render 'managements/schools/data_contrast_list') %>")
$(".management-school-data-form-box").html("<%= j(render 'managements/schools/contrast_search_form') %>")

@ -0,0 +1,9 @@
<div class="edu-con-top clearfix xmt10 bor-grey-e mt10">
<div class="management-school-data-form-box">
<%= render 'managements/schools/contrast_search_form' %>
</div>
</div>
<div class="edu-con-bg01 mt15" id="managements-school-data">
<%= render 'managements/schools/yesterday_data_list'%>
</div>

@ -0,0 +1,2 @@
$("#managements-school-data").html("<%= j(render 'managements/schools/yesterday_data_list') %>")
$(".management-school-data-form-box").html("<%= j(render 'managements/schools/contrast_search_form') %>")

@ -184,6 +184,13 @@
<% end %>
<div class="cl"></div>
</li>
<li class="clearfix mb10">
<label class="panel-form-label fl mr18">运营人员:</label>
<span class="fl">
<input type="checkbox" <%= @user.business ? "checked" : "" %> name="business" value="<%= @user.business? ? 1 : 0 %>" id="person_9" class="magic-checkbox" style="float:left; margin-top: 8px;">
<label for="person_9"></label>
</span>
</li>
<li class="clearfix mb10 hascontont">
<label class="panel-form-label fl mr18">职业:</label>
<select id="userIdentity" name="identity" nh_required="1" class="fl input-height mr15 select-width">

@ -0,0 +1,7 @@
zh:
school_daily_report:
teacher_increase_count: 新增教师
student_increase_count: 新增学生
course_increase_count: 新增课堂
shixun_increase_count: 新增实训
active_user_count: 活跃用户

@ -286,6 +286,7 @@ RedmineApp::Application.routes.draw do ## oauth相关
get 'welcome/ccf' => 'welcome#ccf'
get 'welcome/shixun_to_local' => 'welcome#shixun_to_local'
get 'welcome/local_to_shixun' => 'welcome#local_to_shixun'
get 'welcome/local_init' => 'welcome#local_init'
# get 'competitions/home' => 'competitions#home'
# get 'competitions/hn' => 'competitions#index'
@ -725,6 +726,8 @@ RedmineApp::Application.routes.draw do ## oauth相关
delete :delete_partner
get :customers_list
get :school_report, controller: 'managements::schools', action: 'statistics'
get :school_yesterday_data, controller: 'managements::schools', action: 'yesterday_data'
get :school_data_contrast, controller: 'managements::schools', action: 'data_contrast'
end
end
# Enable Grack support

@ -0,0 +1,24 @@
# Use this file to easily define all of your cron jobs.
#
# It's helpful, but not entirely necessary to understand cron before proceeding.
# http://en.wikipedia.org/wiki/Cron
# Example:
#
# set :output, "/path/to/my/cron_log.log"
#
# every 2.hours do
# command "/usr/bin/some_great_command"
# runner "MyModel.some_method"
# rake "some:great:rake:task"
# end
#
# every 4.days do
# runner "AnotherModel.prune_old_records"
# end
# Learn more: http://github.com/javan/whenever
every 1.days, at: '5:00 am' do
runner 'StatisticSchoolDailyReportTask.new.call'
end

@ -0,0 +1,18 @@
class CreateSchoolDailyReports < ActiveRecord::Migration
def change
create_table :school_daily_reports do |t|
t.integer :school_id
t.string :school_name
t.integer :teacher_increase_count
t.integer :student_increase_count
t.integer :course_increase_count
t.integer :shixun_increase_count
t.integer :active_user_count
t.date :date
t.timestamps
end
add_index :school_daily_reports, [:school_id, :date], unique: true
end
end

@ -0,0 +1,5 @@
class AddBusinessToUser < ActiveRecord::Migration
def change
add_column :users, :business, :boolean, :default => false
end
end

@ -0,0 +1,103 @@
#coding=utf-8
namespace :school_daily_report do
desc 'statistic school daily report data before now'
task :statistic, [:date] => :environment do |_, args|
date = Time.zone.parse(args[:date]).beginning_of_day
current_date = (Time.zone.now - 5.hour).beginning_of_day
custom_logger("statistic range: #{date}..#{current_date}")
while current_date > date
date_str = date.strftime('%Y-%m-%d')
# 检查当天数据是否已经统计
if SchoolDailyReport.exists?(date: date)
custom_logger("Skip! statistics data exist, date: #{date_str}")
date += 1.day
next
end
school_count = School.count
query_times = school_count % query_size == 0 ? school_count / query_size : (school_count / query_size) + 1
custom_logger("Start statistic => Date: #{date_str}, school count: #{school_count}, insert times: #{query_times} ~")
query_times.times do |index|
sql = school_daily_report_sql(date, query_size, index * query_size)
reports = School.find_by_sql(sql)
data = reports.map do |report|
[
report['id'], report['name'], report['teacher_count'], report['student_count'], report['course_count'],
report['shixun_count'], report['active_user_count'], date_str, current_datetime, current_datetime
]
end
batch_create_school_daily_reports!(data)
end
custom_logger("Statistic complete! date: #{date_str}")
date += 1.day
end
end
desc 'clear school daily report data'
task clear: :environment do
SchoolDailyReport.destroy_all
end
def query_size
100
end
def current_datetime
Time.zone.now.strftime('%Y-%m-%d %H:%M:%S')
end
def custom_logger(str)
p(str)
end
def batch_create_school_daily_reports!(arr)
sql = build_insert_report_sql(arr)
SchoolDailyReport.connection.execute(sql)
end
def build_insert_report_sql(arr)
prefix = 'INSERT INTO school_daily_reports(school_id, school_name, teacher_increase_count, student_increase_count, '\
'course_increase_count, shixun_increase_count, active_user_count, date, created_at, updated_at) VALUES'
# [[1,2], [3,4]] => ['"1", "2"', '"3", "4"'] => '("1", "2"),("3", "4")'
values = '(' + arr.map { |item| '"' + item.join('","') + '"' }.join('),(') + ')'
prefix + values
end
def school_daily_report_sql(date, limit, offset)
begin_date = (date + 5.hour).strftime('%Y-%m-%d %H:%M:%S')
end_date = (date + 1.day + 5.hour).strftime('%Y-%m-%d %H:%M:%S')
<<-SQL
SELECT schools.id, schools.name, (
SELECT COUNT(*) FROM users u
LEFT JOIN user_extensions ue ON ue.user_id = u.id
WHERE ue.school_id = schools.id AND ue.identity = #{User::STUDENT}
AND u.created_on BETWEEN "#{begin_date}" AND "#{end_date}"
) student_count, (
SELECT COUNT(*) FROM users u
LEFT JOIN user_extensions ue ON ue.user_id = u.id
WHERE ue.school_id = schools.id AND ue.identity = #{User::TEACHER}
AND u.created_on BETWEEN "#{begin_date}" AND "#{end_date}"
) teacher_count, (
SELECT COUNT(*) FROM courses cs
WHERE cs.school_id = schools.id
AND cs.created_at BETWEEN "#{begin_date}" AND "#{end_date}"
) course_count, (
SELECT COUNT(*) FROM shixuns sx
LEFT JOIN users u ON sx.user_id = u.id
LEFT JOIN user_extensions ue ON ue.user_id = u.id
WHERE ue.school_id = schools.id AND sx.created_at BETWEEN "#{begin_date}" AND "#{end_date}"
) shixun_count, (
SELECT COUNT(*) FROM users u
LEFT JOIN user_extensions ue ON ue.user_id = u.id
WHERE ue.school_id = schools.id AND u.last_login_on BETWEEN "#{begin_date}" AND "#{end_date}"
) active_user_count FROM schools LIMIT #{limit} OFFSET #{offset}
SQL
end
end

@ -89,7 +89,7 @@ task :add_test_users => :environment do
(1..1000).each do |i|
no = sprintf("%04d", i)
phone = "1560731#{no}"
phone = "5160731#{no}"
us = UsersService.new
user = us.register phone: phone, password: 'edu12345678'
@ -109,7 +109,7 @@ task :add_test_users => :environment do
lastname: lastname,
nickname: '',
sex: 0,
mail: "educoder#{no}@qq.com",
mail: "00educoder#{no}@qq.com",
identity: 1,
te_technical_title: 0,
pro_technical_title: 0,

@ -15,18 +15,6 @@ $(function(){
var searchText = result[1]
$('#search-input').val(searchText)
}
// 未报名用户登录时弹框
// console.log(Cookies.get('enroll_status'));
// if(Cookies.get('enroll_status') == 0){
// Cookies.remove('enroll_status');
// var html='<div class="CompetitionEnrollBox">'+
// '<div class="pr with40">'+
// '<img src="/images/educoder/competition/boxEnroll.png" width="100%"/>'+
// '<a href="javascript:void(0)" class="CloseBox" onclick="CloseBox();"><i class="iconfont icon-roundclose color-grey-c"></i></a>'+
// '<a href="https://www.educoder.net/competitions/gcc-dev-2018/enroll" class="ImmediatelyEnroll">立即报名</a>'+
// '</div></div>';
// $(".newContainer").append(html);
// }
});
function CloseBox(){

Loading…
Cancel
Save