Browse Source

FIX code review

tags/v4.0.0
jasder 4 years ago
parent
commit
03beee6cae
100 changed files with 55 additions and 2990 deletions
  1. +3
    -2
      app/controllers/admins/project_categories_controller.rb
  2. +20
    -20
      app/controllers/application_controller.rb
  3. +1
    -1
      app/controllers/attachments_controller.rb
  4. +1
    -1
      app/controllers/concerns/controller_rescue_handler.rb
  5. +2
    -2
      app/controllers/concerns/git_common.rb
  6. +2
    -2
      app/controllers/concerns/git_helper.rb
  7. +0
    -5
      app/decorators/course_decorator.rb
  8. +0
    -2
      app/decorators/ec_course_target_decorator.rb
  9. +0
    -16
      app/decorators/experience_decorator.rb
  10. +0
    -39
      app/decorators/grade_decorator.rb
  11. +0
    -5
      app/decorators/library_decorator.rb
  12. +0
    -5
      app/decorators/shixun_decorator.rb
  13. +0
    -5
      app/decorators/subject_decorator.rb
  14. +0
    -5
      app/decorators/video_decorator.rb
  15. +0
    -10
      app/forms/add_school_apply_form.rb
  16. +0
    -27
      app/forms/apply_shixun_mirror_form.rb
  17. +0
    -15
      app/forms/examination_banks/save_exam_form.rb
  18. +0
    -12
      app/forms/examination_intelligent_settings/save_exam_form.rb
  19. +0
    -11
      app/forms/examination_intelligent_settings/save_exam_setting_form.rb
  20. +0
    -20
      app/forms/weapps/create_course_form.rb
  21. +0
    -15
      app/forms/weapps/update_course_form.rb
  22. +1
    -1
      app/helpers/admins/projects_helper.rb
  23. +1
    -1
      app/helpers/application_helper.rb
  24. +0
    -2
      app/helpers/boards_helper.rb
  25. +0
    -10
      app/helpers/challenges_helper.rb
  26. +0
    -2
      app/helpers/course_groups_helper.rb
  27. +0
    -2
      app/helpers/course_modules_helper.rb
  28. +0
    -2
      app/helpers/course_second_categories_helper.rb
  29. +0
    -2
      app/helpers/course_stages_helper.rb
  30. +0
    -298
      app/helpers/courses_helper.rb
  31. +0
    -2
      app/helpers/discusses_helper.rb
  32. +0
    -2
      app/helpers/edu_datas_helper.rb
  33. +0
    -150
      app/helpers/graduation_tasks_helper.rb
  34. +0
    -30
      app/helpers/graduation_topics_helper.rb
  35. +0
    -20
      app/helpers/graduation_works_helper.rb
  36. +0
    -2
      app/helpers/hack_user_lastest_codes_helper.rb
  37. +0
    -2
      app/helpers/hacks_helper.rb
  38. +0
    -2
      app/helpers/trustie_hacks_helper.rb
  39. +0
    -69
      app/helpers/weapps/courses_helper.rb
  40. +0
    -20
      app/imports/admins/import_course_member_excel.rb
  41. +0
    -23
      app/jobs/batch_publish_video_notify_job.rb
  42. +0
    -67
      app/jobs/course_add_student_create_works_job.rb
  43. +0
    -19
      app/jobs/course_delete_student_delete_works_job.rb
  44. +0
    -22
      app/jobs/course_delete_student_notify_job.rb
  45. +0
    -12
      app/jobs/create_diff_record_job.rb
  46. +0
    -21
      app/jobs/delete_department_notify_job.rb
  47. +0
    -44
      app/jobs/exercise_publish_notify_job.rb
  48. +0
    -17
      app/jobs/get_aliyun_video_info_job.rb
  49. +0
    -22
      app/jobs/graduation_task_cross_comment_job.rb
  50. +0
    -28
      app/jobs/graduation_task_publish_notify_job.rb
  51. +0
    -33
      app/jobs/resubmit_student_work_notify_job.rb
  52. +1
    -69
      app/models/laboratory.rb
  53. +17
    -17
      app/models/token.rb
  54. +1
    -1
      app/models/user.rb
  55. +0
    -30
      app/queries/admins/course_list_query.rb
  56. +0
    -44
      app/queries/admins/course_query.rb
  57. +0
    -25
      app/queries/admins/department_apply_query.rb
  58. +0
    -32
      app/queries/admins/department_query.rb
  59. +0
    -36
      app/queries/admins/laboratory_shixun_query.rb
  60. +0
    -23
      app/queries/admins/school_query.rb
  61. +0
    -49
      app/queries/admins/subject_query.rb
  62. +0
    -28
      app/queries/users/video_query.rb
  63. +0
    -37
      app/queries/weapps/search_query.rb
  64. +0
    -37
      app/queries/weapps/subject_query.rb
  65. +0
    -20
      app/services/admins/add_department_member_service.rb
  66. +0
    -89
      app/services/admins/check_shixun_mirrors_service.rb
  67. +0
    -35
      app/services/admins/drag_cooperative_service.rb
  68. +0
    -35
      app/services/admins/drag_portal_image_service.rb
  69. +0
    -32
      app/services/admins/drag_weapp_advert_service.rb
  70. +0
    -32
      app/services/admins/drag_weapp_carousel_service.rb
  71. +0
    -63
      app/services/admins/import_course_member_service.rb
  72. +0
    -123
      app/services/admins/school_daily_statistic_service.rb
  73. +0
    -43
      app/services/admins/shixun_auths/agree_apply_service.rb
  74. +0
    -35
      app/services/admins/shixun_auths/refuse_apply_service.rb
  75. +0
    -80
      app/services/admins/statistic_school_contrast_data_service.rb
  76. +0
    -107
      app/services/admins/statistic_school_data_grow_service.rb
  77. +0
    -30
      app/services/admins/subject_auths/agree_apply_service.rb
  78. +0
    -35
      app/services/admins/subject_auths/refuse_apply_service.rb
  79. +0
    -2
      app/services/courses_service.rb
  80. +0
    -44
      app/services/create_add_department_apply_service.rb
  81. +0
    -37
      app/services/create_add_school_apply_service.rb
  82. +0
    -164
      app/services/duplicate_course_service.rb
  83. +1
    -1
      app/services/projects/apply_join_service.rb
  84. +0
    -24
      app/services/reward_experience_service.rb
  85. +1
    -1
      app/services/users/apply_authentication_service.rb
  86. +1
    -1
      app/services/users/apply_professional_auth_service.rb
  87. +1
    -1
      app/services/users/apply_trail_service.rb
  88. +0
    -52
      app/services/users/course_service.rb
  89. +0
    -99
      app/services/users/question_bank_service.rb
  90. +1
    -1
      app/services/users/update_account_service.rb
  91. +0
    -40
      app/services/weapps/create_course_service.rb
  92. +0
    -34
      app/services/weapps/update_course_service.rb
  93. +0
    -22
      app/views/admins/course_lists/index.html.erb
  94. +0
    -1
      app/views/admins/course_lists/index.js.erb
  95. +0
    -37
      app/views/admins/course_lists/shared/_list.html.erb
  96. +0
    -29
      app/views/admins/course_lists/shared/_merge_course_list_modal.html.erb
  97. +0
    -2
      app/views/admins/courses/destroy.js.erb
  98. +0
    -34
      app/views/admins/courses/index.html.erb
  99. +0
    -1
      app/views/admins/courses/index.js.erb
  100. +0
    -29
      app/views/admins/courses/index.xlsx.axlsx

+ 3
- 2
app/controllers/admins/project_categories_controller.rb View File

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



+ 20
- 20
app/controllers/application_controller.rb View File

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


+ 1
- 1
app/controllers/attachments_controller.rb View File

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


+ 1
- 1
app/controllers/concerns/controller_rescue_handler.rb View File

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


+ 2
- 2
app/controllers/concerns/git_common.rb View File

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


+ 2
- 2
app/controllers/concerns/git_helper.rb View File

@@ -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}")


+ 0
- 5
app/decorators/course_decorator.rb View File

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

+ 0
- 2
app/decorators/ec_course_target_decorator.rb View File

@@ -1,2 +0,0 @@
module EcCourseTargetDecorator
end

+ 0
- 16
app/decorators/experience_decorator.rb View File

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

+ 0
- 39
app/decorators/grade_decorator.rb View File

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

+ 0
- 5
app/decorators/library_decorator.rb View File

@@ -1,5 +0,0 @@
module LibraryDecorator
extend ApplicationDecorator

display_time_method :published_at, :created_at, :updated_at
end

+ 0
- 5
app/decorators/shixun_decorator.rb View File

@@ -1,5 +0,0 @@
module ShixunDecorator
def human_status
I18n.t("shixun.status.#{status}")
end
end

+ 0
- 5
app/decorators/subject_decorator.rb View File

@@ -1,5 +0,0 @@
module SubjectDecorator
def can_visited?
published? || User.current.admin? || member?(User.current)
end
end

+ 0
- 5
app/decorators/video_decorator.rb View File

@@ -1,5 +0,0 @@
module VideoDecorator
extend ApplicationDecorator

display_time_method :published_at, :created_at, :updated_at
end

+ 0
- 10
app/forms/add_school_apply_form.rb View File

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

+ 0
- 27
app/forms/apply_shixun_mirror_form.rb View File

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

+ 0
- 15
app/forms/examination_banks/save_exam_form.rb View File

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

+ 0
- 12
app/forms/examination_intelligent_settings/save_exam_form.rb View File

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

+ 0
- 11
app/forms/examination_intelligent_settings/save_exam_setting_form.rb View File

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

+ 0
- 20
app/forms/weapps/create_course_form.rb View File

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

+ 0
- 15
app/forms/weapps/update_course_form.rb View File

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

+ 1
- 1
app/helpers/admins/projects_helper.rb View File

@@ -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
- 1
app/helpers/application_helper.rb View File

@@ -1,6 +1,6 @@
# 所有的方法请按首字母的顺序依次列出
module ApplicationHelper
include Educoder::I18n
include Gitlink::I18n
include GitHelper
ONE_MINUTE = 60 * 1000


+ 0
- 2
app/helpers/boards_helper.rb View File

@@ -1,2 +0,0 @@
module BoardsHelper
end

+ 0
- 10
app/helpers/challenges_helper.rb View File

@@ -1,10 +0,0 @@
module ChallengesHelper
def match_begin_symbol str
str.gsub(/\A\r/, "\r\r")
end
end

+ 0
- 2
app/helpers/course_groups_helper.rb View File

@@ -1,2 +0,0 @@
module CourseGroupsHelper
end

+ 0
- 2
app/helpers/course_modules_helper.rb View File

@@ -1,2 +0,0 @@
module CourseModulesHelper
end

+ 0
- 2
app/helpers/course_second_categories_helper.rb View File

@@ -1,2 +0,0 @@
module CourseSecondCategoriesHelper
end

+ 0
- 2
app/helpers/course_stages_helper.rb View File

@@ -1,2 +0,0 @@
module CourseStagesHelper
end

+ 0
- 298
app/helpers/courses_helper.rb View File

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

+ 0
- 2
app/helpers/discusses_helper.rb View File

@@ -1,2 +0,0 @@
module DiscussesHelper
end

+ 0
- 2
app/helpers/edu_datas_helper.rb View File

@@ -1,2 +0,0 @@
module EduDatasHelper
end

+ 0
- 150
app/helpers/graduation_tasks_helper.rb View File

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

+ 0
- 30
app/helpers/graduation_topics_helper.rb View File

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

+ 0
- 20
app/helpers/graduation_works_helper.rb View File

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

+ 0
- 2
app/helpers/hack_user_lastest_codes_helper.rb View File

@@ -1,2 +0,0 @@
module HackUserLastestCodesHelper
end

+ 0
- 2
app/helpers/hacks_helper.rb View File

@@ -1,2 +0,0 @@
module HacksHelper
end

+ 0
- 2
app/helpers/trustie_hacks_helper.rb View File

@@ -1,2 +0,0 @@
module TrustieHacksHelper
end

+ 0
- 69
app/helpers/weapps/courses_helper.rb View File

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

+ 0
- 20
app/imports/admins/import_course_member_excel.rb View File

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

+ 0
- 23
app/jobs/batch_publish_video_notify_job.rb View File

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

+ 0
- 67
app/jobs/course_add_student_create_works_job.rb View File

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

+ 0
- 19
app/jobs/course_delete_student_delete_works_job.rb View File

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

+ 0
- 22
app/jobs/course_delete_student_notify_job.rb View File

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

+ 0
- 12
app/jobs/create_diff_record_job.rb View File

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

+ 0
- 21
app/jobs/delete_department_notify_job.rb View File

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

+ 0
- 44
app/jobs/exercise_publish_notify_job.rb View File

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

+ 0
- 17
app/jobs/get_aliyun_video_info_job.rb View File

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

+ 0
- 22
app/jobs/graduation_task_cross_comment_job.rb View File

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

+ 0
- 28
app/jobs/graduation_task_publish_notify_job.rb View File

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

+ 0
- 33
app/jobs/resubmit_student_work_notify_job.rb View File

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

+ 1
- 69
app/models/laboratory.rb View File

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


+ 17
- 17
app/models/token.rb View File

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


+ 1
- 1
app/models/user.rb View File

@@ -690,7 +690,7 @@ class User < Owner
end

def self.generate_salt
Educoder::Utils.random_hex(16)
Gitlink::Utils.random_hex(16)
end

# 全部已认证


+ 0
- 30
app/queries/admins/course_list_query.rb View File

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

+ 0
- 44
app/queries/admins/course_query.rb View File

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

+ 0
- 25
app/queries/admins/department_apply_query.rb View File

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

+ 0
- 32
app/queries/admins/department_query.rb View File

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

+ 0
- 36
app/queries/admins/laboratory_shixun_query.rb View File

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

+ 0
- 23
app/queries/admins/school_query.rb View File

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

+ 0
- 49
app/queries/admins/subject_query.rb View File

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

+ 0
- 28
app/queries/users/video_query.rb View File

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

+ 0
- 37
app/queries/weapps/search_query.rb View File

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

+ 0
- 37
app/queries/weapps/subject_query.rb View File

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

+ 0
- 20
app/services/admins/add_department_member_service.rb View File

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

+ 0
- 89
app/services/admins/check_shixun_mirrors_service.rb View File

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

+ 0
- 35
app/services/admins/drag_cooperative_service.rb View File

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

+ 0
- 35
app/services/admins/drag_portal_image_service.rb View File

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

+ 0
- 32
app/services/admins/drag_weapp_advert_service.rb View File

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

+ 0
- 32
app/services/admins/drag_weapp_carousel_service.rb View File

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

+ 0
- 63
app/services/admins/import_course_member_service.rb View File

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

+ 0
- 123
app/services/admins/school_daily_statistic_service.rb View File

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

+ 0
- 43
app/services/admins/shixun_auths/agree_apply_service.rb View File

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

+ 0
- 35
app/services/admins/shixun_auths/refuse_apply_service.rb View File

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

+ 0
- 80
app/services/admins/statistic_school_contrast_data_service.rb View File

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

+ 0
- 107
app/services/admins/statistic_school_data_grow_service.rb View File

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

+ 0
- 30
app/services/admins/subject_auths/agree_apply_service.rb View File

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

+ 0
- 35
app/services/admins/subject_auths/refuse_apply_service.rb View File

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

+ 0
- 2
app/services/courses_service.rb View File

@@ -1,2 +0,0 @@
class CoursesService
end

+ 0
- 44
app/services/create_add_department_apply_service.rb View File

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

+ 0
- 37
app/services/create_add_school_apply_service.rb View File

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

+ 0
- 164
app/services/duplicate_course_service.rb View File

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

+ 1
- 1
app/services/projects/apply_join_service.rb View File

@@ -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}")


+ 0
- 24
app/services/reward_experience_service.rb View File

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

+ 1
- 1
app/services/users/apply_authentication_service.rb View File

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

+ 1
- 1
app/services/users/apply_professional_auth_service.rb View File

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


+ 1
- 1
app/services/users/apply_trail_service.rb View File

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


+ 0
- 52
app/services/users/course_service.rb View File

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

+ 0
- 99
app/services/users/question_bank_service.rb View File

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

+ 1
- 1
app/services/users/update_account_service.rb View File

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


+ 0
- 40
app/services/weapps/create_course_service.rb View File

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

+ 0
- 34
app/services/weapps/update_course_service.rb View File

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

+ 0
- 22
app/views/admins/course_lists/index.html.erb View File

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

+ 0
- 1
app/views/admins/course_lists/index.js.erb View File

@@ -1 +0,0 @@
$(".course-list-list-container").html("<%= j render partial: 'admins/course_lists/shared/list', locals: { courses: @course_lists }%>");

+ 0
- 37
app/views/admins/course_lists/shared/_list.html.erb View File

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

+ 0
- 29
app/views/admins/course_lists/shared/_merge_course_list_modal.html.erb View File

@@ -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">&times;</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>

+ 0
- 2
app/views/admins/courses/destroy.js.erb View File

@@ -1,2 +0,0 @@
alert("删除成功");
$(".course-item-<%= @course.id %>").find(".delete-course-action").remove();

+ 0
- 34
app/views/admins/courses/index.html.erb View File

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

+ 0
- 1
app/views/admins/courses/index.js.erb View File

@@ -1 +0,0 @@
$('.course-list-container').html("<%= j( render partial: 'admins/courses/shared/list', locals: { courses: @courses } ) %>");

+ 0
- 29
app/views/admins/courses/index.xlsx.axlsx View File

@@ -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 changed in this diff

Loading…
Cancel
Save