Merge branch 'dev_aliyun' of http://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

dev_tj
cxt 5 years ago
commit e9cee80255

@ -456,6 +456,25 @@ class SubjectsController < ApplicationController
end
end
def statistics_new
# data = Subjects::DataStatisticService.new(@subject)
# Rails.logger.info("study_count: #{data.study_count}")
# Rails.logger.info("course_study_count: #{ data.course_study_count}")
# Rails.logger.info("passed_count: #{data.passed_count}")
# Rails.logger.info("course_used_count: #{data.course_used_count}")
# Rails.logger.info("school_used_count: #{data.school_used_count}")
# data_1 = Subjects::CourseUsedInfoService.call(@subject)
# Rails.logger.info("study_count: #{data_1}")
# data_2 = Subjects::ShixunUsedInfoService.call(@subject)
# Rails.logger.info("study_count: #{data_2}")
data_3 = Subjects::UserUsedInfoService.call(@subject)
Rails.logger.info("study_count: #{data_3}")
render_ok()
end
def shixun_report
end

@ -206,7 +206,7 @@ module TidingDecorator
format_str % [parent_container.shixun.name, parent_container.position]
end
when 'Memo', 'Message' then
message = parent_container.parent_id.present? ? message_content_helper(parent_container.content) : parent_container.subject
message = parent_container.main_subject
I18n.t(locale_format(parent_container_type, parent_container.parent_id.present?)) % message
when 'HomeworkCommon' then
I18n.t(locale_format(parent_container_type)) % parent_container.name

@ -41,6 +41,11 @@ class Memo < ApplicationRecord
Memo.where(parent_id: id).includes(:author).reorder("created_at asc")
end
# 主贴的名称
def main_subject
parent.present? ? parent.subject : subject
end
private
def send_tiding

@ -39,6 +39,11 @@ class Message < ApplicationRecord
message_detail.update_attributes(content: content)
end
# 主贴的名称
def main_subject
parent.present? ? parent.subject : subject
end
def copy_attachments_to_new_message(new_message, user)
attachments.each do |attach|
new_message.attachments << Attachment.new(attach.attributes.except("id").merge(

@ -5,6 +5,7 @@ class Myshixun < ApplicationRecord
has_one :shixun_modify, :dependent => :destroy
belongs_to :user
belongs_to :user_extension, foreign_key: :user_id
belongs_to :shixun, counter_cache: true
has_one :last_executable_task, -> { where(status: [0, 1]).reorder(created_at: :asc) }, class_name: 'Game'
@ -21,7 +22,7 @@ class Myshixun < ApplicationRecord
end
def output_times
games.pluck(:evaluate_count).sum.to_i
games.map(&:evaluate_count).sum.to_i
end
def repo_path

@ -30,6 +30,8 @@ class Shixun < ApplicationRecord
has_one :first_tag_repertoire, through: :first_shixun_tag_repertoire, source: :tag_repertoire
has_many :homework_commons_shixuns, class_name: 'HomeworkCommonsShixun'
has_many :homework_commons, through: :homework_commons_shixuns
has_many :fork_shixuns, foreign_key: "fork_from", class_name: 'Shixun'
#实训的关卡
@ -59,6 +61,9 @@ class Shixun < ApplicationRecord
# Jupyter数据集,附件
has_many :data_sets, ->{where(attachtype: 2)}, class_name: 'Attachment', as: :container, dependent: :destroy
# 试卷的实训题
has_many :exercise_questions
scope :search_by_name, ->(keyword) { where("name like ? or description like ? ",
"%#{keyword}%", "%#{keyword}%") }

@ -25,6 +25,11 @@ class Subject < ApplicationRecord
has_many :courses, -> { where("is_delete = 0").order("courses.created_at ASC") }
has_many :laboratory_subjects, dependent: :destroy
# 学习统计
has_one :subject_record, dependent: :destroy
has_many :subject_course_records, dependent: :destroy
has_many :subject_shixun_infos, dependent: :destroy
has_many :subject_user_infos, dependent: :destroy
validates :name, length: { maximum: 60 }
validates :description, length: { maximum: 8000 }

@ -0,0 +1,3 @@
class SubjectCourseRecord < ApplicationRecord
belongs_to :subject
end

@ -0,0 +1,3 @@
class SubjectRecord < ApplicationRecord
belongs_to :subject
end

@ -0,0 +1,3 @@
class SubjectShixunInfo < ApplicationRecord
belongs_to :subject
end

@ -0,0 +1,3 @@
class SubjectUserInfo < ApplicationRecord
belongs_to :subject
end

@ -43,6 +43,7 @@ class User < ApplicationRecord
has_many :shixun_members, :dependent => :destroy
has_many :shixuns, :through => :shixun_members
has_many :myshixuns, :dependent => :destroy
has_many :games, :dependent => :destroy
has_many :study_shixuns, through: :myshixuns, source: :shixun # 已学习的实训
has_many :course_messages
has_many :courses, foreign_key: 'tea_id', dependent: :destroy

@ -0,0 +1,40 @@
class Subjects::CourseUsedInfoService < ApplicationService
attr_reader :subject
def initialize(subject)
@subject = subject
@shixun_ids = subject.shixuns.pluck(:id)
end
def call
return if subject.blank?
homework_commons =
HomeworkCommon.joins(:homework_commons_shixun)
.where(homework_type: %i[practice])
.where(homework_commons_shixuns: {shixun_id: @shixun_ids})
course_ids = homework_commons.pluck(:course_id)
homework_common_ids = homework_commons.pluck("homework_commons.id")
schools = School.joins(:courses).where(courses: {id: course_ids}).group("schools.id").select("schools.*, count(courses.id) course_count")
# name将该课程使用到课堂的单位
# course_count: 将该课程使用到课堂的数量
# student_count: 课堂的学生总数(去掉重复)
# choice_shixun_num: 选用该课程实训的个数(去重)
# choice_shixun_frequency: 选用该课程实训的次数
course_info = []
schools.map do |school|
name = school.name
course_count = school.course_count
student_count = school.courses.joins(:course_members).where(course_members: {role: 4, course_id: course_ids}).size
shixun_ids = school.courses.joins(homework_commons: :homework_commons_shixun)
.where(homework_commons: {id: homework_common_ids})
.pluck("homework_commons_shixuns.shixun_id")
choice_shixun_frequency = shixun_ids.size
choice_shixun_num = shixun_ids.uniq.size
course_info << {school_id: school.id, school_name: name, course_count: course_count, student_count: student_count,
choice_shixun_num: choice_shixun_num, choice_shixun_frequency: choice_shixun_frequency}
end
course_info
end
end

@ -0,0 +1,72 @@
class Subjects::DataStatisticService < ApplicationService
attr_reader :subject
def initialize(subject)
@subject = subject
@shixuns = subject.shixuns
@shixun_ids = @shixuns.pluck(:id)
end
# 学习总人数:
# 文案解释:学习该课程的全部人数(学习总人数=课堂学习人数+自主学习人数)
# 开发备注只要点击该课程的任何一个实训生成了tpi都算一个学习人数去重一个人数计算1次
def study_count
@shixuns.joins(:myshixuns).pluck("myshixuns.user_id").uniq.size
end
# 课堂学习人数:
# 文案解释:通过课堂学习该课程的人数
# 开发备注只要通过课堂进入并点击了实训生成了tpi则算一个可以学习人数去重一个人数计算1次
def course_study_count
# 实训作业
sw_user_ids = StudentWork.where.not(myshixun_id: 0).joins(homework_common: :homework_commons_shixun)
.where(homework_commons_shixuns: {shixun_id: @shixun_ids}).pluck("student_works.user_id")
# 试卷的实训题
esa_user_ids = ExerciseShixunAnswer.joins(exercise_shixun_challenge: :shixun)
.where(shixuns: {id: @shixun_ids}).pluck("exercise_shixun_answers.user_id")
(sw_user_ids + esa_user_ids).uniq.size
end
# 自主学习人数:
# 文案解释:通过自主学习该课程的人数
# 开发备注非课程进入生成了实训的tpi去重。一个人数计算1次
def initiative_study
study_count - course_study_count
end
# 通关总人数:
# 文案解释:
# 通关该课程所有实训的人数去重。一个人数计算1次
def passed_count
@shixuns.includes(:myshixuns).where(myshixuns: {status: 1}).pluck("myshixuns.user_id").uniq.size
end
# 使用课堂数:
# 文案解释:使用该课程的课堂数量
# 开发备注课堂加入该课程的实训到自己课堂则算一个使用课堂数。去重一个课堂计算1次
def course_used_count
hc_course_ids =
HomeworkCommon.joins(:homework_commons_shixun)
.where(homework_type: %i[practice])
.where(homework_commons_shixuns: {shixun_id: @shixun_ids}).pluck("homework_commons.course_id").uniq
ex_course_ids =
Exercise.joins(:exercise_questions)
.where(exercise_questions: {question_type: 5, shixun_id: @shixun_ids}).pluck("exercises.course_id").uniq
(hc_course_ids + ex_course_ids).uniq.size
end
# 使用单位数:
# 文案解释:使用该课程的单位数量(包括自主学习者所在单位)
# 开发备注:凡事该单位有使用该课程的实训(自主学习+课堂使用)都算;(去重,一个单位计算一次)
def school_used_count
school_ids.size
end
private
def school_ids
@shixuns.joins(myshixuns: :user_extension).pluck("user_extensions.school_id").uniq
end
end

@ -0,0 +1,30 @@
class Subjects::ShixunUsedInfoService < ApplicationService
attr_reader :subject, :stages
def initialize(subject)
@subject = subject
@stages = subject.stages.includes(shixuns: [myshixuns: :games, homework_commons_shixuns: [homework_common: :course]])
end
def call
shixun_infos = []
stages.each do |stage|
position = stage.position
stage.shixuns.each_with_index do |shixun, index|
stage = "#{position}-#{index+1}"
name = shixun.name
challenge_count = shixun.challenges_count
course_count = shixun.homework_commons.map{|hc| hc.course_id}.uniq.size
school_count = shixun.homework_commons.map{|hc| hc.course&.school_id}.uniq.size
used_count = shixun.myshixuns_count
passed_count = shixun.myshixuns.select{|m| m.status == 1}.size
evaluate_count = shixun.myshixuns.map{|m| m.output_times }.sum
passed_ave_time = passed_count > 0 ? shixun.myshixuns.map{|m| m.total_cost_time}.sum : 0
shixun_infos << {stage: stage, name: name, challenge_count: challenge_count, course_count: course_count,
school_count: school_count, used_count: used_count, passed_count: passed_count,
evaluate_count: evaluate_count, passed_ave_time: passed_ave_time, shixun_id: shixun.id}
end
end
shixun_infos
end
end

@ -0,0 +1,28 @@
class Subjects::UserUsedInfoService < ApplicationService
attr_reader :subject, :shixun_ids
def initialize(subject)
@subject = subject
@shixun_ids = subject.shixuns.pluck(:id)
end
def call
users_info = []
users = User.includes(myshixuns: :games).where(myshixuns: {shixun_id: shixun_ids}, games: {status: 2})
users.each do |user|
myshixuns = user.myshixuns.select{|m| shixun_ids.include?(m.shixun_id)}
name = "#{user.lastname}#{user.firstname}"
passed_myshixun_count = myshixuns.select{|m| m.status == 1}.size
passed_games_count = myshixuns.map{|m| m.games.select{|g| g.status == 2}.size }.size
code_line_count = 0
evaluate_count = myshixuns.map{|m| m.output_times }.sum
cost_time = myshixuns.map{|m|m.total_cost_time }.sum
users_info << {user_id: user.id, name: name, passed_myshixun_count: passed_myshixun_count,
passed_games_count: passed_games_count, code_line_count: code_line_count,
evaluate_count: evaluate_count, cost_time: cost_time}
end
users_info
end
end

@ -394,6 +394,7 @@ Rails.application.routes.draw do
get 'cancel_publish'
get 'cancel_has_publish'
get 'statistics'
get 'statistics_new'
get 'shixun_report'
get 'school_report'
post 'update_attr'

@ -0,0 +1,14 @@
class CreateSubjectRecords < ActiveRecord::Migration[5.2]
def change
create_table :subject_records do |t|
t.references :subject, unique: true
t.integer :study_count, default: 0
t.integer :course_study_count, default: 0
t.integer :initiative_study, default: 0
t.integer :passed_count, default: 0
t.integer :course_used_count, default: 0
t.integer :school_used_count, default: 0
t.timestamps
end
end
end

@ -0,0 +1,16 @@
class CreateSubjectCourseRecords < ActiveRecord::Migration[5.2]
def change
create_table :subject_course_records do |t|
t.references :subject
t.references :school
t.string :school_name
t.integer :course_count, default: 0
t.integer :student_count, default: 0
t.integer :choice_shixun_num, default: 0
t.integer :choice_shixun_frequency, default: 0
t.timestamps
end
add_index :subject_course_records, [:school_id, :subject_id], unique: true, name: "couse_and_school_index"
end
end

@ -0,0 +1,21 @@
class CreateSubjectShixunInfos < ActiveRecord::Migration[5.2]
def change
create_table :subject_shixun_infos do |t|
t.references :subject
t.references :shixun
t.string :stage
t.string :shixun_name
t.integer :challenge_count, default: 0
t.integer :course_count, default: 0
t.integer :school_count, default: 0
t.integer :used_count, default: 0
t.integer :passed_count, default: 0
t.integer :evaluate_count, default: 0
t.integer :passed_ave_time, default: 0
t.timestamps
end
add_index :subject_shixun_infos, [:shixun_id, :subject_id], unique: true
end
end

@ -0,0 +1,18 @@
class CreateSubjectUserInfos < ActiveRecord::Migration[5.2]
def change
create_table :subject_user_infos do |t|
t.references :user
t.references :subject
t.string :username
t.integer :passed_myshixun_count, default: 0
t.integer :passed_games_count, default: 0
t.integer :code_line_count, default: 0
t.integer :evaluate_count, default: 0
t.integer :cost_time, default: 0
t.timestamps
end
add_index :subject_user_infos, [:user_id, :subject_id], unique: true
end
end

@ -0,0 +1,5 @@
class ModifyMyshixunIdForStudentWorks < ActiveRecord::Migration[5.2]
def change
StudentWork.where(myshixun_id: nil).update_all(myshixun_id: 0)
end
end

@ -0,0 +1,111 @@
desc "统计实践课程的学习统计数据"
namespace :subjects do
task data_statistic: :environment do
puts("---------------------data_statistic_begin")
Rails.logger.info("---------------------data_statistic_begin")
subjects = Subject.where(status: 2)
subjects.find_each do |subject|
puts("---------------------data_statistic: #{subject.id}")
Rails.logger.info("---------------------data_statistic: #{subject.id}")
sr = SubjectRecord.find_or_create_by!(subject_id: subject.id)
data = Subjects::DataStatisticService.new(subject)
study_count = data.study_count
# 总人数没有变化的话,不同课堂之类的变化了
course_study_count = (study_count == sr.study_count ? sr.course_study_count : data.course_study_count)
passed_count = (study_count == sr.study_count ? sr.passed_count : data.passed_count)
course_used_count = (study_count == sr.study_count ? sr.course_used_count : data.course_used_count)
school_used_count = (study_count == sr.study_count ? sr.school_used_count : data.school_used_count)
update_params = {
study_count: study_count,
course_study_count: course_study_count,
initiative_study: (study_count - course_study_count),
passed_count: passed_count,
course_used_count: course_used_count,
school_used_count: school_used_count
}
sr.update_attributes!(update_params)
end
puts("---------------------data_statistic_end")
Rails.logger.info("---------------------data_statistic_end")
end
task course_info_statistic: :environment do
puts("---------------------course_info_statistic_begin")
Rails.logger.info("---------------------course_info_statistic_begin")
subjects = Subject.where(status: 2)
subjects.find_each do |subject|
puts("---------------------course_info_statistic: #{subject.id}")
Rails.logger.info("---------------------course_info_statistic: #{subject.id}")
data = Subjects::CourseUsedInfoService.call(subject)
data.each do |key|
scr = SubjectCourseRecord.find_or_create_by!(school_id: key[:school_id], subject_id: subject.id)
update_params = {
school_name: key[:school_name],
course_count: key[:course_count],
student_count: key[:student_count],
choice_shixun_num: key[:choice_shixun_num],
choice_shixun_frequency: key[:choice_shixun_frequency]
}
scr.update_attributes(update_params)
end
end
puts("---------------------course_info_statistic_end")
Rails.logger.info("---------------------course_info_statistic_end")
end
task shixun_info_statistic: :environment do
puts("---------------------shixun_info_statistic_begin")
Rails.logger.info("---------------------shixun_info_statistic_begin")
subjects = Subject.where(status: 2)
subjects.find_each(batch_size: 100) do |subject|
puts("---------------------shixun_info_statistic: #{subject.id}")
Rails.logger.info("---------------------shixun_info_statistic: #{subject.id}")
data = Subjects::ShixunUsedInfoService.call(subject)
data.each do |key|
ssi = SubjectShixunInfo.find_or_create_by!(shixun_id: key[:shixun_id], subject_id: subject.id)
update_params = {
stage: key[:stage],
shixun_name: key[:name],
challenge_count: key[:challenge_count],
course_count: key[:course_count],
school_count: key[:school_count],
used_count: key[:used_count],
passed_count: key[:passed_count],
evaluate_count: key[:evaluate_count],
passed_ave_time: key[:passed_ave_time]
}
ssi.update_attributes(update_params)
end
end
puts("---------------------shixun_info_statistic_end")
Rails.logger.info("---------------------shixun_info_statistic_end")
end
task user_info_statistic: :environment do
puts("---------------------user_info_statistic_begin")
Rails.logger.info("---------------------user_info_statistic_begin")
subjects = Subject.where(status: 2)
subjects.find_each(batch_size: 100) do |subject|
puts("---------------------user_info_statistic: #{subject.id}")
data = Subjects::UserUsedInfoService.call(subject)
data.each do |key|
sui = SubjectUserInfo.find_or_create_by!(user_id: key[:user_id], subject_id: subject.id)
update_params = {
username: key[:name],
passed_myshixun_count: key[:passed_myshixun_count],
passed_games_count: key[:passed_games_count],
code_line_count: key[:code_line_count],
evaluate_count: key[:evaluate_count],
cost_time: key[:cost_time]
}
sui.update_attributes(update_params)
end
end
puts("---------------------user_info_statistic_end")
Rails.logger.info("---------------------user_info_statistic_end")
end
end

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

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

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

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