dev_partners
huang 6 years ago
commit 41a1795b32

1
.gitignore vendored

@ -22,6 +22,7 @@
.DS_Store
public/api_doc/
/.metadata
.byebug_history
vendor/cache
/files
/public/images/avatars

@ -60,6 +60,12 @@ gem 'kaminari'
gem 'elasticsearch-model'
gem 'elasticsearch-rails'
gem 'oauth2'
# xlsx
gem 'axlsx', '3.0.0.pre'
gem 'axlsx_rails', '0.3.0'
#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
@ -1120,4 +1127,35 @@ class ApplicationController < ActionController::Base
Time.now < Time.new(2019, 4, 23, 2)
end
# 获取Oauth Client
def get_client(site)
client_id = Redmine::Configuration['client_id']
client_secret = Redmine::Configuration['client_secret']
OAuth2::Client.new(client_id, client_secret, site: site)
end
def handle_openi_request
site = Redmine::Configuration['openi_domain']
root_url = Redmine::Configuration['educoder_domain']
get_code_url = "/oauth/get_code"
original_url = request.original_url
client = get_client(site)
redirect_uri = "#{root_url}#{get_code_url}"
authorize_url = client.auth_code.authorize_url(redirect_uri: redirect_uri)
authorize_url = authorize_url + "&gen_code=true&state=1&original_url=#{original_url}"
redirect_to authorize_url
end
def user_login_and_from_openi?
url = request.referer.nil? ? Redmine::Configuration['educoder_domain'] : request.referer
flag = URI(url).host == URI(Redmine::Configuration['openi_domain']).host && !current_user.logged?
logger.info "----------------------- request referer: #{request.referer} -------------------------"
logger.info "----------------------- url after processed: #{url} -------------------------"
logger.info "----------------------- host: #{URI(url).host} --------------------------"
logger.info "----------------------- handle_flag: #{flag} -------------------------"
flag
end
end

@ -7,6 +7,11 @@ class AvatarController < ApplicationController
include ApplicationHelper
def upload
if params[:source_type] == "User" && !(User.current.admin? || User.current.id == params[:source_id].to_i)
render_403
return
end
# Make sure that API users get used to set this content type
# as it won't trigger Rails' automatic parsing of the request body for parameters
unless request.content_type == 'application/octet-stream'

@ -1,6 +1,8 @@
# encoding: utf-8
class ChallengesController < ApplicationController
layout "base_shixun"
# 如要添加或修改before_filter时请将handle_openi_request这个before_filter放至第一位
# before_filter :handle_openi_request, if: -> { user_login_and_from_openi? }, only: [:index]
before_filter :check_authentication, :except => [:index]
before_filter :find_shixun, :only => [:index, :new, :create, :destroy, :challenge_build, :update_evaluation, :add_choose_question, :new_choose_question,
:choose_type_show, :edit_choose_question, :update_choose_question, :destroy_challenge_choose]
@ -465,7 +467,9 @@ class ChallengesController < ApplicationController
render_404
return
else
if (@shixun.status == 0 && !User.current.manager_of_shixun?(@shixun)) || @shixun.status == -1
logger.info("operable: ##{@shixun.operable?}")
logger.info("@shixun.status: ##{@shixun.status}")
if (@shixun.status == 0 && !User.current.manager_of_shixun?(@shixun)) || (!@shixun.operable? && !User.current.admin?)
render_403
return
end

@ -44,31 +44,31 @@ class CollegesController < ApplicationController
def statistics
logger.info("#########################{params}")
@teachers_count = User.find_by_sql("SELECT COUNT(users.`id`) AS teacher_count FROM users LEFT JOIN user_extensions ON users.id=user_extensions.user_id WHERE
user_extensions.`school_id` = #{@department.school_id} AND user_extensions.`identity` = 0").first.try(:teacher_count)
user_extensions.`school_id` = #{@school.id} AND user_extensions.`identity` = 0").first.try(:teacher_count)
@students_count = User.find_by_sql("SELECT COUNT(users.`id`) AS student_count FROM users LEFT JOIN user_extensions ON users.id=user_extensions.user_id WHERE
user_extensions.`school_id` = #{@department.school_id} AND user_extensions.`identity` = 1").first.try(:student_count)
user_extensions.`school_id` = #{@school.id} AND user_extensions.`identity` = 1").first.try(:student_count)
# Redo这样做内存会卡死的
# user_ids = User.find_by_sql("SELECT users.id FROM users LEFT JOIN user_extensions ON users.id=user_extensions.user_id WHERE user_extensions.`school_id` = #{@department.school_id}").map(&:id)
# user_ids = User.find_by_sql("SELECT users.id FROM users LEFT JOIN user_extensions ON users.id=user_extensions.user_id WHERE user_extensions.`school_id` = #{@school.id}").map(&:id)
# Redo是否直接使用count会更好
all_course_ids = Course.joins("join users u on courses.tea_id = u.id").joins("join user_extensions ue on u.id = ue.user_id").where("courses.id != 1309 and ue.school_id = #{@department.school_id}")
all_course_ids = Course.joins("join users u on courses.tea_id = u.id").joins("join user_extensions ue on u.id = ue.user_id").where("courses.id != 1309 and ue.school_id = #{@school.id}")
@courses_count = all_course_ids.size
# Redo对于量比较大的尽量不使用笛卡尔积
# @shixuns_count = Shixun.where(:status => [2, 3], :user_id => user_ids).size
@shixuns_count = Shixun.find_by_sql("select count(s.id) as shixun_count from users u right join shixuns s on u.id=s.user_id and s.status in (2, 3) inner join user_extensions ue on
u.id=ue.user_id and ue.school_id=#{@department.school_id}").first.try(:shixun_count)
u.id=ue.user_id and ue.school_id=#{@school.id}").first.try(:shixun_count)
# @shixun_time_sum = (Game.where(:user_id => user_ids).pluck(:cost_time).sum / (24*60*60.0)).ceil
@shixun_time_sum = (Game.find_by_sql("select sum(g.cost_time) cost_time from users u RIGHT join games g on u.id=g.user_id inner join user_extensions ue on
u.id=ue.user_id and ue.school_id=#{@department.school_id}").first.try(:cost_time).to_i / (24 * 60 * 60.0)).ceil
u.id=ue.user_id and ue.school_id=#{@school.id}").first.try(:cost_time).to_i / (24 * 60 * 60.0)).ceil
# select count(sw.id) from users u left join student_works sw on u.id=sw.user_id and sw.myshixun_id is not null and sw.work_status !=0 inner join user_extensions ue on u.id=ue.user_id and ue.school_id=117 ;
# @shixun_report_count = StudentWork.where("work_status != 0 and user_id in (#{user_ids.join(',').strip == "" ? -1 : user_ids.join(',')}) and myshixun_id is not null").count
@shixun_report_count = StudentWork.find_by_sql("SELECT count(*) as sw_count FROM `student_works` where user_id in (SELECT users.id FROM users RIGHT JOIN user_extensions ON users.id=user_extensions.user_id WHERE
user_extensions.`school_id`=#{@department.school_id}) and work_status between 1 and 2 and myshixun_id !=0").first.try(:sw_count)
user_extensions.`school_id`=#{@school.id}) and work_status between 1 and 2 and myshixun_id !=0").first.try(:sw_count)
@teachers = User.find_by_sql("SELECT users.id, users.login, users.lastname, users.firstname, users.nickname, IFNULL((SELECT count(shixuns.id) FROM shixuns where shixuns.user_id =users.id group by shixuns.user_id), 0) AS publish_shixun_count,
(SELECT count(c.id) FROM courses c, members m, member_roles mr WHERE m.course_id = c.id AND m.id=mr.member_id AND mr.role_id in (3,7,9) AND m.user_id=users.id AND c.is_delete = 0) as course_count
FROM `users`, user_extensions ue where users.id=ue.user_id and ue.identity=0 and ue.school_id=#{@department.school_id} ORDER BY publish_shixun_count desc, course_count desc, id desc LIMIT 10")
FROM `users`, user_extensions ue where users.id=ue.user_id and ue.identity=0 and ue.school_id=#{@school.id} ORDER BY publish_shixun_count desc, course_count desc, id desc LIMIT 10")
# ).order("publish_shixun_count desc, experience desc").limit(10)
@teachers =
@teachers.map do |teacher|
@ -97,9 +97,12 @@ class CollegesController < ApplicationController
shixun_ids = HomeworkCommonsShixuns.find_by_sql("SELECT hcs.shixun_id FROM homework_commons_shixuns hcs, homework_commons hc
WHERE hc.course_id in (#{all_course_ids.map(&:id).join(',').strip == "" ? -1 : all_course_ids.map(&:id).join(',')})
AND hcs.homework_common_id = hc.id").map(&:shixun_id)
shixun_tags = TagRepertoire.find_by_sql("SELECT tr.`name`, COUNT(str.shixun_id) as shixun_count FROM tag_repertoires tr, shixun_tag_repertoires str WHERE tr.id = str.tag_repertoire_id AND str.shixun_id IN (#{shixun_ids.join(',').strip == "" ? -1 : shixun_ids.join(',')}) GROUP BY tr.id order by shixun_count desc")
shixun_tags = TagRepertoire.find_by_sql("SELECT tr.`name`, COUNT(str.shixun_id) as shixun_count FROM tag_repertoires tr,
shixun_tag_repertoires str WHERE tr.id = str.tag_repertoire_id AND str.shixun_id
IN (#{shixun_ids.join(',').strip == "" ? -1 : shixun_ids.join(',')}) GROUP BY tr.id
order by shixun_count desc")
all_shixun_count = shixun_tags.map(&:shixun_count).sum
other_count = all_shixun_count - shixun_tags[0..8].map(&:shixun_count).sum
other_count = all_shixun_count.to_i - shixun_tags[0..8].map(&:shixun_count).sum.to_i
@shixun_tags_name = []
@shixun_tags_data = []
shixun_tags[0..8].each do |tag|
@ -128,7 +131,7 @@ class CollegesController < ApplicationController
(select count(m.id) from messages m inner join boards b on b.id=m.board_id and b.parent_id=0 where b.course_id=c.id group by c.id) as messages_count,
c.tea_id, c.name, c.is_end,
(SELECT MAX(created_at) FROM `course_activities` ca WHERE ca.course_id = c.id) AS update_time
FROM `courses` c WHERE (c.school_id = #{@department.school_id} and c.is_delete = 0)")
FROM `courses` c WHERE (c.school_id = #{@school.id} and c.is_delete = 0)")
@courses.each do |course|
course[:evaluating_count] = Output.find_by_sql("select sum(g.evaluate_count) as evaluating_count from games g inner join
@ -137,6 +140,7 @@ class CollegesController < ApplicationController
course[:task_count] = course.hcm_count.to_i + course.attachments_count.to_i + course.messages_count.to_i + course.hcm_nonshixun_count.to_i + course.exercises_count.to_i + course.polls_count.to_i
end
@courses = @courses.sort{|x,y| [y[:evaluating_count], y[:task_count]] <=> [x[:evaluating_count], x[:task_count]] }
@courses = @courses.sort_by { |course| course.is_end ? 1 : 0 }
# SELECT c.id, (select concat(firstname,lastname) from users u where u.id=c.tea_id) as username,
# (select count(sfc.id) from students_for_courses sfc where c.id=sfc.course_id group by c.id) as student_count,
@ -153,11 +157,11 @@ class CollegesController < ApplicationController
# 学生实训
def student_shixun
user_ids = User.find_by_sql("SELECT users.id FROM users, user_extensions WHERE users.id=user_extensions.user_id AND user_extensions.`school_id` = #{@department.school_id}").map(&:id)
user_ids = User.find_by_sql("SELECT users.id FROM users, user_extensions WHERE users.id=user_extensions.user_id AND user_extensions.`school_id` = #{@school.id}").map(&:id)
@students = User.find_by_sql("SELECT users.id, users.login, users.lastname, users.firstname, users.nickname, users.grade,
users.experience, ue.student_id, (SELECT COUNT(myshixuns.id) FROM `myshixuns` WHERE myshixuns.user_id
= users.id AND myshixuns.status = 1 GROUP BY users.id) AS myshixun_count FROM users join user_extensions ue on
users.id = ue.user_id where ue.school_id = #{@department.school_id} AND ue.identity = 1 AND `users`.`type` IN ('User', 'AnonymousUser') ORDER BY experience DESC, myshixun_count DESC LIMIT 10")
users.id = ue.user_id where ue.school_id = #{@school.id} AND ue.identity = 1 AND `users`.`type` IN ('User', 'AnonymousUser') ORDER BY experience DESC, myshixun_count DESC LIMIT 10")
## outputs基数过大用inner join有奇效
@shixun_tags = TagRepertoire.find_by_sql(%Q{
@ -168,7 +172,7 @@ class CollegesController < ApplicationController
AND str.shixun_id = myshixuns.`shixun_id`
AND myshixuns.id = games.`myshixun_id`
AND myshixuns.`user_id` IN (
SELECT users.id FROM users, user_extensions WHERE users.id=user_extensions.user_id AND user_extensions.`school_id` = #{@department.school_id}
SELECT users.id FROM users, user_extensions WHERE users.id=user_extensions.user_id AND user_extensions.`school_id` = #{@school.id}
)
) a on a.id = outputs.game_id and outputs.`test_set_position` = 1 group by trid
ORDER BY test_count DESC
@ -193,50 +197,50 @@ class CollegesController < ApplicationController
@eval_data = []
case @index
when "day"
same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(end_day - 365.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 365.days).end_of_day}'").first.try(:count).to_i
last_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
last_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(end_day - 1.day).beginning_of_day}' AND outputs.created_at < '#{(end_day - 1.day).end_of_day}'").first.try(:count).to_i
@time_range = "#{end_day.strftime("%Y-%m-%d")}~#{end_day.strftime("%Y-%m-%d")}"
@time_data = ["2:00", "4:00", "6:00", "8:00", "10:00", "12:00", "14:00", "16:00", "18:00", "20:00", "22:00", "24:00"]
for i in 0..11
@eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
@eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{end_day.beginning_of_day + (i * 2).hour}' AND outputs.created_at < '#{end_day.beginning_of_day + ((i + 1) * 2).hour}'").first.try(:count).to_i
end
when "week"
start_day = end_day - 6.days
same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 365.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 365.days).end_of_day}'").first.try(:count).to_i
last_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
last_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 7.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 7.days).end_of_day}'").first.try(:count).to_i
@time_range = "#{start_day.strftime("%Y-%m-%d")}~#{end_day.strftime("%Y-%m-%d")}"
for i in 0..6
@time_data << (start_day + i.days).strftime("%m.%d")
@eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
@eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day + i.days).beginning_of_day}' AND outputs.created_at < '#{(start_day + (i + 1).days).end_of_day}'").first.try(:count).to_i
end
when "mon"
start_day = end_day - 30.days
same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 365.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 365.days).end_of_day}'").first.try(:count).to_i
last_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
last_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 30.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 30.days).end_of_day}'").first.try(:count).to_i
@time_range = "#{start_day.strftime("%Y-%m-%d")}~#{end_day.strftime("%Y-%m-%d")}"
for i in 0..9
@time_data << (start_day + (3 * i).days).strftime("%m.%d")
@eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
@eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day + (3 * i).days).beginning_of_day}' AND outputs.created_at < '#{(start_day + (3 * (i + 1)).days).end_of_day}'").first.try(:count).to_i
end
when "year"
start_day = end_day - 365.days
same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 365.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 365.days).end_of_day}'").first.try(:count).to_i
last_count = same_count
@time_range = "#{start_day.strftime("%Y-%m-%d")}~#{end_day.strftime("%Y-%m-%d")}"
for i in 0..11
@time_data << (start_day + i.month).strftime("%m.%d")
@eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
@eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day + i.days).beginning_of_day}' AND outputs.created_at < '#{(start_day + (i + 1).days).end_of_day}'").first.try(:count).to_i
end
end
@ -244,9 +248,9 @@ class CollegesController < ApplicationController
@same_rate = (@new_count == 0 || same_count == 0) ? 0 : (@new_count * 1.0 / same_count - 1).to_f
@last_rate = (@new_count == 0 || last_count == 0) ? 0 : (@new_count * 1.0 / last_count - 1).to_f
@total_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
@total_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 ").first.try(:count).to_i
@trend_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@department.school_id}) b
@trend_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{Time.now - 7.days}'").first.try(:count).to_i
end
@ -254,10 +258,10 @@ class CollegesController < ApplicationController
def manager_auth
# unless (User.current.admin? || DepartmentMember.where(:user_id => User.current.id, :department_id => @department.id).first.present?)
unless (User.current.admin? ||
DepartmentMember.where(:user_id => User.current.id, :department_id => @department.id).first.present? ||
(User.current.user_extensions.try(:school_id) == @department.school_id && User.current.user_extensions.try(:identity) == 0) ||
(@department.school.try(:customer_id) && User.current.try(:partner).try(:customer_ids) && User.current.try(:partner).try(:customer_ids).include?(@department.school.try(:customer_id))))
unless (User.current.admin? || User.current.business? ||
(@department.present? && DepartmentMember.where(:user_id => User.current.id, :department_id => @department.id).first.present?) ||
(User.current.user_extensions.try(:school_id) == @school.id && User.current.user_extensions.try(:identity) == 0) ||
(@school.try(:customer_id) && User.current.try(:partner).try(:customer_ids) && User.current.try(:partner).try(:customer_ids).include?(@school.try(:customer_id))))
render_403
end
end
@ -266,6 +270,8 @@ class CollegesController < ApplicationController
@department = Department.find_by_identifier(params[:id])
if @department.present?
@school = @department.school
else
@school = School.find_by_id(params[:id])
end
rescue ActiveRecord::RecordNotFound
render_404

@ -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

@ -0,0 +1,5 @@
class Managements::BaseController < ApplicationController
layout 'base_management'
before_filter :require_business
end

@ -0,0 +1,80 @@
class Managements::SchoolsController < Managements::BaseController
before_filter :set_navigation_bar
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
respond_to do |format|
format.html { load_statistic_total }
format.js
end
end
def data_grow
@sub_type = 2
params[:data_type] ||= 'grow'
params[:sort_by] ||= :teacher_increase_count
params[:sort_direction] ||= :desc
service = Management::SchoolDataGrowService.new(params)
@grow_summary = service.grow_summary
@obj_count, @reports = service.call
@obj_pages = Paginator.new(@obj_count, Management::SchoolDataGrowService::PAGE_SIZE, params[:page])
end
def data_contrast
params[:contrast_column] = :teacher_increase_count if params[:contrast_column].blank?
params[:sort_direction] ||= :desc
params[:sort_by] ||= :percentage
# 无对比日期时直接返回无数据页面
if useless_contrast_date_parameter?
@obj_count, @reports = 0, []
return
end
@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
def statistics_xlsx
@schools = Management::SchoolReportService.new(params).call
filename = ["学校统计总表", params[:keyword], Time.zone.now.strftime('%Y%m%d%H%M%S')].join('-') << ".xlsx"
render xlsx: "statistics_xlsx", filename: filename
end
private
def set_navigation_bar
@menu_type = 1
end
def contrast_column_select_options
@select_options = Management::SchoolDataContrastService::CONTRAST_COLUMN_LIST.map do |column|
[I18n.t("school_daily_report.#{column}"), column]
end
end
def useless_contrast_date_parameter?
params[:begin_date].blank? && params[:end_date].blank? &&
params[:other_begin_date].blank? &&params[:other_end_date].blank?
end
def load_statistic_total
@teacher_total = User.teacher.count
@student_total = User.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
end
end

@ -1,6 +1,12 @@
# encoding: utf-8
class ManagementsController < ApplicationController
before_filter :require_admin
before_filter :require_business
before_filter :require_admin, :only => [:shixun_setting_list, :mirror_repository, :mirror_picture_shixuns, :editmd_template,
:editmd_template, :subject_level_system, :subject_setting_list, :auto_users_trial,
:evaluate_records, :identity_authentication, :identity_authentication, :professional_authentication,
:shixun_authorization, :graduation_standard, :ec_template, :codemirror_template,
:course_guide_template, :shixun_quality_score, :tech_system, :update_notice, :setting_banner,
:training_2018]
layout 'base_management'
include ManagementsHelper
include SortHelper
@ -63,7 +69,6 @@ class ManagementsController < ApplicationController
# 工程认证视频导入模板
def ec_template
@template = EcTemplate.where(nil)
end
def add_template
@ -197,6 +202,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]
@ -1005,7 +1011,7 @@ class ManagementsController < ApplicationController
end
@courselist = @courselist.reorder("created_at desc")
@courselist_count = @courselist.count
@limit = 15
@is_remote = true
@page = params['page'] ? params['page'].to_i : 1
@ -1191,7 +1197,7 @@ end
if params[:search].blank?
@partners = Partner.includes(:school).order("partners.created_at desc")
else
@partners = Partner.where("name like ? ", "%#{params[:search]}%").includes(:school).order("partners.created_at desc")
@partners = Partner.includes(:school).where("schools.name like ? ", "%#{params[:search]}%").order("partners.created_at desc")
end
@current_partner = nil
@ -1212,6 +1218,14 @@ end
end
def delete_partner
partner = Partner.find params[:partner_id]
partner.destroy
@partners = Partner.includes(:school).order("partners.created_at desc")
@current_partner = nil
end
# 添加客户
def customers_list
@search = params[:search]
@ -1219,11 +1233,10 @@ end
partner_id = params[:partner_id]
@partner = Partner.find partner_id
@customers = @partner.customers
if @customers.present?
@schools = School.where("(partner_id != ? or partner_id is NULL) and customer_id is NULL", @partner.id)
else
@schools = School.where("customer_id is null and (partner_id != ? or partner_id is NULL)", @partner.id)
end
existed_school_ids = @customers.pluck(:school_id)
existed_school_ids = existed_school_ids.present? ? existed_school_ids.join(",") : -1
@schools = School.where("id not in (#{existed_school_ids})")
if params[:search]
@schools = @schools.where("name like ?", "%#{@search}%")
end
@ -1247,13 +1260,14 @@ end
def add_customers
school_ids = params[:school_ids]
if school_ids.length > 0
partner_id = params[:partner_id]
if school_ids.length > 0 && partner_id.present?
school_ids.each do |s|
school = School.where("id = ?",s).first
if school.present?
customer = Customer.new(partner_id: params[:partner_id])
customer = Customer.new(school_id: s)
customer.save!
school.update_attributes(:customer_id => customer.id)
PartnerCustomer.create(partner_id: partner_id,customer_id: customer.id )
end
end
render :json => {status: 1, message: "创建成功!"}
@ -1262,17 +1276,20 @@ end
def delete_customers
if params[:customer]
customer = Customer.where(id: params[:customer]).first
@current_partner = customer.partner
customer.school.update_attributes(:customer_id => nil)
customer = Customer.find(params[:customer])
@current_partner = Partner.find(params[:partner_id])
customer.destroy
end
end
# 添加合作伙伴弹框数据
def all_partners
@search = params[:search]
@province = params[:province]
@schools = School.where("partner_id IS NULL")
# 已经选过的合作伙伴不能再再列表中显示
used_school_ids = Partner.pluck(:school_id)
used_school_ids = used_school_ids.blank? ? -1 : used_school_ids.join(",")
@schools = School.where("id not in (#{used_school_ids})")
if params[:search]
@schools = @schools.where("name like ?", "%#{@search}%")
@ -1296,26 +1313,20 @@ end
end
end
def add_partner
school_ids = params[:school_ids]
if school_ids.length > 0
school_ids.each do |s|
school = School.where("id = ?",s).first
if school.present? && school.partner_id.nil?
partner = Partner.new(name: school.name)
old_partner = Partner.where(:school_id => s)
if old_partner.blank?
partner = Partner.new(school_id: s)
partner.save
school.update_attributes(:partner_id => partner.id)
end
end
end
render :json => {status: 1, message: "创建成功!"}
end
# 删除部门管理员
def delete_depart_member
DepartmentMember.where(:department_id => params[:depart], :user_id => params[:user_id]).destroy_all
@ -1405,7 +1416,8 @@ end
def update_depart_identifier
if params[:depart] && params[:identifier]
@department = Department.where(:id => params[:depart]).first
@department.update_attributes(:identifier => params[:identifier]) if @department.present?
identifier = params[:identifier].strip.blank? ? nil : params[:identifier].strip
@department.update_attributes(:identifier => identifier) if @department.present?
end
end
@ -3624,7 +3636,7 @@ end
apply_user.tidings.where(:tiding_type => "Apply").update_all(:status => 1)
Tiding.create(:user_id => apply_user.user_id ,:trigger_user_id => 0, :container_id => apply_user.id, :container_type => "ApplyUserAuthentication", :belong_container_id => apply_user.user_id, :belong_container_type =>'User', :status => 1, :tiding_type => "System")
@unapproved_user = ApplyUserAuthentication.where(:status => 0, :auth_type => 1).order("updated_at desc")
@unapproved_user_count = @unapproved_user.count
@limit = 15
@ -4096,7 +4108,7 @@ end
sheet1 = book.create_worksheet :name => "sheet"
blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10
sheet1.row(0).default_format = blue
sheet1.row(0).concat(["序号","创建者","发布时间", "ID", "实训名称","技术平台","fork源", "实践任务"])
sheet1.row(0).concat(["序号","创建者","发布时间", "ID", "实训名称","技术平台","fork源", "实践任务", "实训链接"])
count_row = 1
shixuns.find_each do |shixun|
sheet1[count_row, 0] = count_row
@ -4107,6 +4119,7 @@ end
sheet1[count_row, 5] = show_shixun_mirror(shixun)
sheet1[count_row, 6] = shixun.fork_identifier
sheet1[count_row, 7] = shixun.challenges.count
sheet1[count_row, 7] = Setting.server_url + shixun_path(shixun)
count_row += 1
end
book.write xls_report

@ -1,6 +1,5 @@
#encoding: utf-8
class OauthController < ApplicationController
require
include ApplicationHelper
before_filter :user_setup
@ -152,8 +151,73 @@ class OauthController < ApplicationController
render json: user_info.to_json
end
####--Start-- 获取Openi的授权码access_token以及用户信息。为在openi登录的用户创建相关的educoder用户 ####
IDENTITY_SITE = Redmine::Configuration['openi_domain']
ROOT_URL = Redmine::Configuration['educoder_domain']
DEFAULT_PASSWORD = 'a12345678'.freeze
TOKEN_CALL_BACK = '/oauth/get_token_callback'.freeze
USER_INFO = '/oauth/userinfo'.freeze
def get_code
# 从OpenI发过来的回调中获取授权码
code = params[:code]
# 利用授权码从OpenI这里获取access_token
client = get_client(IDENTITY_SITE)
redirect_uri = "#{ROOT_URL}#{TOKEN_CALL_BACK}"
access_token_hash = client.auth_code.get_token(code, redirect_uri: redirect_uri).to_hash
# 利用access_token获取OpenI的用户信息
access_token = access_token_hash[:access_token]
get_info_url = "#{IDENTITY_SITE}#{USER_INFO}?access_token=#{access_token}"
response = HTTParty.get(get_info_url)
body_json = JSON.parse response.body
openi_user_id = body_json['token']
avatar_url = body_json['avatar_url']
login = body_json['login']
name = body_json['name']
email = body_json['email']
# 根据获取的用户信息来查询数据库如已经存在对应的Educoder用户则直接访问用户要访问的实训页面否则为其创建用户后再访问实训页面
openi = Openi.find_by_login(login)
unless openi
ActiveRecord::Base.transaction do
# 如果Educoder中已存在与该OpenI用户的邮箱相同的用户则会直接跳转到登录educoder的登录页面
existing_user = User.find_by_mail(email)
break if existing_user.present?
user = User.new(lastname: name, mail: email, mail_notification: email)
user.login = generate_login('m')
user.password = DEFAULT_PASSWORD
user.certification = 1
user.save!
UserExtensions.create!(user_id: user.id, school_id: School.first.id, identity: 4, gender: 0)
openi = Openi.create!(user_id: user.id, openi_user_id: openi_user_id, avatar_url: avatar_url, login: login, name: name, email: email)
end
end
self.logged_user = openi.user if openi.present? && openi.user.present?
original_url = params[:original_url]
if current_user.logged?
redirect_to original_url
else
redirect_to signin_path
end
end
def get_token_callback
end
####--End-- 获取Openi的授权码access_token以及用户信息。为在openi登录的用户创建相关的educoder用户 ####
private
# 为新创建的用户随机生成以m为前缀的用户名m表示该用户是用邮箱注册
def generate_login(login_pre)
us = UsersService.new
us.generate_user_login(login_pre)
end
def require_login
require "base64"

@ -10,6 +10,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]

@ -1,9 +1,12 @@
# encoding: utf-8
class SubjectsController < ApplicationController
layout 'base_subject'
# 如要添加或修改before_filter时请将handle_openi_request这个before_filter放至第一位
# before_filter :handle_openi_request, if: -> { user_login_and_from_openi? }, only: [:show]
before_filter :require_login, :except => [:show, :index]
before_filter :check_authentication, :except => [:show, :index]
before_filter :find_subject, :except => [:index, :new, :create, :create_subject, :new_subject, :append_to_stage, :send_to_course]
before_filter :require_admin, :only => [:destroy]
include ApplicationHelper
include SubjectsHelper

@ -59,6 +59,7 @@ class UsersController < ApplicationController
#visitor
before_filter :recorded_visitor, :only => [:show, :user_fanslist, :user_watchlist, :user_visitorlist]
before_filter :require_admin, :only => [:destroy]
helper :sort
helper :attachments
@ -274,7 +275,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")
@ -315,7 +316,7 @@ class UsersController < ApplicationController
end
def message_detail
if User.current == @user || User.current.admin?
if User.current == @user || User.current.admin? || User.current.business?
@target_user = User.where(:id => params[:user_id]).includes(:user_extensions).first
if @target_user.present?
@message_list = @user.private_messages.where(:target_id => params[:user_id], :status => [0, 1]).order("send_time asc")
@ -939,7 +940,7 @@ class UsersController < ApplicationController
@limit = 16
if 1 == @index
# @shixuns_result = Shixun.where(:status => [2,3]).where("name like ?", "%#{@search}%").reorder("created_at desc")
@shixuns_result = Shixun.where("name like ? and hidden=0", "%#{@search}%").reorder("myshixuns_count desc")
@shixuns_result = Shixun.where("name like ? and hidden=0 and status != -1", "%#{@search}%").reorder("myshixuns_count desc")
@shixuns_result_count = @shixuns_result.count
@shixun_pages = Paginator.new @shixuns_result_count, @limit, params['page'] || 1
@offset ||= @shixun_pages.offset

File diff suppressed because it is too large Load Diff

@ -0,0 +1,45 @@
module CustomSortable
extend ActiveSupport::Concern
included do |base|
base.instance_variable_set("@_sort_options", {})
base.instance_variable_set("@_sort_columns", [])
base.instance_variable_set("@_sort_directions", %w(asc desc))
end
def custom_sort(relations, sort_by, sort_direction)
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.to_s, sort_direction.to_s)
order_method = self.class.sort_options[:reorder] ? :reorder : :order
relations.send(order_method, "#{sort_by} #{sort_direction}")
end
def multiple_custom_sort(relations, opts)
opts.each do |sort_by, sort_direction|
relations = custom_sort(relations, sort_by, sort_direction)
end
relations
end
module ClassMethods
def sort_columns(*columns)
opts = columns.extract_options!
@_sort_options[:default_by] = opts[:default_by].to_s
@_sort_options[:default_direction] = opts[:default_direction].to_s
@_sort_options[:reorder] = opts[:reorder]
@_sort_columns = columns.map(&:to_s)
end
def check_sort_parameter_validate(sort_by, sort_direction)
(sort_by.blank? || @_sort_columns.include?(sort_by)) && @_sort_directions.include?(sort_direction)
end
def sort_options
@_sort_options
end
end
end

@ -1,6 +1,7 @@
class Customer < ActiveRecord::Base
default_scope :order => 'customers.created_at desc'
belongs_to :partner
has_one :school
has_many :partners, :through => :partner_customers
has_many :partner_customers, :dependent => :destroy
belongs_to :school
has_many :users
end

@ -63,33 +63,21 @@ class HomeworkCommon < ActiveRecord::Base
#作业类型
def homework_type_ch
type = self.homework_type
case type
when 1
type = "普通"
when 2
type = "编程"
when 3
type = "分组"
when 4
type = "实训"
case homework_type
when 1 then '普通'
when 2 then '编程'
when 3 then '分组'
when 4 then '实训'
end
type
end
def homework_type_module
type = self.homework_type
case type
when 1
type = "common_homework"
when 2
type = "code_homework"
when 3
type = "group_homework"
when 4
type = "shixun_homework"
case homework_type
when 1 then 'common_homework'
when 2 then 'code_homework'
when 3 then 'group_homework'
when 4 then 'shixun_homework'
end
type
end
def act_as_activity

@ -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,8 @@
class Openi < ActiveRecord::Base
attr_accessible :allow, :avatar_url, :email, :login, :name, :openi_user_id, :user_id
belongs_to :user
def self.find_by_login(login)
Openi.where(login: login).first
end
end

@ -2,7 +2,8 @@ class Partner < ActiveRecord::Base
# attr_accessible :name, :active
attr_accessor :active
has_one :school
has_many :customers
belongs_to :school
has_many :customers, :through => :partner_customers
has_many :partner_customers, :dependent => :destroy
has_many :users
end

@ -0,0 +1,5 @@
class PartnerCustomer < ActiveRecord::Base
# attr_accessible :title, :body
belongs_to :partner
belongs_to :customer
end

@ -16,8 +16,8 @@ class School < ActiveRecord::Base
has_many :ec_majors, :through => :ec_major_schools
has_many :ec_major_schools, :dependent => :destroy
belongs_to :partner
belongs_to :customer
has_many :partners, :dependent => :destroy
has_many :customers, :dependent => :destroy
# banner图片信息
has_many :school_images, :dependent => :destroy
@ -64,7 +64,7 @@ class School < ActiveRecord::Base
def statistic_url
dep = departments.where("identifier is not null").first
url = dep.present? ? "/colleges/#{dep.identifier}/statistics" : ""
url = dep.present? && !dep.identifier.blank? ? "/colleges/#{dep.identifier}/statistics" : "/colleges/#{self.id}/statistics"
end
def course_act_time

@ -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
@ -54,20 +55,27 @@ class Shixun < ActiveRecord::Base
scope :visible, lambda{where(status: [2,3])}
scope :min, lambda { select([:id, :name, :gpid, :modify_time, :reset_time, :language, :propaedeutics, :status, :identifier, :test_set_permission, :hide_code, :forbid_copy,
:webssh, :user_id, :code_hidden, :task_pass, :exec_time, :multi_webssh]) }
scope :min, lambda { select([:id, :name, :gpid, :modify_time, :reset_time, :language, :propaedeutics, :status, :identifier,
:test_set_permission, :hide_code, :forbid_copy, :hidden, :webssh, :user_id, :code_hidden,
:task_pass, :exec_time, :multi_webssh]) }
scope :published, lambda{where(status: 2)}
scope :field_for_recommend, lambda{ select([:id, :name, :identifier, :myshixuns_count]) }
include ApplicationHelper
has_many :tidings, :as => :container, :dependent => :destroy
scope :visible, -> { where(status: -1) }
#scope :visible, -> { where(status: -1) }
after_create :send_tiding
def should_compile?
self.mirror_repositories.published_main_mirror.first.try(:should_compile)
end
# 可供使用的实训
def operable?
logger.info("####")
self.status != -1 && !self.hidden
end
def is_published?
self.status > 1 ? true : false
end

@ -17,7 +17,8 @@ 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.business? || current_user.id == shixun.try(:user_id) ||
current_user.is_certification_teacher) && (shixun.operable?)) || current_user.admin?
return{:status => 403}
end
game_challenge = Challenge.min.find(game.challenge_id)

@ -0,0 +1,61 @@
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
count = reports.count('distinct(school_id)')
reports = reports.group(:school_id).limit(PAGE_SIZE).offset(offset)
[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
"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
end

@ -0,0 +1,81 @@
class Management::SchoolDataGrowService
include CustomSortable
PAGE_SIZE = 20
attr_reader :params
sort_columns :teacher_increase_count, :student_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 = query_reports.group(:school_id)
count = reports.count.count
reports = reports.select(
'school_id, school_name,'\
'SUM(teacher_increase_count) teacher_increase_count,'\
'SUM(student_increase_count) student_increase_count,'\
'SUM(course_increase_count) course_increase_count,'\
'SUM(shixun_increase_count) shixun_increase_count,'\
'SUM(active_user_count) active_user_count'
)
reports = custom_sort(reports, params[:sort_by], params[:sort_direction])
reports = reports.limit(PAGE_SIZE).offset(offset)
[count, reports]
end
def grow_summary
@_grow_summary ||= begin
query_reports.select(
'SUM(teacher_increase_count) teacher_increase_count,'\
'SUM(student_increase_count) student_increase_count,'\
'SUM(course_increase_count) course_increase_count,'\
'SUM(shixun_increase_count) shixun_increase_count,'\
'SUM(active_user_count) active_user_count'
).first
end
end
private
def query_reports
reports = SchoolDailyReport.where(date: query_date)
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
end
def query_date
if params[:grow_begin_date].present?
begin_time = Time.zone.parse(params[:grow_begin_date])
end_date = if params[:grow_end_date].present?
Time.zone.parse(params[:grow_end_date])
end
end_date.blank? || end_date == begin_time ? begin_time : begin_time..end_date
else
yesterday
end
end
def yesterday
# 每日凌晨5点为节点, 25日凌晨4点、3点、2点等等未到更新数据时间点看到的数据是23日-24日的统计数据
(Time.zone.now - 5.hours).beginning_of_day - 1.days
end
def offset
(params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * PAGE_SIZE
end
end

@ -0,0 +1,54 @@
class Management::SchoolReportService
include CustomSortable
attr_reader :params
sort_columns :student_count, :teacher_count, :homework_count, :other_homework_count,
:course_count, :active_course_count, :nearly_course_time,
default_by: :teacher_count, default_direction: :desc
def initialize(params)
@params = params
end
def call
schools = School.select(select_columns_sql)
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
schools = custom_sort(schools, params[:sort_by], params[:sort_direction])
schools
end
private
def select_columns_sql
<<-SQL
schools.id, schools.name,
(
SELECT COUNT(*) FROM user_extensions ue
WHERE ue.school_id = schools.id AND ue.identity = #{User::STUDENT}
) student_count,
(
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
LEFT JOIN courses ON courses.id = hc.course_id
WHERE courses.school_id = schools.id AND hc.homework_type = 4
) homework_count,
(
SELECT COUNT(*) FROM homework_commons hc
LEFT JOIN courses ON courses.id = hc.course_id
WHERE courses.school_id = schools.id AND hc.homework_type IN (1,3)
) other_homework_count,
(SELECT COUNT(*) FROM courses cs WHERE cs.school_id = schools.id) course_count ,
(SELECT MAX(cs.updated_at) FROM courses cs WHERE cs.school_id = schools.id) nearly_course_time ,
(SELECT COUNT(*) FROM courses acs WHERE acs.school_id = schools.id AND acs.is_end = false) active_course_count
SQL
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" %>

@ -30,10 +30,10 @@
<input type="text" class="winput-240-30 edu-txt-center" value="<%= @time_range %>" id="time-condition" readonly/>
</li>
<li class="fr count_student_test">
<a href="<%= student_eval_college_path(@department, :index => 'day') %>" data-remote="true" class="<%= @index == "day" ? "active" : "" %>">日</a>
<a href="<%= student_eval_college_path(@department, :index => 'week') %>" data-remote="true" class="<%= @index == "week" ? "active" : "" %>">周</a>
<a href="<%= student_eval_college_path(@department, :index => 'mon') %>" data-remote="true" class="<%= @index == "mon" ? "active" : "" %>">月</a>
<a href="<%= student_eval_college_path(@department, :index => 'year') %>" data-remote="true" class="<%= @index == "year" ? "active" : "" %>">年</a>
<a href="<%= student_eval_college_path(@school, :index => 'day') %>" data-remote="true" class="<%= @index == "day" ? "active" : "" %>">日</a>
<a href="<%= student_eval_college_path(@school, :index => 'week') %>" data-remote="true" class="<%= @index == "week" ? "active" : "" %>">周</a>
<a href="<%= student_eval_college_path(@school, :index => 'mon') %>" data-remote="true" class="<%= @index == "mon" ? "active" : "" %>">月</a>
<a href="<%= student_eval_college_path(@school, :index => 'year') %>" data-remote="true" class="<%= @index == "year" ? "active" : "" %>">年</a>
</li>
</div>
<div id="studentTestCount" style="width: 1200px;height: 440px;"></div>

@ -44,15 +44,15 @@
<li><span><%= @shixuns_count %></span>个</li>
<li><span><%= @shixun_report_count %></span>个</li>
<li><span data-tip-down="所有学员的实训耗时之和"><span><%= @shixun_time_sum %></span>天</span></li>
<li><span><%= @department.host_count.to_i %></span>台</li>
<li><span><%= @department.present? ? @department.host_count.to_i : @school.departments.first.try(:host_count).to_i %></span>台</li>
</div>
</div>
<div class="white-panel mb20 pl0 clearfix">
<li class="active" index="1"><a href="javascript:void(0);">课堂</a></li>
<li index="2"><a href="<%= student_shixun_college_path(@department) %>" data-remote="true">学生实训</a></li>
<li index="2"><a href="<%= student_shixun_college_path(@school) %>" data-remote="true">学生实训</a></li>
<!--<li><a href="<%#= engineering_capability_college_path(@department) %>" data-remote="true">工程能力</a></li>-->
<li index="4"><a href="<%= student_eval_college_path(@department) %>" data-remote="true">学生测评</a></li>
<li index="4"><a href="<%= student_eval_college_path(@school) %>" data-remote="true">学生测评</a></li>
</div>
<div class="panelContent panelContent-1">
@ -153,7 +153,7 @@
})
});
$.get('<%= course_statistics_college_path(@department) %>');
$.get('<%= course_statistics_college_path(@school) %>');
$(".count_student_test a").click(function(){
$(".count_student_test a").removeClass("active");

@ -6,7 +6,7 @@
<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;">
@ -73,16 +73,14 @@
<div class="edu-menu-list" style="top:60px;width: 240px;">
<div class="overPart"></div>
<ul class="fl with50 edu-txt-center pr ul-leftline">
<% unless User.current.user_extensions.try(:identity) == 1 %>
<li><%= link_to '新建课堂', new_course_path() %></li>
<% end %>
<li><%= link_to '新建课堂', new_course_path() %></li>
<li><%= link_to '新建实训', new_shixun_path() %></li>
<li><%= link_to '新建实训课程', new_subject_path() %></li>
<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>
@ -98,9 +96,9 @@
<% 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>
<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>
@ -128,11 +126,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 %>
});

@ -24,31 +24,31 @@
<!--<li><%#= link_to "活动竞赛", competitions_path %></li>-->
</ul>
<div class="posi-search unlogin" id="posi-search" style="display: none" >
<div class="search-all clearfix">
<!--<a href="javascript:void(0)" class="search-clear fl" onclick="closeSearch();">×</a>-->
<div class="fl pr search-clear edu-menu-panel" style="display: none">
<input type="hidden" id="search_type" value="1">
<span class="searchkey">实训</span><i class="fa fa-angle-down ml5 font-16"></i>
<ul id="searchkey" class="edu-menu-list edu-txt-center" style="min-width: 80px;right: -10px;top: 50px;">
<li><a href="javascript:void(0)">实训</a></li>
<li><a href="javascript:void(0)">课堂</a></li>
<li><a href="javascript:void(0)">用户</a></li>
</ul>
</div>
<div class="seperateLine"></div>
<input type="text" class="search-input fl" id="search-input" name="search_keyword" placeholder="搜索实训项目"/>
<a href="javascript:void(0)" class="search-icon fl" id="header_keyword_search">
<!--<svg class="icon fl mt23" width="20px" height="20px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#333333" d="M463.9 804.4c-194.7 0-353.1-158.4-353.1-353.1S269.2 98.2 463.9 98.2 817 256.6 817 451.3 658.6 804.4 463.9 804.4z m0-651.9c-164.8 0-298.8 134-298.8 298.8s134 298.8 298.8 298.8 298.8-134 298.8-298.8-134-298.8-298.8-298.8zM884.9 926.6c-7.2 0-14.4-2.9-19.8-8.6l-198-210.6c-10.3-10.9-9.7-28.1 1.2-38.4 10.9-10.3 28.1-9.8 38.4 1.2l198 210.6c10.3 10.9 9.7 28.1-1.2 38.4-5.2 5-11.9 7.4-18.6 7.4z" /></svg>-->
<i class="iconfont icon-sousuo color-blue mt14 fl"></i>
</a>
<div class="search-all clearfix">
<!--<a href="javascript:void(0)" class="search-clear fl" onclick="closeSearch();">×</a>-->
<div class="fl pr search-clear edu-menu-panel" style="display: none">
<input type="hidden" id="search_type" value="1">
<span class="searchkey">实训</span><i class="fa fa-angle-down ml5 font-16"></i>
<ul id="searchkey" class="edu-menu-list edu-txt-center" style="min-width: 80px;right: -10px;top: 50px;">
<li><a href="javascript:void(0)">实训</a></li>
<li><a href="javascript:void(0)">课堂</a></li>
<li><a href="javascript:void(0)">用户</a></li>
</ul>
</div>
<div class="seperateLine"></div>
<input type="text" class="search-input fl" id="search-input" name="search_keyword" placeholder="搜索实训项目"/>
<a href="javascript:void(0)" class="search-icon fl" id="header_keyword_search">
<!--<svg class="icon fl mt23" width="20px" height="20px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#333333" d="M463.9 804.4c-194.7 0-353.1-158.4-353.1-353.1S269.2 98.2 463.9 98.2 817 256.6 817 451.3 658.6 804.4 463.9 804.4z m0-651.9c-164.8 0-298.8 134-298.8 298.8s134 298.8 298.8 298.8 298.8-134 298.8-298.8-134-298.8-298.8-298.8zM884.9 926.6c-7.2 0-14.4-2.9-19.8-8.6l-198-210.6c-10.3-10.9-9.7-28.1 1.2-38.4 10.9-10.3 28.1-9.8 38.4 1.2l198 210.6c10.3 10.9 9.7 28.1-1.2 38.4-5.2 5-11.9 7.4-18.6 7.4z" /></svg>-->
<i class="iconfont icon-sousuo color-blue mt14 fl"></i>
</a>
</div>
</div>
</div>
<span class="font-15 fr mt15 ml15">
<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" %>
<em class="vertical-line"></em>
<%= link_to '注册', user_join_path, :class => "ml5 color-white" %>
</span>
<div class="fr head-right">
<a href="javascript:void(0)" id="search-open" class="fl headIcon">
@ -66,8 +66,8 @@
<li><%= link_to '新建项目', new_project_path() %></li>
</ul>
<ul class="fl with50 edu-txt-center">
<li><%= link_to "加入课堂", signin_path, :remote => true %></li>
<li><%= link_to "加入项目", applied_join_project_path, :remote => true %></li>
<li><%= link_to "加入课堂", signin_path, :remote => true %></li>
<li><%= link_to "加入项目", applied_join_project_path, :remote => true %></li>
</ul>
</div>
</div>

@ -28,9 +28,9 @@
<div class="newContainer"> <!-- 页面全部内容 -->
<div class="newHeader" id="nHeader"> <!-- 头部 -->
<% if User.current.logged? %>
<%= render :partial => 'layouts/logined_header' %>
<%= render :partial => 'layouts/logined_header' %>
<% else%>
<%= render :partial => 'layouts/unlogin_header' %>
<%= render :partial => 'layouts/unlogin_header' %>
<% end%>
<div class="cl"></div>
</div>

@ -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>

@ -32,16 +32,18 @@
</p>
<ul class="edu-admin-nav clearfix bor-grey-e">
<!--<li class="fl edu-admin-nav-li"><a href="javascript:void(0);" class="edu-admin-nav-a">主页</a></li>-->
<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_data_grow_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>
<ul class="edu-admin-nav-inner edu-absolute">
<li><%= link_to "课程列表", classroom_managements_path %></li>
<li><%= link_to "课堂列表", classroom_classment_managements_path %></li>
<li><%= link_to "实训作业", shixun_task_managements_path%></li>
<li><%= link_to "项目列表", project_list_managements_path%></li>
<!-- <li>统计总表</li>-->
<!-- <li>统计总表对比</li>-->
<!-- <li>统计总表日新增</li>-->
</ul>
</li>
<li class="fl edu-admin-nav-li edu-position <%= 'active' if @menu_type == 3 %>"><a href="javascript:void(0);" class="edu-admin-nav-a">精选实训+</a>
@ -107,9 +109,9 @@
</li>
<li class="fl edu-admin-nav-li edu-position <%= 'active' if @menu_type == 10 %>"><a href="javascript:void(0);" class="edu-admin-nav-a">审批</a>
<ul class="edu-admin-nav-inner">
<li><%= link_to "实名认证", :controller => "managements", :action => "identity_authentication" %></li>
<li><%= link_to "职业认证", :controller => "managements", :action => "professional_authentication" %></li>
<li><%= link_to "试用授权", :controller => "managements", :action => "trial_authorization" %></li>
<li><%= link_to "实名认证", identity_authentication_managements_path %></li>
<li><%= link_to "职业认证", professional_authentication_managements_path %></li>
<li><%= link_to "试用授权", trial_authorization_managements_path %></li>
<li><%= link_to "部门审批", depart_managements_path %></li>
<li><%= link_to '单位审批', unit_managements_path %></li>
<li><%= link_to '实训发布', shixun_authorization_managements_path %></li>

@ -26,8 +26,8 @@
</script>
</head>
<body>
<div class="newContainer">
<%= yield %>
</div>
<div class="newContainer">
<%= yield %>
</div>
</body>
</html>

@ -10,7 +10,7 @@
<span><%= index + 1 %></span>
<span class="task-hide"><%= customer.school.name %></span>
<span>
<a href="javascript:void(0)" onclick="delete_confirm_box_2('<%= delete_customers_managements_path(customer: customer.id) %>',
<a href="javascript:void(0)" onclick="delete_confirm_box_2('<%= delete_customers_managements_path(customer: customer.id, partner_id: @current_partner.try(:id)) %>',
'确定要删除该客户吗')" class="color-grey-9">删除</a>
</span>
<span>

@ -1,14 +1,12 @@
<% @partners.each_with_index do |partner,index| %>
<li class="clearfix">
<%= link_to "#{partner.name}", partners_managements_path(:partner => partner), :class => "#{partner.id == @current_partner.id ? 'active' : ''} fl" %>
<% if false %>
<%= link_to "#{partner.school.name}", partners_managements_path(:partner => partner), :class => "#{@current_partner && partner.id == @current_partner.id ? 'active' : ''} fl" %>
<div class="fr mr10 edu-menu-panel mt5">
<i class="iconfont icon-sandian color-grey-9 font-14"></i>
<ul class="edu-menuSmall-list edu-txt-center">
<li><a href="javascript:void(0)">查看</a></li>
<li><a href="javascript:void(0)" onclick="delPartners();">删除</a></li>
<li><a href="<%= partners_managements_path(:partner => partner) %>">查看</a></li>
<li><a href="javascript:void(0)" onclick="delPartners('<%= delete_partner_managements_path(:partner_id => partner) %>');">删除</a></li>
</ul>
</div>
<% end %>
</li>
<% end %>

@ -17,7 +17,7 @@
</li>
<li class="clearfix mb5">
<% if !user.try(:user_extensions).school_id.blank? && user.try(:user_extensions).try(:school) %>
<span><%= user.try(:user_extensions).school.name %><%= user.try(:user_extensions).department ? ' - '+user.try(:user_extensions).department.name.to_s : '' %></span>
<a href="<%= user.try(:user_extensions).school.statistic_url %>" target="_blank" class="color-blue"><%= user.try(:user_extensions).school.name %><%= user.try(:user_extensions).department ? ' - '+user.try(:user_extensions).department.name.to_s : '' %></a>
<% end %>
<% if user.try(:user_extensions) && user.try(:user_extensions).identity %>
<span class="ml30"><%= user.identity %></span>

@ -0,0 +1 @@
$("#partner_list").html("<%= j(render :partial => "partner_list") %>")

@ -6,7 +6,7 @@
</div>
<div class="clearfix mt20">
<div class="with25 fl">
<%= link_to "+添加",all_partners_managements_path,remote:true,class:"color-blue addOperation" %>
<%= link_to "+添加", all_partners_managements_path,remote:true,class:"color-blue addOperation" %>
<ul class="partnerList" id="partner_list">
<%= render :partial => "partner_list" %>
</ul>
@ -31,7 +31,7 @@
}
function delPartners(){
delete_confirm_box_2("","确定删除合作伙伴?");
function delPartners(url){
delete_confirm_box_2(url,"确定删除合作伙伴?");
}
</script>

@ -0,0 +1,305 @@
<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] %>
<!-- 新增数据 -->
<%= hidden_field_tag :grow_begin_date, params[:grow_begin_date] %>
<%= hidden_field_tag :grow_end_date, params[:grow_end_date] %>
<div class="grow-date-container" style="width: 450px;display: <%= params[:data_type] == 'grow' ? 'block' : 'none' %>">
<%= text_field_tag :grow_date_input, params[:grow_date_input],
class: 'grow-date-input winput-220-30', placeholder: '请选择时间段',
style: 'width: 400px;' %>
</div>
<div class="contrast-date-container" style="width: 450px;display: <%= params[:data_type] == 'contrast' ? 'block' : 'none' %>">
<%= 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>
<div style="float: left;">
<%= hidden_field_tag :data_type, params[:data_type] || 'grow' %>
<% 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 grow-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 grow-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 growFormUrl = "<%= school_data_grow_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 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("task-btn-orange")) { return }
changeDataType("contrast");
submitForm();
});
searchForm.on('click', ".grow-btn", function(){
if(growBtn.hasClass("task-btn-orange")) { return }
changeDataType("grow");
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 : 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("task-btn-orange");
growBtn.removeClass("task-btn-orange");
dataTypeInput.val('contrast');
growDateContainer.hide();
contrastDateContainer.show();
clearGrowDateInput();
} else {
contrastBtn.removeClass("task-btn-orange");
growBtn.addClass("task-btn-orange");
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 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 baseOptions = {
dateFormat: 'yy-mm-dd',
minDate: new Date('2017-04-01'),
maxDate: -1
}
var contrastDateOptions = {
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;
}
},
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();
}
};
contrastDateOptions = $.extend({}, locale, baseOptions, contrastDateOptions);
searchForm.find(".date-input").datepicker(contrastDateOptions);
searchForm.find(".other-date-input").datepicker(contrastDateOptions);
var growOptions = {
onSelect: function(selectedDate) {
if(!$(this).data().datepicker.first){
$(this).data().datepicker.inline = true;
$(this).data().datepicker.first = selectedDate;
growBeginDateInput.val("");
growEndDateInput.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;
}
growBeginDateInput.val(begin_date);
growEndDateInput.val(end_date);
// 展示所选时间
$(this).val(begin_date + " 至 " + end_date);
$(this).data().datepicker.inline = false;
}
},
onClose:function(){
var date = $(this).data().datepicker.first;
if (date && growBeginDateInput.val() == '') {
growBeginDateInput.val(date);
growEndDateInput.val(date);
}
delete $(this).data().datepicker.first;
$(this).data().datepicker.inline = false;
submitForm();
}
};
growOptions = $.extend({}, locale, baseOptions, growOptions)
searchForm.find(".grow-date-input").datepicker(growOptions);
});
</script>

@ -0,0 +1,88 @@
<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;' %>
<% if @obj_count.nonzero? %>
<div style="position: absolute; left: 20px; bottom: 0; font-size: 12px;">
说明:新增数=时段二-时段一;新增百分比=(新增数/时段一)*100%(保留小数点后五位)
</div>
<% end %>
</div>
<% if @obj_count.nonzero? %>
<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="22%">时段一<br><%= "#{params[:begin_date]}至#{params[:end_date]}" %></th>
<th width="22%">时段二<br><%= "#{params[:other_begin_date]}至#{params[:other_end_date]}" %></th>
<th width="20%" colspan="2">
变化情况
<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>
<%
increase = report['other_total'] - report['total']
percentage = report['total'].zero? ? increase.to_f * 100 : (increase / report['total'].to_f) * 100
%>
<% if increase > 0 %>
<td class="edu-txt-right pr20 right-border relative color-red">
+<%= increase %>
</td>
<td class="edu-txt-left pl20 color-red">+<%= percentage.round(5) %>%</td>
<% elsif increase.zero? %>
<td class="edu-txt-right pr20 right-border" style="position: relative;">
<%= increase %>
</td>
<td class="edu-txt-left pl20"><%= percentage.round(5) %>%</td>
<% else %>
<td class="edu-txt-right pr20 right-border relative color-green">
<%= increase %>
</td>
<td class="edu-txt-left pl20 color-green"><%= percentage.round(5) %>%</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>
<% else %>
<div style="padding-top: 150px; height: 250px; text-align: center; color: grey; font-size: 14px;">
暂无数据,请选择时间段对比
</div>
<% end %>
<style>
.right-border::after {
position: absolute;
top: 10px;
right: 0;
content: '';
width: 0;
height: 20px;
border-right: 1px solid #000;
}
</style>

@ -0,0 +1,51 @@
<div style="background-color: #fafafa;">
统计总计:
<% if params[:grow_begin_date].present? %>
<%= params[:grow_date_input] %>
<% else %>
昨日至今日,
<% end %>
新增教师<span class="color-red"><%= @grow_summary.teacher_increase_count || 0 %></span>人,
新增学生<span class="color-red"><%= @grow_summary.student_increase_count || 0 %></span>人,
新增课堂<span class="color-red"><%= @grow_summary.course_increase_count || 0 %></span>个,
新增实训<span class="color-red"><%= @grow_summary.shixun_increase_count || 0 %></span>个,
活跃用户<span class="color-red"><%= @grow_summary.active_user_count || 0 %></span>个
</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="24%" class="edu-txt-left">单位名称</th>
<th width="12%"><%= sort_tag('新增教师', name: 'teacher_increase_count', path: school_data_grow_managements_path) %></th>
<th width="12%"><%= sort_tag('新增学生', name: 'student_increase_count', path: school_data_grow_managements_path) %></th>
<th width="12%"><%= sort_tag('新增课堂', name: 'course_increase_count', path: school_data_grow_managements_path) %></th>
<th width="12%"><%= sort_tag('新增实训', name: 'shixun_increase_count', path: school_data_grow_managements_path) %></th>
<th width="12%"><%= sort_tag('活跃用户', name: 'active_user_count', path: school_data_grow_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_data_grow_ref_pages">
<%= pagination_links_full @obj_pages, @obj_count, per_page_links: false, remote: true, flag: true, is_new: true, path: school_data_grow_managements_path(params.except(:page)) %>
</ul>
<div class="cl"></div>
</div>
</div>

@ -0,0 +1,42 @@
<table class="edu-pop-table edu-txt-center" cellpadding="0" cellspacing="0" style="table-layout: fixed">
<thead>
<tr>
<th width="6%">序号</th>
<th width="6%">ID</th>
<th width="14%" class="edu-txt-left">单位名称</th>
<th width="10%"><%= sort_tag('教师总人数', name: 'teacher_count', path: school_report_managements_path) %></th>
<th width="10%"><%= sort_tag('学生总人数', name: 'student_count', path: school_report_managements_path) %></th>
<th width="10%"><%= sort_tag('课堂总数', name: 'course_count', path: school_report_managements_path) %></th>
<th width="10%"><%= sort_tag('正在进行课堂数', name: 'active_course_count', path: school_report_managements_path) %></th>
<th width="10%"><%= sort_tag('实训作业总数', name: 'homework_count', path: school_report_managements_path) %></th>
<th width="10%"><%= sort_tag('其它作业总数', name: 'other_homework_count', path: school_report_managements_path) %></th>
<th width="14%"><%= sort_tag('动态时间', name: 'nearly_course_time', path: school_report_managements_path) %></th>
</tr>
</thead>
<tbody>
<% @schools.each_with_index do |school, index| %>
<tr>
<td><%= (@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>
<td><%= school['student_count'] %></td>
<td><%= school['course_count'] %></td>
<td><%= school['active_course_count'] %></td>
<td><%= school['homework_count'] %></td>
<td><%= school['other_homework_count'] %></td>
<td><%= format_time school['nearly_course_time'] %></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_report_ref_pages">
<%= pagination_links_full @obj_pages, @obj_count, per_page_links: false, remote: true, flag: true, is_new: true, path: school_report_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/data_grow_list'%>
</div>

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

@ -0,0 +1,45 @@
<div class="edu-con-top clearfix xmt10 bor-grey-e mt10">
<%= form_tag(school_report_managements_path(params), method: :get, remote: true, id: 'school_report_search_form') do %>
<%= 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', onclick: "$('#school_report_search_form').submit();" %>
<%= link_to '清除', 'javascript:clearSearchCondition()', class: 'fl task-btn ml5 mt2 mt10' %>
<div style="float: right;">
<%= link_to '导出Excel', school_statistics_xlsx_managements_path(format: :xlsx),
class: 'fl task-btn task-btn-orange mt10 mr20 export-statistic-btn',
onclick: 'exportSchoolStatistic();' %>
</div>
<% end %>
</div>
<div class="edu-con-bg01 clearfix mt10 bor-grey-e pt10 pb10">
<div class="pl15">
统计总计:
教师总人数<span class="color-red"><%= @teacher_total %></span>人,
学生总人数<span class="color-red"><%= @student_total %></span>人,
课堂总数<span class="color-red"><%= @course_total %></span>个,
正在进行课堂总数<span class="color-red"><%= @active_course_total %></span>个,
实训作业总数<span class="color-red"><%= @shixun_homework_total %></span>个,
其它作业总数<span class="color-red"><%= @other_homework_total %></span>个,
</div>
</div>
<div class="edu-con-bg01 mt15" id="managements_school_report">
<%= render 'managements/schools/statistics_list'%>
</div>
<script>
function clearSearchCondition(){
$("#school_report_search_form input[name='keyword']").val("");
$('#school_report_search_form').submit();
}
function exportSchoolStatistic(){
var form = $("#school_report_search_form")
var exportLink = form.find(".export-statistic-btn");
var keyword = form.find("input[name='keyword']").val();
exportLink.attr("href", exportLink.attr("href").split('?')[0] + "?keyword=" + keyword);
}
</script>

@ -0,0 +1 @@
$("#managements_school_report").html("<%= j(render 'managements/schools/statistics_list') %>")

@ -0,0 +1,20 @@
wb = xlsx_package.workbook
wb.add_worksheet(name: "统计总表") do |sheet|
sheet.add_row %w(ID 单位名称 教师总人数 学生总人数 课堂总数 正在进行课堂数 实训作业总数 其它作业总数 动态时间)
total = @schools.count
buffer_size = 500
times = total % 500 > 0 ? total / 500 + 1 : total / 500
times.times do |index|
schools = @schools.limit(buffer_size).offset(index * buffer_size)
schools.each do |school|
sheet.add_row([
school['id'].to_s, school['name'].to_s, school['teacher_count'].to_s, school['student_count'].to_s,
school['course_count'].to_s, school['active_course_count'].to_s, school['homework_count'].to_s,
school['other_homework_count'].to_s, format_time(school['nearly_course_time'])
])
end
end
end

@ -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_business" class="magic-checkbox" style="float:left; margin-top: 8px;">
<label for="person_business"></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">
@ -193,14 +200,12 @@
<option value="2">专业人士</option>
</select>
<select id="teacher" name="te_technical_title" nhname="tag_1" nh_tag_0="true" class="fl input-height select-width">
<option value="0" style="display:none">请选择职称</option>
<option value="教授">教授</option>
<option value="副教授">副教授</option>
<option value="讲师">讲师</option>
<option value="助教">助教</option>
</select>
<select id="profession" name="pro_technical_title" nhname="tag_1" nh_tag_2="true" class="fl input-height select-width">
<option value="0" style="display:none">请选择职称</option>
<option value="企业管理者">企业管理者</option>
<option value="部门管理者">部门管理者</option>
<option value="高级工程师">高级工程师</option>
@ -614,6 +619,13 @@
$("#user_form_link").on("click",function(){
var check = document.getElementById('person_business').checked;
if(check){
document.getElementById('person_business').value = "1";
}else{
document.getElementById('person_business').value = "0";
}
my_account_form_submit();
});
function my_account_form_submit(){

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

@ -33,6 +33,9 @@ RedmineApp::Application.routes.draw do ## oauth相关
match 'oauth/cb', to: 'oauth#test_callback', :via => :get
match 'oauth/userinfo', to: 'oauth#get_userinfo', :via => :get
match 'oauth/get_code', to: 'oauth#get_code', :via => :get
match 'oauth/get_token_callback', to: 'oauth#get_token_callback', :via => :get
get 'ecloud/ecloud_login', to: 'ecloud#ecloud_login_callback'
post 'ecloud/bs_new', to: 'ecloud#bs_new'
post 'ecloud/bs_update', to: 'ecloud#bs_update'
@ -720,7 +723,12 @@ RedmineApp::Application.routes.draw do ## oauth相关
post 'update_level_for_subject'
post :add_customers
delete :delete_customers
delete :delete_partner
get :customers_list
get :school_report, controller: 'managements::schools', action: 'statistics'
get :school_data_grow, controller: 'managements::schools', action: 'data_grow'
get :school_data_contrast, controller: 'managements::schools', action: 'data_contrast'
get :school_statistics_xlsx, controller: 'managements::schools', action: 'statistics_xlsx'
end
end
# Enable Grack support

@ -89,6 +89,8 @@ wiki_compression:
default: ""
default_language:
default: zh
server_url:
default: https://www.educoder.net/
host_name:
default: forge.trustie.net
host_course:
@ -211,7 +213,7 @@ default_projects_modules:
# - dts
default_projects_tracker_ids:
serialized: true
default:
default:
# Role given to a non-admin user who creates a project
new_project_user_role_id:
format: int

@ -0,0 +1,9 @@
class CreatePartnerCustomers < ActiveRecord::Migration
def change
create_table :partner_customers do |t|
t.references :partner
t.references :customer
t.timestamps
end
end
end

@ -0,0 +1,29 @@
class ModifyPartnerAndCustomer < ActiveRecord::Migration
def up
add_column :customers, :school_id, :integer
add_column :partners, :school_id, :integer
schools = School.where("customer_id is not null or partner_id is not null")
schools.each do |school|
if school.customer_id
customer = Customer.find_by_id(school.customer_id)
customer.update_column(:school_id, school.id) if customer
end
if school.partner_id
partner = Partner.find_by_id(school.partner_id)
partner.update_column(:school_id, school.id) if partner
end
end
# 迁移关联关系
customers = Customer.where(nil)
customers.each do |customer|
PartnerCustomer.create(partner_id: customer.partner_id, customer_id: customer.id)
end
end
def down
end
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,15 @@
class CreateOpenis < ActiveRecord::Migration
def change
create_table :openis do |t|
t.integer :user_id
t.integer :openi_user_id
t.string :login
t.string :avatar_url
t.string :name
t.string :email
t.integer :allow
t.timestamps
end
end
end

@ -0,0 +1,9 @@
class AddIndexToSchoolDailyReports < ActiveRecord::Migration
def change
add_index :school_daily_reports, [:date, :teacher_increase_count]
add_index :school_daily_reports, [:date, :student_increase_count]
add_index :school_daily_reports, [:date, :course_increase_count]
add_index :school_daily_reports, [:date, :shixun_increase_count]
add_index :school_daily_reports, [:date, :active_user_count]
end
end

@ -0,0 +1,108 @@
#coding=utf-8
namespace :school_daily_report do
desc 'daily statistic school task'
task daily_statistic: :environment do
StatisticSchoolDailyReportTask.new.call
end
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

@ -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(){
@ -158,7 +146,8 @@ $(function(){
}
var new_href = href.replace(/page=(\d*)/, 'page=' + page);
console.log(new_href);
$.get(new_href);
// $.get(new_href);
$.ajax({url: new_href, dataType: 'script'})
return false;
}
}

@ -43,13 +43,29 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
function removeExceptGitDir(dir) {
// readdirSync
const list = fs2.readdirSync(dir)
// if (err) return done(err);
var pending = list.length;
// if (!pending) return done(null, results);
list.forEach(function(file) {
if (file.indexOf('.git') == -1) {
file = path.resolve(dir, file);
fs.removeSync(file)
}
});
}
// First, read the current file sizes in build directory.
// This lets us display how much they changed later.
measureFileSizesBeforeBuild(paths.appBuild)
.then(previousFileSizes => {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
fs.emptyDirSync(paths.appBuild);
// fs.emptyDirSync(paths.appBuild);
removeExceptGitDir(paths.appBuild)
// Merge with the public folder
copyPublicFolder();
// Start the webpack build
@ -186,6 +202,14 @@ function generateNewIndexJsp() {
fs2.writeFile(outputPath, result, 'utf8', function (err) {
if (err) return console.log(err);
commitAndPush();
});
});
}
function commitAndPush() {
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { console.log(stdout) }
var options = {cwd:"./build"};
exec("git status && git commit -am 'b' && git push", options, puts);
}

@ -56,9 +56,8 @@ If you continue to experience problems please contact your Trustie administrator
温馨提示:为了给大家提供更优质的服务
</p>
<p class="font-18">
平台拟于<span style="color: red">2019年4月23日00:00--02:00</span>进行全面升级,带来不便,敬请谅解!
平台拟于<span style="color: red">2019年4月27日17:00--18:30</span>进行全面升级,带来不便,敬请谅解!
</p>
</div>
</div>
</body>
</html>

@ -0,0 +1,11 @@
FactoryGirl.define do
factory :openi do
user_id 1
openi_user_id 1
login "MyString"
avatar_url "MyString"
name "MyString"
email "MyString"
allow 1
end
end

@ -0,0 +1,5 @@
FactoryGirl.define do
factory :partner_customer do
end
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Openi, :type => :model do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe PartnerCustomer, :type => :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save