forked from Gitlink/forgeplus
Merge branch 'featrue_codereview' into develop
This commit is contained in:
commit
4f33e1194c
|
@ -33,12 +33,13 @@ class Admins::ProjectCategoriesController < Admins::BaseController
|
|||
end
|
||||
|
||||
def update
|
||||
if @project_category.update_attributes({name: @name, pinned_index: params[:project_category][:pinned_index].to_i}) && save_image_file(params[:logo], 'logo')
|
||||
if @project_category.update_attributes({name: @name, pinned_index: params[:project_category][:pinned_index].to_i})
|
||||
save_image_file(params[:logo], 'logo')
|
||||
redirect_to admins_project_categories_path
|
||||
flash[:success] = '更新成功'
|
||||
else
|
||||
redirect_to admins_project_categories_path
|
||||
flash[:success] = '更新失败'
|
||||
flash[:danger] = '更新失败'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ class ApplicationController < ActionController::Base
|
|||
when 1, 2, 4, 9
|
||||
# 手机类型的发送
|
||||
sigle_para = {phone: value}
|
||||
status = Educoder::Sms.send(mobile: value, code: code)
|
||||
status = Gitlink::Sms.send(mobile: value, code: code)
|
||||
tip_exception(-2, code_msg(status)) if status != 0
|
||||
when 8, 3, 5
|
||||
# 邮箱类型的发送
|
||||
|
@ -183,7 +183,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# 异常提醒
|
||||
def tip_exception(status = -1, message)
|
||||
raise Educoder::TipException.new(status, message)
|
||||
raise Gitlink::TipException.new(status, message)
|
||||
end
|
||||
|
||||
def missing_template
|
||||
|
@ -192,7 +192,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# 弹框提醒
|
||||
def tip_show_exception(status = -2, message)
|
||||
raise Educoder::TipException.new(status, message)
|
||||
raise Gitlink::TipException.new(status, message)
|
||||
end
|
||||
|
||||
def normal_status(status = 0, message)
|
||||
|
@ -272,18 +272,18 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# 测试版前端需求
|
||||
logger.info("subdomain:#{request.subdomain}")
|
||||
if request.subdomain != "www"
|
||||
if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
|
||||
User.current = User.find 81403
|
||||
elsif params[:debug] == 'student'
|
||||
User.current = User.find 8686
|
||||
elsif params[:debug] == 'admin'
|
||||
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
|
||||
user = User.find 36480
|
||||
User.current = user
|
||||
cookies.signed[:user_id] = user.id
|
||||
end
|
||||
end
|
||||
# if request.subdomain != "www"
|
||||
# if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
|
||||
# User.current = User.find 81403
|
||||
# elsif params[:debug] == 'student'
|
||||
# User.current = User.find 8686
|
||||
# elsif params[:debug] == 'admin'
|
||||
# logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
|
||||
# user = User.find 36480
|
||||
# User.current = user
|
||||
# cookies.signed[:user_id] = user.id
|
||||
# end
|
||||
# end
|
||||
# User.current = User.find 81403
|
||||
end
|
||||
|
||||
|
@ -373,7 +373,7 @@ class ApplicationController < ActionController::Base
|
|||
JSON.parse(res)
|
||||
rescue Exception => e
|
||||
uid_logger_error("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new("实训平台繁忙(繁忙等级:84)")
|
||||
raise Gitlink::TipException.new("实训平台繁忙(繁忙等级:84)")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -392,7 +392,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
rescue Exception => e
|
||||
uid_logger("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new(message)
|
||||
raise Gitlink::TipException.new(message)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -416,7 +416,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
rescue Exception => e
|
||||
uid_logger("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new("服务器繁忙")
|
||||
raise Gitlink::TipException.new("服务器繁忙")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -588,8 +588,8 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# 获取Oauth Client
|
||||
def get_client(site)
|
||||
client_id = Rails.configuration.educoder['client_id']
|
||||
client_secret = Rails.configuration.educoder['client_secret']
|
||||
client_id = Rails.configuration.Gitlink['client_id']
|
||||
client_secret = Rails.configuration.Gitlink['client_secret']
|
||||
|
||||
OAuth2::Client.new(client_id, client_secret, site: site)
|
||||
end
|
||||
|
|
|
@ -196,7 +196,7 @@ class AttachmentsController < ApplicationController
|
|||
end
|
||||
|
||||
def file_save_to_ucloud(path, file, content_type)
|
||||
ufile = Educoder::Ufile.new(
|
||||
ufile = Gitlink::Ufile.new(
|
||||
ucloud_public_key: edu_setting('public_key'),
|
||||
ucloud_private_key: edu_setting('private_key'),
|
||||
ucloud_public_read: true,
|
||||
|
|
|
@ -20,7 +20,7 @@ module ControllerRescueHandler
|
|||
end
|
||||
# rescue_from ActionView::MissingTemplate, with: :object_not_found
|
||||
# rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
|
||||
rescue_from Educoder::TipException, with: :tip_show
|
||||
rescue_from Gitlink::TipException, with: :tip_show
|
||||
rescue_from ::ActionView::MissingTemplate, with: :missing_template
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
|
||||
rescue_from ActionController::ParameterMissing, with: :render_parameter_missing
|
||||
|
|
|
@ -36,10 +36,10 @@ module GitCommon
|
|||
begin
|
||||
@commits = GitService.commits(repo_path: @repo_path)
|
||||
logger.info("git first commit is #{@commits.try(:first)}")
|
||||
raise Educoder::TipException.new("请先创建版本库") if @commits.nil?
|
||||
raise Gitlink::TipException.new("请先创建版本库") if @commits.nil?
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
raise Educoder::TipException.new("提交记录异常")
|
||||
raise Gitlink::TipException.new("提交记录异常")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ module GitHelper
|
|||
|
||||
rescue Exception => e
|
||||
Rails.logger.error(e.message)
|
||||
raise Educoder::TipException.new("文档内容获取异常")
|
||||
raise Gitlink::TipException.new("文档内容获取异常")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -64,7 +64,7 @@ module GitHelper
|
|||
|
||||
# 版本库Fork功能
|
||||
def project_fork(container, original_rep_path, username)
|
||||
raise Educoder::TipException.new("fork源路径为空,fork失败!") if original_rep_path.blank?
|
||||
raise Gitlink::TipException.new("fork源路径为空,fork失败!") if original_rep_path.blank?
|
||||
# 将要生成的仓库名字
|
||||
new_repo_name = "#{username.try(:strip)}/#{container.try(:identifier)}#{ Time.now.strftime("%Y%m%d%H%M%S")}"
|
||||
# uid_logger("start fork container: repo_name is #{new_repo_name}")
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
module CourseDecorator
|
||||
def can_visited?
|
||||
is_public == 1 || User.current.admin_or_business? || User.current.member_of_course?(self)
|
||||
end
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module EcCourseTargetDecorator
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
module ExperienceDecorator
|
||||
def container_type_text
|
||||
I18n.t("experience.container_type.#{container_type.to_s.underscore}")
|
||||
end
|
||||
|
||||
def content
|
||||
case container_type.to_s.underscore
|
||||
when 'game' then
|
||||
game = Game.find_by(id: container_id)
|
||||
game.present? ? "通过实训“#{game.challenge.shixun.name}”的第#{game.challenge.position}关获得的奖励" : ''
|
||||
when 'shixun_publish' then
|
||||
shixun = Shixun.find_by(id: container_id)
|
||||
shixun.present? ? "发布实训“#{shixun.name}”获得的奖励" : ''
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,39 +0,0 @@
|
|||
module GradeDecorator
|
||||
def container_type_text
|
||||
I18n.t("grade.container_type.#{container_type.to_s.underscore}")
|
||||
end
|
||||
|
||||
def content
|
||||
case container_type.to_s.underscore
|
||||
when 'avatar' then '用户首次上传头像获得的奖励'
|
||||
when 'phone' then '用户首次绑定手机号码获得的奖励'
|
||||
when 'mail' then '用户首次绑定邮箱获得的奖励'
|
||||
when 'attendance' then '用户每天签到获得的奖励'
|
||||
when 'account' then '新用户首次填写基本资料获得的奖励'
|
||||
when 'memo' then '发布的评论或者帖子获得平台奖励'
|
||||
when 'discusses' then '发布的评论获得平台奖励'
|
||||
when 'star' then '用户给实训评分获得的随机奖励'
|
||||
when 'feedback' then '反馈的问题获得平台奖励'
|
||||
when 'authentication' then '用户首次完成实名认证获得的奖励'
|
||||
when 'professional' then '用户首次完成职业认证获得的奖励'
|
||||
when 'answer' then
|
||||
game = Game.find_by(id: container_id)
|
||||
game.present? ? "查看实训“#{game.challenge.shixun.name}”第#{game.challenge.position}关的参考答案消耗的金币" : ''
|
||||
when 'game' then
|
||||
game = Game.find_by(id: container_id)
|
||||
game.present? ? "通过实训“#{game.challenge.shixun.name}”的第#{game.challenge.position}关获得的奖励" : ''
|
||||
when 'test_set' then
|
||||
game = Game.find_by(id: container_id)
|
||||
game.present? ? "查看实训“#{game.challenge.shixun.name}”的第#{game.challenge.position}关的隐藏测试集消耗的金币" : ''
|
||||
when 'shixun_publish' then
|
||||
shixun = Shixun.find_by(id: container_id)
|
||||
shixun.present? ? "发布实训“#{shixun.name}”获得的奖励" : ''
|
||||
when 'check_ta_answer' then
|
||||
game = Game.find_by(id: container_id)
|
||||
game.present? ? "查看实训“#{game.challenge.shixun.name}”第#{game.challenge.position}关的TA人解答消耗的金币" : ''
|
||||
when 'hack' then
|
||||
hack = Hack.find_by(id: container_id)
|
||||
hack.present? ? "完成了题目解答“#{hack.name}”,获得金币奖励:#{hack.score}" : ''
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
module LibraryDecorator
|
||||
extend ApplicationDecorator
|
||||
|
||||
display_time_method :published_at, :created_at, :updated_at
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
module ShixunDecorator
|
||||
def human_status
|
||||
I18n.t("shixun.status.#{status}")
|
||||
end
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
module SubjectDecorator
|
||||
def can_visited?
|
||||
published? || User.current.admin? || member?(User.current)
|
||||
end
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
module VideoDecorator
|
||||
extend ApplicationDecorator
|
||||
|
||||
display_time_method :published_at, :created_at, :updated_at
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
class AddSchoolApplyForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :name, :province, :city, :address, :remarks
|
||||
|
||||
validates :name, presence: true
|
||||
# validates :province, presence: true
|
||||
# validates :city, presence: true
|
||||
# validates :address, presence: true
|
||||
end
|
|
@ -1,27 +0,0 @@
|
|||
class ApplyShixunMirrorForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :language, :runtime, :run_method, :attachment_id
|
||||
|
||||
validates :language, presence: true
|
||||
validates :runtime, presence: true
|
||||
validates :run_method, presence: true
|
||||
validates :attachment_id, presence: true, numericality: { only_integer: true }
|
||||
|
||||
validate :ensure_attachment_presence
|
||||
def ensure_attachment_presence
|
||||
return unless attachment_id
|
||||
|
||||
if attachment.blank?
|
||||
errors.add(:attachment_id, :attachment_not_exist)
|
||||
end
|
||||
end
|
||||
|
||||
def attachment
|
||||
@attachment ||= Attachment.find_by_id(attachment_id)
|
||||
end
|
||||
|
||||
def to_json
|
||||
{ language: language, runtime: runtime, run_method: run_method, attachment_id: attachment_id }.to_json
|
||||
end
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
class ExaminationBanks::SaveExamForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :discipline_id, :sub_discipline_id, :difficulty, :name, :duration, :tag_discipline_id
|
||||
|
||||
validates :discipline_id, presence: true
|
||||
validates :sub_discipline_id, presence: true
|
||||
validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true }
|
||||
validates :name, presence: true, length: { maximum: 60, too_long: "不能超过60个字符" }
|
||||
validate :validate_duration
|
||||
|
||||
def validate_duration
|
||||
raise '时长应为大于0的整数' if duration.present? && duration.to_i < 1
|
||||
end
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
class ExaminationIntelligentSettings::SaveExamForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :name, :duration
|
||||
|
||||
validates :name, presence: true, length: { maximum: 60 }
|
||||
validate :validate_duration
|
||||
|
||||
def validate_duration
|
||||
raise '时长应为大于0的整数' if duration.present? && duration.to_i < 1
|
||||
end
|
||||
end
|
|
@ -1,11 +0,0 @@
|
|||
class ExaminationIntelligentSettings::SaveExamSettingForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :discipline_id, :sub_discipline_id, :source, :difficulty, :tag_discipline_id, :question_settings
|
||||
|
||||
validates :discipline_id, presence: true
|
||||
validates :sub_discipline_id, presence: true
|
||||
validates :source, presence: true
|
||||
validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true }
|
||||
validates :question_settings, presence: true
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
class Weapps::CreateCourseForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :course
|
||||
attr_accessor :name, :course_list_name, :credit, :course_module_types, :end_date
|
||||
|
||||
validates :name, presence: true
|
||||
validates :course_list_name, presence: true
|
||||
|
||||
validate :course_name_prefix
|
||||
validate :check_course_modules
|
||||
|
||||
def course_name_prefix
|
||||
raise '课堂名称应以课程名称开头' unless name.index(course_list_name) && name.index(course_list_name) == 0
|
||||
end
|
||||
|
||||
def check_course_modules
|
||||
raise '请至少添加一个课堂模块' if course_module_types.blank?
|
||||
end
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
class Weapps::UpdateCourseForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :course
|
||||
attr_accessor :name, :course_list_name, :credit, :end_date
|
||||
|
||||
validates :name, presence: true
|
||||
validates :course_list_name, presence: true
|
||||
|
||||
validate :course_name_prefix
|
||||
|
||||
def course_name_prefix
|
||||
raise '课堂名称应以课程名称开头' unless name.index(course_list_name) && name.index(course_list_name) == 0
|
||||
end
|
||||
end
|
|
@ -4,7 +4,7 @@ module Admins::ProjectsHelper
|
|||
owner = project.owner
|
||||
|
||||
if owner.is_a?(User)
|
||||
link_to(project.owner&.real_name, "/users/#{project&.owner&.login}", target: '_blank')
|
||||
link_to(project.owner&.real_name, "/#{project&.owner&.login}", target: '_blank')
|
||||
elsif owner.is_a?(Organization)
|
||||
link_to(project.owner&.real_name, "/organize/#{project&.owner&.login}", target: '_blank')
|
||||
else
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# 所有的方法请按首字母的顺序依次列出
|
||||
module ApplicationHelper
|
||||
include Educoder::I18n
|
||||
include Gitlink::I18n
|
||||
include GitHelper
|
||||
|
||||
ONE_MINUTE = 60 * 1000
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
module BoardsHelper
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
module ChallengesHelper
|
||||
|
||||
def match_begin_symbol str
|
||||
str.gsub(/\A\r/, "\r\r")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module CourseGroupsHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module CourseModulesHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module CourseSecondCategoriesHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module CourseStagesHelper
|
||||
end
|
|
@ -1,298 +0,0 @@
|
|||
module CoursesHelper
|
||||
|
||||
def member_manager group, teachers
|
||||
str = ""
|
||||
members = teachers.select{|teacher| teacher.teacher_course_groups.pluck(:course_group_id).include?(group.id) || teacher.teacher_course_groups.size == 0}
|
||||
str = members.uniq.size == teachers.size ? "全部教师" : members.map{|member| member.user.real_name}.join("、")
|
||||
str
|
||||
# teachers.each do |member|
|
||||
# if member.teacher_course_groups.exists?(course_group_id: group.id) || member.teacher_course_groups.size == 0
|
||||
# str << member.user.real_name
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
def edit_auth group, teachers
|
||||
User.current.admin_or_business? ||
|
||||
teachers.select{|teacher| teacher.user_id == User.current.id &&
|
||||
(teacher.teacher_course_groups.pluck(:course_group_id).include?(group.id) || teacher.teacher_course_groups.size == 0)}.size > 0
|
||||
end
|
||||
|
||||
# 是否有切换为学生的入口
|
||||
def switch_student_role is_teacher, course, user
|
||||
is_teacher && course.course_members.where(user_id: user.id, role: %i(STUDENT)).exists?
|
||||
end
|
||||
|
||||
# 是否有切换为教师的入口
|
||||
def switch_teacher_role is_student, course, user
|
||||
is_student && course.course_members.where(user_id: user.id, role: %i(CREATOR PROFESSOR)).exists?
|
||||
end
|
||||
|
||||
# 是否有切换为助教的入口
|
||||
def switch_assistant_role is_student, course, user
|
||||
is_student && course.course_members.where(user_id: user.id, role: %i(ASSISTANT_PROFESSOR)).exists?
|
||||
end
|
||||
|
||||
# 课堂结束天数
|
||||
def course_end_date end_date
|
||||
if end_date.present?
|
||||
curr = Time.new
|
||||
date = ((Date.parse(end_date.to_s) - Date.parse(curr.to_s)).to_i)
|
||||
date > 0 ? "#{date}天后" : ""
|
||||
end
|
||||
end
|
||||
|
||||
# 课堂模块的url
|
||||
def module_url mod, course
|
||||
return nil if mod.blank? or course.blank?
|
||||
case mod.module_type
|
||||
when "announcement"
|
||||
"/courses/#{course.id}/informs"
|
||||
when "online_learning"
|
||||
"/courses/#{course.id}/online_learning"
|
||||
when "shixun_homework"
|
||||
"/courses/#{course.id}/shixun_homeworks/#{mod.id}"
|
||||
when "common_homework"
|
||||
"/courses/#{course.id}/common_homeworks/#{mod.id}"
|
||||
when "group_homework"
|
||||
"/courses/#{course.id}/group_homeworks/#{mod.id}"
|
||||
when "graduation"
|
||||
"/courses/#{course.id}/graduation_topics/#{mod.id}"
|
||||
when "exercise"
|
||||
"/courses/#{course.id}/exercises/#{mod.id}"
|
||||
when "poll"
|
||||
"/courses/#{course.id}/polls/#{mod.id}"
|
||||
when "attachment"
|
||||
"/courses/#{course.id}/files/#{mod.id}"
|
||||
when "board"
|
||||
course_board = course.course_board
|
||||
"/courses/#{course.id}/boards/#{course_board.id}"
|
||||
when "course_group"
|
||||
"/courses/#{course.id}/course_groups"
|
||||
when "statistics"
|
||||
"/courses/#{course.id}/statistics"
|
||||
when "video"
|
||||
"/courses/#{course.id}/course_videos"
|
||||
end
|
||||
end
|
||||
|
||||
# 子目录对应的url
|
||||
def category_url category, course
|
||||
case category.category_type
|
||||
when "shixun_homework"
|
||||
"/courses/#{course.id}/shixun_homework/#{category.id}"
|
||||
when "graduation"
|
||||
if category.name == "毕设选题"
|
||||
"/courses/#{course.id}/graduation_topics/#{category.course_module_id}"
|
||||
else
|
||||
"/courses/#{course.id}/graduation_tasks/#{category.course_module_id}"
|
||||
end
|
||||
when "attachment"
|
||||
"/courses/#{course.id}/file/#{category.id}"
|
||||
end
|
||||
end
|
||||
|
||||
# 子目录下的任务数
|
||||
def category_task_count course, category, user
|
||||
case category.category_type
|
||||
when "shixun_homework"
|
||||
get_homework_commons_count(course, 4, category.id)
|
||||
when "graduation"
|
||||
if category.name == "毕设选题"
|
||||
course.graduation_topics_count
|
||||
else
|
||||
course.graduation_tasks_count
|
||||
end
|
||||
when "attachment"
|
||||
get_attachment_count(course, category.id)
|
||||
end
|
||||
end
|
||||
|
||||
# 课堂模块的任务数
|
||||
def course_task_count(course, module_type)
|
||||
case module_type
|
||||
when "shixun_homework"
|
||||
get_homework_commons_count(course, 4, 0)
|
||||
when "common_homework"
|
||||
get_homework_commons_count(course, 1, 0)
|
||||
when "group_homework"
|
||||
get_homework_commons_count(course, 3, 0)
|
||||
when "graduation"
|
||||
0
|
||||
when "exercise"
|
||||
course.exercises_count
|
||||
when "poll"
|
||||
course.polls_count
|
||||
when "attachment"
|
||||
get_attachment_count(course, 0)
|
||||
when "board"
|
||||
course_board = course.course_board
|
||||
course_board.present? ? course_board.messages.size : 0
|
||||
when "course_group"
|
||||
course.course_groups_count
|
||||
when "announcement"
|
||||
course.informs.count
|
||||
when "online_learning"
|
||||
course.shixuns.count
|
||||
when "video"
|
||||
course.course_videos.count + course.live_links.count
|
||||
end
|
||||
end
|
||||
|
||||
# 当前用户可见的课堂作业,type指定作业类型, category_id指定二级目录
|
||||
def visible_homework course, user, type, category_id=0
|
||||
if user.teacher_of_course?(course)
|
||||
homeworks = course.homework_commons.where("homework_type = #{type} and course_second_category_id = #{category_id}")
|
||||
elsif user.member_of_course?(course)
|
||||
member = course.course_members.find_by(user_id: user.id, role: 4)
|
||||
if member.try(:course_group_id).to_i == 0
|
||||
homeworks = course.homework_commons.where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}'
|
||||
and unified_setting = 1 and course_second_category_id = #{category_id}")
|
||||
else
|
||||
not_homework_ids = course.homework_group_settings.where("course_group_id = #{member.try(:course_group_id)} and
|
||||
(publish_time > '#{Time.now}' or publish_time is null)").pluck(:homework_common_id)
|
||||
# not_homework_ids = not_homework_ids.blank? ? "(-1)" : "(" + not_homework_ids.map(&:homework_common_id).join(",") + ")"
|
||||
homeworks = course.homework_commons.where.not(id: not_homework_ids).where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}'
|
||||
and course_second_category_id = #{category_id}")
|
||||
end
|
||||
else
|
||||
homeworks = course.homework_commons.where("homework_type = #{type} and publish_time <= '#{Time.now}' and unified_setting = 1
|
||||
and course_second_category_id = #{category_id}")
|
||||
end
|
||||
homeworks
|
||||
end
|
||||
|
||||
# 当前用户可见的课堂试卷
|
||||
def visible_exercise course, user
|
||||
if user.teacher_of_course?(course)
|
||||
exercises = course.exercises
|
||||
elsif user.member_of_course?(course)
|
||||
member = course.course_members.find_by(user_id: user.id, role: 4)
|
||||
if member.try(:course_group_id).to_i == 0
|
||||
exercises = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1")
|
||||
else
|
||||
not_exercise_ids = course.exercise_group_settings.where("course_group_id = #{member.try(:course_group_id)} and
|
||||
(publish_time > '#{Time.now}' or publish_time is null)").pluck(:exercise_id)
|
||||
exercises = course.exercises.where.not(id: not_exercise_ids).where("publish_time <= '#{Time.now}'")
|
||||
end
|
||||
else
|
||||
exercises = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1")
|
||||
end
|
||||
exercises
|
||||
end
|
||||
|
||||
# 当前用户可见的课堂问卷
|
||||
def visible_poll course, user
|
||||
if user.teacher_of_course?(course)
|
||||
polls = course.polls
|
||||
elsif user.member_of_course?(course)
|
||||
member = course.course_members.find_by(user_id: user.id, role: 4)
|
||||
if member.try(:course_group_id).to_i == 0
|
||||
polls = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1")
|
||||
else
|
||||
not_poll_ids = course.poll_group_settings.where("course_group_id = #{member.try(:course_group_id)} and
|
||||
(publish_time > '#{Time.now}' or publish_time is null)").pluck(:poll_id)
|
||||
polls = course.polls.where.not(id: not_poll_ids).where("publish_time <= '#{Time.now}'")
|
||||
end
|
||||
else
|
||||
polls = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1")
|
||||
end
|
||||
polls
|
||||
end
|
||||
|
||||
# 当前用户可见的课堂资源,category_id指定资源的目录
|
||||
def visible_attachment course, user, category_id=0
|
||||
result = []
|
||||
course.attachments.where(course_second_category_id: category_id).each do |attachment|
|
||||
if attachment.unified_setting
|
||||
if attachment.is_public == 1 && attachment.is_publish == 1 || user == attachment.author || user.teacher_of_course?(course) || (user.member_of_course?(course) && attachment.is_publish == 1)
|
||||
result << attachment
|
||||
end
|
||||
else
|
||||
if attachment.is_public == 1 && attachment.is_publish == 1 && !user.member_of_course?(course) || user == attachment.author || user.teacher_of_course?(course)
|
||||
result << attachment
|
||||
elsif user.member_of_course?(course) && attachment.is_publish == 1
|
||||
member = course.course_members.find_by(user_id: user.id, role: 4)
|
||||
if member.try(:course_group_id).to_i == 0 && attachment.unified_setting
|
||||
result << attachment
|
||||
elsif attachment.attachment_group_settings.where("course_group_id = #{member.try(:course_group_id)} and publish_time > '#{Time.now}'").count == 0
|
||||
result << attachment
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# 获取课堂的资源数
|
||||
def get_attachment_count(course, category_id)
|
||||
category_id.to_i == 0 ? course.attachments.size : course.attachments.where(course_second_category_id: category_id).size
|
||||
end
|
||||
|
||||
# 获取课堂的作业数
|
||||
def get_homework_commons_count(course, type, category_id)
|
||||
category_id == 0 ? HomeworkCommon.where(course_id: course.id, homework_type: type).size :
|
||||
HomeworkCommon.where(course_id: course.id, homework_type: type, course_second_category_id: category_id).size
|
||||
end
|
||||
|
||||
|
||||
# 获取课堂的任务数(作业数+试卷数+问卷数)
|
||||
def get_tasks_count(course)
|
||||
course.homework_commons_count + course.exercises_count + course.polls_count
|
||||
end
|
||||
|
||||
# 当前用户可见的毕设任务
|
||||
def visible_graduation_task course, user
|
||||
if user.teacher_of_course?(course)
|
||||
tasks = course.graduation_tasks
|
||||
else
|
||||
tasks = course.graduation_tasks.where("publish_time <= '#{Time.now}'")
|
||||
end
|
||||
tasks
|
||||
end
|
||||
|
||||
# 分班情况
|
||||
def course_group_info course, user_id
|
||||
course_group_ids = course.group_course_power(user_id)
|
||||
course_groups =
|
||||
if course_group_ids.present?
|
||||
course.course_groups.where(id: course_group_ids).includes(:course_members)
|
||||
else
|
||||
course.course_groups.includes(:course_members)
|
||||
end
|
||||
group_info = []
|
||||
if !course_groups.blank?
|
||||
course_groups.each do |group|
|
||||
group_info << {course_group_id: group.id, group_group_name: group.name, count: group.course_members_count}
|
||||
end
|
||||
|
||||
none_group_count = course.students.where(course_group_id: 0).size
|
||||
group_info << {course_group_id: 0, group_group_name: "未分班", count: none_group_count} if none_group_count > 0 && !course_group_ids.present?
|
||||
end
|
||||
|
||||
return group_info
|
||||
end
|
||||
|
||||
def left_group_info course
|
||||
group_info = []
|
||||
if course.course_groups_count > 0
|
||||
none_group_count = course.students.where(course_group_id: 0).size
|
||||
group_info << {category_id: 0, category_name: "未分班", position: course.course_groups.pluck(:position).max.to_i + 1,
|
||||
category_count: none_group_count, category_type: false,
|
||||
second_category_url: "/courses/#{@course.id}/course_groups/0"}
|
||||
course.course_groups.each do |course_group|
|
||||
group_info << {category_id: course_group.id, category_name: course_group.name, position: course_group.position,
|
||||
category_count: course_group.course_members_count, category_type: false,
|
||||
second_category_url: "/courses/#{@course.id}/course_groups/#{course_group.id}"}
|
||||
end
|
||||
end
|
||||
group_info
|
||||
end
|
||||
|
||||
def last_subject_shixun course, myshixuns
|
||||
myshixun = myshixuns.sort{|x,y| y[:updated_at] <=> x[:updated_at] }.first
|
||||
return "" unless myshixun
|
||||
stage_shixun = course.course_stage_shixuns.where(shixun_id: myshixun.shixun_id).take
|
||||
progress = stage_shixun&.course_stage&.position.to_s + "-" + stage_shixun&.position.to_s + " " + myshixun.shixun&.name
|
||||
end
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module DiscussesHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module EduDatasHelper
|
||||
end
|
|
@ -1,150 +0,0 @@
|
|||
module GraduationTasksHelper
|
||||
include CoursesHelper
|
||||
# 教师评阅
|
||||
def teacher_comment task, user_id
|
||||
[{ id: 0 ,name: "未评", count: task.uncomment_count(user_id)}, {id: 1, name: "已评", count: task.comment_count(user_id)}]
|
||||
end
|
||||
|
||||
# 作品状态
|
||||
def task_status task, user_id
|
||||
[{id: 0, name: "未提交", count: task.unfinished_count(user_id)},
|
||||
{id: 1, name: "按时提交", count: task.finished_count(user_id)},
|
||||
{id: 2, name: "延时提交", count: task.delay_finished_count(user_id)}]
|
||||
end
|
||||
|
||||
# 交叉评阅
|
||||
def cross_comment task, user_id
|
||||
if task.cross_comment && task.status >= 3
|
||||
[{id: 1, name: "只看我的交叉评阅", count: task.graduation_work_comment_assignations.myself(user_id).count}]
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def task_curr_status task, course
|
||||
result = {}
|
||||
status = []
|
||||
time = ""
|
||||
|
||||
if course.try(:is_end)
|
||||
status << "已结束"
|
||||
time = course.end_date.present? ? course.end_date.strftime("%Y-%m-%d") : ""
|
||||
else
|
||||
if task.status > 1 && task.allow_late && (task.late_time.nil? || task.late_time > Time.now)
|
||||
status << "补交中"
|
||||
end
|
||||
|
||||
case task.status
|
||||
when 0
|
||||
status << "未发布"
|
||||
time = task.publish_time.present? ? "将于 #{format_time(task.publish_time)} 发布" : "创建于#{time_from_now(task.created_at)}"
|
||||
when 1
|
||||
if task.end_time && task.end_time >= Time.now
|
||||
status << "提交中"
|
||||
time = how_much_time(task.end_time)
|
||||
end
|
||||
when 2
|
||||
status << "评阅中"
|
||||
time = task.comment_time.present? ? how_much_time(task.comment_time) : course.end_date.present? ? how_much_time(course.end_date.end_of_day) : ""
|
||||
when 3
|
||||
status << "交叉评阅中"
|
||||
time = course.end_date.present? ? how_much_time(course.end_date.end_of_day) : ""
|
||||
end
|
||||
|
||||
status << "未开启补交" if (!task.allow_late && task.status != 0) #6.11 -hs 新增status不等于0
|
||||
|
||||
# 如果还在补交阶段则显示补交结束时间
|
||||
if task.status > 1 && task.allow_late && task.late_time && task.late_time > Time.now
|
||||
time = how_much_time(task.late_time)
|
||||
end
|
||||
end
|
||||
|
||||
result[:status] = status
|
||||
result[:time] = time
|
||||
result
|
||||
end
|
||||
|
||||
# 作品数统计:type: 1 已提交 0 未提交
|
||||
def grduationwork_count task, type
|
||||
works = task.graduation_works
|
||||
type == 1 ? works.select{|work| work.work_status != 0}.size : works.select{|work| work.work_status == 0}.size
|
||||
end
|
||||
|
||||
# 普通/分组 作业作品状态数组
|
||||
def graduation_work_status task, user_id, course
|
||||
status = []
|
||||
work = task.graduation_works.find_by(user_id: user_id)
|
||||
|
||||
work = work || GraduationWork.create(graduation_task_id: task.id, user_id: user_id)
|
||||
late_time = task.late_time || course.end_date
|
||||
|
||||
if course.is_end && work && work.work_status > 0
|
||||
status << "查看作品"
|
||||
elsif !course.is_end
|
||||
if task.publish_time && task.publish_time < Time.now
|
||||
# 作业未截止时
|
||||
if task.end_time > Time.now
|
||||
if task.task_type == 2 && task.base_on_project
|
||||
if work.project_id.nil? || work.project_id == 0
|
||||
status << "创建项目"
|
||||
status << "关联项目"
|
||||
elsif work.work_status == 0
|
||||
status << "取消关联"
|
||||
status << "提交作品"
|
||||
else
|
||||
status << "修改作品"
|
||||
end
|
||||
else
|
||||
if work.work_status == 0
|
||||
status << "提交作品"
|
||||
else
|
||||
status << "修改作品"
|
||||
end
|
||||
end
|
||||
|
||||
# 补交阶段
|
||||
elsif task.allow_late && (late_time.nil? || late_time > Time.now)
|
||||
if task.task_type == 2 && task.base_on_project
|
||||
if work.project_id.nil? || work.project_id == 0
|
||||
status << "创建项目"
|
||||
status << "关联项目"
|
||||
elsif work.work_status == 0
|
||||
status << "取消关联"
|
||||
status << "补交作品"
|
||||
else
|
||||
status << "补交附件"
|
||||
status << "查看作品"
|
||||
end
|
||||
else
|
||||
if work.work_status == 0
|
||||
status << "补交作品"
|
||||
else
|
||||
status << "补交附件"
|
||||
status << "查看作品"
|
||||
end
|
||||
end
|
||||
|
||||
# 匿评阶段
|
||||
elsif work.work_status != 0
|
||||
status << "查看作品"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 阶段剩余时间
|
||||
def task_left_time task
|
||||
if task.publish_time && task.publish_time < Time.now
|
||||
if task.end_time > Time.now
|
||||
status = "剩余提交时间"
|
||||
time = "#{how_much_time(task.end_time)}"
|
||||
else
|
||||
if task.allow_late && task.late_time && task.late_time >= Time.now
|
||||
status = "剩余补交时间"
|
||||
time = "#{how_much_time(task.late_time)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
{status: status, time: time}
|
||||
end
|
||||
end
|
|
@ -1,30 +0,0 @@
|
|||
module GraduationTopicsHelper
|
||||
|
||||
# 课题类型
|
||||
def topic_type
|
||||
[{id: 1, name: "设计"}, {id: 2, name: "论文"}, {id: 3, name: "创作"}]
|
||||
end
|
||||
|
||||
# 课程来源
|
||||
def topic_source
|
||||
[{id: 1, name: "生产/社会实际"}, {id: 2, name:"结合科研"}, {id: 3, name: "其它"}]
|
||||
end
|
||||
|
||||
# 课题性质1
|
||||
def topic_property_first
|
||||
[{id: 1, name: "真题"}, {id: 2, name:"模拟题"}]
|
||||
end
|
||||
|
||||
# 课题性质2
|
||||
def topic_property_second
|
||||
[{id: 1, name: "纵向课题"}, {id: 2, name:"横向课题"}, {id: 3, name: "自选"}]
|
||||
end
|
||||
|
||||
# 课题重复
|
||||
def topic_repeat
|
||||
[{id: 1, name: "新题"}, {id: 2, name:"往届题,有新要求"}, {id: 3, name: "往届题,无新要求"}]
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
module GraduationWorksHelper
|
||||
include GraduationTasksHelper
|
||||
|
||||
# 作品最终成绩
|
||||
# 参数: work作品, current_user用户,course_identity用户在课堂的身份
|
||||
def work_final_score work, current_user, course_identity
|
||||
work_score =
|
||||
if work.work_score.nil?
|
||||
"--"
|
||||
else
|
||||
if work.check_score_power? current_user, course_identity
|
||||
format("%.1f", work.work_score < 0 ? 0 : work.work_score.round(1))
|
||||
else
|
||||
"**"
|
||||
end
|
||||
end
|
||||
# work_score 最终成绩; late_penalty 迟交扣分; final_score 最终评分
|
||||
{username: work.user.full_name, login: work.user.login, work_score: work_score, final_score: work.final_score}
|
||||
end
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module HackUserLastestCodesHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module HacksHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module TrustieHacksHelper
|
||||
end
|
|
@ -1,69 +0,0 @@
|
|||
module Weapps::CoursesHelper
|
||||
require 'chinese_pinyin'
|
||||
|
||||
def teacher_list teachers, user_course_identity
|
||||
data = []
|
||||
teachers.each do |teacher|
|
||||
if teacher.user.present?
|
||||
teacher_user = teacher.user
|
||||
name = teacher_user.real_name
|
||||
role = teacher.role == "CREATOR" ? "管理员" : teacher.role == "PROFESSOR" ? "教师" : "助教"
|
||||
member_roles = user_course_identity < Course::ASSISTANT_PROFESSOR ? teacher_user.course_role(teacher.course) : []
|
||||
item = {name: name, course_member_id: teacher.id, login: teacher_user.login, user_id: teacher.user_id, role: role,
|
||||
school: teacher_user.school_name, image_url: url_to_avatar(teacher_user), member_roles: member_roles}
|
||||
pinyin = Pinyin.t(name.strip, splitter: '')
|
||||
first_char = pinyin[0]
|
||||
letter = first_letter first_char
|
||||
if data.pluck(:letter).include?(letter)
|
||||
data.select{|a|a[:letter]==letter}.first[:items] << item
|
||||
else
|
||||
data << {letter: letter, items: [item]}
|
||||
end
|
||||
end
|
||||
end
|
||||
# data = data.sort do |a, b|
|
||||
# [a[:letter]] <=> [b[:letter]]
|
||||
# end
|
||||
# data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后
|
||||
return data
|
||||
end
|
||||
|
||||
|
||||
def student_list students, excellent, user_course_identity
|
||||
data = []
|
||||
students.each do |student|
|
||||
if student.user.present?
|
||||
student_user = student.user
|
||||
name = student_user.real_name
|
||||
phone = excellent ? "" : student_user.hidden_phone
|
||||
member_roles = user_course_identity < Course::ASSISTANT_PROFESSOR ? student_user.course_role(student.course) : []
|
||||
item = {name: name, course_member_id: student.id, login: student_user.login, user_id: student.user_id,
|
||||
student_id: student_user.student_id, image_url: url_to_avatar(student_user), phone: phone, member_roles: member_roles}
|
||||
pinyin = Pinyin.t(name.strip, splitter: '')
|
||||
first_char = pinyin[0]
|
||||
letter = first_letter first_char
|
||||
if data.pluck(:letter).include?(letter)
|
||||
data.select{|a|a[:letter]==letter}.first[:items] << item
|
||||
else
|
||||
data << {letter: letter, items: [item]}
|
||||
end
|
||||
end
|
||||
end
|
||||
# data = data.sort do |a, b|
|
||||
# [a[:letter]] <=> [b[:letter]]
|
||||
# end
|
||||
# data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后
|
||||
return data
|
||||
end
|
||||
|
||||
def first_letter char
|
||||
if char.ord >= 97 && char.ord <= 122
|
||||
letter = (char.ord - 32).chr.to_s
|
||||
elsif char.ord >= 65 && char.ord <= 90
|
||||
letter = char
|
||||
else
|
||||
letter = '#'
|
||||
end
|
||||
letter
|
||||
end
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
class Admins::ImportCourseMemberExcel < BaseImportXlsx
|
||||
Data = Struct.new(:student_id, :name, :course_id, :role, :course_group_name, :school_id)
|
||||
|
||||
def read_each(&block)
|
||||
sheet.each_row_streaming(pad_cells: true, offset: 1) do |row|
|
||||
data = row.map(&method(:cell_value))[0..5]
|
||||
block.call Data.new(*data)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_sheet_valid!
|
||||
raise_import_error('请按照模板格式导入') if sheet.row(1).size != 6
|
||||
end
|
||||
|
||||
def cell_value(obj)
|
||||
obj&.cell_value&.to_s&.strip
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# 批量发布视频 消息任务
|
||||
class BatchPublishVideoNotifyJob < ApplicationJob
|
||||
queue_as :notify
|
||||
|
||||
def perform(user_id, video_ids)
|
||||
user = User.find_by(id: user_id)
|
||||
return if user.blank?
|
||||
|
||||
attrs = %i[user_id trigger_user_id container_id container_type tiding_type status created_at updated_at]
|
||||
|
||||
same_attrs = {
|
||||
user_id: 1,
|
||||
trigger_user_id: user.id,
|
||||
container_type: 'Video',
|
||||
tiding_type: 'Apply', status: 0
|
||||
}
|
||||
Tiding.bulk_insert(*attrs) do |worker|
|
||||
user.videos.where(id: video_ids).each do |video|
|
||||
worker.add same_attrs.merge(container_id: video.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,67 +0,0 @@
|
|||
# 学生加入课堂时创建相关任务作品
|
||||
class CourseAddStudentCreateWorksJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform(course_id, student_ids)
|
||||
course = Course.find_by(id: course_id)
|
||||
return if course.blank?
|
||||
|
||||
# 如果之前存在相关作品,则更新is_delete字段
|
||||
student_works = StudentWork.joins(:homework_common).where(user_id: student_ids, homework_commons: {course_id: course.id})
|
||||
student_works.update_all(is_delete: 0)
|
||||
|
||||
exercise_users = ExerciseUser.joins(:exercise).where(user_id: student_ids, exercises: {course_id: course.id})
|
||||
exercise_users.update_all(is_delete: 0)
|
||||
|
||||
poll_users = PollUser.joins(:poll).where(user_id: student_ids, polls: {course_id: course.id})
|
||||
poll_users.update_all(is_delete: 0)
|
||||
|
||||
graduation_works = course.graduation_works.where(user_id: student_ids)
|
||||
graduation_works.update_all(is_delete: 0)
|
||||
|
||||
attrs = %i[homework_common_id user_id created_at updated_at]
|
||||
|
||||
StudentWork.bulk_insert(*attrs) do |worker|
|
||||
student_ids.each do |user_id|
|
||||
same_attrs = {user_id: user_id}
|
||||
course.homework_commons.where(homework_type: %i[normal group practice]).each do |homework|
|
||||
next if StudentWork.where(user_id: user_id, homework_common_id: homework.id).any?
|
||||
worker.add same_attrs.merge(homework_common_id: homework.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
attrs = %i[exercise_id user_id created_at updated_at]
|
||||
ExerciseUser.bulk_insert(*attrs) do |worker|
|
||||
student_ids.each do |user_id|
|
||||
same_attrs = {user_id: user_id}
|
||||
course.exercises.each do |exercise|
|
||||
next if ExerciseUser.where(user_id: user_id, exercise_id: exercise.id).any?
|
||||
worker.add same_attrs.merge(exercise_id: exercise.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
attrs = %i[poll_id user_id created_at updated_at]
|
||||
PollUser.bulk_insert(*attrs) do |worker|
|
||||
student_ids.each do |user_id|
|
||||
same_attrs = {user_id: user_id}
|
||||
course.polls.each do |poll|
|
||||
next if PollUser.where(user_id: user_id, poll_id: poll.id).any?
|
||||
worker.add same_attrs.merge(poll_id: poll.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
attrs = %i[graduation_task_id user_id course_id created_at updated_at]
|
||||
GraduationWork.bulk_insert(*attrs) do |worker|
|
||||
student_ids.each do |user_id|
|
||||
same_attrs = {user_id: user_id, course_id: course.id}
|
||||
course.graduation_tasks.each do |task|
|
||||
next if GraduationWork.where(user_id: user_id, graduation_task_id: task.id).any?
|
||||
worker.add same_attrs.merge(graduation_task_id: task.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,19 +0,0 @@
|
|||
class CourseDeleteStudentDeleteWorksJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform(course_id, student_ids)
|
||||
course = Course.find_by(id: course_id)
|
||||
return if course.blank?
|
||||
|
||||
student_works = StudentWork.joins(:homework_common).where(user_id: student_ids, homework_commons: {course_id: course.id})
|
||||
student_works.update_all(is_delete: 1)
|
||||
|
||||
exercise_users = ExerciseUser.joins(:exercise).where(user_id: student_ids, exercises: {course_id: course.id})
|
||||
exercise_users.update_all(is_delete: 1)
|
||||
|
||||
poll_users = PollUser.joins(:poll).where(user_id: student_ids, polls: {course_id: course.id})
|
||||
poll_users.update_all(is_delete: 1)
|
||||
|
||||
course.graduation_works.where(user_id: student_ids).update_all(is_delete: 1)
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
# 删除课堂用户
|
||||
class CourseDeleteStudentNotifyJob < ApplicationJob
|
||||
queue_as :notify
|
||||
|
||||
def perform(course_id, student_ids, trigger_user_id)
|
||||
course = Course.find_by(id: course_id)
|
||||
return if course.blank?
|
||||
|
||||
attrs = %i[user_id trigger_user_id container_id container_type belong_container_id
|
||||
belong_container_type tiding_type created_at updated_at]
|
||||
|
||||
same_attrs = {
|
||||
trigger_user_id: trigger_user_id, container_id: course.id, container_type: 'DeleteCourseMember',
|
||||
belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'System'
|
||||
}
|
||||
Tiding.bulk_insert(*attrs) do |worker|
|
||||
student_ids.each do |user_id|
|
||||
worker.add same_attrs.merge(user_id: user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
class CreateDiffRecordJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform(user_id, obj_id, obj_klass, column_name, before, after)
|
||||
user = User.find_by(id: user_id)
|
||||
obj = obj_klass.constantize.find_by(id: obj_id)
|
||||
|
||||
return if user.blank? || obj.blank?
|
||||
|
||||
CreateDiffRecordService.call(user, obj, column_name, before, after)
|
||||
end
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
# 删除部门 消息通知
|
||||
class DeleteDepartmentNotifyJob < ApplicationJob
|
||||
queue_as :notify
|
||||
|
||||
def perform(department_id, operator_id, user_ids)
|
||||
department = Department.unscoped.find_by(id: department_id)
|
||||
return if department.blank? || user_ids.blank?
|
||||
|
||||
attrs = %i[ user_id trigger_user_id container_id container_type tiding_type status created_at updated_at]
|
||||
|
||||
same_attrs = {
|
||||
trigger_user_id: operator_id, container_id: department.id, container_type: 'Department',
|
||||
status: 4, tiding_type: 'System'
|
||||
}
|
||||
Tiding.bulk_insert(*attrs) do |worker|
|
||||
user_ids.each do |user_id|
|
||||
worker.add same_attrs.merge(user_id: user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,44 +0,0 @@
|
|||
# 试卷发布 消息通知
|
||||
class ExercisePublishNotifyJob < ApplicationJob
|
||||
queue_as :notify
|
||||
|
||||
def perform(exercise_id, group_ids)
|
||||
exercise = Exercise.find_by(id: exercise_id)
|
||||
return if exercise.blank?
|
||||
user = exercise.user
|
||||
course = exercise.course
|
||||
|
||||
if group_ids.present?
|
||||
students = course.students.where(course_group_id: group_ids)
|
||||
subquery = course.teacher_course_groups.where(course_group_id: group_ids).select(:course_member_id)
|
||||
teachers = course.teachers.where(id: subquery)
|
||||
else
|
||||
students = course.students
|
||||
teachers = course.teachers
|
||||
end
|
||||
|
||||
attrs = %i[
|
||||
user_id trigger_user_id container_id container_type parent_container_id parent_container_type
|
||||
belong_container_id belong_container_type viewed tiding_type created_at updated_at
|
||||
]
|
||||
|
||||
same_attrs = {
|
||||
trigger_user_id: user.id, container_id: exercise.id, container_type: 'Exercise',
|
||||
parent_container_id: exercise.id, parent_container_type: 'ExercisePublish',
|
||||
belong_container_id: exercise.course_id, belong_container_type: 'Course',
|
||||
viewed: 0, tiding_type: 'Exercise'
|
||||
}
|
||||
Tiding.bulk_insert(*attrs) do |worker|
|
||||
teacher_ids = teachers.pluck(:user_id)
|
||||
unless exercise.tidings.exists?(parent_container_type: 'ExercisePublish', user_id: teacher_ids)
|
||||
teacher_ids.each do |user_id|
|
||||
worker.add same_attrs.merge(user_id: user_id)
|
||||
end
|
||||
end
|
||||
|
||||
students.pluck(:user_id).each do |user_id|
|
||||
worker.add same_attrs.merge(user_id: user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# 获取阿里云视频信息
|
||||
class GetAliyunVideoInfoJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform(vod_video_id)
|
||||
video = Video.find_by(uuid: vod_video_id)
|
||||
return if video.blank? || video.vod_uploading?
|
||||
|
||||
result = AliyunVod::Service.get_play_info(video.uuid)
|
||||
cover_url = result.dig('VideoBase', 'CoverURL')
|
||||
file_url = (result.dig('PlayInfoList', 'PlayInfo') || []).first&.[]('PlayURL')
|
||||
|
||||
video.cover_url = cover_url if cover_url.present? && video.cover_url.blank?
|
||||
video.file_url = file_url if file_url.present?
|
||||
video.save!
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
# 毕设任务的交叉评阅分配
|
||||
class GraduationTaskCrossCommentJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform(graduation_task_id)
|
||||
task = GraduationTask.find_by(id: graduation_task_id)
|
||||
return if task.blank?
|
||||
|
||||
task.graduation_task_group_assignations.includes(:graduation_group, :graduation_work).each do |assignation|
|
||||
graduation_group = assignation.graduation_group
|
||||
work = assignation.graduation_work
|
||||
if graduation_group.present? && work.present?
|
||||
member_ids = graduation_group.course_members.pluck(:user_id).uniq
|
||||
member_ids.each do |user_id|
|
||||
unless work.graduation_work_comment_assignations.exists?(user_id: user_id)
|
||||
work.graduation_work_comment_assignations << GraduationWorkCommentAssignation.new(user_id: user_id, graduation_task_id: task.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
# 任务发布 消息通知
|
||||
class GraduationTaskPublishNotifyJob < ApplicationJob
|
||||
queue_as :notify
|
||||
|
||||
def perform(graduation_task_id)
|
||||
task = GraduationTask.find_by(id: graduation_task_id)
|
||||
return if task.blank?
|
||||
course = task.course
|
||||
return if course.blank?
|
||||
|
||||
attrs = %i[
|
||||
user_id trigger_user_id container_id container_type parent_container_id parent_container_type
|
||||
belong_container_id belong_container_type viewed tiding_type created_at updated_at
|
||||
]
|
||||
|
||||
same_attrs = {
|
||||
trigger_user_id: task.user_id, container_id: task.id, container_type: 'GraduationTask',
|
||||
parent_container_id: task.id, parent_container_type: 'TaskPublish',
|
||||
belong_container_id: task.course_id, belong_container_type: 'Course',
|
||||
viewed: 0, tiding_type: 'GraduationTask'
|
||||
}
|
||||
Tiding.bulk_insert(*attrs) do |worker|
|
||||
course.course_members.pluck(:user_id).uniq.each do |user_id|
|
||||
worker.add same_attrs.merge(user_id: user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,33 +0,0 @@
|
|||
class ResubmitStudentWorkNotifyJob < ApplicationJob
|
||||
queue_as :notify
|
||||
|
||||
def perform(homework_id, student_ids)
|
||||
homework = HomeworkCommon.find_by(id: homework_id)
|
||||
return if homework.blank? || student_ids.blank?
|
||||
course = homework.course
|
||||
|
||||
attrs = %i[user_id trigger_user_id container_id container_type parent_container_id parent_container_type
|
||||
belong_container_id belong_container_type tiding_type viewed created_at updated_at]
|
||||
|
||||
same_attrs = {
|
||||
container_type: 'ResubmitStudentWork', parent_container_id: homework.id, parent_container_type: 'HomeworkCommon',
|
||||
belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'HomeworkCommon', viewed: 0
|
||||
}
|
||||
Tiding.bulk_insert(*attrs) do |worker|
|
||||
student_ids.each do |user_id|
|
||||
next unless User.exists?(id: user_id)
|
||||
|
||||
work = homework.student_works.find_by(user_id: user_id)
|
||||
next if work.blank?
|
||||
score_user_ids = work.student_works_scores.where.not(score: nil).where(reviewer_role: [1, 2]).pluck(user_id).uniq
|
||||
next if score_user_ids.blank?
|
||||
|
||||
attrs = same_attrs.merge(trigger_user_id: user_id, container_id: work.id)
|
||||
|
||||
score_user_ids.each do |user_id|
|
||||
worker.add attrs.merge(user_id: user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -44,7 +44,7 @@ class Laboratory < ApplicationRecord
|
|||
|
||||
def site
|
||||
rails_env = EduSetting.get('rails_env')
|
||||
suffix = rails_env && rails_env != 'production' ? ".#{rails_env}.trustie.net" : '.trustie.net'
|
||||
suffix = rails_env && rails_env != 'production' ? ".#{rails_env}.gitlink.org.cn" : '.gitlink.org.cn'
|
||||
|
||||
identifier ? "#{identifier}#{suffix}" : ''
|
||||
end
|
||||
|
@ -74,74 +74,6 @@ class Laboratory < ApplicationRecord
|
|||
RequestStore.store[:current_laboratory] ||= User.anonymous
|
||||
end
|
||||
|
||||
def shixuns
|
||||
if main_site?
|
||||
not_shixun_ids = Shixun.joins(:laboratory_shixuns).where("laboratory_shixuns.laboratory_id != #{Laboratory.current.id}")
|
||||
Shixun.where.not(id: not_shixun_ids.pluck(:shixun_id))
|
||||
elsif sync_shixun
|
||||
laboratory_shixun_ids = laboratory_shixuns.pluck(:shixun_id)
|
||||
school_shixun_ids = Shixun.joins("join user_extensions on shixuns.user_id=user_extensions.user_id").where(user_extensions: { school_id: school_id }).pluck(:id)
|
||||
shixun_ids = laboratory_shixun_ids + school_shixun_ids
|
||||
Shixun.where(id: shixun_ids.uniq)
|
||||
else
|
||||
Shixun.joins(:laboratory_shixuns).where(laboratory_shixuns: { laboratory_id: id })
|
||||
end
|
||||
end
|
||||
|
||||
def subjects
|
||||
if main_site?
|
||||
not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{Laboratory.current.id}")
|
||||
Subject.where.not(id: not_subject_ids.pluck(:subject_id))
|
||||
elsif sync_subject
|
||||
laboratory_subject_ids = laboratory_subjects.pluck(:subject_id)
|
||||
school_subject_ids = Subject.joins("join user_extensions on subjects.user_id=user_extensions.user_id").where(user_extensions: { school_id: school_id }).pluck(:id)
|
||||
subject_ids = laboratory_subject_ids + school_subject_ids
|
||||
Subject.where(id: subject_ids.uniq)
|
||||
else
|
||||
Subject.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: id })
|
||||
end
|
||||
end
|
||||
|
||||
def all_courses
|
||||
main_site? || !sync_course ? courses : courses.or(Course.where(school_id: school_id))
|
||||
end
|
||||
|
||||
def shixun_repertoires
|
||||
where_sql = ShixunTagRepertoire.where("shixun_tag_repertoires.tag_repertoire_id = tag_repertoires.id")
|
||||
|
||||
# 云上实验室过滤
|
||||
unless main_site?
|
||||
where_sql = where_sql.joins("JOIN laboratory_shixuns ls ON ls.shixun_id = shixun_tag_repertoires.shixun_id "\
|
||||
"AND ls.laboratory_id = #{id}")
|
||||
end
|
||||
where_sql = where_sql.select('1').to_sql
|
||||
tags = TagRepertoire.where("EXISTS(#{where_sql})").distinct.includes(sub_repertoire: :repertoire)
|
||||
|
||||
tags_map = tags.group_by(&:sub_repertoire)
|
||||
sub_reps_map = tags_map.keys.group_by(&:repertoire)
|
||||
|
||||
sub_reps_map.keys.sort_by(&:updated_at).reverse.map do |repertoire|
|
||||
repertoire_hash = repertoire.as_json(only: %i[id name])
|
||||
repertoire_hash[:sub_repertoires] =
|
||||
sub_reps_map[repertoire].sort_by(&:updated_at).reverse.map do |sub_repertoire|
|
||||
sub_repertoire_hash = sub_repertoire.as_json(only: %i[id name])
|
||||
sub_repertoire_hash[:tags] = tags_map[sub_repertoire].sort_by(&:updated_at).reverse.map { |tag| tag.as_json(only: %i[id name]) }
|
||||
sub_repertoire_hash
|
||||
end
|
||||
repertoire_hash
|
||||
end
|
||||
end
|
||||
|
||||
def subject_repertoires
|
||||
exist_sql = Subject.where('subjects.repertoire_id = repertoires.id')
|
||||
|
||||
unless main_site?
|
||||
exist_sql = exist_sql.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: id })
|
||||
end
|
||||
|
||||
Repertoire.where("EXISTS(#{exist_sql.select('1').to_sql})").order(updated_at: :desc).distinct
|
||||
end
|
||||
|
||||
# 是否为主站
|
||||
def main_site?
|
||||
id == 1
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer default("0"), not null
|
||||
# action :string(30) default(""), not null
|
||||
# value :string(40) default(""), not null
|
||||
# created_on :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_tokens_on_user_id (user_id)
|
||||
# tokens_value (value) UNIQUE
|
||||
#
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer default("0"), not null
|
||||
# action :string(30) default(""), not null
|
||||
# value :string(40) default(""), not null
|
||||
# created_on :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_tokens_on_user_id (user_id)
|
||||
# tokens_value (value) UNIQUE
|
||||
#
|
||||
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
|
@ -105,7 +105,7 @@ class Token < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def self.generate_token_value
|
||||
Educoder::Utils.random_hex(20)
|
||||
Gitlink::Utils.random_hex(20)
|
||||
end
|
||||
|
||||
def self.delete_user_all_tokens(user)
|
||||
|
|
|
@ -690,7 +690,7 @@ class User < Owner
|
|||
end
|
||||
|
||||
def self.generate_salt
|
||||
Educoder::Utils.random_hex(16)
|
||||
Gitlink::Utils.random_hex(16)
|
||||
end
|
||||
|
||||
# 全部已认证
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
class Admins::CourseListQuery < ApplicationQuery
|
||||
include CustomSortable
|
||||
|
||||
attr_reader :params
|
||||
|
||||
sort_columns :created_at, default_by: :created_at, default_direction: :desc
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
course_lists = CourseList.all
|
||||
|
||||
# 关键字模糊查询
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
search_type = params[:search_type] || "0"
|
||||
case search_type
|
||||
when "0"
|
||||
course_lists = course_lists.joins(:user)
|
||||
.where('CONCAT(lastname, firstname) like :keyword OR users.nickname like :keyword', keyword: "%#{keyword}%")
|
||||
when "1"
|
||||
course_lists = course_lists.where('name like :keyword', keyword: "%#{keyword}%")
|
||||
end
|
||||
end
|
||||
|
||||
custom_sort(course_lists, params[:sort_by], params[:sort_direction])
|
||||
end
|
||||
end
|
|
@ -1,44 +0,0 @@
|
|||
class Admins::CourseQuery < ApplicationQuery
|
||||
include CustomSortable
|
||||
|
||||
attr_reader :params
|
||||
|
||||
sort_columns :created_at, default_by: :created_at, default_direction: :desc, default_table: 'courses'
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
courses = Course.all
|
||||
|
||||
courses = courses.where(id: params[:id]) if params[:id].present?
|
||||
|
||||
# 状态过滤
|
||||
status =
|
||||
case params[:status].to_s.strip
|
||||
when 'processing' then 0
|
||||
when 'ended' then 1
|
||||
end
|
||||
courses = courses.where(is_end: status) if status
|
||||
|
||||
# 单位
|
||||
if params[:school_id].present?
|
||||
courses = courses.where(school_id: params[:school_id])
|
||||
end
|
||||
|
||||
# 首页展示
|
||||
if params[:homepage_show].present? && params[:homepage_show].to_s == 'true'
|
||||
courses = courses.where(homepage_show: true)
|
||||
end
|
||||
|
||||
# 关键字
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword
|
||||
sql = 'CONCAT(lastname, firstname) LIKE :keyword OR users.nickname LIKE :keyword OR courses.name LIKE :keyword OR course_lists.name LIKE :keyword'
|
||||
courses = courses.joins(:teacher, :course_list).where(sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
custom_sort(courses, params[:sort_by], params[:sort_direction])
|
||||
end
|
||||
end
|
|
@ -1,25 +0,0 @@
|
|||
class Admins::DepartmentApplyQuery < ApplicationQuery
|
||||
include CustomSortable
|
||||
|
||||
attr_reader :params
|
||||
|
||||
sort_columns :created_at, default_by: :created_at, default_direction: :desc
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
status = params[:status]
|
||||
|
||||
applies = ApplyAddDepartment.where(status: status) if status.present?
|
||||
|
||||
# 关键字模糊查询
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
applies = applies.where('name LIKE :keyword', keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
custom_sort(applies, params[:sort_by], params[:sort_direction])
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
class Admins::DepartmentQuery < ApplicationQuery
|
||||
include CustomSortable
|
||||
|
||||
attr_reader :params
|
||||
|
||||
sort_columns :created_at, default_by: :created_at, default_direction: :desc
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
departments = Department.where(is_auth: true).without_deleted
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
departments = departments.joins(:school)
|
||||
.where('schools.name LIKE :keyword OR departments.name LIKE :keyword', keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
if params[:with_member].to_s == 'true'
|
||||
subquery = DepartmentMember.where('department_id = departments.id').select('1 AS one').to_sql
|
||||
departments = departments.where("EXISTS(#{subquery})")
|
||||
end
|
||||
|
||||
if params[:with_identifier].to_s == 'true'
|
||||
departments = departments.where.not(identifier: nil).where.not(identifier: '')
|
||||
end
|
||||
|
||||
custom_sort(departments, params[:sort_by], params[:sort_direction])
|
||||
end
|
||||
end
|
|
@ -1,36 +0,0 @@
|
|||
class Admins::LaboratoryShixunQuery < ApplicationQuery
|
||||
attr_reader :laboratory, :params
|
||||
|
||||
def initialize(laboratory, params)
|
||||
@laboratory = laboratory
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
laboratory_shixuns = laboratory.laboratory_shixuns.joins(:shixun)
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
like_sql = 'shixuns.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword'
|
||||
laboratory_shixuns = laboratory_shixuns.joins(shixun: :user).where(like_sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
# 实训状态
|
||||
laboratory_shixuns = laboratory_shixuns.where(shixuns: { status: params[:status] }) if params[:status].present?
|
||||
|
||||
# 技术平台
|
||||
if params[:tag_id].present?
|
||||
laboratory_shixuns = laboratory_shixuns.joins(shixun: :shixun_mirror_repositories)
|
||||
.where(shixun_mirror_repositories: { mirror_repository_id: params[:tag_id] })
|
||||
end
|
||||
|
||||
# 首页展示、单位自建
|
||||
%i[homepage ownership].each do |column|
|
||||
if params[column].present? && params[column].to_s == 'true'
|
||||
laboratory_shixuns = laboratory_shixuns.where(column => true)
|
||||
end
|
||||
end
|
||||
|
||||
laboratory_shixuns
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
class Admins::SchoolQuery < ApplicationQuery
|
||||
include CustomSortable
|
||||
|
||||
attr_reader :params
|
||||
|
||||
sort_columns :users_count, :created_at, default_by: :created_at, default_direction: :desc
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
schools = School.all
|
||||
|
||||
keyword = strip_param(:keyword)
|
||||
Rails.logger.info("###########{keyword}")
|
||||
if keyword
|
||||
schools = schools.where('schools.name LIKE ?', "%#{keyword}%")
|
||||
end
|
||||
schools = schools.left_joins(:user_extensions).select('schools.*, IFNULL(count(user_extensions.user_id),0) users_count').group('schools.id')
|
||||
custom_sort schools, params[:sort_by], params[:sort_direction]
|
||||
end
|
||||
end
|
|
@ -1,49 +0,0 @@
|
|||
class Admins::SubjectQuery < ApplicationQuery
|
||||
include CustomSortable
|
||||
|
||||
attr_reader :params
|
||||
|
||||
sort_columns :created_at, default_by: :created_at, default_direction: :desc, default_table: 'subjects'
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
subjects = Subject.all
|
||||
|
||||
subjects = subjects.where(id: params[:id]) if params[:id].present?
|
||||
|
||||
# 状态过滤
|
||||
status =
|
||||
case params[:status].to_s.strip
|
||||
when "editing" then {status: 0}
|
||||
when "applying" then {status: 2, public: [0, 1]}
|
||||
when "pending" then {public: 1}
|
||||
when "published" then {public: 2}
|
||||
end
|
||||
|
||||
subjects = subjects.where(status) if status
|
||||
|
||||
# 创建者单位
|
||||
if params[:school_id].present?
|
||||
subjects = subjects.joins(user: :user_extension).where(user_extensions: { school_id: params[:school_id] })
|
||||
end
|
||||
|
||||
# 首页展示、金课
|
||||
%i[homepage_show excellent].each do |column|
|
||||
if params[column].present? && params[column].to_s == 'true'
|
||||
subjects = subjects.where(column => true)
|
||||
end
|
||||
end
|
||||
|
||||
# 关键字
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword
|
||||
sql = 'CONCAT(lastname, firstname) LIKE :keyword OR users.nickname LIKE :keyword OR subjects.name LIKE :keyword'
|
||||
subjects = subjects.joins(:user).where(sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
custom_sort(subjects, params[:sort_by], params[:sort_direction])
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
class Users::VideoQuery < ApplicationQuery
|
||||
include CustomSortable
|
||||
|
||||
sort_columns :published_at, :title, default_by: :published_at, default_direction: :desc
|
||||
|
||||
attr_reader :user, :params
|
||||
|
||||
def initialize(user, params)
|
||||
@user = user
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
videos = user.videos
|
||||
|
||||
videos =
|
||||
case params[:status]
|
||||
when 'published' then videos.published
|
||||
when 'processing' then videos.processing
|
||||
else videos.published
|
||||
end
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
videos = videos.where('title LIKE ?', "%#{keyword}%") if keyword.present?
|
||||
|
||||
custom_sort(videos, params[:sort_by], params[:sort_direction])
|
||||
end
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
class Weapps::SearchQuery < ApplicationQuery
|
||||
include ElasticsearchAble
|
||||
|
||||
attr_reader :params
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
modal_name.search(keyword, search_options)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def search_options
|
||||
hash = {
|
||||
fields: [:name],
|
||||
page: page,
|
||||
per_page: per_page
|
||||
}
|
||||
hash.merge(where: { status: 2 }) if modal_name == Shixun
|
||||
|
||||
hash
|
||||
end
|
||||
|
||||
def modal_name
|
||||
@_modal_name ||= begin
|
||||
case params[:type].to_s
|
||||
when 'subject' then Subject
|
||||
when 'shixun' then Shixun
|
||||
when 'course' then Course
|
||||
else Subject
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
class Weapps::SubjectQuery < ApplicationQuery
|
||||
include CustomSortable
|
||||
attr_reader :params
|
||||
|
||||
def initialize(current_laboratory, params)
|
||||
@current_laboratory = current_laboratory
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
subjects = @current_laboratory.subjects.unhidden.publiced.show_moblied
|
||||
|
||||
# 课程体系的过滤
|
||||
if params[:sub_discipline_id].present?
|
||||
subjects = subjects.joins(:sub_disciplines).where(sub_disciplines: {id: params[:sub_discipline_id]})
|
||||
elsif params[:discipline_id].present?
|
||||
subjects = subjects.joins(:sub_disciplines).where(sub_disciplines: {discipline_id: params[:discipline_id]})
|
||||
else
|
||||
subjects = subjects.joins(:sub_discipline_containers).where(sub_discipline_containers: {container_type: "Subject"})
|
||||
end
|
||||
|
||||
subjects = subjects.left_joins(:shixuns).select('subjects.id, subjects.name, subjects.excellent, subjects.stages_count, subjects.status, subjects.homepage_show,
|
||||
subjects.shixuns_count, subjects.updated_at, IFNULL(sum(shixuns.myshixuns_count), 0) myshixuns_count')
|
||||
.group('subjects.id').order("subjects.homepage_show #{sort_type}, #{order_type} #{sort_type}")
|
||||
subjects
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order_type
|
||||
Subject.column_names.include?(params[:order]) ? params[:order] : 'updated_at'
|
||||
end
|
||||
|
||||
def sort_type
|
||||
%w(desc asc).include?(params[:sort]) ? params[:sort] : "desc"
|
||||
end
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
class Admins::AddDepartmentMemberService < ApplicationService
|
||||
|
||||
attr_reader :department, :params
|
||||
|
||||
def initialize(department, params)
|
||||
@department = department
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
columns = %i[]
|
||||
DepartmentMember.bulk_insert(*columns) do |worker|
|
||||
Array.wrap(params[:user_ids]).compact.each do |user_id|
|
||||
next if department.department_members.exists?(user_id: user_id)
|
||||
|
||||
worker.add(department_id: department.id, user_id: user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,89 +0,0 @@
|
|||
class Admins::CheckShixunMirrorsService < ApplicationService
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
def call
|
||||
bridge_images
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
check_sync_mirrors!
|
||||
|
||||
check_mirrors!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mirrors
|
||||
bridge_images['images']
|
||||
end
|
||||
|
||||
def sync_mirrors
|
||||
bridge_images['imagesNotSync']
|
||||
end
|
||||
|
||||
def check_mirrors!
|
||||
return if mirrors.blank?
|
||||
image_names = []
|
||||
|
||||
mirrors.each do |data|
|
||||
mirror = JSON.parse(data)
|
||||
|
||||
name_repository = MirrorRepository.find_by(name: mirror['imageName'])
|
||||
id_repository = MirrorRepository.find_by(mirrorID: mirror['imageID'])
|
||||
|
||||
image_names << mirror['imageName']
|
||||
|
||||
if name_repository.blank? && id_repository.present? # 镜像名称被修改
|
||||
id_repository.update_column(:status, 2)
|
||||
MirrorOperationRecord.create!(mirror_repository_id: id_repository.id, mirror_id: mirror['imageID'],
|
||||
mirror_name: mirror['imageName'], status: 2, user_id: -1)
|
||||
elsif name_repository.blank? # 镜像不存在、创建镜像
|
||||
new_repository = MirrorRepository.create!(mirrorID: mirror['imageID'], name: mirror['imageName'])
|
||||
MirrorOperationRecord.create!(mirror_repository_id: new_repository.id, mirror_id: mirror['imageID'],
|
||||
mirror_name: mirror['imageName'], status: 0, user_id: -1)
|
||||
elsif name_repository.mirrorID != mirror['imageID'] # 镜像ID被修改
|
||||
name_repository.update_column(:status, 2)
|
||||
MirrorOperationRecord.create!(mirror_repository_id: name_repository.id, mirror_id: mirror['imageID'],
|
||||
mirror_name: mirror['imageName'], status: 1, user_id: -1)
|
||||
end
|
||||
end
|
||||
|
||||
# 判断中间层镜像是否被删除
|
||||
MirrorRepository.find_each do |mirror|
|
||||
next if mirror&.name.blank? || image_names.index(mirror.name)
|
||||
|
||||
mirror.update_column(:status, 4)
|
||||
MirrorOperationRecord.create!(mirror_repository_id: mirror.id, mirror_id: mirror&.mirrorID,
|
||||
mirror_name: mirror.name, status: 3, user_id: -1)
|
||||
end
|
||||
end
|
||||
|
||||
def check_sync_mirrors!
|
||||
return if sync_mirrors.blank?
|
||||
|
||||
sync_mirrors.each do |data|
|
||||
mirror = JSON.parse(data)
|
||||
|
||||
repository = MirrorRepository.find_by(name: mirror['imageName'])
|
||||
next if repository.blank? || repository.status != 1
|
||||
|
||||
repository.update_column(:status, 5)
|
||||
MirrorOperationRecord.create!(mirror_repository_id: repository.id, mirror_id: mirror['imageID'],
|
||||
mirror_name: mirror['imageName'], status: 4, user_id: -1)
|
||||
end
|
||||
end
|
||||
|
||||
def bridge_images
|
||||
@_bridge_images ||= begin
|
||||
url = "#{EduSetting.get('cloud_bridge')}/bridge/docker/images"
|
||||
res = Faraday.get(url)
|
||||
res = JSON.parse(res.body)
|
||||
raise Error, '拉取镜像信息异常' if res && res['code'] != 0
|
||||
|
||||
res
|
||||
rescue => e
|
||||
Rails.logger.error("get response failed ! #{e.message}")
|
||||
raise Error, '实训云平台繁忙(繁忙等级:84)'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
class Admins::DragCooperativeService < ApplicationService
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
attr_reader :move, :after
|
||||
|
||||
def initialize(move, after)
|
||||
@move = move
|
||||
@after = after # 移动后下一个位置的元素
|
||||
end
|
||||
|
||||
def call
|
||||
return if move.position + 1 == after&.position # 未移动
|
||||
raise Error, '未知错误' if after && move.img_type != after.img_type
|
||||
|
||||
coo_imgs = CooImg.where(img_type: move.img_type)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
if after.blank? # 移动至末尾
|
||||
total = coo_imgs.count
|
||||
|
||||
coo_imgs.where('position > ?', move.position).update_all('position = position - 1')
|
||||
move.update!(position: total)
|
||||
return
|
||||
end
|
||||
|
||||
if move.position > after.position # 前移
|
||||
coo_imgs.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1')
|
||||
move.update!(position: after.position)
|
||||
else # 后移
|
||||
coo_imgs.where('position > ? AND position <= ?', move.position, after.position).update_all('position = position - 1')
|
||||
move.update!(position: after.position)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
class Admins::DragPortalImageService < ApplicationService
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
attr_reader :laboratory, :move, :after
|
||||
|
||||
def initialize(laboratory, move, after)
|
||||
@laboratory = laboratory
|
||||
@move = move
|
||||
@after = after # 移动后下一个位置的元素
|
||||
end
|
||||
|
||||
def call
|
||||
return if move.position + 1 == after&.position # 未移动
|
||||
|
||||
images = laboratory.portal_images
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
if after.blank? || move.id == after.id # 移动至末尾
|
||||
total = images.count
|
||||
|
||||
images.where('position > ?', move.position).update_all('position = position - 1')
|
||||
move.update!(position: total)
|
||||
return
|
||||
end
|
||||
|
||||
if move.position > after.position # 前移
|
||||
images.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1')
|
||||
move.update!(position: after.position)
|
||||
else # 后移
|
||||
images.where('position > ? AND position < ?', move.position, after.position).update_all('position = position - 1')
|
||||
move.update!(position: after.position - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
class Admins::DragWeappAdvertService < ApplicationService
|
||||
attr_reader :move, :after
|
||||
|
||||
def initialize(move, after)
|
||||
@move = move
|
||||
@after = after # 移动后下一个位置的元素
|
||||
end
|
||||
|
||||
def call
|
||||
return if move.position + 1 == after&.position # 未移动
|
||||
|
||||
adverts = WeappSettings::Advert.all
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
if after.blank? || move.id == after.id # 移动至末尾
|
||||
total = adverts.count
|
||||
|
||||
adverts.where('position > ?', move.position).update_all('position = position - 1')
|
||||
move.update!(position: total)
|
||||
return
|
||||
end
|
||||
|
||||
if move.position > after.position # 前移
|
||||
adverts.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1')
|
||||
move.update!(position: after.position)
|
||||
else # 后移
|
||||
adverts.where('position > ? AND position < ?', move.position, after.position).update_all('position = position - 1')
|
||||
move.update!(position: after.position - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
class Admins::DragWeappCarouselService < ApplicationService
|
||||
attr_reader :move, :after
|
||||
|
||||
def initialize(move, after)
|
||||
@move = move
|
||||
@after = after # 移动后下一个位置的元素
|
||||
end
|
||||
|
||||
def call
|
||||
return if move.position + 1 == after&.position # 未移动
|
||||
|
||||
carousels = WeappSettings::Carousel.all
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
if after.blank? || move.id == after.id # 移动至末尾
|
||||
total = carousels.count
|
||||
|
||||
carousels.where('position > ?', move.position).update_all('position = position - 1')
|
||||
move.update!(position: total)
|
||||
return
|
||||
end
|
||||
|
||||
if move.position > after.position # 前移
|
||||
carousels.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1')
|
||||
move.update!(position: after.position)
|
||||
else # 后移
|
||||
carousels.where('position > ? AND position < ?', move.position, after.position).update_all('position = position - 1')
|
||||
move.update!(position: after.position - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,63 +0,0 @@
|
|||
class Admins::ImportCourseMemberService < ApplicationService
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
attr_reader :file, :result
|
||||
|
||||
def initialize(file)
|
||||
@file = file
|
||||
@result = { success: 0, fail: [] }
|
||||
end
|
||||
|
||||
def call
|
||||
raise Error, '文件不存在' if file.blank?
|
||||
|
||||
excel = Admins::ImportCourseMemberExcel.new(file)
|
||||
excel.read_each(&method(:create_course_member))
|
||||
|
||||
result
|
||||
rescue ApplicationImport::Error => ex
|
||||
raise Error, ex.message
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_course_member(data)
|
||||
raise '课堂角色必须为 2、3、4' unless [2, 3, 4].include?(data.role.to_i)
|
||||
|
||||
user = User.joins(:user_extension).where(user_extensions: { student_id: data.student_id, school_id: data.school_id }).first
|
||||
raise '该学号的用户不存在' if user.blank?
|
||||
course = Course.find_by(id: data.course_id)
|
||||
raise '该课堂不存在' if course.blank?
|
||||
|
||||
course_group = nil
|
||||
if data.course_group_name.present?
|
||||
course_group = course.course_groups.find_or_create_by!(name: data.course_group_name)
|
||||
end
|
||||
|
||||
member = course.course_members.find_by(user_id: user.id, role: data.role.to_i)
|
||||
# 如果已是课堂成员且是学生身份and不在指定的分班则移动到该分班
|
||||
if member.present? && member.role == 'STUDENT' && course_group && member.course_group_id != course_group&.id.to_i
|
||||
member.update!(course_group_id: course_group&.id.to_i)
|
||||
elsif member.blank?
|
||||
course.course_members.create!(user_id: user.id, role: data.role.to_i, course_group_id: course_group&.id.to_i)
|
||||
extra =
|
||||
case data.role.to_i
|
||||
when 2 then 9
|
||||
when 3 then 7
|
||||
else 10
|
||||
end
|
||||
|
||||
Tiding.create!(user_id: user.id, trigger_user_id: course.tea_id, container_id: course.id,
|
||||
container_type: 'TeacherJoinCourse', belong_container_id: course.id,
|
||||
belong_container_type: 'Course', tiding_type: 'System', extra: extra)
|
||||
end
|
||||
|
||||
result[:success] += 1
|
||||
rescue Exception => ex
|
||||
fail_data = data.as_json
|
||||
fail_data[:data] = fail_data.values.join(',')
|
||||
fail_data[:message] = ex.message
|
||||
|
||||
result[:fail] << fail_data
|
||||
end
|
||||
end
|
|
@ -1,123 +0,0 @@
|
|||
class Admins::SchoolDailyStatisticService < ApplicationService
|
||||
include CustomSortable
|
||||
|
||||
attr_reader :params
|
||||
|
||||
sort_columns :student_count, :teacher_count, :homework_count, :other_homework_count,
|
||||
:course_count, :active_course_count, :nearly_course_time, :shixun_count, :shixun_evaluate_count,
|
||||
default_by: :teacher_count, default_direction: :desc
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
schools = School.group('schools.id')
|
||||
|
||||
keyword = params[:keyword].try(:to_s).try(:strip)
|
||||
if keyword.present?
|
||||
schools = schools.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
count = schools.count.count
|
||||
|
||||
# 根据排序字段进行查询
|
||||
schools = query_by_sort_column(schools, params[:sort_by])
|
||||
schools = custom_sort(schools, params[:sort_by], params[:sort_direction])
|
||||
|
||||
schools = schools.limit(page_size).offset(offset)
|
||||
# 查询并组装其它数据
|
||||
schools = package_other_data(schools)
|
||||
|
||||
[count, schools]
|
||||
end
|
||||
|
||||
def package_other_data(schools)
|
||||
ids = schools.map(&:id)
|
||||
|
||||
student_map = UserExtension.where(school_id: ids, identity: :student).group(:school_id).count
|
||||
teacher_map = UserExtension.where(school_id: ids, identity: :teacher).group(:school_id).count
|
||||
|
||||
homeworks = HomeworkCommon.joins(:course)
|
||||
shixun_homework_map = homeworks.where(homework_type: 4, courses: { school_id: ids }).group('school_id').count
|
||||
other_homework_map = homeworks.where(homework_type: [1, 3], courses: { school_id: ids }).group('school_id').count
|
||||
|
||||
courses = Course.where(is_delete: 0, school_id: ids).group('school_id')
|
||||
course_map = courses.count
|
||||
nearly_course_time_map = courses.joins(:course_acts).maximum('course_activities.updated_at')
|
||||
active_course_map = courses.where(is_end: false).count
|
||||
|
||||
shixun_map = Shixun.joins(user: :user_extension).where(user_extensions: { identity: :teacher, school_id: ids })
|
||||
.where(fork_from: nil).group('school_id').count
|
||||
|
||||
reports = SchoolReport.where(school_id: ids)
|
||||
evaluate_count_map = reports.each_with_object({}) { |report, obj| obj[report.school_id] = report.shixun_evaluate_count }
|
||||
|
||||
schools.map do |school|
|
||||
{
|
||||
id: school.id,
|
||||
name: school.name,
|
||||
teacher_count: teacher_map[school.id],
|
||||
student_count: student_map[school.id],
|
||||
homework_count: shixun_homework_map[school.id],
|
||||
other_homework_count: other_homework_map[school.id],
|
||||
course_count: course_map[school.id],
|
||||
nearly_course_time: nearly_course_time_map[school.id],
|
||||
active_course_count: active_course_map[school.id],
|
||||
shixun_count: shixun_map.fetch(school.id, 0),
|
||||
shixun_evaluate_count: evaluate_count_map.fetch(school.id, 0)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def query_by_sort_column(schools, sort_by_column)
|
||||
base_query_column = 'schools.id, schools.name'
|
||||
|
||||
case sort_by_column.to_s
|
||||
when 'teacher_count' then
|
||||
schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0')
|
||||
.select("#{base_query_column}, COUNT(*) teacher_count")
|
||||
when 'student_count' then
|
||||
schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 1')
|
||||
.select("#{base_query_column}, COUNT(*) student_count")
|
||||
when 'homework_count' then
|
||||
schools.joins('LEFT JOIN courses ON courses.school_id = schools.id')
|
||||
.joins('LEFT JOIN homework_commons hc ON hc.course_id = courses.id AND hc.homework_type = 4')
|
||||
.select("#{base_query_column}, COUNT(*) homework_count")
|
||||
when 'other_homework_count' then
|
||||
schools.joins('LEFT JOIN courses ON courses.school_id = schools.id')
|
||||
.joins('LEFT JOIN homework_commons hc ON hc.course_id = courses.id AND hc.homework_type IN (1, 3)')
|
||||
.select("#{base_query_column}, COUNT(*) other_homework_count")
|
||||
when 'course_count' then
|
||||
schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0')
|
||||
.select("#{base_query_column}, COUNT(*) course_count")
|
||||
when 'shixun_count' then
|
||||
schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0')
|
||||
.joins('LEFT JOIN users ON users.id = ue.user_id')
|
||||
.joins('LEFT JOIN shixuns sx ON sx.user_id = users.id AND sx.fork_from IS NULL')
|
||||
.select("#{base_query_column}, COUNT(*) shixun_count")
|
||||
when 'shixun_evaluate_count' then
|
||||
schools.joins('LEFT JOIN school_reports ON school_reports.school_id = schools.id')
|
||||
.select("#{base_query_column}, shixun_evaluate_count")
|
||||
when 'nearly_course_time' then
|
||||
schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0')
|
||||
.joins('LEFT JOIN course_activities acs ON acs.course_id = cs.id')
|
||||
.select("#{base_query_column}, MAX(acs.updated_at) nearly_course_time")
|
||||
when 'active_course_count' then
|
||||
schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0 AND cs.is_end = false')
|
||||
.select("#{base_query_column}, COUNT(*) active_course_count")
|
||||
else
|
||||
schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0')
|
||||
.select("#{base_query_column}, COUNT(*) teacher_count")
|
||||
end
|
||||
end
|
||||
|
||||
def page_size
|
||||
params[:per_page] || 20
|
||||
end
|
||||
|
||||
def offset
|
||||
(params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * page_size
|
||||
end
|
||||
end
|
|
@ -1,43 +0,0 @@
|
|||
class Admins::ShixunAuths::AgreeApplyService < ApplicationService
|
||||
attr_reader :apply, :user, :shixun
|
||||
|
||||
def initialize(apply, user)
|
||||
@apply = apply
|
||||
@user = user
|
||||
@shixun = Shixun.find(apply.container_id)
|
||||
end
|
||||
|
||||
def call
|
||||
ActiveRecord::Base.transaction do
|
||||
apply.update!(status: 1, dealer_id: user.id)
|
||||
shixun.update!(public: 2, publish_time: Time.now)
|
||||
|
||||
# 奖励金币、经验
|
||||
reward_grade_and_experience!
|
||||
|
||||
deal_tiding!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reward_grade_and_experience!
|
||||
score = shixun.all_score
|
||||
shixun_creator = shixun.user
|
||||
|
||||
RewardGradeService.call(shixun_creator, container_id: shixun.id, container_type: 'shixunPublish', score: score)
|
||||
|
||||
Experience.create!(user_id: shixun_creator.id, container_id: shixun.id, container_type: 'shixunPublish', score: score)
|
||||
shixun_creator.update_column(:experience, shixun_creator.experience.to_i + score)
|
||||
end
|
||||
|
||||
def deal_tiding!
|
||||
apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1)
|
||||
|
||||
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
|
||||
container_id: apply.id, container_type: 'ApplyAction',
|
||||
parent_container_id: apply.container_id, parent_container_type: apply.container_type,
|
||||
belong_container_id: apply.container_id, belong_container_type: 'Shixun',
|
||||
status: 1, tiding_type: 'System')
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
class Admins::ShixunAuths::RefuseApplyService < ApplicationService
|
||||
attr_reader :apply, :user, :shixun, :params
|
||||
|
||||
def initialize(apply, user, params)
|
||||
@apply = apply
|
||||
@user = user
|
||||
@shixun = Shixun.find(apply.container_id)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
ActiveRecord::Base.transaction do
|
||||
shixun.update!(public: 0)
|
||||
apply.update!(status: 2, reason: reason, dealer_id: user.id)
|
||||
|
||||
deal_tiding!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reason
|
||||
params[:reason].to_s.strip
|
||||
end
|
||||
|
||||
def deal_tiding!
|
||||
apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1)
|
||||
|
||||
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
|
||||
container_id: apply.id, container_type: 'ApplyAction',
|
||||
parent_container_id: apply.container_id, parent_container_type: apply.container_type,
|
||||
belong_container_id: apply.container_id, belong_container_type: 'Shixun',
|
||||
status: 2, tiding_type: 'System')
|
||||
end
|
||||
end
|
|
@ -1,80 +0,0 @@
|
|||
class Admins::StatisticSchoolContrastDataService < ApplicationService
|
||||
ParameterError = Class.new(StandardError)
|
||||
|
||||
PAGE_SIZE = 20
|
||||
CONTRAST_COLUMN_LIST = %w(
|
||||
teacher_increase_count student_increase_count course_increase_count
|
||||
shixun_increase_count active_user_count shixun_homework_count shixun_evaluate_count
|
||||
).freeze
|
||||
|
||||
attr_reader :params, :sort_direction, :contrast_column
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
@sort_direction = params[:sort_direction].to_s
|
||||
@contrast_column = params[:contrast_column].to_s
|
||||
end
|
||||
|
||||
def call
|
||||
validate_parameter!
|
||||
reports = School.joins(:school_daily_reports).select(select_columns)
|
||||
|
||||
keyword = params[:keyword].try(:to_s).try(:strip)
|
||||
if keyword.present?
|
||||
reports = reports.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
count = reports.count('distinct(schools.id)')
|
||||
|
||||
sql = query_report_sql(reports.group('schools.id').to_sql)
|
||||
reports = SchoolDailyReport.find_by_sql(sql)
|
||||
|
||||
[count, reports]
|
||||
end
|
||||
|
||||
private
|
||||
def validate_parameter!
|
||||
if %i[begin_date end_date other_begin_date other_end_date].any? { |key| params[key].blank? }
|
||||
raise ParameterError
|
||||
end
|
||||
|
||||
unless %w(desc asc).include?(sort_direction)
|
||||
raise ParameterError
|
||||
end
|
||||
|
||||
unless CONTRAST_COLUMN_LIST.include?(contrast_column)
|
||||
raise ParameterError
|
||||
end
|
||||
end
|
||||
|
||||
def format_date(date)
|
||||
Time.zone.parse(date).strftime("%Y-%m-%d")
|
||||
end
|
||||
|
||||
def offset
|
||||
(params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * PAGE_SIZE
|
||||
end
|
||||
|
||||
def select_columns
|
||||
if contrast_column != 'active_user_count'
|
||||
"schools.id school_id, schools.name school_name,"\
|
||||
"(SUM(IF(date BETWEEN '#{format_date(params[:begin_date])}' AND '#{format_date(params[:end_date])}', #{contrast_column}, 0))) total,"\
|
||||
"(SUM(IF(date BETWEEN '#{format_date(params[:other_begin_date])}' AND '#{format_date(params[:other_end_date])}', #{contrast_column}, 0))) other_total"
|
||||
else
|
||||
# 活跃用户对比时处理方法不同
|
||||
relations = SchoolDailyActiveUser.select('COUNT(distinct user_id)').joins(:school_daily_report)
|
||||
.where('school_id = schools.id')
|
||||
total_subquery = relations.where("date BETWEEN '#{format_date(params[:begin_date])}' AND '#{format_date(params[:end_date])}'").to_sql
|
||||
other_total_subquery = relations.where("date BETWEEN '#{format_date(params[:other_begin_date])}' AND '#{format_date(params[:other_end_date])}'").to_sql
|
||||
|
||||
"schools.id school_id, schools.name school_name, (#{total_subquery}) AS total, (#{other_total_subquery}) AS other_total"
|
||||
end
|
||||
end
|
||||
|
||||
def query_report_sql(from_sql)
|
||||
order_by = "(total = 0 AND other_total != 0) #{sort_direction}, (percentage != 0) #{sort_direction}, percentage #{sort_direction}"
|
||||
|
||||
"SELECT reports.*, (other_total - total) increase, (IF(other_total - total = 0, 0.0, round((other_total - total) / IF(total = 0, 1, total), 5))) percentage "\
|
||||
"FROM (#{from_sql}) reports ORDER BY #{order_by} LIMIT #{PAGE_SIZE} OFFSET #{offset}"
|
||||
end
|
||||
end
|
|
@ -1,107 +0,0 @@
|
|||
class Admins::StatisticSchoolDataGrowService < ApplicationService
|
||||
include CustomSortable
|
||||
|
||||
PAGE_SIZE = 20
|
||||
|
||||
attr_reader :params
|
||||
|
||||
sort_columns :teacher_increase_count, :student_increase_count,
|
||||
:course_increase_count, :shixun_increase_count, :uniq_active_user_count,
|
||||
:shixun_homework_count, :shixun_evaluate_count,
|
||||
default_by: :teacher_increase_count, default_direction: :desc
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
reports = School.where(nil)
|
||||
|
||||
reports = search_filter(reports)
|
||||
|
||||
count = reports.count
|
||||
|
||||
subquery = SchoolDailyActiveUser.select('COUNT(distinct(user_id))').joins(:school_daily_report)
|
||||
.where(date_condition_sql).where("school_id is not null and school_id = schools.id").to_sql
|
||||
reports = reports.joins("LEFT JOIN school_daily_reports sdr ON sdr.school_id = schools.id AND #{date_condition_sql}")
|
||||
reports = reports.select(
|
||||
'schools.id school_id, schools.name 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(shixun_homework_count) shixun_homework_count,'\
|
||||
'SUM(shixun_evaluate_count) shixun_evaluate_count,'\
|
||||
"(#{subquery}) uniq_active_user_count,"\
|
||||
'SUM(active_user_count) active_user_count').group('schools.id')
|
||||
|
||||
reports = custom_sort(reports, params[:sort_by], params[:sort_direction])
|
||||
reports = reports.order('school_id asc').limit(PAGE_SIZE).offset(offset)
|
||||
|
||||
[count, reports]
|
||||
end
|
||||
|
||||
def grow_summary
|
||||
@_grow_summary ||= begin
|
||||
reports = School.joins("LEFT JOIN school_daily_reports sdr ON sdr.school_id = schools.id")
|
||||
.where(date_condition_sql)
|
||||
|
||||
subquery = SchoolDailyActiveUser.select('COUNT(distinct user_id)')
|
||||
.joins('LEFT JOIN school_daily_reports sdr ON sdr.id = school_daily_active_users.school_daily_report_id')
|
||||
.where(date_condition_sql).to_sql
|
||||
reports = search_filter(reports)
|
||||
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(shixun_homework_count) shixun_homework_count,'\
|
||||
'SUM(shixun_evaluate_count) shixun_evaluate_count,'\
|
||||
"(#{subquery}) uniq_active_user_count,"\
|
||||
'SUM(active_user_count) active_user_count'
|
||||
).first
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def search_filter(relations)
|
||||
keyword = params[:keyword].try(:to_s).try(:strip)
|
||||
if keyword.present?
|
||||
relations = relations.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
relations
|
||||
end
|
||||
|
||||
def date_condition_sql
|
||||
date = query_date
|
||||
if date.is_a?(Range)
|
||||
"date BETWEEN '#{date.min.strftime('%Y-%m-%d')}' AND '#{date.max.strftime('%Y-%m-%d')}'"
|
||||
else
|
||||
"date = '#{date.strftime('%Y-%m-%d')}'"
|
||||
end
|
||||
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
|
|
@ -1,30 +0,0 @@
|
|||
class Admins::SubjectAuths::AgreeApplyService < ApplicationService
|
||||
attr_reader :apply, :user, :subject
|
||||
|
||||
def initialize(apply, user)
|
||||
@apply = apply
|
||||
@user = user
|
||||
@subject = Subject.find(apply.container_id)
|
||||
end
|
||||
|
||||
def call
|
||||
ActiveRecord::Base.transaction do
|
||||
apply.update!(status: 1, dealer_id: user.id)
|
||||
subject.update!(public: 2, publish_time: Time.now)
|
||||
|
||||
deal_tiding!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deal_tiding!
|
||||
apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1)
|
||||
|
||||
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
|
||||
container_id: apply.id, container_type: 'ApplyAction',
|
||||
parent_container_id: apply.container_id, parent_container_type: apply.container_type,
|
||||
belong_container_id: apply.container_id, belong_container_type: 'Subject',
|
||||
status: 1, tiding_type: 'System')
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
class Admins::SubjectAuths::RefuseApplyService < ApplicationService
|
||||
attr_reader :apply, :user, :subject, :params
|
||||
|
||||
def initialize(apply, user, params)
|
||||
@apply = apply
|
||||
@user = user
|
||||
@subject = Subject.find(apply.container_id)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
ActiveRecord::Base.transaction do
|
||||
subject.update!(public: 0)
|
||||
apply.update!(status: 2, reason: reason, dealer_id: user.id)
|
||||
|
||||
deal_tiding!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reason
|
||||
params[:reason].to_s.strip
|
||||
end
|
||||
|
||||
def deal_tiding!
|
||||
apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1)
|
||||
|
||||
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
|
||||
container_id: apply.id, container_type: 'ApplyAction',
|
||||
parent_container_id: apply.container_id, parent_container_type: apply.container_type,
|
||||
belong_container_id: apply.container_id, belong_container_type: 'Subject',
|
||||
status: 2, tiding_type: 'System')
|
||||
end
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
class CoursesService
|
||||
end
|
|
@ -1,44 +0,0 @@
|
|||
class CreateAddDepartmentApplyService < ApplicationService
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
attr_reader :user, :params
|
||||
|
||||
def initialize(user, params)
|
||||
@user = user
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
name = params[:name].to_s.strip
|
||||
raise Error, '名称不能为空' if name.blank?
|
||||
|
||||
school = School.find_by(id: params[:school_id])
|
||||
raise Error, '学校/单位不存在' if school.blank?
|
||||
raise Error, '部门已存在' if school.departments.exists?(name: name)
|
||||
|
||||
department = Department.new
|
||||
department.name = name
|
||||
department.school = school
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
department.save!
|
||||
|
||||
attrs = {
|
||||
user_id: user.id, department: department, school: school,
|
||||
name: department.name, remarks: params[:remarks], status: 0,
|
||||
}
|
||||
apply = ApplyAddDepartment.create!(attrs)
|
||||
|
||||
unless user.professional_certification?
|
||||
user.user_extension.update!(department_id: department.id)
|
||||
end
|
||||
|
||||
# 向管理员发送通知
|
||||
message = AppliedMessage.new(user_id: 1, status: 0, applied_user_id: user.id, viewed: 0,
|
||||
applied_id: apply.id, applied_type: 'ApplyAddDepartment', name: department.name)
|
||||
message.save(validate: false)
|
||||
end
|
||||
|
||||
department
|
||||
end
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
class CreateAddSchoolApplyService < ApplicationService
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
attr_reader :user, :params
|
||||
|
||||
def initialize(user, params)
|
||||
@user = user
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
AddSchoolApplyForm.new(params).validate!
|
||||
|
||||
name = params[:name].to_s.strip
|
||||
raise Error, '学校/单位已经存在' if name.present? && School.exists?(name: name)
|
||||
|
||||
school = School.new
|
||||
school.name = name
|
||||
school.province = params[:province].to_s.strip
|
||||
school.city = params[:city].to_s.strip
|
||||
school.address = params[:address].to_s.strip
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
school.save!
|
||||
|
||||
school_attrs = school.as_json(only: %i[name province city address])
|
||||
ApplyAddSchool.create!(school_attrs.merge(school: school, user_id: user.id, remarks: params[:remarks]))
|
||||
|
||||
# 向管理员发送通知
|
||||
message = AppliedMessage.new(user_id: 1, status: 0, applied_user_id: user.id, viewed: 0,
|
||||
applied_id: school.id, applied_type: 'ApplyAddSchools', name: school.name)
|
||||
message.save(validate: false)
|
||||
end
|
||||
|
||||
school
|
||||
end
|
||||
end
|
|
@ -1,164 +0,0 @@
|
|||
class DuplicateCourseService < ApplicationService
|
||||
attr_reader :origin_course, :user, :course
|
||||
|
||||
def initialize(origin_course, user)
|
||||
@user = user
|
||||
@origin_course = origin_course
|
||||
end
|
||||
|
||||
def call
|
||||
ActiveRecord::Base.transaction do
|
||||
@course = copy_course!
|
||||
|
||||
copy_course_modules!
|
||||
|
||||
join_course!
|
||||
|
||||
copy_homework_commons!
|
||||
|
||||
copy_exercises!
|
||||
|
||||
copy_polls!
|
||||
|
||||
copy_attachments!
|
||||
|
||||
course
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def copy_course!
|
||||
create_attrs = origin_course.as_json(only: %i[name class_period credit course_list_id])
|
||||
create_attrs.merge!(tea_id: user.id, school_id: user.school_id, is_public: 0, is_copy: 1)
|
||||
|
||||
Course.create!(create_attrs)
|
||||
end
|
||||
|
||||
def copy_course_modules!
|
||||
@second_category_list = {}
|
||||
origin_course.course_modules.each do |course_module|
|
||||
attrs = course_module.as_json(only: %i[module_type position hidden module_name])
|
||||
new_course_module = CourseModule.create!(attrs.merge(course_id: course.id))
|
||||
# 复制子目录
|
||||
course_module.course_second_categories.each do |second_category|
|
||||
category_attr = second_category.as_json(only: %i[category_type name position])
|
||||
new_second_category =
|
||||
CourseSecondCategory.create!(category_attr.merge(course_id: course.id, course_module_id: new_course_module.id))
|
||||
@second_category_list[second_category.id] = new_second_category.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def join_course!
|
||||
CourseMember.create!(course_id: course.id, user_id: user.id, role: 1)
|
||||
end
|
||||
|
||||
def copy_homework_commons!
|
||||
origin_course.homework_commons.where(homework_type: %i[normal group practice]).find_each do |origin_homework|
|
||||
homework_attrs = origin_homework.as_json(only: %i[name description homework_type homework_bank_id reference_answer])
|
||||
|
||||
course_second_category_id = @second_category_list[origin_homework.course_second_category_id]
|
||||
|
||||
homework = HomeworkCommon.create!(homework_attrs.merge(user_id: user.id, course_id: course.id,
|
||||
course_second_category_id:course_second_category_id))
|
||||
|
||||
origin_homework.attachments.find_each do |origin_attachment|
|
||||
attachment = origin_attachment.copy
|
||||
attrs = { container: homework, author_id: origin_homework.user_id, copy_from: origin_attachment.id }
|
||||
attachment.assign_attributes(attrs)
|
||||
attachment.save!
|
||||
|
||||
origin_attachment.increment!(:quotes)
|
||||
end
|
||||
|
||||
homework.create_homework_detail_manual!
|
||||
|
||||
if homework.group_homework_type?
|
||||
attrs = origin_homework.homework_detail_group.as_json(only: %i[min_num max_num base_on_project])
|
||||
homework.create_homework_detail_group!(attrs)
|
||||
elsif homework.practice_homework_type?
|
||||
HomeworkCommonsShixun.create!(homework_common_id: homework.id, shixun_id: origin_homework.homework_commons_shixun.shixun_id)
|
||||
HomeworksService.new.create_shixun_homework_cha_setting(homework, origin_homework.shixuns.first)
|
||||
end
|
||||
|
||||
|
||||
origin_homework.increment!(:quotes)
|
||||
origin_homework.homework_bank.increment!(:quotes) if origin_homework.homework_bank
|
||||
end
|
||||
end
|
||||
|
||||
def copy_exercises!
|
||||
origin_course.exercises.find_each do |origin_exercise|
|
||||
attrs = origin_exercise.as_json(only: %i[exercise_name exercise_description exercise_bank_id])
|
||||
exercise = course.exercises.create!(attrs.merge(user_id: user.id))
|
||||
|
||||
origin_exercise.exercise_questions.find_each do |origin_question|
|
||||
question_attrs = origin_question.as_json(only: %i[question_title question_type question_number question_score shixun_name shixun_id is_ordered level])
|
||||
# question_attrs[:question_type] ||= 1
|
||||
question = exercise.exercise_questions.create!(question_attrs)
|
||||
|
||||
exercise_choice_map = {}
|
||||
origin_question.exercise_choices.each_with_index do |origin_choice, index|
|
||||
choice_attrs = { choice_position: index + 1, choice_text: origin_choice.choice_text }
|
||||
choice = question.exercise_choices.create!(choice_attrs)
|
||||
|
||||
# exercise_choice_map[origin_choice.id] = choice.id 标准答案中存的是choice_position, 直接取原题的exercise_choice_id就行
|
||||
end
|
||||
|
||||
origin_question.exercise_standard_answers.find_each do |origin_answer|
|
||||
question.exercise_standard_answers.create!(
|
||||
exercise_choice_id: origin_answer.exercise_choice_id,
|
||||
answer_text: origin_answer.answer_text
|
||||
)
|
||||
end
|
||||
|
||||
origin_question.exercise_shixun_challenges.each_with_index do |sc, index|
|
||||
question.exercise_shixun_challenges.create!({position: index+1, challenge_id: sc.challenge_id,
|
||||
shixun_id: sc.shixun_id, question_score: sc.question_score})
|
||||
end
|
||||
end
|
||||
|
||||
origin_exercise.exercise_bank.increment!(:quotes) if exercise.exercise_bank
|
||||
end
|
||||
end
|
||||
|
||||
def copy_polls!
|
||||
origin_course.polls.includes(poll_questions: :poll_answers).find_each do |origin_poll|
|
||||
poll_attrs = origin_poll.as_json(only: %i[polls_name polls_description exercise_bank_id])
|
||||
poll = course.polls.create!(poll_attrs.merge(user_id: user.id))
|
||||
|
||||
origin_poll.poll_questions.each do |origin_question|
|
||||
attr_names = %i[question_title question_type is_necessary question_number max_choices min_choices]
|
||||
question_attrs = origin_question.as_json(only: attr_names)
|
||||
question_attrs[:question_type] ||= 1
|
||||
|
||||
question = poll.poll_questions.create!(question_attrs)
|
||||
|
||||
origin_question.poll_answers.each_with_index do |origin_answer, index|
|
||||
question.poll_answers.create!(answer_position: index + 1, answer_text: origin_answer.answer_text)
|
||||
end
|
||||
end
|
||||
|
||||
origin_poll.exercise_bank.increment!(:quotes) if origin_poll.exercise_bank
|
||||
end
|
||||
end
|
||||
|
||||
def copy_attachments!
|
||||
origin_course.attachments.each do |origin_attachment|
|
||||
attachment = origin_attachment.copy
|
||||
# attachment.tag_list.add(origin_attachment.tag_list) # tag关联
|
||||
attachment.container = course
|
||||
attachment.created_on = Time.now
|
||||
attachment.publish_time = nil
|
||||
attachment.author_id = User.current.id
|
||||
attachment.copy_from = origin_attachment.copy_from || origin_attachment.id
|
||||
attachment.is_publish = 0
|
||||
attachment.attachtype ||= 4
|
||||
attachment.course_second_category_id = @second_category_list[origin_attachment.course_second_category_id]
|
||||
|
||||
attachment.save!
|
||||
origin_course.update_quotes(attachment)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -65,7 +65,7 @@ class Projects::ApplyJoinService < ApplicationService
|
|||
owner = project.user
|
||||
return if owner.phone.blank?
|
||||
|
||||
Educoder::Sms.send(mobile: owner.phone, send_type:'applied_project_info',
|
||||
Gitlink::Sms.send(mobile: owner.phone, send_type:'applied_project_info',
|
||||
user_name: owner.show_name, name: project.name)
|
||||
rescue Exception => ex
|
||||
Rails.logger.error("发送短信失败 => #{ex.message}")
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
class RewardExperienceService
|
||||
attr_reader :user, :attrs
|
||||
|
||||
def initialize(user, **attrs)
|
||||
@user = user
|
||||
@attrs = attrs.slice(*%i[container_id container_type score])
|
||||
end
|
||||
|
||||
def call
|
||||
return if user.experiences.exists?(attrs.except(:score))
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
experience = user.experiences.create!(attrs)
|
||||
|
||||
user.increment!(:experience, experience.score)
|
||||
|
||||
experience
|
||||
end
|
||||
end
|
||||
|
||||
def self.call(user, **attrs)
|
||||
new(user, attrs).call
|
||||
end
|
||||
end
|
|
@ -52,7 +52,7 @@ class Users::ApplyAuthenticationService < ApplicationService
|
|||
end
|
||||
|
||||
def sms_notify_admin
|
||||
Educoder::Sms.notify_admin(send_type: 'apply_auth')
|
||||
Gitlink::Sms.notify_admin(send_type: 'apply_auth')
|
||||
rescue => ex
|
||||
Util.logger_error(ex)
|
||||
end
|
||||
|
|
|
@ -62,7 +62,7 @@ class Users::ApplyProfessionalAuthService < ApplicationService
|
|||
def sms_notify_admin
|
||||
sms_cache = Rails.cache.read('apply_pro_certification')
|
||||
if sms_cache.nil?
|
||||
Educoder::Sms.notify_admin(send_type: 'apply_pro_certification')
|
||||
Gitlink::Sms.notify_admin(send_type: 'apply_pro_certification')
|
||||
Rails.cache.write('apply_pro_certification', 1, expires_in: 5.minutes)
|
||||
end
|
||||
rescue => ex
|
||||
|
|
|
@ -51,7 +51,7 @@ class Users::ApplyTrailService < ApplicationService
|
|||
end
|
||||
|
||||
def send_trial_apply_notify!
|
||||
Educoder::Sms.notify_admin(send_type:'user_apply_auth')
|
||||
Gitlink::Sms.notify_admin(send_type:'user_apply_auth')
|
||||
rescue => ex
|
||||
Rails.logger.error('发送通知管理员短信失败')
|
||||
Rails.logger.error(ex.message)
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
class Users::CourseService
|
||||
include CustomSortable
|
||||
|
||||
sort_columns :created_at, :updated_at, default_by: :updated_at, default_direction: :desc
|
||||
|
||||
attr_reader :user, :params
|
||||
|
||||
def initialize(user, params)
|
||||
@user = user
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
courses = category_scope_courses.not_deleted.not_excellent
|
||||
|
||||
courses = status_filter(courses)
|
||||
|
||||
custom_sort(courses, params[:sort_by], params[:sort_direction])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def category_scope_courses
|
||||
case params[:category]
|
||||
when 'study' then
|
||||
user.as_student_courses.started
|
||||
when 'manage' then
|
||||
user.manage_courses
|
||||
else
|
||||
ids = user.as_student_courses.started.pluck(:id) + user.manage_courses.pluck(:id)
|
||||
Course.where(id: ids)
|
||||
end
|
||||
end
|
||||
|
||||
def status_filter(relations)
|
||||
# 只有自己查看才有过滤
|
||||
return relations unless observed_logged_user?
|
||||
|
||||
case params[:status]
|
||||
when 'processing' then
|
||||
relations.processing
|
||||
when 'end' then
|
||||
relations.ended
|
||||
else
|
||||
relations
|
||||
end
|
||||
end
|
||||
|
||||
def observed_logged_user?
|
||||
User.current.id == user.id
|
||||
end
|
||||
end
|
|
@ -1,99 +0,0 @@
|
|||
class Users::QuestionBankService
|
||||
attr_reader :user, :params
|
||||
|
||||
def initialize(user, params)
|
||||
@user = user
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
relations = class_name.classify.constantize.all
|
||||
|
||||
relations = category_filter(relations)
|
||||
relations = type_filter(relations) if params[:type].present?
|
||||
|
||||
relations = relations.where(course_list_id: params[:course_list_id]) if params[:course_list_id].present?
|
||||
|
||||
custom_sort(relations, params[:sort_by], params[:sort_direction])
|
||||
end
|
||||
|
||||
def course_lists
|
||||
relation_name = class_name.underscore.pluralize.to_sym
|
||||
course_lists = CourseList.joins(relation_name).where.not(relation_name => { id: nil })
|
||||
|
||||
category_condition =
|
||||
case params[:object_type]
|
||||
when 'normal' then { homework_type: 1 }
|
||||
when 'group' then { homework_type: 3 }
|
||||
when 'exercise' then { container_type: 'Exercise' }
|
||||
when 'poll' then { container_type: 'Poll' }
|
||||
when 'gtask', 'gtopic' then {}
|
||||
else raise ArgumentError
|
||||
end
|
||||
course_lists = course_lists.where(relation_name => category_condition) if category_condition.present?
|
||||
|
||||
type_condition =
|
||||
case params[:type]
|
||||
when 'personal' then { user_id: user.id }
|
||||
when 'publicly' then { is_public: true }
|
||||
else {}
|
||||
end
|
||||
course_lists = course_lists.where(relation_name => type_condition) if type_condition.present?
|
||||
|
||||
course_lists.distinct.select(:id, :name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def class_name
|
||||
@_class_name ||= begin
|
||||
case params[:object_type]
|
||||
when 'normal', 'group' then 'HomeworkBank'
|
||||
when 'exercise', 'poll' then 'ExerciseBank'
|
||||
when 'gtask' then 'GtaskBank'
|
||||
when 'gtopic' then 'GtopicBank'
|
||||
else raise ArgumentError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def category_filter(relations)
|
||||
case params[:object_type]
|
||||
when 'normal' then
|
||||
relations.where(homework_type: 1)
|
||||
when 'group' then
|
||||
relations.where(homework_type: 3)
|
||||
when 'exercise' then
|
||||
relations.where(container_type: 'Exercise')
|
||||
when 'poll' then
|
||||
relations.where(container_type: 'Poll')
|
||||
when 'gtask', 'gtopic' then
|
||||
relations.all
|
||||
else
|
||||
raise ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
def type_filter(relations)
|
||||
case params[:type]
|
||||
when 'personal' then relations.where(user_id: user.id)
|
||||
when 'publicly' then relations.where(is_public: true)
|
||||
else relations
|
||||
end
|
||||
end
|
||||
|
||||
def custom_sort(relations, sort_by, sort_direction)
|
||||
case sort_by
|
||||
when 'updated_at' then
|
||||
relations.order("updated_at #{sort_direction}, id #{sort_direction}")
|
||||
when 'name' then
|
||||
relations.order("CONVERT(name USING gbk) COLLATE gbk_chinese_ci #{sort_direction}")
|
||||
when 'contributor' then
|
||||
order_sql = "CONVERT (users.lastname USING gbk) COLLATE gbk_chinese_ci #{sort_direction},"\
|
||||
" CONVERT (users.firstname USING gbk) COLLATE gbk_chinese_ci #{sort_direction}"
|
||||
relations.joins(:user).where(users: { status: 1 }).order(order_sql)
|
||||
else
|
||||
relations
|
||||
end
|
||||
end
|
||||
end
|
|
@ -71,7 +71,7 @@ class Users::UpdateAccountService < ApplicationService
|
|||
end
|
||||
|
||||
def sms_notify_admin name
|
||||
Educoder::Sms.send(mobile:'17680641960', send_type:'teacher_register', name: name, user_name:'管理员')
|
||||
Gitlink::Sms.send(mobile:'17680641960', send_type:'teacher_register', name: name, user_name:'管理员')
|
||||
rescue => ex
|
||||
Util.logger_error(ex)
|
||||
end
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
class Weapps::CreateCourseService < ApplicationService
|
||||
attr_reader :course, :params
|
||||
|
||||
def initialize(course, params)
|
||||
@course = course
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
Weapps::CreateCourseForm.new(form_params).validate!
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
course.name = params[:name].to_s.strip
|
||||
course.school_id = course.teacher&.school_id
|
||||
course.is_public = 0
|
||||
course.credit = params[:credit].blank? ? nil : params[:credit]
|
||||
course.end_date = params[:end_date].blank? ? nil : params[:end_date]
|
||||
course_list = CourseList.find_by(name: params[:course_list_name].to_s.strip)
|
||||
if course_list
|
||||
course.course_list_id = course_list.id
|
||||
else
|
||||
new_course_list = CourseList.create!(name: params[:course_list_name].to_s.strip, user_id: course.tea_id, is_admin: 0)
|
||||
course.course_list_id = new_course_list.id
|
||||
end
|
||||
course.is_end = course.end_date.present? && course.end_date < Date.today
|
||||
|
||||
course.save!
|
||||
|
||||
course.generate_invite_code
|
||||
CourseMember.create!(course_id: course.id, user_id: course.tea_id, role: 1)
|
||||
course.create_course_modules(params[:course_module_types])
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def form_params
|
||||
params.merge(course: course)
|
||||
end
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
class Weapps::UpdateCourseService < ApplicationService
|
||||
attr_reader :course, :params
|
||||
|
||||
def initialize(course, params)
|
||||
@course = course
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
Weapps::UpdateCourseForm.new(form_params).validate!
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
course.name = params[:name].to_s.strip
|
||||
course.credit = params[:credit].blank? ? nil : params[:credit]
|
||||
course.end_date = params[:end_date].blank? ? nil : params[:end_date]
|
||||
course_list = CourseList.find_by(name: params[:course_list_name].to_s.strip)
|
||||
if course_list
|
||||
course.course_list_id = course_list.id
|
||||
else
|
||||
new_course_list = CourseList.create!(name: params[:course_list_name].to_s.strip, user_id: course.tea_id, is_admin: 0)
|
||||
course.course_list_id = new_course_list.id
|
||||
end
|
||||
course.is_end = course.end_date.present? && course.end_date < Date.today
|
||||
course.save!
|
||||
end
|
||||
course
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def form_params
|
||||
params.merge(course: course)
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('课程列表') %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container course-list-list-form">
|
||||
<%= form_tag(admins_course_lists_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
|
||||
<div class="form-group">
|
||||
<label>搜索类型:</label>
|
||||
<% auto_trial_options = [['创建者姓名', 0], ['课程名称', 1]] %>
|
||||
<%= select_tag(:search_type, options_for_select(auto_trial_options), class: 'form-control') %>
|
||||
</div>
|
||||
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '输入关键字搜索') %>
|
||||
<%= submit_tag('搜索', class: 'btn btn-primary ml-3','data-disable-with': '搜索中...') %>
|
||||
<%= link_to "清除",admins_course_lists_path,class: "btn btn-default",id:"course-lists-clear-search",'data-disable-with': '清除中...' %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="box admin-list-container course-list-list-container">
|
||||
<%= render partial: 'admins/course_lists/shared/list', locals: { courses: @course_lists } %>
|
||||
</div>
|
||||
|
||||
<%= render 'admins/course_lists/shared/merge_course_list_modal' %>
|
|
@ -1 +0,0 @@
|
|||
$(".course-list-list-container").html("<%= j render partial: 'admins/course_lists/shared/list', locals: { courses: @course_lists }%>");
|
|
@ -1,37 +0,0 @@
|
|||
<table class="table table-hover text-center shixuns-list-table">
|
||||
<thead class="thead-light">
|
||||
<th width="4%">序号</th>
|
||||
<th width="8%">ID</th>
|
||||
<th width="38%" class="text-left">课程名称</th>
|
||||
<th width="10%">课堂数</th>
|
||||
<th width="10%">创建者</th>
|
||||
<th width="12%"><%= sort_tag('创建时间', name: 'created_at', path: admins_course_lists_path) %></th>
|
||||
<th width="18%">操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if courses.present? %>
|
||||
<% courses.each_with_index do |course_list,index| %>
|
||||
<tr id="course-list-item-<%= course_list.id %>">
|
||||
<td><%= list_index_no(@params_page.to_i, index) %></td>
|
||||
<td><%= course_list.id %></td>
|
||||
<td class="text-left"><%= course_list.name %></td>
|
||||
<% course_count = course_list.courses.size %>
|
||||
<td><%= course_count %></td>
|
||||
<td><%= link_to course_list.user.try(:real_name),"/users/#{course_list.user.try(:login)}",target:'_blank' %></td>
|
||||
<td><%= format_time course_list.created_at %></td>
|
||||
<td class="operate">
|
||||
<% if course_count == 0 %>
|
||||
<%= delete_link '删除', admins_course_list_path(course_list, element: ".course-list-item-#{course_list.id}"), class: 'delete-department-action' %>
|
||||
<% end %>
|
||||
<%= javascript_void_link '修改', class: 'action', data: { course_list_id: course_list.id,
|
||||
toggle: 'modal', target: '.admin-merge-course-list-modal', url: merge_admins_course_lists_path } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= render 'admins/shared/no_data_for_table' %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= render partial: 'admins/shared/paginate', locals: { objects: courses } %>
|
|
@ -1,29 +0,0 @@
|
|||
<div class="modal fade admin-merge-course-list-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">修改课程</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="admin-merge-course-list-form" data-url="<%= merge_admins_course_lists_path %>">
|
||||
<%= hidden_field_tag(:origin_course_list_id, nil) %>
|
||||
|
||||
<div class="form-group d-flex">
|
||||
<label for="course_list_id" class="col-form-label">更改为:</label>
|
||||
<div class="d-flex flex-column-reverse w-75">
|
||||
<input id="course_list_name" name="course_list_name" placeholder="请输入课程名称" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="error text-danger"></div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
|
||||
<button type="button" class="btn btn-primary submit-btn">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,2 +0,0 @@
|
|||
alert("删除成功");
|
||||
$(".course-item-<%= @course.id %>").find(".delete-course-action").remove();
|
|
@ -1,34 +0,0 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('课堂列表') %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container course-list-form">
|
||||
<%= form_tag(admins_courses_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
|
||||
<div class="form-group mr-1">
|
||||
<label for="status">状态:</label>
|
||||
<% status_options = [['全部', ''], ["正在进行(#{@processed_courses})", 'processing'], ["已结束#{@ended_courses}", 'ended']] %>
|
||||
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-12 col-md-3">
|
||||
<label for="school_name">单位:</label>
|
||||
<%= select_tag :school_id, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %>
|
||||
</div>
|
||||
|
||||
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/课堂名称/课程名称检索') %>
|
||||
|
||||
<div class="form-check mr-2">
|
||||
<%= hidden_field_tag(:homepage_show, false, id:'') %>
|
||||
<%= check_box_tag(:homepage_show, true, params[:homepage_show].to_s == 'true', class: 'form-check-input course-homepage-show') %>
|
||||
<label class="form-check-label" for="homepage_show">只看首页展示</label>
|
||||
</div>
|
||||
|
||||
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
|
||||
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
|
||||
<% end %>
|
||||
<a href="javascript:void(0)" class="btn btn-primary" id="course-export" data-disable-with = '导出中...'>导出</a>
|
||||
</div>
|
||||
|
||||
<div class="box admin-list-container course-list-container">
|
||||
<%= render partial: 'admins/courses/shared/list', locals: { courses: @courses } %>
|
||||
</div>
|
|
@ -1 +0,0 @@
|
|||
$('.course-list-container').html("<%= j( render partial: 'admins/courses/shared/list', locals: { courses: @courses } ) %>");
|
|
@ -1,29 +0,0 @@
|
|||
wb = xlsx_package.workbook
|
||||
|
||||
wb.styles do |s|
|
||||
blue_cell = s.add_style :bg_color => "FAEBDC", :sz => 10,:height => 25,:b => true, :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center}
|
||||
wb.add_worksheet(name: "课堂列表") do |sheet|
|
||||
sheet.add_row %w(ID 课堂名称 成员 资源 普通作业 分组作业 实训作业 试卷 评测次数 私有 状态 单位 创建者 创建时间 动态时间), :height => 25,:style => blue_cell
|
||||
|
||||
@courses.each do |course|
|
||||
data = [
|
||||
course.id,
|
||||
course.name,
|
||||
course.course_members_count,
|
||||
get_attachment_count(course, 0),
|
||||
course.course_homework_count(1),
|
||||
course.course_homework_count(3),
|
||||
course.course_homework_count(4),
|
||||
course.exercises_count,
|
||||
course.evaluate_count,
|
||||
course.is_public == 1 ? "--" : "√",
|
||||
course.is_end ? "已结束" : "正在进行",
|
||||
course.school&.name,
|
||||
course.teacher&.real_name,
|
||||
course.created_at&.strftime('%Y-%m-%d %H:%M'),
|
||||
course.max_activity_time ? course.max_activity_time&.strftime('%Y-%m-%d %H:%M') : "--"
|
||||
]
|
||||
sheet.add_row(data)
|
||||
end
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue