| @@ -1,12 +0,0 @@ | |||||
| class BlobController < ApplicationController | |||||
| def new | |||||
| commit unless @repository.empty? | |||||
| end | |||||
| def create | |||||
| create_commit(Files::CreateService, success_path: after_create_path, | |||||
| failure_view: :new, | |||||
| failure_path: namespace_project_new_blob_path(@project.namespace, @project, @ref)) | |||||
| end | |||||
| end | |||||
| @@ -1,341 +0,0 @@ | |||||
| class ChallengesController < ApplicationController | |||||
| before_action :require_login, :check_auth, except: [:index] | |||||
| before_action :find_shixun, only: [:new, :create, :index] | |||||
| skip_before_action :verify_authenticity_token, only: [:create, :update, :create_choose_question, :crud_answer] | |||||
| before_action :find_challenge, only: [:edit, :show, :update, :create_choose_question, :index_down, :index_up, | |||||
| :edit_choose_question, :show_choose_question, :destroy_challenge_choose, | |||||
| :update_choose_question, :destroy, :crud_answer, :answer] | |||||
| # 关卡更新和操作的权限控制 | |||||
| before_action :update_allowed, except: [:index] | |||||
| # 关卡访问的权限控制 | |||||
| before_action :shixun_access_allowed, only: [:index] | |||||
| include ChallengesHelper | |||||
| # 新建实践题 | |||||
| def new | |||||
| @position = @shixun.challenges.count + 1 | |||||
| @st = params[:st].to_i | |||||
| @task_pass_default = PlatformSample.find_by(samples_type: "taskPass").try(:contents) | |||||
| end | |||||
| # params | |||||
| # challenge:{"subject": "标题", "task_pass": "过关任务", | |||||
| # "diffculty": "关卡难度", "score": "关卡分数", "st": "关卡类型"} 关卡相关信息 | |||||
| # challenge_tag: 关卡标签 | |||||
| # | |||||
| def create | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @challenge = Challenge.new(challenge_params) | |||||
| @challenge.position = @shixun.challenges.count + 1 | |||||
| @challenge.shixun_id = @shixun.id | |||||
| @challenge.user_id = current_user.id | |||||
| @challenge.modify_time = Time.now | |||||
| @challenge.save! | |||||
| # 实训是否需要重置, 非实践任务创建第一个阶段调用, 避免不包含实践任务的实训进行模拟实战报错 todo: 新建实训需要重置TPI | |||||
| # shixun_modify_status_without_publish(@shixun, 1) if @challenge.position != 1 | |||||
| tags = params[:challenge_tag] | |||||
| if tags.present? | |||||
| tags.each do |tag| | |||||
| # TODO 创建tag的时候为什么一直报challenge choose必须存在?? | |||||
| ChallengeTag.create!(name: tag, challenge_id: @challenge.id) | |||||
| end | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error("create challenge failed #{e}") | |||||
| end | |||||
| end | |||||
| end | |||||
| # 创建选择题 | |||||
| def create_choose_question | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @challenge_choose = ChallengeChoose.new(chooce_params) | |||||
| @challenge_choose.position = @challenge.challenge_chooses.count + 1 | |||||
| @challenge_choose.category = @challenge_choose.standard_answer.length == 1 ? 1 : 2 | |||||
| @challenge_choose.challenge_id = @challenge.id | |||||
| if @challenge_choose.save! | |||||
| # 创建选项 | |||||
| params[:question][:cnt].each_with_index do |test, index| | |||||
| answer = params[:choice][:answer][index] | |||||
| ChallengeQuestion.create(:option_name => test, | |||||
| :challenge_choose_id => @challenge_choose.id, | |||||
| :position => index, :right_key => answer) | |||||
| end | |||||
| # 创建单选多选的技能标签 | |||||
| if params[:challenge_tag].present? | |||||
| params[:challenge_tag].each do |tag| | |||||
| ChallengeTag.create(:name => tag, :challenge_choose_id => @challenge_choose.id, :challenge_id => @challenge.id) | |||||
| end | |||||
| end | |||||
| @challenge.update_column(:score, @challenge.challenge_chooses.sum(:score)) | |||||
| end | |||||
| rescue Exception => e | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| # 选择题详情页面 | |||||
| def show_choose_question | |||||
| @challenge_choose = ChallengeChoose.find params[:choose_id] | |||||
| end | |||||
| # 选择题更新页面 | |||||
| def update_choose_question | |||||
| @challenge_choose = ChallengeChoose.find(params[:choose_id]) | |||||
| ActiveRecord::Base.transaction do | |||||
| if params[:standard_answer] != @challenge_choose.standard_answer | |||||
| @challenge.update_column(:modify_time, Time.now) | |||||
| end | |||||
| @challenge_choose.update_attributes(chooce_params) | |||||
| @challenge.update_column(:score, @challenge.challenge_chooses.sum(:score)) | |||||
| # 单选多选题的更新 | |||||
| category = @challenge_choose.standard_answer.length > 1 ? 2 : 1 | |||||
| @challenge_choose.update_column(:category, category) | |||||
| begin | |||||
| @challenge_choose.challenge_questions.delete_all | |||||
| params[:question][:cnt].each_with_index do |test, index| | |||||
| answer = params[:choice][:answer][index] | |||||
| ChallengeQuestion.create(:option_name => test, :challenge_choose_id => @challenge_choose.id, :position => index, :right_key => answer) | |||||
| end | |||||
| @challenge_choose.challenge_tags.delete_all unless @challenge_choose.challenge_tags.blank? | |||||
| if params[:challenge_tag].present? | |||||
| params[:challenge_tag].each do |tag| | |||||
| ChallengeTag.create(:name => tag, :challenge_choose_id => @challenge_choose.id, :challenge_id => @challenge.id) | |||||
| end | |||||
| end | |||||
| @challenge_choose = ChallengeChoose.find params[:choose_id] | |||||
| rescue Exception => e | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| # 选择题的编辑 | |||||
| def edit_choose_question | |||||
| @challenge_choose = ChallengeChoose.find params[:choose_id] | |||||
| end | |||||
| def destroy_challenge_choose | |||||
| ActiveRecord::Base.transaction do | |||||
| @challenge_choose = ChallengeChoose.where(:id => params[:choose_id]).first | |||||
| pos = @challenge_choose.position | |||||
| @challenge.challenge_chooses.where("position > ?", pos).update_all("position = position - 1") | |||||
| @challenge_choose.destroy | |||||
| @status = 1 | |||||
| # 发起重置请求 TODO: 重置实训需要后续做 | |||||
| # shixun_modify_status_without_publish(@shixun, 1) | |||||
| end | |||||
| end | |||||
| # 编辑模式 | |||||
| # tab 0,nil 过关任务, 1 评测设置, 2 参考答案 | |||||
| def edit | |||||
| @tab = params[:tab].to_i | |||||
| @power = @shixun.status == 0 | |||||
| challenge_num = Challenge.where(:shixun_id => @shixun).count | |||||
| @position = @challenge.position | |||||
| @chooses = @challenge.challenge_chooses | |||||
| if @position < challenge_num | |||||
| @next_challenge = Challenge.where(:shixun_id => @shixun, :position => @position + 1).first | |||||
| end | |||||
| @prev_challenge = Challenge.where(:shixun_id => @shixun, :position => @position - 1).first if @position - 1 > 0 | |||||
| end | |||||
| def index | |||||
| uid_logger("identifier: #{params}") | |||||
| @challenges = @shixun.challenges.fields_for_list | |||||
| @editable = @shixun.status == 0 # before_action:有判断权限,如果没发布,则肯定是管理人员 | |||||
| @user = current_user | |||||
| @shixun.increment!(:visits) | |||||
| end | |||||
| def show | |||||
| @tab = params[:tab].nil? ? 1 : params[:tab].to_i | |||||
| challenge_num = @shixun.challenges_count | |||||
| @power = @shixun.status == 0 # 之前验证走过了是不是管理员,因此这里只用判断是否发布 | |||||
| @position = @challenge.position | |||||
| if @position < challenge_num | |||||
| @next_challenge = Challenge.where(:shixun_id => @shixun, :position => @position + 1).first | |||||
| end | |||||
| @prev_challenge = Challenge.where(:shixun_id => @shixun, :position => @position - 1).first if @position - 1 > 0 | |||||
| end | |||||
| # tab 0:过关任务的更新; 1:评测设置的更新; 2:表示参考答案的更新; | |||||
| def update | |||||
| begin | |||||
| ActiveRecord::Base.transaction do | |||||
| tab = params[:tab].to_i | |||||
| @challenge.update_attributes!(challenge_params) | |||||
| if tab == 0 && @challenge.st == 0 | |||||
| @challenge.challenge_tags.delete_all | |||||
| if params[:challenge_tag].present? | |||||
| params[:challenge_tag].each do |input| | |||||
| ChallengeTag.create!(:name => input, :challenge_id => @challenge.id) | |||||
| end | |||||
| end | |||||
| elsif tab == 1 | |||||
| path = @challenge.path | |||||
| exec_path = @challenge.exec_path | |||||
| test_set = @challenge.test_sets | |||||
| sets_output = test_set.map(&:output) | |||||
| sets_input = test_set.map(&:input) | |||||
| sets_open = test_set.map(&:is_public) | |||||
| set_score = test_set.map(&:score) | |||||
| set_match_rule = test_set.map(&:match_rule) | |||||
| params_hidden = params[:test_set].map{|set| set[:hidden].to_i == 0} | |||||
| params_output = params[:test_set].map{|set| set[:output] } | |||||
| params_input = params[:test_set].map{|set| set[:input] } | |||||
| params_score = params[:test_set].map{|set| set[:score]} | |||||
| params_test_set = params[:test_set].map{|set| set[:match_rule]} | |||||
| # 测试集变化则需要更新(输入、 输出、 是否隐藏) | |||||
| if sets_output != params_output || sets_open != params_hidden || sets_input != params_input || | |||||
| set_score != params_score || params_test_set != set_match_rule | |||||
| test_set.delete_all unless test_set.blank? | |||||
| params[:test_set].each_with_index do |set, index| | |||||
| # last: 末尾匹配, full: 全完匹配 | |||||
| logger.info("set: #{set}; match_rule : #{set[:match_rule]}") | |||||
| match_rule = set[:match_rule] == 'last' ? 'last' : 'full' | |||||
| TestSet.create!(:challenge_id => @challenge.id, | |||||
| :input => "#{set[:input]}", | |||||
| :output => "#{set[:output]}", | |||||
| :is_public => params_hidden[index], | |||||
| :score => set[:score], | |||||
| :match_rule => "#{match_rule}", | |||||
| :position => (index + 1)) | |||||
| end | |||||
| @challenge.update_column(:modify_time, Time.now) | |||||
| # 测试集的 | |||||
| @shixun.myshixuns.update_all(:system_tip => 0) | |||||
| end | |||||
| if params[:challenge][:show_type].to_i == -1 | |||||
| @challenge.update_attributes(picture_path: nil, web_route: nil, expect_picture_path: nil, original_picture_path: nil) | |||||
| end | |||||
| # 关卡评测执行文件如果被修改,需要修改脚本内容 | |||||
| logger.info("############shixun_publiced:#{@shixun.public == 0}") | |||||
| if @shixun.public == 0 | |||||
| script = modify_shixun_script @shixun, @shixun.evaluate_script | |||||
| @shixun.shixun_info.update_column(:evaluate_script, script) | |||||
| end | |||||
| # TODO: | |||||
| # if path != params[:challenge][:path] | |||||
| # shixun_modify_status_without_publish(@shixun, 1) | |||||
| # end | |||||
| #Attachment.attach_files(@challenge, params[:attachments]) | |||||
| end | |||||
| end | |||||
| rescue Exception => e | |||||
| logger.error("##update_challenges: ##{e.message}") | |||||
| tip_exception("#{e.message}") | |||||
| end | |||||
| end | |||||
| # 参考答案的'增,删,改' | |||||
| # POST: /shixuns/:id/challenges/:id/crud_answer | |||||
| # {'challenge_answer': [ | |||||
| # {'name': 'name', contents: 'contents', score: 10}, | |||||
| # {...}, | |||||
| # {...}, ...] | |||||
| #} | |||||
| def crud_answer | |||||
| if @challenge.challenge_answers && params[:challenge_answer].blank? | |||||
| @challenge.challenge_answers.destroy_all | |||||
| else | |||||
| raise '参考答案不能为空' if params[:challenge_answer].empty? | |||||
| raise '占比之和必须为100%' if params[:challenge_answer].map{|a| a[:score]}.sum != 100 | |||||
| ActiveRecord::Base.transaction do | |||||
| @challenge.challenge_answers.destroy_all if @challenge.challenge_answers | |||||
| params[:challenge_answer].each_with_index do |answer, index| | |||||
| # 内容为空不保存 | |||||
| next if answer[:contents].blank? | |||||
| ChallengeAnswer.create!(name: answer[:name], contents: answer[:contents], | |||||
| level: index+1, score: answer[:score], challenge_id: @challenge.id) | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| # 查看参考答案接口 | |||||
| def answer | |||||
| @answers = @challenge.challenge_answers | |||||
| end | |||||
| def index_down | |||||
| next_challenge = @challenge.next_challenge | |||||
| position = @challenge.position | |||||
| @challenge.update_attribute(:position, (position + 1)) | |||||
| next_challenge.update_attribute(:position, next_challenge.position - 1) | |||||
| # 关卡位置被修改,需要修改脚本 | |||||
| script = modify_shixun_script @shixun, @shixun.evaluate_script | |||||
| @shixun.shixun_info.update_column(:evaluate_script, script) | |||||
| end | |||||
| def index_up | |||||
| position = @challenge.position | |||||
| last_challenge = @challenge.last_challenge | |||||
| @challenge.update_attribute(:position, (position - 1)) | |||||
| last_challenge.update_attribute(:position, last_challenge.position + 1) | |||||
| # 关卡位置被修改,需要修改脚本 | |||||
| script = modify_shixun_script @shixun, @shixun.evaluate_script | |||||
| @shixun.shixun_info.update_column(:evaluate_script, script) | |||||
| end | |||||
| def destroy | |||||
| next_challenges = @shixun.challenges.where("position > #{@challenge.position}") | |||||
| next_challenges.update_all("position = position - 1") | |||||
| # Todo: 实训修改后,关卡需要重置 | |||||
| # shixun_modify_status_without_publish(@shixun, 1) | |||||
| @challenge.destroy | |||||
| # 关卡位置被删除,需要修改脚本 | |||||
| script = modify_shixun_script @shixun, @shixun.evaluate_script | |||||
| @shixun.shixun_info.update_column(:evaluate_script, script) | |||||
| end | |||||
| private | |||||
| def find_shixun | |||||
| @shixun = Shixun.find_by_identifier(params[:shixun_identifier]) | |||||
| end | |||||
| # 通用接口 | |||||
| def find_challenge | |||||
| @challenge = Challenge.find params[:id] | |||||
| @shixun = Shixun.find_by!(identifier: params[:shixun_identifier]) | |||||
| end | |||||
| def challenge_params | |||||
| tip_exception("评测时间不能超过300秒") if params[:challenge][:exec_time].to_i > 300 | |||||
| params.require(:challenge).permit(:subject, :task_pass, :difficulty, :score, :st, :modify_time, :test_set_average, | |||||
| :path, :exec_path, :show_type, :original_picture_path, :test_set_score, | |||||
| :expect_picture_path, :picture_path, :web_route, :answer, :exec_time) | |||||
| end | |||||
| def chooce_params | |||||
| params.require(:challenge_choose).permit(:subject, :answer, | |||||
| :standard_answer, :score, :difficult) | |||||
| end | |||||
| def update_allowed | |||||
| unless current_user.manager_of_shixun?(@shixun) | |||||
| raise Educoder::TipException.new(403, "..") | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,75 +0,0 @@ | |||||
| class CommentsController < ApplicationController | |||||
| before_action :find_hack | |||||
| before_action :require_login | |||||
| # 评论 | |||||
| def create | |||||
| begin | |||||
| @discuss = @hack.discusses.new(comment_params) # 管理员回复的能够显示 | |||||
| @discuss.hidden = false | |||||
| @discuss.user_id = current_user.id | |||||
| @discuss.save! | |||||
| rescue Exception => e | |||||
| uid_logger_error("create discuss failed : #{e.message}") | |||||
| render_error("评论异常") | |||||
| end | |||||
| end | |||||
| # 回复 | |||||
| def reply | |||||
| begin | |||||
| @discuss = @hack.discusses.new(reply_params) | |||||
| @discuss.hidden = false | |||||
| @discuss.user_id = current_user.id | |||||
| @discuss.root_id = params[:comments][:parent_id] | |||||
| @discuss.save! | |||||
| rescue Exception => e | |||||
| uid_logger_error("reply discuss failed : #{e.message}") | |||||
| render_error("回复评论异常") | |||||
| end | |||||
| end | |||||
| # 列表 | |||||
| def index | |||||
| discusses = | |||||
| if current_user.admin_or_business? | |||||
| @hack.discusses.where(root_id: nil) | |||||
| else | |||||
| @hack.discusses.where(root_id: nil, hidden: false) | |||||
| end | |||||
| @discusses_count = discusses.count | |||||
| @discusses= paginate discusses | |||||
| end | |||||
| # 删除 | |||||
| def destroy | |||||
| @hack.discusses.find_by(id: params[:id]).destroy | |||||
| render_ok | |||||
| end | |||||
| # 隐藏、取消隐藏 | |||||
| def hidden | |||||
| if current_user.admin_or_business? | |||||
| @discuss = @hack.discusses.where(id: params[:id]).first | |||||
| @discuss.update_attribute(:hidden, params[:hidden].to_i == 1) | |||||
| sucess_status | |||||
| else | |||||
| Educoder::TipException(403, "..") | |||||
| end | |||||
| end | |||||
| private | |||||
| def find_hack | |||||
| @hack = Hack.find_by_identifier(params[:hack_identifier]) | |||||
| end | |||||
| def comment_params | |||||
| params.require(:comments).permit(:content) | |||||
| end | |||||
| def reply_params | |||||
| params.require(:comments).permit(:content, :parent_id) | |||||
| end | |||||
| end | |||||
| @@ -1,38 +0,0 @@ | |||||
| class ComposeProjectsController < ApplicationController | |||||
| #未做完 | |||||
| before_action :require_login | |||||
| before_action :set_compose | |||||
| def create | |||||
| project_ids = params[:project_ids] | |||||
| ComposeProject.transaction do | |||||
| project_ids.each do |p| | |||||
| project = Project.select(:id, :user_id).find(p) | |||||
| unless project.blank? || ComposeProject.exists?(user_id: project.user_id, project_id: p, compose_id: @compose.id) | |||||
| ComposeProject.create!(user_id: project.user_id, project_id: p, compose_id: @compose.id, position: p) | |||||
| end | |||||
| end | |||||
| end | |||||
| normal_status(0, "添加成功") | |||||
| end | |||||
| def destroy | |||||
| project_ids = params[:project_ids] | |||||
| if ComposeProject.where(project_id: project_ids, compose_id: @compose.id).delete_all | |||||
| normal_status(0, "项目删除成功") | |||||
| else | |||||
| normal_status(-1, "项目删除失败") | |||||
| end | |||||
| end | |||||
| private | |||||
| def set_compose | |||||
| @compose = Compose.find(params[:compose_id]) | |||||
| unless @compose.present? | |||||
| normal_status(-1, "组织不存在") | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,99 +0,0 @@ | |||||
| class ComposesController < ApplicationController | |||||
| before_action :require_login, except: [:index] | |||||
| before_action :find_compose, except: [:index, :new,:create] | |||||
| def index | |||||
| @order_type = params[:order] || "created_at" | |||||
| @search_name = params[:search] | |||||
| composes = Compose.compose_includes | |||||
| if @search_name.present? | |||||
| composes = composes.where("title like ?", "%#{@search_name}%") | |||||
| end | |||||
| composes = composes.order("#{@order_type} desc") | |||||
| @page = params[:page] || 1 | |||||
| @limit = params[:limit] || 15 | |||||
| @composes_size = composes.size | |||||
| @composes = composes.page(@page).per(@limit) | |||||
| end | |||||
| def new | |||||
| end | |||||
| def create | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @compose = Compose.new(compose_params.merge(user_id: current_user.id)) | |||||
| if @compose.save | |||||
| ComposeUser.create!(user_id: current_user.id, compose_id: @compose.id, is_manager: 1) | |||||
| normal_status(0,"组织创建成功") | |||||
| else | |||||
| error_messages = @compose.errors.messages[:title][0] | |||||
| normal_status(-1,"组织创建失败:#{error_messages}") | |||||
| end | |||||
| rescue Exception => e | |||||
| tip_exception("#{e}") | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| def edit | |||||
| end | |||||
| def update | |||||
| if @compose.update_attributes(compose_params) | |||||
| normal_status(0,"组织更新成功") | |||||
| else | |||||
| error_messages = @compose.errors.messages[:title][0] | |||||
| normal_status(-1,"组织更新失败:#{error_messages}") | |||||
| end | |||||
| end | |||||
| def destroy | |||||
| if @compose.destroy | |||||
| normal_status(0,"组织删除成功") | |||||
| else | |||||
| normal_status(-1,"组织删除失败,请稍后重试") | |||||
| end | |||||
| end | |||||
| def show | |||||
| compose_projects_ids = @compose&.compose_projects&.pluck(:project_id) | |||||
| search = params[:search] | |||||
| if compose_projects_ids.size > 0 | |||||
| compose_projects = Project.where(id: compose_projects_ids) | |||||
| if search.present? | |||||
| compose_projects = compose_projects.where("name like ? ", "%#{search.to_s.strip}%") | |||||
| end | |||||
| else | |||||
| compose_projects = [] | |||||
| end | |||||
| @compose_projects_size = compose_projects.size | |||||
| if @compose_projects_size > 0 | |||||
| @page = params[:page] || 1 | |||||
| @limit = params[:limit] || 15 | |||||
| @compose_projects = compose_projects.page(@page).per(@limit) | |||||
| else | |||||
| @compose_projects = compose_projects | |||||
| end | |||||
| end | |||||
| private | |||||
| def compose_params | |||||
| params.require(:compose).permit(:user_id, :title, :description, :show_mode, :compose_mode, :compose_users_count, :compose_projects_count) | |||||
| end | |||||
| def find_compose | |||||
| @compose = Compose.find(params[:compose_id]) | |||||
| unless @compose.present? | |||||
| normal_status(-1, "组织不存在") | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,73 +0,0 @@ | |||||
| class CourseGroupsController < ApplicationController | |||||
| before_action :require_login, :check_auth | |||||
| before_action :set_group, except: [:create] | |||||
| before_action :find_course, only: [:create] | |||||
| before_action :teacher_allowed, except: [:set_invite_code_halt] | |||||
| def create | |||||
| tip_exception("分班名称不能为空") if params[:name].blank? | |||||
| if @course.course_groups.where(name: params[:name]).count > 0 | |||||
| normal_status(-1, "已存在同名分班") | |||||
| else | |||||
| course_group = @course.course_groups.create!(name: params[:name], position: @course.course_groups.count + 1) | |||||
| render :json => {group_id: course_group.id, status: 0, message: "创建成功"} | |||||
| end | |||||
| end | |||||
| def destroy | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @course.course_groups.where("position > #{@group.position}").update_all("position = position - 1") | |||||
| # 将该分班的学生转到未分班 | |||||
| @group.course_members.update_all(course_group_id: 0) | |||||
| @group.destroy | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception("删除分班失败") | |||||
| end | |||||
| end | |||||
| end | |||||
| # 分班重命名 | |||||
| def rename_group | |||||
| tip_exception("名称不能为空") if params[:name].blank? | |||||
| if @course.course_groups.where(name: params[:name]).count > 0 | |||||
| normal_status(-1, "已存在同名分班") | |||||
| else | |||||
| @group.update_attributes(name: params[:name].strip) | |||||
| normal_status(0, "更新成功") | |||||
| end | |||||
| end | |||||
| # 分班的拖动 | |||||
| def move_category | |||||
| tip_exception("移动失败") if params[:position].blank? | |||||
| unless params[:position].to_i == @group.position | |||||
| if params[:position].to_i < @group.position | |||||
| @course.course_groups.where("position < #{@group.position} and position >= ?", params[:position]).update_all("position = position + 1") | |||||
| else | |||||
| @course.course_groups.where("position > #{@group.position} and position <= ?", params[:position]).update_all("position = position - 1") | |||||
| end | |||||
| @group.update_attributes(position: params[:position]) | |||||
| normal_status(0, "移动成功") | |||||
| else | |||||
| normal_status(-1, "位置没有变化") | |||||
| end | |||||
| end | |||||
| # 邀请码停用/启用 | |||||
| def set_invite_code_halt | |||||
| teacher = @course.teachers.find_by(user_id: current_user.id) | |||||
| tip_exception(403, "无权限") unless current_user.admin_or_business? || | |||||
| (teacher.present? && (teacher.teacher_course_groups.pluck(:course_group_id).include?(@group.id) || teacher.teacher_course_groups.size == 0)) | |||||
| @group.update!(invite_code_halt: !@group.invite_code_halt) | |||||
| normal_status(0, "成功") | |||||
| end | |||||
| private | |||||
| def set_group | |||||
| @group = CourseGroup.find_by!(id: params[:id]) | |||||
| @course = @group.course | |||||
| end | |||||
| end | |||||
| @@ -1,68 +0,0 @@ | |||||
| class CourseModulesController < ApplicationController | |||||
| before_action :require_login, :check_auth | |||||
| before_action :set_module, except: [:unhidden_modules] | |||||
| before_action :find_course, only: [:unhidden_modules] | |||||
| before_action :teacher_or_admin_allowed, except: [:add_second_category] | |||||
| before_action :teacher_allowed, only: [:add_second_category] | |||||
| # 模块置顶 | |||||
| def sticky_module | |||||
| # position为1则不做处理,否则该模块的position置为1,position小于当前模块的position加1 | |||||
| unless @course_module.position == 1 | |||||
| @course.course_modules.where("position < #{@course_module.position}").update_all("position = position + 1") | |||||
| @course_module.update_attributes(position: 1) | |||||
| end | |||||
| normal_status(0, "置顶成功") | |||||
| end | |||||
| # 模块隐藏 | |||||
| def hidden_module | |||||
| tip_exception("请至少保留一个课堂模块") if @course.none_hidden_course_modules.where.not(id: @course_module.id).size == 0 | |||||
| @course_module.update_attributes(hidden: 1) | |||||
| normal_status(0, "更新成功") | |||||
| end | |||||
| # 模块重命名 | |||||
| def rename_module | |||||
| name = params[:name].strip | |||||
| tip_exception("名称不能为空") if name.blank? | |||||
| tip_exception("已存在同名模块") if @course.course_modules.exists?(module_name: name) | |||||
| @course_module.update_attributes(module_name: name) | |||||
| case @course_module.module_type | |||||
| when 'board' | |||||
| @course.course_board.update_columns(name: name) | |||||
| end | |||||
| normal_status(0, "更新成功") | |||||
| end | |||||
| # 模块的显示 | |||||
| def unhidden_modules | |||||
| tip_exception("请选择要显示的模块") if params[:module_ids].blank? | |||||
| @course.course_modules.where(id: params[:module_ids]).update_all(hidden: 0) | |||||
| normal_status(0, "更新成功") | |||||
| end | |||||
| # 添加二级目录 | |||||
| def add_second_category | |||||
| tip_exception("子目录名称不能为空") if params[:name].blank? | |||||
| tip_exception("已存在同名子目录") if @course_module.course_second_categories.exists?(name: params[:name].strip) | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| category = @course_module.course_second_categories.create!(name: params[:name].strip, category_type: @course_module.module_type, | |||||
| course_id: @course.id, position: @course_module.course_second_categories.count + 1) | |||||
| render :json => {category_id: category.id, status: 0, message: "添加成功"} | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception("添加子目录失败") | |||||
| end | |||||
| end | |||||
| end | |||||
| private | |||||
| def set_module | |||||
| @course_module = CourseModule.find_by!(id: params[:id]) | |||||
| @course = @course_module.course | |||||
| end | |||||
| end | |||||
| @@ -1,60 +0,0 @@ | |||||
| class CourseSecondCategoriesController < ApplicationController | |||||
| before_action :require_login, :check_auth | |||||
| before_action :set_category | |||||
| before_action :teacher_allowed | |||||
| # 目录重命名 | |||||
| def rename_category | |||||
| tip_exception("毕设子目录不能重命名") if @category.category_type == "graduation" | |||||
| tip_exception("名称不能为空") if params[:name].blank? | |||||
| tip_exception("已存在同名子目录") if @course_module.course_second_categories.exists?(name: params[:name].strip) | |||||
| @category.update_attributes!(name: params[:name].strip) | |||||
| normal_status(0, "更新成功") | |||||
| end | |||||
| # 子目录的拖动 | |||||
| def move_category | |||||
| tip_exception("移动失败") if params[:position].blank? | |||||
| unless params[:position].to_i == @category.position | |||||
| if params[:position].to_i < @category.position | |||||
| @course_module.course_second_categories.where("position < #{@category.position} and position >= ?", params[:position]).update_all("position = position + 1") | |||||
| else | |||||
| @course_module.course_second_categories.where("position > #{@category.position} and position <= ?", params[:position]).update_all("position = position - 1") | |||||
| end | |||||
| @category.update!(position: params[:position]) | |||||
| normal_status(0, "移动成功") | |||||
| else | |||||
| normal_status(-1, "位置没有变化") | |||||
| end | |||||
| end | |||||
| def destroy | |||||
| tip_exception("毕设子目录不能删除") if @category.category_type == "graduation" | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @course_module.course_second_categories.where("position > #{@category.position}").update_all("position = position - 1") | |||||
| # 更新相应对象的子目录id | |||||
| if @course_module.module_type == "shixun_homework" | |||||
| @category.homework_commons.update_all(course_second_category_id: 0) | |||||
| @right_url = "/courses/#{@course.id}/shixun_homeworks/#{@course_module.id}" | |||||
| elsif @course_module.module_type == "attachment" | |||||
| Attachment.where(course_second_category_id: @category.id).update_all(course_second_category_id: 0) | |||||
| @right_url = "/courses/#{@course.id}/files/#{@course_module.id}" | |||||
| end | |||||
| @category.destroy | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception("删除子目录失败") | |||||
| end | |||||
| end | |||||
| end | |||||
| private | |||||
| def set_category | |||||
| @category = CourseSecondCategory.find_by!(id: params[:id]) | |||||
| @course_module = @category.course_module | |||||
| @course = @course_module.try(:course) | |||||
| end | |||||
| end | |||||
| @@ -1,13 +0,0 @@ | |||||
| class DepartmentsController < ApplicationController | |||||
| skip_before_action :check_sign | |||||
| def for_option | |||||
| render_ok(departments: current_school.departments.without_deleted.select(:id, :name).as_json) | |||||
| end | |||||
| private | |||||
| def current_school | |||||
| @_current_school ||= School.find(params[:id]) | |||||
| end | |||||
| end | |||||
| @@ -1,6 +0,0 @@ | |||||
| class DisciplinesController < ApplicationController | |||||
| def index | |||||
| end | |||||
| end | |||||
| @@ -1,29 +0,0 @@ | |||||
| class EduDatasController < ApplicationController | |||||
| before_action :find_game | |||||
| skip_before_action :user_setup | |||||
| # skip_before_action :setup_laboratory | |||||
| # layout :false | |||||
| include GitHelper | |||||
| # params[:game_id] | |||||
| def game | |||||
| @shixun = @challenge.shixun | |||||
| @shixun_env = @shixun.mirror_name | |||||
| @shixun_tags = @challenge.challenge_tags.map(&:name) | |||||
| end | |||||
| def code_lines | |||||
| path = @challenge.path | |||||
| myshixun = @game.myshixun | |||||
| # content = git_fle_content(myshixun.repo_path, path) || "" | |||||
| @content = {"content":"#coding=utf-8\n\n#请在此处添加代码完成输出“Hello Python”,注意要区分大小写!\n###### Begin ######\n\n\n\n###### End ######\n\n"} | |||||
| @content[:content].include?("Begin") | |||||
| end | |||||
| private | |||||
| def find_game | |||||
| game_id = params[:game_id] | |||||
| @game = Game.find(game_id) | |||||
| @challenge = @game.challenge | |||||
| end | |||||
| end | |||||
| @@ -1,92 +0,0 @@ | |||||
| class ExaminationBanksController < ApplicationController | |||||
| include PaginateHelper | |||||
| before_action :require_login | |||||
| before_action :certi_identity_auth, only: [:create, :edit, :update, :destroy, :set_public, :revoke_item] | |||||
| before_action :find_exam, except: [:index, :create] | |||||
| before_action :edit_auth, only: [:update, :destroy, :set_public, :revoke_item] | |||||
| before_action :identity_auth, only: [:index] | |||||
| def index | |||||
| exams = ExaminationBankQuery.call(params) | |||||
| @exams_count = exams.size | |||||
| @exams = paginate exams.includes(:user, :examination_items) | |||||
| end | |||||
| def show | |||||
| @items = @exam.examination_items | |||||
| @single_questions = @items.where(item_type: "SINGLE") | |||||
| @multiple_questions = @items.where(item_type: "MULTIPLE") | |||||
| @judgement_questions = @items.where(item_type: "JUDGMENT") | |||||
| @program_questions = @items.where(item_type: "PROGRAM") | |||||
| end | |||||
| def create | |||||
| ActiveRecord::Base.transaction do | |||||
| exam = ExaminationBank.new(user: current_user) | |||||
| # 保存试卷基础信息 | |||||
| exam = ExaminationBanks::SaveExaminationBankService.call(exam, form_params) | |||||
| # 将试题篮中的试题发送到试卷,试卷的题目与试题独立 | |||||
| current_user.item_baskets.includes(:item_bank).each do |basket| | |||||
| item = basket.item_bank | |||||
| if item.present? | |||||
| new_item = ExaminationItem.new | |||||
| new_item.new_item(item, exam, basket.score, basket.position) | |||||
| end | |||||
| end | |||||
| current_user.item_baskets.destroy_all | |||||
| end | |||||
| render_ok | |||||
| rescue ApplicationService::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| def edit; end | |||||
| def update | |||||
| ExaminationBanks::SaveExaminationBankService.call(@exam, form_params) | |||||
| render_ok | |||||
| rescue ApplicationService::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| def destroy | |||||
| ActiveRecord::Base.transaction do | |||||
| ApplyAction.where(container_type: "ExaminationBank", container_id: @exam.id).destroy_all | |||||
| @exam.destroy! | |||||
| render_ok | |||||
| end | |||||
| end | |||||
| def set_public | |||||
| tip_exception(-1, "该试卷已公开") if @exam.public? | |||||
| tip_exception(-1, "请勿重复提交申请") if ApplyAction.where(container_id: @exam.id, container_type: "ExaminationBank", status: 0).exists? | |||||
| ApplyAction.create!(container_id: @exam.id, container_type: "ExaminationBank", user_id: current_user.id) | |||||
| # @exam.update_attributes!(public: 1) | |||||
| render_ok | |||||
| end | |||||
| def revoke_item | |||||
| item = @exam.examination_items.find_by!(item_bank_id: params[:item_id]) | |||||
| ActiveRecord::Base.transaction do | |||||
| @exam.examination_items.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1") | |||||
| item.destroy! | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| private | |||||
| def form_params | |||||
| params.permit(:discipline_id, :sub_discipline_id, :difficulty, :name, :duration, tag_discipline_id: []) | |||||
| end | |||||
| def find_exam | |||||
| @exam = ExaminationBank.find_by!(id: params[:id]) | |||||
| end | |||||
| def edit_auth | |||||
| current_user.admin_or_business? || @exam.user == current_user | |||||
| end | |||||
| end | |||||
| @@ -1,108 +0,0 @@ | |||||
| class ExaminationIntelligentSettingsController < ApplicationController | |||||
| before_action :require_login | |||||
| before_action :certi_identity_auth, only: [:create, :optinal_items, :save_exam, :exchange_one_item, :exchange_items] | |||||
| before_action :find_exam, only: [:exchange_one_item, :exchange_items, :save_exam] | |||||
| def optinal_items | |||||
| sub_discipline_id = params[:sub_discipline_id] | |||||
| tag_discipline_id = params[:tag_discipline_id] | |||||
| difficulty = params[:difficulty] | |||||
| source = params[:source] | |||||
| items = OptionalItemQuery.call(sub_discipline_id, tag_discipline_id, difficulty, source) | |||||
| @single_question_count = items.select{ |item| item.item_type == "SINGLE" }.size | |||||
| @multiple_question_count = items.select{ |item| item.item_type == "MULTIPLE" }.size | |||||
| @judgement_question_count = items.select{ |item| item.item_type == "JUDGMENT" }.size | |||||
| @program_question_count = items.select{ |item| item.item_type == "PROGRAM" }.size | |||||
| end | |||||
| def create | |||||
| ActiveRecord::Base.transaction do | |||||
| exam = ExaminationIntelligentSetting.new(user: current_user) | |||||
| # 保存试卷基础信息 | |||||
| exam = ExaminationIntelligentSettings::SaveSettingService.call(exam, form_params) | |||||
| render_ok({exam_setting_id: exam.id}) | |||||
| end | |||||
| rescue ApplicationService::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| def save_exam | |||||
| new_exam = ExaminationBank.new(user: current_user) | |||||
| # 保存试卷基础信息 | |||||
| ExaminationIntelligentSettings::SaveExaminationService.call(new_exam, save_params, @exam) | |||||
| render_ok | |||||
| rescue ApplicationService::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| def exchange_one_item | |||||
| item = @exam.item_baskets.find_by!(item_bank_id: params[:item_id]) | |||||
| exam_type_setting = @exam.examination_type_settings.find_by!(item_type: item.item_type) | |||||
| # 获取可选的题 | |||||
| items = OptionalItemQuery.call(@exam.sub_discipline_id, @exam.tag_discipline_containers.pluck(:tag_discipline_id), @exam.difficulty, @exam.public) | |||||
| # 可选题中去掉已组卷的试题 | |||||
| type_items = items.select{ |t_item| t_item.item_type == item.item_type } | |||||
| optional_item_ids = (type_items.pluck(:id) - @exam.item_baskets.where(item_type: item.item_type).pluck(:item_bank_id)).uniq | |||||
| # 如果可选的题数等于0则提示无可换的题 | |||||
| tip_exception("无可换的题") if optional_item_ids.size == 0 | |||||
| new_item = ItemBank.find optional_item_ids.sample(1).first | |||||
| ActiveRecord::Base.transaction do | |||||
| @exam.item_baskets << ItemBasket.new(item_bank_id: new_item.id, position: item.position, score: item.score, item_type: new_item.item_type) | |||||
| item.destroy! | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| def exchange_items | |||||
| exam_type_setting = @exam.examination_type_settings.find_by!(item_type: params[:item_type]) | |||||
| choosed_items = @exam.item_baskets.where(item_type: params[:item_type]) | |||||
| # 获取可选的题 | |||||
| items = OptionalItemQuery.call(@exam.sub_discipline_id, @exam.tag_discipline_containers.pluck(:tag_discipline_id), @exam.difficulty, @exam.public) | |||||
| type_items = items.select{ |t_item| t_item.item_type == params[:item_type] } | |||||
| # 可选题中去掉已组卷的试题 | |||||
| choosed_item_ids = choosed_items.pluck(:item_bank_id) | |||||
| optional_item_ids = (type_items.pluck(:id) - choosed_item_ids).uniq | |||||
| # 如果可选的题数等于0则提示无可换的题 | |||||
| tip_exception("无可换的题") if optional_item_ids.size == 0 | |||||
| # 如果可选题数小于设置的题数(n),则在原来的选题中随机选n个,确保换题时能选到新的题 | |||||
| if optional_item_ids.size < exam_type_setting.count | |||||
| absence_count = exam_type_setting.count - optional_item_ids.size | |||||
| optional_item_ids = optional_item_ids + choosed_item_ids.sample(absence_count) | |||||
| end | |||||
| ActiveRecord::Base.transaction do | |||||
| # 取试题分数 | |||||
| score = choosed_items.first&.score || (params[:item_type] == "PROGRAM" ? 10 : 5) | |||||
| choosed_items.destroy_all | |||||
| optional_item_ids.sample(exam_type_setting.count).each_with_index do |item_id, index| | |||||
| new_item = ItemBank.find item_id | |||||
| @exam.item_baskets << ItemBasket.new(item_bank_id: new_item.id, position: index+1, score: score, item_type: new_item.item_type) | |||||
| end | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| private | |||||
| def find_exam | |||||
| @exam = ExaminationIntelligentSetting.find_by!(id: params[:id]) | |||||
| tip_exception(403,"无权限编辑") unless current_user.admin_or_business? || @exam.user_id == current_user.id | |||||
| end | |||||
| def form_params | |||||
| params.permit(:discipline_id, :sub_discipline_id, :difficulty, :source, tag_discipline_id: [], question_settings: %i[item_type count]) | |||||
| end | |||||
| def save_params | |||||
| params.permit(:name, :duration) | |||||
| end | |||||
| end | |||||
| @@ -1,85 +0,0 @@ | |||||
| class ExaminationItemsController < ApplicationController | |||||
| before_action :require_login | |||||
| before_action :certi_identity_auth, only: [:create, :destroy, :delete_item_type, :set_score, :batch_set_score, :adjust_position] | |||||
| before_action :validate_score, only: [:set_score, :batch_set_score] | |||||
| before_action :find_exam, only: [:create, :batch_set_score, :delete_item_type] | |||||
| before_action :find_item, except: [:create, :batch_set_score, :delete_item_type] | |||||
| before_action :edit_auth | |||||
| def create | |||||
| ExaminationItems::SaveItemService.call(current_user, create_params, @exam) | |||||
| render_ok | |||||
| rescue ApplicationService::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| def destroy | |||||
| ActiveRecord::Base.transaction do | |||||
| @exam.examination_items.where(item_type: @item.item_type).where("position > #{@item.position}").update_all("position = position -1") | |||||
| @item.destroy! | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| def delete_item_type | |||||
| items = @exam.examination_items.where(item_type: params[:item_type]) | |||||
| items.destroy_all | |||||
| render_ok | |||||
| end | |||||
| def set_score | |||||
| @item.update_attributes!(score: params[:score]) | |||||
| @questions_score = @exam.examination_items.where(item_type: @item.item_type).pluck(:score).sum | |||||
| @all_score = @exam.examination_items.pluck(:score).sum | |||||
| render_ok({questions_score: @questions_score, all_score: @all_score}) | |||||
| end | |||||
| def batch_set_score | |||||
| @exam.examination_items.where(item_type: params[:item_type]).update_all(score: params[:score]) | |||||
| @questions_score = @exam.examination_items.where(item_type: params[:item_type]).pluck(:score).sum | |||||
| @all_score = @exam.examination_items.pluck(:score).sum | |||||
| render_ok({questions_score: @questions_score, all_score: @all_score}) | |||||
| end | |||||
| def adjust_position | |||||
| same_items = @exam.examination_items.where(item_type: @item.item_type) | |||||
| max_position = same_items.size | |||||
| tip_exception("position超出范围") unless params[:position].present? && params[:position].to_i <= max_position && params[:position].to_i >= 1 | |||||
| ActiveRecord::Base.transaction do | |||||
| if params[:position].to_i > @item.position | |||||
| same_items.where("position > #{@item.position} and position <= #{params[:position].to_i}").update_all("position=position-1") | |||||
| @item.update_attributes!(position: params[:position]) | |||||
| elsif params[:position].to_i < @item.position | |||||
| same_items.where("position < #{@item.position} and position >= #{params[:position].to_i}").update_all("position=position+1") | |||||
| @item.update_attributes!(position: params[:position]) | |||||
| else | |||||
| return normal_status(-1, "排序无变化") | |||||
| end | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| private | |||||
| def find_exam | |||||
| @exam = ExaminationBank.find_by!(id: params[:exam_id]) | |||||
| end | |||||
| def create_params | |||||
| params.permit(item_ids: []) | |||||
| end | |||||
| def find_item | |||||
| @item = ExaminationItem.find_by!(id: params[:id]) | |||||
| @exam = @item.examination_bank | |||||
| end | |||||
| def validate_score | |||||
| tip_exception("分值不能为空") unless params[:score].present? | |||||
| tip_exception("分值需大于0") unless params[:score].to_f > 0 | |||||
| end | |||||
| def edit_auth | |||||
| current_user.admin_or_business? || @exam.user == current_user | |||||
| end | |||||
| end | |||||
| @@ -1,400 +0,0 @@ | |||||
| class FilesController < ApplicationController | |||||
| include MessagesHelper | |||||
| before_action :require_login, :check_auth, except: %i[index] | |||||
| before_action :find_course, except: %i[public_with_course_and_project mine_with_course_and_project] | |||||
| before_action :find_ids, only: %i[bulk_delete bulk_send bulk_move bulk_public bulk_publish] | |||||
| before_action :file_validate_sort_type, only: :index | |||||
| before_action :validate_send_message_to_course_params, only: :bulk_send | |||||
| before_action :set_pagination, only: %i[index public_with_course_and_project mine_with_course_and_project] | |||||
| before_action :validate_upload_params, only: %i[upload import] | |||||
| before_action :find_file, only: %i[show setting update] | |||||
| before_action :publish_params, only: %i[upload import update] | |||||
| SORT_TYPE = %w[created_on downloads quotes] | |||||
| def index | |||||
| sort = params[:sort] || 0 # 0: 降序;1: 升序 | |||||
| sort_type = params[:sort_type] || 'created_on' # created_on:时间排序, downloads:下载次数排序; quotes: 引用次数排序 | |||||
| @course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id | |||||
| @user = current_user | |||||
| @attachments = @course_second_category_id.to_i == 0 ? @course.attachments.includes(:course_second_category) : @course.attachments.by_course_second_category_id(@course_second_category_id) | |||||
| @attachments = @attachments.includes(author: [:user_extension, :course_members]) | |||||
| .ordered(sort: sort.to_i, sort_type: sort_type.strip) | |||||
| get_category(@course, @course_second_category_id) | |||||
| @total_count = @attachments.size | |||||
| if @user.course_identity(@course) == 5 | |||||
| member = @course.course_members.find_by(user_id: current_user.id, is_active: 1) | |||||
| if member.try(:course_group_id).to_i == 0 | |||||
| @attachments = @attachments.published.unified_setting | |||||
| else | |||||
| not_atta_ids = @course.attachment_group_settings.none_published.where("course_group_id = #{member.try(:course_group_id)}").pluck(:attachment_id) | |||||
| @attachments = @attachments.where.not(id: not_atta_ids).published | |||||
| end | |||||
| elsif @user.course_identity(@course) > 5 | |||||
| @attachments = @attachments.publiced.published | |||||
| end | |||||
| @publish_count = @attachments.published.size | |||||
| @unpublish_count = @total_count - @publish_count | |||||
| @attachments = @attachments.by_keywords(params[:search]) | |||||
| @attachments = @attachments.page(@page).per(@page_size) | |||||
| end | |||||
| def bulk_publish | |||||
| return normal_status(403, "您没有权限进行操作") if current_user.course_identity(@course) >= 5 | |||||
| # tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0 | |||||
| attachments = @course.attachments.by_ids(@attachment_ids) | |||||
| ActiveRecord::Base.transaction do | |||||
| # 有分班设置时 | |||||
| # if @course.course_group_module? && @course.course_groups_count != 0 && params[:group_ids] | |||||
| # group_ids = params[:group_ids]&.reject(&:blank?) | |||||
| # charge_group_ids = @course.charge_group_ids(current_user) | |||||
| # publish_groups = charge_group_ids & group_ids if group_ids | |||||
| # | |||||
| # attachments.each do |atta| | |||||
| # if atta.published? && !atta.unified_setting || !atta.published? | |||||
| # create_atta_group_settings atta | |||||
| # atta.update_attributes!(unified_setting: 0) if atta.unified_setting | |||||
| # none_publish_settings = atta.attachment_group_settings.where(course_group_id: publish_groups).none_published | |||||
| # none_publish_settings.update_all(publish_time: Time.now) | |||||
| # end | |||||
| # end | |||||
| # end | |||||
| # 未发布的资源更新状态 | |||||
| attachments.where(is_publish: 0).update_all(is_publish: 1, publish_time: Time.now) | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| def bulk_delete | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @course.attachments.by_ids(@attachment_ids).destroy_all | |||||
| rescue Exception => e | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| def bulk_send | |||||
| return normal_status(403, "您没有权限进行该操作") unless current_user.teacher_of_course?(@course) | |||||
| course_ids = params[:to_course_ids] | |||||
| begin | |||||
| @attachment_ids.each do |id| | |||||
| @attachment = @course.attachments.find_by_id id | |||||
| course_ids.each do |course_id| | |||||
| course = Course.find_by_id course_id | |||||
| unless @attachment.nil? || course.nil? | |||||
| course.attachments << course.attachments.build(@attachment.attributes.except("id").merge( | |||||
| quotes: 0, | |||||
| downloads: 0, | |||||
| author_id: current_user.id, | |||||
| created_on: Time.now, | |||||
| course_second_category_id: 0 # TODO 暂时只支持发送到其他课堂的主目录 | |||||
| )) | |||||
| end | |||||
| end | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| def bulk_move | |||||
| return normal_status(403, "您没有权限进行该操作") unless current_user.teacher_of_course?(@course) | |||||
| to_category_id = params[:to_category_id] || 0 # 默认移动到主目录 | |||||
| unless to_category_id == 0 | |||||
| course_second_category = @course.course_second_categories.find_by_id to_category_id | |||||
| return normal_status(2, "参数to_category_id有误,该目录不存在") if course_second_category.nil? | |||||
| end | |||||
| begin | |||||
| @course.attachments.by_ids(@attachment_ids).update_all(course_second_category_id: to_category_id) | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| def bulk_public | |||||
| @user = current_user | |||||
| return normal_status(403, "您没有权限进行该操作") unless @user.teacher_of_course?(@course) | |||||
| @course.attachments.by_ids(@attachment_ids).update_all(is_public: 1) | |||||
| end | |||||
| def public_with_course_and_project | |||||
| @attachments = Attachment.publiced.simple_columns | |||||
| .contains_course_and_project | |||||
| .includes(:container, author: :user_extension) | |||||
| .by_filename_or_user_name(params[:search]) | |||||
| .ordered(sort: 0, sort_type: 'created_on') | |||||
| @total_count = @attachments.size | |||||
| @attachments = @attachments.page(@page).per(@page_size) | |||||
| end | |||||
| def mine_with_course_and_project | |||||
| @current_user = current_user | |||||
| @attachments = Attachment.mine(current_user) | |||||
| .simple_columns | |||||
| .contains_course_and_project | |||||
| .by_keywords(params[:search]) | |||||
| .ordered(sort: 0, sort_type: 'created_on') | |||||
| @total_count = @attachments.size | |||||
| @attachments = @attachments.page(@page).per(@page_size) | |||||
| end | |||||
| # 上传资源 | |||||
| def upload | |||||
| attachment_ids = params[:attachment_ids] | |||||
| course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id | |||||
| # is_unified_setting = params.has_key?(:is_unified_setting) ? params[:is_unified_setting] : true | |||||
| # publish_time = params[:publish_time] | |||||
| # course_group_publish_times = params[:course_group_publish_times] || [] | |||||
| begin | |||||
| attachment_ids.each do |attchment_id| | |||||
| attachment = Attachment.find_by_id attchment_id | |||||
| unless attachment.nil? | |||||
| attachment.container = @course | |||||
| attachment.course_second_category_id = course_second_category_id | |||||
| attachment.description = params[:description] | |||||
| attachment.is_public = params[:is_public] && @course.is_public == 1 ? 1 : 0 | |||||
| attachment.is_publish = @atta_is_publish | |||||
| attachment.delay_publish = @atta_delay_publish | |||||
| attachment.publish_time = @atta_publish_time | |||||
| attachment.unified_setting = @unified_setting | |||||
| if @unified_setting == 0 | |||||
| attachment_group_setting attachment, params[:group_settings] | |||||
| end | |||||
| # attachment.set_publish_time(publish_time) if is_unified_setting | |||||
| # attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank? | |||||
| attachment.save! | |||||
| end | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| # 选用资源 & 导入资源 | |||||
| def import | |||||
| return normal_status(403, "您没有权限进行该操作") unless current_user.teacher_of_course?(@course) || current_user.student_of_course?(@course) | |||||
| attachment_ids = params[:attachment_ids] | |||||
| course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id | |||||
| begin | |||||
| attachment_ids.each do |attachment_id| | |||||
| ori = Attachment.find_by_id(attachment_id) | |||||
| # 同一个资源可以多次发送到课堂 | |||||
| # @course.attachments.each do |att| | |||||
| # @exist = false | |||||
| # if att.id == ori.id || (!att.copy_from.nil? && !ori.copy_from.nil? && att.copy_from == ori.copy_from) || att.copy_from == ori.id || att.id == ori.copy_from | |||||
| # att.created_on = Time.now | |||||
| # att.save | |||||
| # @exist = true | |||||
| # break | |||||
| # end | |||||
| # end | |||||
| # | |||||
| # next if @exist | |||||
| attach_copied_obj = ori.copy | |||||
| attach_copied_obj.container = @course | |||||
| attach_copied_obj.created_on = Time.now | |||||
| attach_copied_obj.author = current_user | |||||
| attach_copied_obj.is_public = 0 | |||||
| attach_copied_obj.is_publish = @atta_is_publish | |||||
| attach_copied_obj.delay_publish = @atta_delay_publish | |||||
| attach_copied_obj.publish_time = @atta_publish_time | |||||
| attach_copied_obj.unified_setting = @unified_setting | |||||
| if @unified_setting == 0 | |||||
| attachment_group_setting attach_copied_obj, params[:group_settings] | |||||
| end | |||||
| attach_copied_obj.course_second_category_id = course_second_category_id | |||||
| attach_copied_obj.copy_from = ori.copy_from.nil? ? ori.id : ori.copy_from | |||||
| if attach_copied_obj.attachtype == nil | |||||
| attach_copied_obj.attachtype = 4 | |||||
| end | |||||
| attach_copied_obj.save | |||||
| ori.update_columns(quotes: ori.quotes.to_i + 1) | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| # 资源设置 | |||||
| def update | |||||
| return normal_status(403, "您没有权限进行该操作") if current_user.course_identity(@course) >= 5 && @file.author != current_user | |||||
| is_public = params[:is_public] | |||||
| @old_attachment = @file | |||||
| @new_attachment = Attachment.find_by_id params[:new_attachment_id] | |||||
| begin | |||||
| unless @new_attachment.nil? | |||||
| @new_attachment_history = @old_attachment.become_history | |||||
| @new_attachment_history.save! | |||||
| old_course_second_category_id = @old_attachment.course_second_category_id | |||||
| @old_attachment.copy_attributes_from_new_attachment(@new_attachment) | |||||
| @old_attachment.course_second_category_id = old_course_second_category_id | |||||
| @old_attachment.save! | |||||
| @new_attachment.delete | |||||
| end | |||||
| @old_attachment.is_public = is_public == true && @course.is_public == 1 ? 1 : 0 | |||||
| @old_attachment.is_publish = @atta_is_publish | |||||
| @old_attachment.delay_publish = @atta_delay_publish | |||||
| @old_attachment.publish_time = @atta_publish_time | |||||
| @old_attachment.unified_setting = @unified_setting | |||||
| if @unified_setting == 0 | |||||
| attachment_group_setting @old_attachment, params[:group_settings] | |||||
| else | |||||
| @old_attachment.attachment_group_settings.destroy_all | |||||
| end | |||||
| if params[:description] && !params[:description].strip.blank? && params[:description] != @old_attachment.description | |||||
| @old_attachment.description = params[:description] | |||||
| end | |||||
| # @old_attachment.set_public(is_public) | |||||
| # if is_unified_setting | |||||
| # @old_attachment.set_publish_time(publish_time) | |||||
| # @old_attachment.attachment_group_settings.destroy_all | |||||
| # end | |||||
| # if publish_time.blank? && @course.course_groups.size > 0 && !is_unified_setting | |||||
| # @old_attachment.set_course_group_publish_time(@course, course_group_publish_times) | |||||
| # end | |||||
| @old_attachment.save! | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| def show | |||||
| return normal_status(403, "您没有权限进行该操作") if !current_user.teacher_of_course?(@course) && current_user != @file.author | |||||
| @attachment_histories = @file.attachment_histories | |||||
| end | |||||
| def histories | |||||
| @user = current_user | |||||
| @file = @course.attachments.find_by_id params[:id] | |||||
| return normal_status(-2, "该课程下没有id为 #{params[:id]}的资源") if @file.nil? | |||||
| return normal_status(403, "您没有权限进行该操作") if @user != @file.author && !@user.teacher_of_course?(@course) && !@file.public? | |||||
| @attachment_histories = @file.attachment_histories | |||||
| end | |||||
| def get_category(course, category_id) | |||||
| if category_id == 0 | |||||
| category = course.attachment_course_modules.first | |||||
| @category_id = category.try(:id) | |||||
| @category_name = category.try(:module_name) | |||||
| else | |||||
| category = CourseSecondCategory.find category_id | |||||
| @category_id = category.try(:id) | |||||
| @category_name = category.try(:name) | |||||
| end | |||||
| end | |||||
| private | |||||
| def find_file | |||||
| @file = Attachment.find params[:id] | |||||
| end | |||||
| def find_attachment_ids(attachment_ids = params[:attachment_ids]) | |||||
| return normal_status(-2, "参数attachment_ids不能为空!") if attachment_ids.blank? | |||||
| return normal_status(-2, "参数attachment_ids格式错误!") if !attachment_ids.is_a? Array | |||||
| end | |||||
| def find_course_second_category_id | |||||
| course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id | |||||
| if course_second_category_id != 0 | |||||
| course_second_category = CourseSecondCategory.find_by(id: course_second_category_id, category_type: "attachment") | |||||
| return normal_status(-2, "未来找到course_second_category为 #{course_second_category_id} 的目录") if course_second_category.nil? | |||||
| end | |||||
| end | |||||
| def find_ids | |||||
| @attachment_ids = params[:ids] || [] | |||||
| find_attachment_ids(@attachment_ids) | |||||
| end | |||||
| def file_validate_sort_type | |||||
| normal_status(-2, "参数sort_type暂时只支持 'created_on', 'quotes', 'downloads'") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip) | |||||
| end | |||||
| def validate_upload_params | |||||
| find_attachment_ids | |||||
| find_course_second_category_id | |||||
| end | |||||
| def publish_params | |||||
| tip_exception("缺少发布参数") if params[:delay_publish].blank? | |||||
| @unified_setting = 1 | |||||
| # if params[:delay_publish].to_i == 1 && @course.course_group_module? && @course.course_groups_count != 0 | |||||
| # tip_exception("分班发布设置不能为空") if params[:group_settings].blank? | |||||
| # min_publish_time = params[:group_settings].pluck(:publish_time).reject(&:blank?).min | |||||
| # max_publish_time = params[:group_settings].pluck(:publish_time).reject(&:blank?).max | |||||
| # tip_exception("分班发布设置不能为空") if min_publish_time.blank? | |||||
| # | |||||
| # # 分班设置中的时间一样且包含所有分班 则按统一设置处理,否则是非统一设置 | |||||
| # @unified_setting = 0 unless min_publish_time == max_publish_time && params[:group_settings].pluck(:group_id).flatten.sort == @course.course_groups.pluck(:id).sort | |||||
| # els | |||||
| if params[:delay_publish].to_i == 1 | |||||
| tip_exception("缺少延期发布的时间参数") if params[:publish_time].blank? | |||||
| min_publish_time = params[:publish_time] | |||||
| end | |||||
| @atta_is_publish = params[:delay_publish].to_i == 1 && min_publish_time.to_time > Time.now ? 0 : 1 | |||||
| @atta_delay_publish = params[:delay_publish].to_i | |||||
| @atta_publish_time = params[:delay_publish].to_i == 1 ? min_publish_time : Time.now | |||||
| end | |||||
| def create_atta_group_settings atta | |||||
| if atta.attachment_group_settings.size != @course.course_groups.size | |||||
| @course.course_groups.where.not(id: atta.attachment_group_settings.pluck(:course_group_id)).each do |group| | |||||
| atta.attachment_group_settings << AttachmentGroupSetting.new(course_group_id: group.id, course_id: @course.id, | |||||
| publish_time: atta.publish_time) | |||||
| end | |||||
| end | |||||
| end | |||||
| def attachment_group_setting attachment, group_setting | |||||
| create_atta_group_settings attachment | |||||
| group_setting.each do |setting| | |||||
| tip_exception("分班id不能为空") if setting[:group_id].length == 0 | |||||
| tip_exception("发布时间不能为空") if setting[:publish_time].blank? | |||||
| AttachmentGroupSetting.where(attachment_id: attachment.id, course_group_id: setting[:group_id]). | |||||
| update_all(publish_time: setting[:publish_time]) | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,84 +0,0 @@ | |||||
| class GitsController < ApplicationController | |||||
| skip_before_action :check_sign | |||||
| # 说明: | |||||
| # 以下Git认证只针对新版git,Gitlab的Git认证不走该控制器 | |||||
| # 思路: | |||||
| # 1、用户通过Git客户端推送代码的时候,这个时候Git客户端肯定会强制用户输入邮箱的 | |||||
| # 2、通过web端版本库界面更新代码(如果用户邮箱不存在,则用系统备用邮箱) | |||||
| # 供 git-workhorse反向调用认证 | |||||
| def auth | |||||
| # HTTP_AUTHORIZATION: "Basic 这里base64编码的的密码(user:passwd)" | |||||
| decodes = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) | |||||
| rand_code = decodes.sample(10).join | |||||
| logger.info("11111112222223333 HTTP_AUTHORIZATION: #{request.env["HTTP_AUTHORIZATION"]}") | |||||
| logger.info("1111111 git auth start: code is #{rand_code}, time is #{Time.now}") | |||||
| # logger.info("#########-----request_env: #{request.env}") | |||||
| # {"service"=>"git-receive-pack", "controller"=>"gits", "action"=>"auth", | |||||
| # "url"=>"forge01/cermyt39.git/info/refs"} | |||||
| # | |||||
| gituser = edu_setting('git_username') | |||||
| gitpassword = edu_setting('git_password') | |||||
| result = false | |||||
| if request.env["HTTP_AUTHORIZATION"] && request.env["HTTP_AUTHORIZATION"].split(" ").length == 2 | |||||
| username_password = Base64.decode64(request.env["HTTP_AUTHORIZATION"].split(" ")[1]) | |||||
| if username_password.split(":")[0].nil? || username_password.split(":")[1].nil? | |||||
| result = false | |||||
| else | |||||
| input_username = username_password.split(":")[0].strip() | |||||
| input_password = username_password.split(":")[1].strip() | |||||
| uid_logger("git start auth: input_username is #{input_username}") | |||||
| # Git 超级权限用户 | |||||
| if input_username.strip == gituser.strip && input_password.strip == gitpassword.strip | |||||
| result = true | |||||
| else | |||||
| # 用户是否对对象拥有权限 | |||||
| system_user = User.find_by_login(input_username) || User.find_by_mail(input_username) || User.find_by_phone(input_username) | |||||
| # 如果用户名密码错误 | |||||
| if system_user.blank? || system_user && !system_user.check_password?(input_password) | |||||
| uid_logger_error("git start: password is wrong") | |||||
| result = false | |||||
| else | |||||
| git_url = params["url"] | |||||
| username = git_url.split("/")[0] | |||||
| shixunname = git_url.split("/")[1].split(".")[0] | |||||
| repo_name = username + "/" + shixunname | |||||
| uid_logger("git start: repo_name is #{repo_name}") | |||||
| shixun = Shixun.select([:id, :user_id, :repo_name, :identifier]).where(repo_name: repo_name).first | |||||
| if shixun.blank? | |||||
| shixun_id = ShixunSecretRepository.where(repo_name: repo_name).pluck(:shixun_id).first | |||||
| logger.info("####repo_name:#{repo_name}") | |||||
| logger.info("####shixun_id:#{shixun_id}") | |||||
| shixun = Shixun.select([:id, :user_id, :repo_name, :identifier]).find_by(id: shixun_id) | |||||
| end | |||||
| uid_logger("git start auth: shixun identifier is #{shixun.try(:identifier)}") | |||||
| uid_logger("git start auth: systemuser is #{system_user.try(:login)}") | |||||
| if shixun.present? | |||||
| logger.info("#######{system_user.manager_of_shixun?(shixun)}") | |||||
| if system_user.present? && system_user.manager_of_shixun?(shixun) | |||||
| result = true | |||||
| else | |||||
| uid_logger_error("gituser is not shixun manager") | |||||
| result = false | |||||
| end | |||||
| else | |||||
| uid_logger_error("shixun is not exist") | |||||
| # result = false | |||||
| result = true # 为了测试跳出 | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| authenticate_or_request_with_http_basic do |username, password| | |||||
| result | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,568 +0,0 @@ | |||||
| class GraduationWorksController < ApplicationController | |||||
| before_action :require_login, :check_auth | |||||
| before_action :find_task, only: [:new, :create, :search_member_list, :check_project, :relate_project, | |||||
| :cancel_relate_project, :delete_work] | |||||
| before_action :find_work, only: [:show, :edit, :update, :revise_attachment, :supply_attachments, :comment_list, | |||||
| :add_score, :delete_score, :adjust_score, :assign_teacher] | |||||
| before_action :user_course_identity | |||||
| before_action :task_public | |||||
| before_action :teacher_allowed, only: [:add_score, :adjust_score, :assign_teacher] | |||||
| before_action :course_student, only: [:new, :create, :edit, :update, :search_member_list, :relate_project, | |||||
| :cancel_relate_project, :delete_work] | |||||
| before_action :my_work, only: [:edit, :update, :revise_attachment] | |||||
| before_action :published_task, only: [:new, :create, :edit, :update, :search_member_list, :relate_project, | |||||
| :cancel_relate_project, :revise_attachment] | |||||
| before_action :edit_duration, only: [:edit, :update, :delete_work] | |||||
| before_action :open_work, only: [:show, :supply_attachments, :comment_list] | |||||
| def new | |||||
| if @task.task_type == 2 && @task.base_on_project | |||||
| work = @task.graduation_works.where(user_id: current_user.id).first | |||||
| if work.present? && (work.work_status != 0 || work.project_id == 0) | |||||
| normal_status(403, "") | |||||
| end | |||||
| end | |||||
| @user = current_user | |||||
| end | |||||
| # 搜索课堂学生 | |||||
| def search_member_list | |||||
| unless params[:search].blank? | |||||
| # 有搜索条件时搜索课堂所有学生包括已提交的 | |||||
| users = User.joins(:graduation_works).where("concat(users.lastname, users.firstname) like ? and | |||||
| graduation_task_id = #{@task.id}", "%#{params[:search]}%") | |||||
| user_ids = users.pluck(:id) - [current_user.id] | |||||
| @members = @course.students.where(user_id: user_ids) | |||||
| else | |||||
| # 没有搜索条件时搜索课堂所有未提交的学生 | |||||
| user_ids = @task.graduation_works.where("work_status = 0").pluck(:user_id) - [current_user.id] | |||||
| @members = @course.students.where(user_id: user_ids) | |||||
| end | |||||
| page = params[:page] ? params[:page].to_i : 1 | |||||
| limit = params[:limit] ? params[:limit].to_i : 10 | |||||
| # todo user_extension | |||||
| @members = @members.page(page).per(limit).includes(:course_group, user: :user_extension) | |||||
| end | |||||
| def delete_work | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| work = @task.graduation_works.find_by!(user_id: params[:user_id]) | |||||
| tip_exception("只有组长才能删除组员") if work.commit_user_id != current_user.id | |||||
| work.update!(description: nil, project_id: 0, late_penalty: 0, work_status: 0, commit_time: nil, | |||||
| update_time: nil, group_id: 0, commit_user_id: nil, final_score: nil, work_score: nil, | |||||
| teacher_score: nil, teaching_asistant_score: nil, update_user_id: nil) | |||||
| work.attachments.destroy_all | |||||
| work.tidings.destroy_all | |||||
| normal_status("删除成功") | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| end | |||||
| end | |||||
| # 判断项目是否已有其他作品关联上了 | |||||
| def check_project | |||||
| tip_exception("项目id不能为空") if params[:project_id].blank? | |||||
| work = @task.graduation_works.where(project_id: params[:project_id]).first | |||||
| @is_relate = work.present? | |||||
| @relate_user = work.present? ? work.user.real_name : "" | |||||
| end | |||||
| def relate_project | |||||
| tip_exception("项目id不能为空") if params[:project_id].blank? | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| # 判断项目是否存在且当前用户是项目管理员 | |||||
| project = Project.where(id: params[:project_id]).first | |||||
| member = Member.where(project_id: project.try(:id), user_id: current_user.id).first | |||||
| if project.present? && member.present? && member.member_roles.first.try(:role_id) == 3 | |||||
| work = @task.graduation_works.where("user_id = #{current_user.id}").first || | |||||
| GraduationWork.create(user_id: current_user.id, graduation_task_id: @task.id, course_id: @task.course_id) | |||||
| if work.work_status == 0 && work.project_id == 0 | |||||
| work.update!(project_id: project.id, update_time: Time.now) | |||||
| # 将老师加入项目 | |||||
| project_member = project.members.where(user_id: @task.user_id).first | |||||
| if project_member.present? | |||||
| project_member.member_roles.first.update!(role_id: 3) if project_member.member_roles.first.present? | |||||
| else | |||||
| member = Member.create(user_id: @task.user_id, project_id: project.id) | |||||
| member.member_roles << MemberRole.new(role_id: 3) | |||||
| Tiding.create(user_id: @task.user_id, trigger_user_id: current_user.id, container_id: project.id, | |||||
| container_type: 'ManagerJoinProject', belong_container_id: project.id, | |||||
| belong_container_type: "Project", tiding_type: "System", extra: 3) | |||||
| end | |||||
| normal_status("关联成功") | |||||
| else | |||||
| tip_exception("不能重复关联项目") | |||||
| end | |||||
| else | |||||
| tip_exception("该项目不存在") | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| def cancel_relate_project | |||||
| work = @task.graduation_works.where(user_id: current_user.id, work_status: 0).first | |||||
| if work.present? && work.project.present? | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| member = work.project.members.where(user_id: @task.user_id).first | |||||
| member.destroy if member.present? | |||||
| Tiding.where(user_id: @task.user_id, trigger_user_id: current_user.id, container_id: work.project.id, | |||||
| container_type: 'ManagerJoinProject').destroy_all | |||||
| work.update!(project_id: 0) | |||||
| normal_status("取消关联成功") | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| else | |||||
| tip_exception("无法取消关联") | |||||
| end | |||||
| end | |||||
| def create | |||||
| graduation_work = @task.graduation_works.where(user_id: current_user.id).first || | |||||
| GraduationWork.create(user_id: current_user.id, graduation_task_id: @task.id, course_id: @task.course_id) | |||||
| update_check graduation_work | |||||
| tip_exception("作业不可重复提交") if graduation_work.work_status != 0 | |||||
| tip_exception("已过了提交时间") if @course.is_end || (@task.end_time < Time.now && (!@task.allow_late || | |||||
| (@task.late_time.present? && @task.late_time < Time.now))) | |||||
| student_ids = [current_user.id] | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| # work.update_attributes(graduation_work_params) | |||||
| graduation_work.description = params[:description] | |||||
| graduation_work.commit_time = Time.now | |||||
| graduation_work.update_time = Time.now | |||||
| graduation_work.commit_user_id = current_user.id | |||||
| graduation_work.update_user_id = current_user.id | |||||
| graduation_work.course_id = @course.id | |||||
| graduation_work.group_id = @task.task_type == 2 ? @task.graduation_works.where("work_status != 0").map(&:group_id).max.to_i + 1 : 0 | |||||
| #提交作品时,计算是否迟交 | |||||
| graduation_work.late_penalty = @task.end_time < Time.now.to_s ? @task.late_penalty : 0 | |||||
| graduation_work.work_status = @task.end_time < Time.now.to_s ? 2 : 1 | |||||
| if graduation_work.save! | |||||
| Attachment.associate_container(params[:attachment_ids], graduation_work.id, graduation_work.class) | |||||
| if @task.task_type == 2 | |||||
| members = (params[:user_ids] || []).collect(&:to_i) - [current_user.id] | |||||
| members = @course.students.pluck(:user_id) & members | |||||
| student_ids += members | |||||
| for i in 0 .. members.count-1 | |||||
| stu_work = @task.graduation_works.where(user_id: members[i].to_i).first || GraduationWork.new | |||||
| stu_work.update!(user_id: members[i].to_i, description: graduation_work.description, | |||||
| graduation_task_id: @task.id, project_id: graduation_work.project_id, | |||||
| late_penalty: graduation_work.late_penalty, work_status: graduation_work.work_status, | |||||
| commit_time: Time.now, update_time: Time.now, group_id: graduation_work.group_id, | |||||
| commit_user_id: current_user.id, update_user_id: current_user.id) | |||||
| stu_work.save! | |||||
| graduation_work.attachments.each do |attachment| | |||||
| att = attachment.copy | |||||
| att.author_id = attachment.author_id | |||||
| stu_work.attachments << att | |||||
| end | |||||
| end | |||||
| end | |||||
| @task.update_column(:updated_at, Time.now) | |||||
| # todo 更新对应的毕设任务课堂动态 | |||||
| # update_course_activity(@taskhomework.class,@task.id) | |||||
| @work_id = graduation_work.id | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| SubmitGraduationWorkNotifyJob.perform_later(@task.id, student_ids) | |||||
| end | |||||
| end | |||||
| def edit | |||||
| @task_user = current_user | |||||
| if @task.task_type == 2 | |||||
| @commit_user_id = @work.commit_user_id | |||||
| @work_members = @course.students.where(user_id: @task.graduation_works.where(group_id: @work.group_id).pluck(:user_id)). | |||||
| order("course_members.id=#{@work.commit_user_id} desc").includes(:course_group, user: :user_extension) | |||||
| end | |||||
| end | |||||
| def update | |||||
| update_check @work | |||||
| student_ids = [] | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @work.description = params[:description] | |||||
| @work.update_time = Time.now | |||||
| @work.update_user_id = current_user.id | |||||
| # @work.commit_user_id = current_user.id | |||||
| if @work.save! | |||||
| Attachment.associate_container(params[:attachment_ids], @work.id, @work.class) | |||||
| #如果学生作品被打分后修改,应该给老师提示 | |||||
| student_ids << @work.user_id if @work.scored? | |||||
| if @task.task_type == 2 | |||||
| graduation_works = @task.graduation_works.where("group_id = #{@work.group_id} and user_id != #{@work.user_id}") | |||||
| work_user_ids = graduation_works.pluck(:user_id) | |||||
| params_user_ids = (params[:user_ids] || []).collect(&:to_i) - [@work.user_id] | |||||
| params_user_ids = @course.students.pluck(:user_id) & params_user_ids | |||||
| # 原成员更新描述、更新时间以及附件 | |||||
| @task.graduation_works.where(group_id: @work.group_id, user_id: (work_user_ids & params_user_ids)).each do |work| | |||||
| work.update!(update_time: Time.now, description: @work.description, update_user_id: current_user.id) | |||||
| work.attachments.destroy_all | |||||
| @work.attachments.each do |attachment| | |||||
| att = attachment.copy | |||||
| att.author_id = attachment.author_id | |||||
| work.attachments << att | |||||
| end | |||||
| student_ids << work.user_id if work.scored? | |||||
| end | |||||
| # 删除的成员 | |||||
| delete_user_ids = work_user_ids - params_user_ids | |||||
| @task.graduation_works.where(group_id: @work.group_id, user_id: delete_user_ids).each do |work| | |||||
| work.attachments.destroy_all | |||||
| # work.student_works_scores.destroy_all | |||||
| work.tidings.destroy_all | |||||
| end | |||||
| @task.graduation_works.where(group_id: @work.group_id, user_id: delete_user_ids). | |||||
| update_all(work_status: 0, description: nil, late_penalty: 0, commit_time: nil, update_time: nil, | |||||
| final_score: nil, teacher_score: nil, work_score: nil, project_id: 0, group_id: 0, | |||||
| commit_user_id: nil, update_user_id: nil) | |||||
| # 新增加的成员 | |||||
| (params_user_ids - work_user_ids).each do |user_id| | |||||
| stu_work = @task.graduation_works.where(user_id: user_id).empty? ? GraduationWork.new : | |||||
| @task.graduation_works.where(user_id: user_id).first | |||||
| stu_work.update!(user_id: user_id, description: @work.description, graduation_task_id: @task.id, | |||||
| project_id: @work.project_id, late_penalty: @work.late_penalty, | |||||
| work_status: @work.work_status, commit_time: Time.now, update_time: Time.now, | |||||
| group_id: @work.group_id, commit_user_id: @work.commit_user_id, update_user_id: current_user.id) | |||||
| @work.attachments.each do |attachment| | |||||
| att = attachment.copy | |||||
| att.author_id = attachment.author_id | |||||
| stu_work.attachments << att | |||||
| end | |||||
| student_ids << user_id | |||||
| end | |||||
| end | |||||
| normal_status("更新成功") | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| SubmitGraduationWorkNotifyJob.perform_later(@task.id, student_ids) if student_ids.present? | |||||
| end | |||||
| end | |||||
| def show | |||||
| @current_user = current_user | |||||
| @is_author = @work.user_id == current_user.id | |||||
| @work_members = @task.task_type == 1 ? [] : @task.graduation_works.where.not(user_id: @work.user_id). | |||||
| where(group_id: @work.group_id).includes(:user) | |||||
| @attachments = @work.attachments.where("attachtype != 7 or attachtype is null") | |||||
| end | |||||
| def comment_list | |||||
| @current_user = current_user | |||||
| @last_comment = @work.graduation_work_scores.where(user_id: @current_user.id).last | |||||
| @comment_scores = @work.graduation_work_scores.reorder("created_at desc").includes(:user) | |||||
| end | |||||
| # 给作品评分 | |||||
| def add_score | |||||
| tip_exception("该学生的分数已经过调整,不能再评阅") if @work.ultimate_score | |||||
| tip_exception("分数和评语不能都为空") if params[:score].blank? && params[:comment].blank? | |||||
| tip_exception("分数不能超过0-100") if params[:score] && (params[:score].to_f < 0 || params[:score].to_f > 100) | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| # 没传score则取上次评分成绩 | |||||
| score = GraduationWorkScore.where(user_id: current_user.id, graduation_work_id: @work.id).last | |||||
| new_score = GraduationWorkScore.new | |||||
| new_score.score = params[:score].blank? ? score.try(:score) : params[:score].to_f | |||||
| new_score.comment = params[:comment] if params[:comment] && params[:comment].strip != "" | |||||
| new_score.user_id = current_user.id | |||||
| new_score.graduation_work_id = @work.id | |||||
| new_score.graduation_task_id = @task.id | |||||
| # 如果作品是未提交的状态则更新为已提交 | |||||
| if !new_score.score.nil? && @work.work_status == 0 | |||||
| @work.update!(work_status: 1, commit_time: Time.now) | |||||
| if @task.task_type == 2 | |||||
| @work.update!(group_id: @task.graduation_works.where("work_status != 0").select("distinct group_id").count + 1) | |||||
| end | |||||
| end | |||||
| if @task.cross_comment && @work.graduation_work_comment_assignations.where(user_id: current_user.id).count > 0 | |||||
| new_score.reviewer_role = 2 | |||||
| else | |||||
| new_score.reviewer_role = 1 | |||||
| end | |||||
| if new_score.save! | |||||
| Attachment.associate_container(params[:attachment_ids], new_score.id, new_score.class) | |||||
| # 该用户的历史评阅无效 | |||||
| score.update_column('is_invalid', true) if score.present? && score.score.present? | |||||
| Tiding.create(user_id: @work.user_id, trigger_user_id: User.current.id, container_id: new_score.id, | |||||
| container_type: "GraduationWorkScore", parent_container_id: @work.id, | |||||
| parent_container_type: "GraduationWork", belong_container_id: @task.course_id, | |||||
| belong_container_type: "Course", viewed: 0, tiding_type: "GraduationTask", extra: new_score.reviewer_role) | |||||
| case new_score.reviewer_role | |||||
| when 1 #教师评分取平均分 | |||||
| ts_score = GraduationWorkScore.find_by_sql("SELECT AVG(score) AS score FROM graduation_work_scores WHERE | |||||
| graduation_work_id = #{@work.id} AND reviewer_role = 1 AND score IS NOT NULL AND is_invalid = 0") | |||||
| @work.teacher_score = ts_score.first.score.nil? ? nil : ts_score.first.score.try(:round, 2).to_f | |||||
| # 分组作业整组同评 | |||||
| if @task.task_type == 2 && params[:same_score] | |||||
| add_graduation_score_to_member @work, @task, new_score | |||||
| end | |||||
| when 2 #交叉评分显示平均分 | |||||
| ts_score = GraduationWorkScore.find_by_sql("SELECT AVG(score) AS score FROM graduation_work_scores WHERE | |||||
| graduation_work_id = #{@work.id} AND reviewer_role = 2 AND score IS NOT NULL AND is_invalid = 0") | |||||
| @work.cross_score = ts_score.first.score.nil? ? nil : ts_score.first.score.try(:round, 2).to_f | |||||
| end | |||||
| @task.update_column('updated_at', Time.now) | |||||
| # update_course_activity(@task.class, @task.id) | |||||
| @work.save! | |||||
| normal_status("提交成功") | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| def adjust_score | |||||
| tip_exception("成绩不能为空") if params[:score].blank? | |||||
| tip_exception("成绩不能小于零") if params[:score].to_f < 0 | |||||
| tip_exception("成绩不能大于100") if params[:score].to_f.round(1) > 100 | |||||
| tip_exception("调分原因不能超过100个字符") if params[:comment].present? && params[:comment].length > 100 | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| # 分数不为空的历史评阅都置为失效 | |||||
| @work.graduation_work_scores.where.not(score: nil).update_all(is_invalid: 1) | |||||
| new_score = GraduationWorkScore.new(graduation_work_id: @work.id, score: params[:score].to_f, | |||||
| graduation_task_id: @task.id, comment: "使用调分功能调整了作业最终成绩:#{params[:comment]}", | |||||
| user_id: User.current.id, reviewer_role: 1, is_ultimate: 1) | |||||
| new_score.save! | |||||
| @work.update!(ultimate_score: 1, work_score: params[:score].to_f) | |||||
| Tiding.create!(user_id: @work.user_id, trigger_user_id: current_user.id, container_id: new_score.id, | |||||
| container_type: "AdjustScore", parent_container_id: @task.id, | |||||
| parent_container_type: "GraduationTask", belong_container_id: @course.id, | |||||
| belong_container_type: 'Course', tiding_type: "GraduationTask") | |||||
| normal_status("调分成功") | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| # 删除教师/教辅的评分记录 | |||||
| def delete_score | |||||
| score = @work.graduation_work_scores.where(id: params[:comment_id]).first | |||||
| if score.present? && (score.is_invalid || score.score.nil?) && (score.user == current_user || current_user.admin_or_business?) | |||||
| begin | |||||
| score.destroy | |||||
| normal_status("删除成功") | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| else | |||||
| tip_exception("无法删除") | |||||
| end | |||||
| end | |||||
| def supply_attachments | |||||
| @revise_attachments = @work.attachments.where(attachtype: 7) | |||||
| @last_atta = @revise_attachments.last | |||||
| end | |||||
| def revise_attachment | |||||
| tip_exception("不在补交阶段内") if @course.is_end || @task.end_time > Time.now || !@task.allow_late || | |||||
| (@task.late_time && @task.late_time < Time.now) | |||||
| tip_exception("附件参数有误") if params[:attachment_ids].blank? || !params[:attachment_ids].is_a?(Array) | |||||
| tip_exception("补交附件原因不能为空") if params[:description].blank? | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| revise_attachment = @work.attachments.where(attachtype: 7).reorder("created_on desc").last | |||||
| if revise_attachment.present? && @work.graduation_work_scores.where("created_at > '#{revise_attachment.created_on}' | |||||
| and score is not null").count == 0 | |||||
| revise_attachment.destroy | |||||
| end | |||||
| Attachment.associate_container(params[:attachment_ids], @work.id, @work.class, 7) | |||||
| revise_attachment = Attachment.where(attachtype: 7, container_id: @work.id, container_type: "GraduationWork").last | |||||
| revise_attachment.update!(description: params[:description]) if revise_attachment.present? | |||||
| @work.update!(update_time: Time.now) | |||||
| normal_status("提交成功") | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| # 交叉评阅分配老师 | |||||
| def assign_teacher | |||||
| tip_exception(-1, "user_id不能为空") if params[:user_id].nil? | |||||
| @work_assign_teacher = @work.graduation_work_comment_assignations.find_by(user_id: params[:user_id]) | |||||
| if @work_assign_teacher.present? | |||||
| # graduation_group_id: 已经是答辩组的需要 将答辩组清空 | |||||
| @work_assign_teacher.update!(graduation_group_id: 0) | |||||
| else | |||||
| @work.graduation_work_comment_assignations << GraduationWorkCommentAssignation.new(graduation_task_id: @task.id, | |||||
| user_id: params[:user_id], | |||||
| graduation_group_id: 0) | |||||
| end | |||||
| normal_status("分配成功") | |||||
| end | |||||
| private | |||||
| def find_task | |||||
| begin | |||||
| @task = GraduationTask.find(params[:graduation_task_id]) | |||||
| @course = @task.course | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception("id不存在") | |||||
| end | |||||
| end | |||||
| def find_work | |||||
| begin | |||||
| @work = GraduationWork.find(params[:id]) | |||||
| @task = @work.graduation_task | |||||
| @course = @task.course | |||||
| rescue Exception => e | |||||
| uid_logger(e.message) | |||||
| tip_exception("id不存在") | |||||
| end | |||||
| end | |||||
| def task_public | |||||
| tip_exception(403,"没有操作权限") if @user_course_identity > Course::STUDENT && (@course.is_public == 0 || | |||||
| (@course.is_public == 1 && !@task.is_public)) | |||||
| end | |||||
| def course_student | |||||
| tip_exception(403,"没有操作权限") if @user_course_identity != Course::STUDENT | |||||
| end | |||||
| def my_work | |||||
| tip_exception(403,"没有操作权限") if @work.user_id != current_user.id || @work.work_status == 0 | |||||
| end | |||||
| def published_task | |||||
| tip_exception("不能在非提交时间内操作") if @task.status == 0 || (!@task.allow_late && @task.status > 1) || | |||||
| (@task.allow_late && @task.late_time && @task.late_time < Time.now) | |||||
| end | |||||
| def edit_duration | |||||
| tip_exception("已过了修改时间") if @task.end_time && @task.end_time < Time.now | |||||
| end | |||||
| # 作品是否公开 | |||||
| def open_work | |||||
| tip_exception(403,"没有操作权限") unless (@user_course_identity < Course::STUDENT || current_user == @work.user || @task.open_work) | |||||
| end | |||||
| def update_check work | |||||
| tip_exception("作品描述不能为空") if params[:description].blank? | |||||
| if @task.task_type == 2 | |||||
| tip_exception("小组成员不能为空") if params[:user_ids].blank? | |||||
| tip_exception("小组成员人数不合要求") if params[:user_ids].length > @task.max_num || params[:user_ids].length < @task.min_num | |||||
| tip_exception("请先关联项目") if @task.base_on_project && work.project_id == 0 | |||||
| end | |||||
| end | |||||
| def graduation_work_params | |||||
| params.require(:graduation_work).permit(:description) | |||||
| end | |||||
| def add_graduation_score_to_member work, task, new_score | |||||
| graduation_works = task.graduation_works.where("group_id = #{work.group_id} and id != #{work.id} and ultimate_score = 0") | |||||
| graduation_works.each do |st_work| | |||||
| st_score = GraduationWorkScore.new(user_id: new_score.user_id, score: new_score.score, | |||||
| reviewer_role: new_score.reviewer_role, comment: new_score.comment) | |||||
| st_work.graduation_work_scores << st_score | |||||
| score = GraduationWorkScore.where(user_id: new_score.user_id, graduation_work_id: st_work.id).last | |||||
| # 该用户的历史评阅无效 | |||||
| score.update_column('is_invalid', true) if score.present? && score.score.present? | |||||
| teacher_score = GraduationWorkScore.find_by_sql("SELECT AVG(score) AS score FROM graduation_work_scores WHERE | |||||
| graduation_work_id = #{work.id} AND reviewer_role = 1 AND score IS NOT NULL AND is_invalid = 0") | |||||
| st_work.teacher_score = teacher_score.first.score.nil? ? nil : teacher_score.first.score.try(:round, 2).to_f | |||||
| st_work.save! | |||||
| Tiding.create(user_id: st_work.user_id, trigger_user_id: User.current.id, container_id: st_score.id, | |||||
| container_type: "GraduationWorkScore", parent_container_id: st_work.id, | |||||
| parent_container_type: "GraduationWork", belong_container_id: task.course_id, | |||||
| belong_container_type: "Course", viewed: 0, tiding_type: "GraduationTask", extra: st_score.reviewer_role) | |||||
| # 评阅附件的复制 | |||||
| new_score.attachments.each do |attachment| | |||||
| att = attachment.copy | |||||
| att.author_id = st_score.user_id | |||||
| st_score.attachments << att | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,38 +0,0 @@ | |||||
| class GtopicBanksController < ApplicationController | |||||
| before_action :require_login | |||||
| before_action :find_bank, :bank_visit_auth | |||||
| before_action :bank_admin, only: [:edit, :update] | |||||
| def show | |||||
| @bank_attachments = @bank.attachments | |||||
| end | |||||
| def edit | |||||
| @attachments = @bank.attachments | |||||
| end | |||||
| def update | |||||
| ActiveRecord::Base.transaction do | |||||
| @bank.update_attributes(gtopic_bank_params) | |||||
| Attachment.associate_container(params[:attachment_ids], @bank.id, @bank.class) if params[:attachment_ids] | |||||
| normal_status(0, "更新成功") | |||||
| end | |||||
| end | |||||
| private | |||||
| def find_bank | |||||
| @bank = GtopicBank.find_by!(id: params[:id]) | |||||
| end | |||||
| def bank_admin | |||||
| tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? | |||||
| end | |||||
| def gtopic_bank_params | |||||
| tip_exception("name参数不能为空") if params[:gtopic_bank][:name].blank? | |||||
| tip_exception("description参数不能为空") if params[:gtopic_bank][:description].blank? | |||||
| params.require(:gtopic_bank).permit(:name, :topic_type, :topic_source, :topic_property_first, :description, | |||||
| :topic_property_second, :source_unit, :topic_repeat, :province, :city) | |||||
| end | |||||
| end | |||||
| @@ -1,220 +0,0 @@ | |||||
| class HackUserLastestCodesController < ApplicationController | |||||
| before_action :require_login, except: [:listen_result] | |||||
| before_action :find_my_hack, only: [:show, :code_debug, :code_submit, :update_code, :sync_code, :add_notes, | |||||
| :listen_result, :result, :submit_records, :restore_initial_code] | |||||
| before_action :update_user_hack_status, only: [:code_debug, :code_submit] | |||||
| before_action :require_auth_identity, only: [:add_notes] | |||||
| before_action :require_manager_identity, only: [:show, :update_code, :restore_initial_code, :sync_code] | |||||
| skip_before_action :check_sign, only: [:listen_result] | |||||
| def show | |||||
| @my_hack.update_attribute(:submit_status, 0) if @my_hack.submit_status == 1 | |||||
| @modify = @my_hack.modify_time.to_i < @hack.hack_codes.first.modify_time.to_i | |||||
| end | |||||
| def update_code | |||||
| @my_hack.update_attribute(:code, params[:code]) | |||||
| render_ok | |||||
| end | |||||
| # 恢复初始代码 | |||||
| def restore_initial_code | |||||
| @my_hack.update_attribute(:code, @hack.code) | |||||
| end | |||||
| # 同步代码 | |||||
| def sync_code | |||||
| @my_hack.update_attributes(code: @hack.code, modify_time: Time.now) | |||||
| end | |||||
| # 调试代码 | |||||
| def code_debug | |||||
| exec_mode = "debug" | |||||
| error_status = 501 | |||||
| error_msg = "debug_error" | |||||
| oj_evaluate exec_mode, error_status, error_msg | |||||
| render_ok | |||||
| end | |||||
| # 提交 | |||||
| def code_submit | |||||
| exec_mode = "submit" | |||||
| error_status = 502 | |||||
| error_msg = "submit_error" | |||||
| oj_evaluate exec_mode, error_status, error_msg | |||||
| render_ok | |||||
| end | |||||
| # 提交结果显示 | |||||
| def result | |||||
| if @my_hack.submit_status == 1 | |||||
| render json: {status: 1, message: "正在评测中"} | |||||
| else | |||||
| @mode = params[:mode] | |||||
| @result = | |||||
| if @mode == "submit" | |||||
| @my_hack.hack_user_codes.last | |||||
| elsif @mode == "debug" | |||||
| @my_hack.hack_user_debug | |||||
| end | |||||
| end | |||||
| end | |||||
| # 提交记录 | |||||
| def submit_records | |||||
| records = @my_hack.hack_user_codes | |||||
| @records_count = records.count | |||||
| @records = paginate records.created_order | |||||
| end | |||||
| # 提交记录详情 | |||||
| def record_detail | |||||
| @hack_user = HackUserCode.find params[:id] | |||||
| set = HackSet.find_by(id: @hack_user.error_test_set_id) | |||||
| @pass_set_count = set ? set.position - 1 : 0 | |||||
| @set_count = @hack_user.hack.hack_sets.count | |||||
| @my_hack = @hack_user.hack_user_lastest_code | |||||
| end | |||||
| # 接收中间件返回结果接口 | |||||
| # 调试模式: status: 0 表示评测无错误,其他 表示错误(如编译出错,执行出错,超时等) | |||||
| def listen_result | |||||
| logger.info("###########listen_result:#{params}") | |||||
| begin | |||||
| ojEvaResult = JSON.parse(params[:ojEvaResult]) | |||||
| testCase = ojEvaResult['testCase'] | |||||
| # 只有编译出错时,才正则匹配错误行数 | |||||
| error_line= | |||||
| if ojEvaResult['status'] == "4" || ojEvaResult['status'] == "5" | |||||
| regular_match_error_line ojEvaResult['outPut'], @my_hack.hack.language | |||||
| end | |||||
| # debug 与submit 公用的参数 | |||||
| ds_params = {input: testCase['input'], output: testCase['output'], hack_id: @hack.id, | |||||
| code: ojEvaResult['codeFileContent'], user_id: @my_hack.user_id, error_line: error_line, | |||||
| status: ojEvaResult['status'], error_msg: ojEvaResult['outPut'], | |||||
| execute_time: ojEvaResult['executeTime'], execute_memory: ojEvaResult['executeMem']} | |||||
| ActiveRecord::Base.transaction do | |||||
| # debug模式与submit模式 | |||||
| if ojEvaResult['execMode'] == "debug" | |||||
| save_debug_data ds_params | |||||
| elsif ojEvaResult['execMode'] == "submit" | |||||
| save_submit_data ds_params.merge(expected_output: testCase['expectedOutput'], | |||||
| error_test_set_id: ojEvaResult['failCaseNum']) | |||||
| end | |||||
| # 评测完成后,还原评测中的状态 | |||||
| @my_hack.update_attribute(:submit_status, 0) | |||||
| end | |||||
| render_ok | |||||
| rescue Exception => e | |||||
| logger.error("#########listen_result: #{e.message}") | |||||
| end | |||||
| end | |||||
| def add_notes | |||||
| @my_hack.update_attribute(:notes, params[:notes]) | |||||
| render_ok | |||||
| end | |||||
| private | |||||
| def find_my_hack | |||||
| @my_hack = HackUserLastestCode.find_by(identifier: params[:identifier]) | |||||
| @hack = @my_hack.hack | |||||
| end | |||||
| def oj_evaluate exec_mode, error_status, error_msg | |||||
| request_url = "#{edu_setting('cloud_bridge')}/bridge/ojs/evaluate" | |||||
| test_sets = | |||||
| if exec_mode == "submit" | |||||
| @hack.hack_sets.map{|set| {input: set.input, output: set.output, caseId: set.id}} | |||||
| else | |||||
| [{input: params[:input]}] | |||||
| end | |||||
| testCases = Base64.encode64(test_sets.to_json) | |||||
| #codeFileContent = Base64.urlsafe_encode64(@my_hack.code) | |||||
| debug_params = {execMode: exec_mode, | |||||
| tpiID: @my_hack.identifier, | |||||
| testCases: testCases, | |||||
| platform: @my_hack.language, | |||||
| codeFileContent: @my_hack.code, | |||||
| timeLimit: @hack.time_limit, | |||||
| sec_key: Time.now.to_i} | |||||
| interface_json_post request_url, debug_params, error_status, error_msg | |||||
| # 每次评测提交数增加 | |||||
| @hack.increment!(:submit_num) | |||||
| end | |||||
| # 正则错误行数 | |||||
| def regular_match_error_line content, language | |||||
| content = Base64.decode64(content).force_encoding("utf-8") | |||||
| logger.info("######content: #{content}") | |||||
| case language | |||||
| when 'Java' | |||||
| content.scan(/.java.\d+/).map{|s| s.match(/\d+/)[0].to_i}.min | |||||
| when 'C', 'C++' | |||||
| content.scan(/\d:\d+:/).map{|s| s.match(/\d+/)[0].to_i}.min | |||||
| when 'Python' | |||||
| content.scan(/line \d+/).map{|s| s.match(/\d+/)[0].to_i}.min | |||||
| end | |||||
| end | |||||
| # 存储debug数据 | |||||
| def save_debug_data debug_params | |||||
| if @my_hack.hack_user_debug.present? | |||||
| @my_hack.hack_user_debug.update_attributes!(debug_params) | |||||
| else | |||||
| debug = HackUserDebug.new(debug_params) | |||||
| debug.hack_user_lastest_code_id = @my_hack.id | |||||
| debug.save! | |||||
| end | |||||
| end | |||||
| # 存储submit数据 | |||||
| def save_submit_data submit_params | |||||
| # 通关 | |||||
| if submit_params[:status] == "0" | |||||
| # 编程题已经发布,且之前未通关奖励积分 | |||||
| @hack.increment!(:pass_num) | |||||
| if @hack.status == 1 && !@my_hack.passed? | |||||
| reward_attrs = { container_id: @hack.id, container_type: 'Hack', score: @hack.score } | |||||
| RewardGradeService.call(@my_hack.user, reward_attrs) | |||||
| RewardExperienceService.call(@my_hack.user, reward_attrs) | |||||
| # 评测完成更新通过数 | |||||
| @my_hack.update_attributes(passed: true, passed_time: Time.now) | |||||
| end | |||||
| end | |||||
| # 创建用户评测记录 | |||||
| logger.info("###########submit_params:#{submit_params}") | |||||
| query_index = @my_hack.hack_user_codes.count +1 | |||||
| @my_hack.hack_user_codes.create!(submit_params.merge(query_index: query_index)) | |||||
| end | |||||
| # 调试或提交改变状态 | |||||
| def update_user_hack_status | |||||
| @my_hack.update_attribute(:submit_status, 1) | |||||
| end | |||||
| # 只有自己才能改动代码 | |||||
| def require_identity | |||||
| if @my_hack.user_id != current_user.id | |||||
| tip_exception(403, "..") | |||||
| end | |||||
| end | |||||
| # 老师、自己、管理可以查看他人的编程题 | |||||
| def require_manager_identity | |||||
| unless current_user.certification_teacher? || admin_or_business? || @my_hack.user_id == current_user.id | |||||
| tip_exception(403, "..") | |||||
| end | |||||
| end | |||||
| # 只有自己才能评测 | |||||
| def require_auth_identity | |||||
| unless @my_hack.user_id == current_user.id | |||||
| tip_exception(403, "..") | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,282 +0,0 @@ | |||||
| class HacksController < ApplicationController | |||||
| before_action :require_login, except: [:index] | |||||
| before_action :find_hack, only: [:edit, :update, :publish, :start, :update_set, :delete_set, :destroy, :cancel_publish] | |||||
| before_action :require_teacher_identity, only: [:create] | |||||
| before_action :require_auth_identity, only: [:update, :edit, :publish, :update_set, :delete_set, :destroy, :cancel_publish] | |||||
| # 开启编程,如果第一次开启,创建一条记录,如果已经开启过的话,直接返回标识即可 | |||||
| def start | |||||
| # 未发布的编程题,只能作者、或管理员访问 | |||||
| start_hack_auth | |||||
| user_hack = @hack.hack_user_lastest_codes.where(user_id: current_user.id).first | |||||
| logger.info("#user_hack: #{user_hack}") | |||||
| identifier = | |||||
| if user_hack.present? | |||||
| logger.info("#####user_hack_id:#{user_hack.id}") | |||||
| user_hack.identifier | |||||
| else | |||||
| user_identifier = generate_identifier HackUserLastestCode, 12 | |||||
| user_code = {user_id: current_user.id, code: @hack.code, modify_time: Time.now, | |||||
| identifier: user_identifier, language: @hack.language} | |||||
| @hack.hack_user_lastest_codes.create!(user_code) | |||||
| user_identifier | |||||
| end | |||||
| render_ok(identifier: identifier) | |||||
| end | |||||
| # 首页 | |||||
| def index | |||||
| # 筛选过滤与排序 | |||||
| params_filter_or_order | |||||
| # 我解决的编程题数 | |||||
| user_codes = HackUserLastestCode.joins(:hack).mine_hack(current_user).passed | |||||
| @simple_count = user_codes.where(hacks: {difficult: 1}).count | |||||
| @medium_count = user_codes.where(hacks: {difficult: 2}).count | |||||
| @diff_count = user_codes.where(hacks: {difficult: 3}).count | |||||
| @pass_count = @simple_count + @medium_count + @diff_count | |||||
| @hacks_count = @hacks.count("hacks.id") | |||||
| @hacks = paginate @hacks | |||||
| end | |||||
| def create | |||||
| begin | |||||
| logger.info("##########{hack_params}") | |||||
| tip_exception("一次只能增加50个测试集") if hack_sets_params.size > 50 | |||||
| tip_exception("一次只能增加50个知识点") if params[:tags].size > 50 | |||||
| hack = Hack.new(hack_params) | |||||
| hack.user_id = current_user.id | |||||
| hack.identifier = generate_identifier Hack, 8 | |||||
| tag_params = params[:tags].map{|tag| {tag_discipline_id: tag}} | |||||
| ActiveRecord::Base.transaction do | |||||
| hack.save! | |||||
| # 创建测试集与代码 | |||||
| hack.hack_sets.create!(hack_sets_params) | |||||
| # 新建知识点 | |||||
| hack.tag_discipline_containers.create!(tag_params) if tag_params.present? | |||||
| hack_codes = hack.hack_codes.new(hack_code_params) | |||||
| hack_codes.modify_time = Time.now | |||||
| hack_codes.save! | |||||
| new_item_params = item_params.merge(container: hack, item_type: 'PROGRAM', difficulty: params[:hack][:difficult], user_id: current_user.id) | |||||
| ItemBank.create!(new_item_params) | |||||
| end | |||||
| render_ok({identifier: hack.identifier}) | |||||
| rescue => e | |||||
| logger.error("########create_hack_error: #{e.message}") | |||||
| render_error("创建失败: #{e.message}") | |||||
| end | |||||
| end | |||||
| def update | |||||
| begin | |||||
| # 知识点 | |||||
| tag_discipline_ids = @hack.tag_discipline_containers.pluck(:tag_discipline_id) | |||||
| new_tag_ids = params[:tags].to_a - tag_discipline_ids | |||||
| tag_params = new_tag_ids.map{|tag| {tag_discipline_id: tag}} | |||||
| ActiveRecord::Base.transaction do | |||||
| @hack.update_attributes!(hack_params) | |||||
| set_ids = @hack.hack_sets.pluck(:id) | |||||
| # 更新 | |||||
| param_update_sets params[:update_hack_sets], set_ids | |||||
| # 新建 | |||||
| @hack.hack_sets.create!(hack_sets_params) | |||||
| # 更新代码 | |||||
| code_params = params[:hack_codes][:code] != @hack.code ? hack_code_params.merge(modify_time: Time.now) : hack_code_params | |||||
| @hack.hack_codes.first.update_attributes!(code_params) | |||||
| @hack.tag_discipline_containers.create!(tag_params) if tag_params | |||||
| @hack.tag_discipline_containers.where.not(tag_discipline_id: params[:tags]).destroy_all | |||||
| # 更新题库相关记录 | |||||
| if @hack.item_bank.present? | |||||
| update_item_params = item_params.merge({difficulty: params[:hack][:difficult]}) | |||||
| @hack.item_bank.update!(update_item_params) | |||||
| end | |||||
| end | |||||
| render_ok | |||||
| rescue Exception => e | |||||
| logger.error("####update_hack_error: #{e.message}") | |||||
| render_error("更新失败: #{e.message}") | |||||
| end | |||||
| end | |||||
| # 更新测试集接口 | |||||
| def update_set | |||||
| set = @hack.hack_sets.find_by(id: params[:id]) | |||||
| set.update_attributes!(hack_set_params) | |||||
| render_ok | |||||
| end | |||||
| # 单独删除测试集 | |||||
| def delete_set | |||||
| set = @hack.hack_sets.find_by(id: params[:id]) | |||||
| set.destroy! | |||||
| render_ok | |||||
| end | |||||
| # 发布功能 | |||||
| def publish | |||||
| @hack.update_attribute(:status, 1) | |||||
| base_attrs = { | |||||
| trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id, | |||||
| parent_container_type: "HackPublish", extra: @hack.identifier | |||||
| } | |||||
| @hack.tidings.create!(base_attrs) | |||||
| render_ok | |||||
| end | |||||
| # 取消发布 | |||||
| def cancel_publish | |||||
| @hack.update_attribute(:status, 0) | |||||
| base_attrs = { | |||||
| trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id, | |||||
| parent_container_type: "HackUnPublish", extra: @hack.identifier | |||||
| } | |||||
| @hack.tidings.create!(base_attrs) | |||||
| render_ok | |||||
| end | |||||
| # 发布列表 | |||||
| def unpulished_list | |||||
| limit = params[:limit] || 16 | |||||
| page = params[:page] || 1 | |||||
| hacks = Hack.where(user_id: current_user.id, status: 0) | |||||
| @hacks_count = hacks.count | |||||
| @hacks = hacks.includes(:hack_sets).page(page).per(limit) | |||||
| end | |||||
| def edit; | |||||
| end | |||||
| def new; | |||||
| end | |||||
| def destroy | |||||
| begin | |||||
| base_attrs = { | |||||
| user_id: @hack.user_id, viewed: 0, tiding_type: 'System', trigger_user_id: current_user.id, | |||||
| parent_container_type: "HackDelete", extra: "#{@hack.name}" | |||||
| } | |||||
| @hack.tidings.create!(base_attrs) | |||||
| @hack.destroy | |||||
| render_ok | |||||
| rescue => e | |||||
| logger.error("####hack_delete_error: #{e.message}") | |||||
| render_error("删除失败") | |||||
| end | |||||
| end | |||||
| private | |||||
| # 实名认证老师,管理员与运营人员权限 | |||||
| def require_teacher_identity | |||||
| unless current_user.certification_teacher? || admin_or_business? | |||||
| tip_exception(403, "..") | |||||
| end | |||||
| end | |||||
| # 只有自己,或者管理员才能更新 | |||||
| def require_auth_identity | |||||
| unless @hack.user_id == current_user.id || admin_or_business? | |||||
| tip_exception(403, "..") | |||||
| end | |||||
| end | |||||
| def find_hack | |||||
| @hack = Hack.find_by_identifier(params[:identifier]) | |||||
| end | |||||
| def hack_params | |||||
| params.require(:hack).permit(:name, :description, :difficult, :open_or_not, :time_limit, :score, :sub_discipline_id) | |||||
| end | |||||
| def item_params | |||||
| params.require(:hack).permit(:name, :sub_discipline_id) | |||||
| end | |||||
| def hack_sets_params | |||||
| params.permit(hack_sets: [:input, :output, :position])[:hack_sets] | |||||
| end | |||||
| def hack_set_params | |||||
| params.require(:hack_set).permit(:id, :input, :output, :position) | |||||
| end | |||||
| def hack_code_params | |||||
| params.require(:hack_codes).permit(:code, :language) | |||||
| end | |||||
| def publish_params | |||||
| params.require(:hack).permit(:difficult, :category, :open_or_not, :time_limit, :score) | |||||
| end | |||||
| def param_update_sets sets, all_sets_id | |||||
| delete_set_ids = all_sets_id - sets.map {|set| set[:id]} | |||||
| @hack.hack_sets.where(id: delete_set_ids).destroy_all | |||||
| logger.info("#######sets:#{sets}") | |||||
| sets.each do |set| | |||||
| logger.info("###set[:id]: #{set[:id]}") | |||||
| logger.info("###all_sets: #{all_sets_id.include?(set[:id])}") | |||||
| if all_sets_id.include?(set[:id]) | |||||
| update_attrs = {input: set[:input], output: set[:output], position: set[:position]} | |||||
| @hack.hack_sets.find_by!(id: set[:id]).update_attributes!(update_attrs) | |||||
| end | |||||
| end | |||||
| end | |||||
| def params_filter_or_order | |||||
| # 如果有来源,就不管发布公开私有 | |||||
| select_sql = "hacks.*, if(hacks.hack_user_lastest_codes_count=0, 0, hacks.pass_num/hacks.hack_user_lastest_codes_count) passed_rate" | |||||
| if params[:come_from] | |||||
| hacks = Hack.select(select_sql).mine(current_user.id) | |||||
| else | |||||
| # 全部包括已经发布的,和我的未发布的 | |||||
| if current_user.admin_or_business? | |||||
| hacks = Hack.select(select_sql) | |||||
| else | |||||
| hacks = Hack.select(select_sql).published.opening.or(Hack.select(select_sql).unpublish.mine(current_user.id)) | |||||
| end | |||||
| end | |||||
| # 搜索 | |||||
| if params[:search] | |||||
| hacks = hacks.where("name like ?", "%#{params[:search]}%") | |||||
| end | |||||
| # 难度 | |||||
| if params[:difficult] | |||||
| hacks = hacks.where(difficult: params[:difficult]) | |||||
| end | |||||
| # 状态 | |||||
| if params[:status] | |||||
| user_hacks = HackUserLastestCode.where(user_id: current_user.id) | |||||
| if params[:status].to_i == -1 | |||||
| if user_hacks.present? | |||||
| hacks = hacks.where.not(id: user_hacks.pluck(:hack_id)) | |||||
| end | |||||
| else | |||||
| hacks = hacks.joins(:hack_user_lastest_codes).where(hack_user_lastest_codes: {status: params[:status]}) | |||||
| end | |||||
| end | |||||
| # 分类 | |||||
| if params[:category] | |||||
| hacks = hacks.where(category: params[:category]) | |||||
| end | |||||
| # 语言 | |||||
| if params[:language] | |||||
| hacks = hacks.joins(:hack_codes).where(hack_codes: {language: params[:language]}) | |||||
| end | |||||
| # 排序 | |||||
| sort_by = params[:sort_by] || "hack_user_lastest_codes_count" | |||||
| sort_direction = params[:sort_direction] || "desc" | |||||
| @hacks = hacks.order("#{sort_by} #{sort_direction}") | |||||
| end | |||||
| def start_hack_auth | |||||
| return true if @hack.status == 1 | |||||
| require_auth_identity | |||||
| end | |||||
| end | |||||
| @@ -1,44 +0,0 @@ | |||||
| class HomeController < ApplicationController | |||||
| def index | |||||
| # banner图 | |||||
| images = current_laboratory.portal_images.only_online.order(position: :asc) | |||||
| images = default_laboratory.portal_images.only_online.order(position: :asc) if images.blank? # 未设置时使用EduCoder的轮播图 | |||||
| @images_url = [] | |||||
| images.each do |image| | |||||
| @images_url << {path: image.link, image_url: Util::FileManage.source_disk_file_url(image)} | |||||
| end | |||||
| # 目录分级 | |||||
| @rep_list = current_laboratory.shixun_repertoires | |||||
| shixuns = current_laboratory.shixuns | |||||
| subjects = current_laboratory.subjects | |||||
| if current_laboratory.main_site? | |||||
| shixuns = shixuns.where(homepage_show: true) | |||||
| subjects = subjects.where(homepage_show: true) | |||||
| else | |||||
| shixuns = shixuns.joins(:laboratory_shixuns).where(laboratory_shixuns: { homepage: true, laboratory_id: current_laboratory.id}) | |||||
| subjects = subjects.joins(:laboratory_subjects).where(laboratory_subjects: { homepage: true, laboratory_id: current_laboratory.id}) | |||||
| end | |||||
| @shixuns = shixuns.includes(:tag_repertoires, :challenges).limit(8) | |||||
| @subjects = subjects.includes(:repertoire, :shixuns).limit(8) | |||||
| @main_shixuns = Shixun.where(homepage_show: true).includes(:tag_repertoires, :challenges).limit(8) | |||||
| @main_subjects = Subject.where(homepage_show: true).includes(:shixuns, :repertoire).limit(8) | |||||
| # if current_laboratory.main_site? | |||||
| # @tea_users = User.where(homepage_teacher: 1).includes(:user_extension).limit(10).order("experience desc") | |||||
| # @stu_users = User.where(is_test: 0).includes(:user_extension).where(user_extensions: {identity: 1}).limit(10).order("experience desc") | |||||
| # end | |||||
| end | |||||
| def search | |||||
| @fuzzy_searchs = params[:keyword].split(" ").join("%") | |||||
| @shixuns = Shixun.where("name like ?", "%#{@fuzzy_searchs}%") | |||||
| @total_count = @shixuns.count | |||||
| end | |||||
| end | |||||
| @@ -1,7 +0,0 @@ | |||||
| class HotKeywordsController < ApplicationController | |||||
| def index | |||||
| keywords = [] | |||||
| keywords = HotSearchKeyword.hot(8) if HotSearchKeyword.available? | |||||
| render_ok(keywords: keywords) | |||||
| end | |||||
| end | |||||
| @@ -1,77 +0,0 @@ | |||||
| class ItemBanksController < ApplicationController | |||||
| include PaginateHelper | |||||
| before_action :require_login | |||||
| before_action :certi_identity_auth, only: [:create, :edit, :update, :destroy, :set_public] | |||||
| before_action :find_item, except: [:index, :create] | |||||
| before_action :edit_auth, only: [:update, :destroy, :set_public] | |||||
| before_action :identity_auth, only: [:index] | |||||
| def index | |||||
| items = ItemBankQuery.call(params) | |||||
| @items_count = items.size | |||||
| @items = paginate items.includes(:item_analysis, :user, :container) | |||||
| exam = ExaminationBank.find_by(id: params[:exam_id]) if params[:exam_id].present? | |||||
| exam_setting = ExaminationIntelligentSetting.find_by(id: params[:exam_setting_id]) if params[:exam_setting_id].present? | |||||
| @item_basket_ids = if exam | |||||
| exam.examination_items.pluck(:item_bank_id) | |||||
| elsif exam_setting | |||||
| exam_setting.item_baskets.pluck(:item_bank_id) | |||||
| else | |||||
| current_user.item_baskets.pluck(:item_bank_id) | |||||
| end | |||||
| end | |||||
| def create | |||||
| item = ItemBank.new(user: current_user) | |||||
| ItemBanks::SaveItemService.call(item, form_params) | |||||
| render_ok | |||||
| rescue ApplicationService::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| def edit | |||||
| end | |||||
| def update | |||||
| ItemBanks::SaveItemService.call(@item, form_params) | |||||
| render_ok | |||||
| rescue ApplicationService::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| def destroy | |||||
| ActiveRecord::Base.transaction do | |||||
| ApplyAction.where(container_type: "ItemBank", container_id: @item.id).destroy_all | |||||
| if @item.item_type == "PROGRAM" | |||||
| @item.container&.destroy! | |||||
| else | |||||
| @item.destroy! | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| end | |||||
| def set_public | |||||
| tip_exception(-1, "该试题已公开") if @item.public? | |||||
| tip_exception(-1, "请勿重复提交申请") if ApplyAction.where(container_id: @item.id, container_type: 'ItemBank', status: 0).exists? | |||||
| ApplyAction.create!(container_id: @item.id, container_type: 'ItemBank', user_id: current_user.id) | |||||
| # @item.update_attributes!(public: 1) | |||||
| render_ok | |||||
| end | |||||
| private | |||||
| def find_item | |||||
| @item = ItemBank.find_by!(id: params[:id]) | |||||
| end | |||||
| def edit_auth | |||||
| current_user.admin_or_business? || @item.user == current_user | |||||
| end | |||||
| def form_params | |||||
| params.permit(:discipline_id, :sub_discipline_id, :item_type, :difficulty, :name, :analysis, tag_discipline_id: [], choices: %i[choice_text is_answer]) | |||||
| end | |||||
| end | |||||
| @@ -1,96 +0,0 @@ | |||||
| class ItemBasketsController < ApplicationController | |||||
| before_action :require_login | |||||
| before_action :certi_identity_auth, only: [:create, :delete_item_type, :destroy, :set_score, :batch_set_score, :adjust_position] | |||||
| before_action :validate_score, only: [:set_score, :batch_set_score] | |||||
| helper_method :current_basket | |||||
| def index | |||||
| @item_baskets = basket_items | |||||
| @single_questions = @item_baskets.where(item_type: "SINGLE") | |||||
| @multiple_questions = @item_baskets.where(item_type: "MULTIPLE") | |||||
| @judgement_questions = @item_baskets.where(item_type: "JUDGMENT") | |||||
| @program_questions = @item_baskets.where(item_type: "PROGRAM") | |||||
| end | |||||
| def basket_list | |||||
| @basket_count = current_user.item_baskets.group(:item_type).count | |||||
| end | |||||
| def create | |||||
| ItemBaskets::SaveItemBasketService.call(current_user, create_params, exam_setting) | |||||
| render_ok | |||||
| rescue ApplicationService::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| def destroy | |||||
| item = basket_items.find_by!(item_bank_id: params[:id]) | |||||
| ActiveRecord::Base.transaction do | |||||
| basket_items.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1") | |||||
| item.destroy! | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| def delete_item_type | |||||
| baskets = basket_items.where(item_type: params[:item_type]) | |||||
| baskets.destroy_all | |||||
| render_ok | |||||
| end | |||||
| def set_score | |||||
| current_basket.update_attributes!(score: params[:score]) | |||||
| @questions_score = basket_items.where(item_type: current_basket.item_type).pluck(:score).sum | |||||
| @all_score = basket_items.pluck(:score).sum | |||||
| end | |||||
| def batch_set_score | |||||
| basket_items.where(item_type: params[:item_type]).update_all(score: params[:score]) | |||||
| @questions_score = basket_items.where(item_type: params[:item_type]).pluck(:score).sum | |||||
| @all_score = basket_items.pluck(:score).sum | |||||
| end | |||||
| def adjust_position | |||||
| same_items = basket_items.where(item_type: current_basket.item_type) | |||||
| max_position = same_items.size | |||||
| tip_exception("position超出范围") unless params[:position].present? && params[:position].to_i <= max_position && params[:position].to_i >= 1 | |||||
| ActiveRecord::Base.transaction do | |||||
| if params[:position].to_i > current_basket.position | |||||
| same_items.where("position > #{current_basket.position} and position <= #{params[:position].to_i}").update_all("position=position-1") | |||||
| current_basket.update_attributes!(position: params[:position]) | |||||
| elsif params[:position].to_i < current_basket.position | |||||
| same_items.where("position < #{current_basket.position} and position >= #{params[:position].to_i}").update_all("position=position+1") | |||||
| current_basket.update_attributes!(position: params[:position]) | |||||
| else | |||||
| return normal_status(-1, "排序无变化") | |||||
| end | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| private | |||||
| def create_params | |||||
| params.permit(item_ids: []) | |||||
| end | |||||
| def exam_setting | |||||
| @_exam_setting = ExaminationIntelligentSetting.find_by(id: params[:exam_setting_id]) | |||||
| end | |||||
| def basket_items | |||||
| @_items = params[:exam_setting_id] ? exam_setting.item_baskets : current_user.item_baskets | |||||
| end | |||||
| def current_basket | |||||
| @_current_basket = ItemBasket.find_by!(id: params[:id]) | |||||
| tip_exception(403, "无权限编辑") unless current_user.admin_or_business? || @_current_basket.user_id.to_i == current_user.id || | |||||
| @_current_basket.examination_intelligent_setting&.user_id.to_i == current_user.id | |||||
| @_current_basket | |||||
| end | |||||
| def validate_score | |||||
| tip_exception("分值不能为空") unless params[:score].present? | |||||
| tip_exception("分值需大于0") unless params[:score].to_f > 0 | |||||
| end | |||||
| end | |||||
| @@ -1,199 +0,0 @@ | |||||
| class MemosController < ApplicationController | |||||
| before_action :require_login, except: [:show, :index] | |||||
| before_action :check_account, only: [:new, :create, :reply] | |||||
| before_action :set_memo, only: [:show, :edit, :update, :destroy, :sticky_or_cancel, :hidden, :more_reply] | |||||
| before_action :validate_memo_params, only: [:create, :update] | |||||
| before_action :owner_or_admin, only: [:edit, :update, :destroy] | |||||
| before_action :require_business, only: [:sticky_or_cancel, :hidden] | |||||
| include ApplicationHelper | |||||
| # GET /memos | |||||
| # GET /memos.json | |||||
| def index | |||||
| @user = current_user | |||||
| @memos = Memo.all | |||||
| s_order = (params[:order] == "replies_count" ? "all_replies_count" : params[:order]) || "updated_at" | |||||
| # @tidding_count = unviewed_tiddings(current_user) if current_user.present? | |||||
| page = params[:page] || 1 | |||||
| limit = params[:limit] || 15 | |||||
| search = params[:search] | |||||
| forum_id = params[:forum] | |||||
| tag_repertoire_id = params[:tag_repertoire_id] | |||||
| sql = | |||||
| if forum_id | |||||
| !search.blank? ? "forum_id = #{forum_id} and root_id is null and subject like '%#{search}%'" : | |||||
| "forum_id = #{forum_id} and root_id is null" | |||||
| elsif !search.blank? | |||||
| "forum_id in(3, 5, 16) and root_id is null and subject like '%#{search}%'" | |||||
| else | |||||
| "forum_id in(3, 5, 16) and root_id is null" | |||||
| end | |||||
| if tag_repertoire_id | |||||
| memo_ids = MemoTagRepertoire.where(tag_repertoire_id: tag_repertoire_id).pluck(:memo_id) | |||||
| memo_ids = memo_ids ? memo_ids.join(",") : -1 | |||||
| sql += " and #{Memo.table_name}.id in(#{memo_ids})" | |||||
| end | |||||
| if params[:order] == "updated_at" | |||||
| sql += " and all_replies_count != 0" | |||||
| end | |||||
| memos = Memo.field_for_list.where("#{sql}") | |||||
| @memos_count = memos.length | |||||
| @memos = memos.order("sticky = 1 desc, #{Memo.table_name}.#{s_order} desc").page(page).per(limit) | |||||
| @memos = @memos.includes(:praise_treads, :tag_repertoires, author: :user_extension) | |||||
| # @my_memos_count = Memo.user_posts(current_user.try(:id)).count | |||||
| @tags_info = MemoTagRepertoire.find_by_sql("SELECT tag_repertoire_id, tr.name, count(*) cnt | |||||
| FROM memo_tag_repertoires mtr join tag_repertoires tr on | |||||
| tr.id = mtr.tag_repertoire_id group by tag_repertoire_id order by cnt desc, | |||||
| tag_repertoire_id desc limit 9") | |||||
| @hot_memos = Memo.field_for_recommend.posts.hot.includes(:tag_repertoires).limit(4) | |||||
| @recommend_shixuns = DiscussesService.new.recommends | |||||
| end | |||||
| # GET /memos/1.json | |||||
| def show | |||||
| # tidding_count = unviewed_tiddings(current_user) if current_user | |||||
| @user = current_user | |||||
| @memo.update_column(:viewed_count, @memo.viewed_count+1) | |||||
| @memos = @memo.reply_for_memo.includes(:praise_treads, author: :user_extension).order("created_at desc").limit(10) | |||||
| @attachments = @memo.attachments | |||||
| @recommend_shixuns = DiscussesService.new.recommends | |||||
| end | |||||
| # GET /memos/new | |||||
| def new | |||||
| @tag_list = TagRepertoire.field_for_list.order("name asc") | |||||
| end | |||||
| # GET /memos/1/edit | |||||
| def edit | |||||
| @tag_list = TagRepertoire.field_for_list.order("name asc") | |||||
| @memo_tags = @memo.tag_repertoires.field_for_list | |||||
| @attachments = @memo.attachments | |||||
| end | |||||
| # POST /memos.json | |||||
| def create | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @memo = Memo.new(memo_params) | |||||
| @memo.author = current_user | |||||
| @memo.save! | |||||
| Attachment.associate_container(params[:attachment_ids], @memo.id, @memo.class.name) | |||||
| params[:tags].each do |tag| | |||||
| MemoTagRepertoire.create!(memo_id: @memo.id, tag_repertoire_id: tag) | |||||
| end | |||||
| render :json => {memo_id: @memo.id, status: 0, message: "帖子创建成功"} | |||||
| rescue Exception => e | |||||
| tip_exception("帖子创建失败,原因:#{e}") | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| # PATCH/PUT /memos/1.json | |||||
| def update | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @memo.update_attributes!(memo_params) | |||||
| Attachment.associate_container(params[:attachment_ids], @memo.id, @memo.class.name) | |||||
| @memo.memo_tag_repertoires.destroy_all | |||||
| params[:tags].each do |tag| | |||||
| MemoTagRepertoire.create!(memo_id: @memo.id, tag_repertoire_id: tag) | |||||
| end | |||||
| normal_status("帖子更新成功") | |||||
| rescue Exception => e | |||||
| tip_exception("帖子更新失败,原因:#{e}") | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| # DELETE /memos/1 | |||||
| # DELETE /memos/1.json | |||||
| def destroy | |||||
| @memo.destroy | |||||
| normal_status("删除成功") | |||||
| end | |||||
| def sticky_or_cancel | |||||
| tip_exception("只能对主贴进行置顶操作") unless @memo.parent_id.nil? | |||||
| begin | |||||
| @memo.update_attributes!(sticky: !@memo.sticky) | |||||
| normal_status("更新成功") | |||||
| rescue Exception => e | |||||
| tip_exception("更新失败,原因:#{e}") | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| def hidden | |||||
| tip_exception("不能对主贴进行隐藏操作") if @memo.parent_id.nil? | |||||
| begin | |||||
| @memo.update_attributes!(hidden: @memo.hidden == 0 ? 1 : 0) | |||||
| normal_status("更新成功") | |||||
| rescue Exception => e | |||||
| tip_exception("更新失败,原因:#{e}") | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| def reply | |||||
| tip_exception("parent_id不能为空") if params[:parent_id].blank? | |||||
| tip_exception("content不能为空") if params[:content].blank? | |||||
| tip_exception("内容不能超过2000字符") if params[:content].length > 2000 | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| memo = Memo.find_by!(id: params[:parent_id]) | |||||
| @reply = Memo.new | |||||
| @reply.content = params[:content] | |||||
| @reply.author = current_user | |||||
| @reply.forum_id = memo.forum_id | |||||
| @reply.subject = memo.subject | |||||
| @reply.root_id = memo.root_id || memo.id | |||||
| memo.children << @reply | |||||
| m = Memo.find_by!(id: @reply.root_id) | |||||
| m.update_attributes!(all_replies_count: m.all_replies_count + 1) | |||||
| rescue Exception => e | |||||
| tip_exception("回复失败,原因:#{e}") | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| def more_reply | |||||
| @user = current_user | |||||
| page = params[:page] || 2 | |||||
| limit = params[:limit] || 10 | |||||
| offset = (page.to_i - 1) * limit | |||||
| @memos_count = Memo.where(parent_id: @memo.id).count | |||||
| @memos = Memo.limit(limit).where(parent_id: @memo.id).includes(:author, :praise_treads).order("created_at desc").offset(offset) | |||||
| end | |||||
| private | |||||
| # Use callbacks to share common setup or constraints between actions. | |||||
| def set_memo | |||||
| @memo = Memo.find(params[:id]) | |||||
| end | |||||
| def owner_or_admin | |||||
| tip_exception(403, "无权限操作") unless @memo.author == current_user || current_user.admin? || current_user.business? | |||||
| end | |||||
| # Never trust parameters from the scary internet, only allow the white list through. | |||||
| def memo_params | |||||
| params.require(:memo).permit(:subject, :content, :forum_id) | |||||
| end | |||||
| def validate_memo_params | |||||
| tip_exception("话题名称不能为空") if params[:subject].blank? | |||||
| tip_exception("话题内容不能为空") if params[:content].blank? | |||||
| tip_exception("话题类型不能为空") if params[:forum_id].blank? | |||||
| tip_exception("技术标签不能为空") if params[:forum_id].to_i == 5 && params[:tags].blank? | |||||
| end | |||||
| end | |||||
| @@ -1,225 +0,0 @@ | |||||
| class MessagesController < ApplicationController | |||||
| include MessagesHelper | |||||
| SORT_TYPE = %w[time hot] | |||||
| before_action :require_login, :check_auth, only: %i[create update sticky_top bulk_delete create destroy bulk_send bulk_move bulk_public] | |||||
| before_action :find_board, only: [:create, :index, :bulk_delete, :bulk_move, :bulk_send, :bulk_public] | |||||
| before_action :find_message, only: [:update, :destroy, :sticky_top, :reply_list, :destroy, :reply] | |||||
| before_action :validate_delete_params, only: %i[bulk_delete bulk_public] | |||||
| before_action :message_validate_create_params, only: :create | |||||
| before_action :validate_update_params, only: :update | |||||
| before_action :validate_sort_type, only: :index | |||||
| before_action :validate_send_message_to_course_params, only: :bulk_send | |||||
| before_action :validate_move_params, only: :bulk_move | |||||
| def index | |||||
| @page = params[:page] || 1 | |||||
| @page_size = params[:page_size] || 15 | |||||
| sort = params[:sort].to_i == 1 ? 'asc' : 'desc' | |||||
| sort_type = params[:sort_type] || 'time' | |||||
| if @board.parent_id == 0 | |||||
| messages = Message.where(board_id: @board.course.boards.pluck(:id)) | |||||
| else | |||||
| messages = @board.messages | |||||
| end | |||||
| messages = messages.root_nodes.by_keywords(params[:search]) | |||||
| messages = messages.reorder('(sticky = 1) DESC') # 置顶 | |||||
| messages = | |||||
| case sort_type | |||||
| when 'time' then messages.order("created_on #{sort}") | |||||
| when 'hot' then messages.order("descendants_count #{sort}") | |||||
| else messages.order("created_on #{sort}") | |||||
| end | |||||
| messages = messages.includes(:author, :board) | |||||
| @messages = Kaminari.paginate_array(messages).page(@page).per(@page_size) | |||||
| ids = @messages.map(&:id) | |||||
| @praises_count_map = Message.where(root_id: ids).group(:root_id).sum(:praises_count) | |||||
| end | |||||
| def reply_list | |||||
| @page = params[:page] || 1 | |||||
| @page_size = params[:page_size] || 10 | |||||
| @current_user = current_user || nil | |||||
| @messages = @message.children.preload_messages.includes(:message_detail, :praise_treads) | |||||
| # @messages = @messages.ordered(sort: 1) unless @message.parent_id.nil? | |||||
| @user_course_identity = current_user.course_identity(@message.board.course) | |||||
| case @user_course_identity | |||||
| when 5, 6, 7 | |||||
| @messages = @messages.visible | |||||
| end | |||||
| @messages = @messages.reorder("messages.created_on desc") | |||||
| @messages = @messages.page(@page).per(@page_size) | |||||
| end | |||||
| def reply | |||||
| return normal_status(-1, "回复内容不能为空") if params[:content].blank? | |||||
| return normal_status(-1, "回复内容不能超过2000字符") if params[:content].length > 2000 | |||||
| @reply = Message.create!(board: @message.board, root_id: @message.root_id || @message.id, | |||||
| author: current_user, parent: @message, | |||||
| message_detail_attributes: { | |||||
| content: params[:content] | |||||
| }) | |||||
| end | |||||
| def sticky_top | |||||
| return normal_status(403, "您没有权限进行该操作") unless current_user.teacher_of_course?(@message.board.course) | |||||
| @message.update_attributes(:sticky => @message.sticky == 1 ? 0 : 1) | |||||
| end | |||||
| def bulk_delete | |||||
| ActiveRecord::Base.transaction do | |||||
| begin | |||||
| @messages = @board.messages.by_ids(params[:ids]) | |||||
| @messages.destroy_all | |||||
| rescue Exception => e | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| end | |||||
| def new | |||||
| @message = Message.new | |||||
| end | |||||
| def show | |||||
| @message = Message.includes(:attachments, :message_detail, | |||||
| :children, :author => :user_extension, | |||||
| :board => [{course: :board_course_modules}]) | |||||
| .find_by_id params[:id] | |||||
| return normal_status(-2, "ID为#{params[:id]}的帖子不存在") if @message.nil? | |||||
| @attachment_size = @message.attachments.size | |||||
| @message.update_visits | |||||
| @current_user = current_user | |||||
| end | |||||
| def update | |||||
| return normal_status(403, "您没有权限进行该操作") if current_user != @message.author && !current_user.teacher_of_course?(@message.board.course) | |||||
| begin | |||||
| board = @message.board&.course&.boards.find_by!(id: params[:select_board_id]) | |||||
| email_notify = @message.email_notify ? 1 : @message.board&.course.email_notify && params[:email_notify] | |||||
| send_email = !@message.email_notify && email_notify | |||||
| h = {is_md: true, email_notify: email_notify, board_id: board&.id} | |||||
| m_params = message_params.merge(h) | |||||
| @message.update_attributes(m_params) | |||||
| Attachment.associate_container(params[:attachment_ids], @message.id, @message.class.name) | |||||
| @message.update_content(params[:content]) | |||||
| notify_course_students(@message, @message.board&.course) if send_email | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| def create | |||||
| return normal_status(403, "您没有权限进行该操作") unless current_user.admin_or_business? || current_user.member_of_course?(@board.course) | |||||
| begin | |||||
| @message = Message.new(message_params) | |||||
| @message.author = current_user | |||||
| @message.board_id = params[:select_board_id] | |||||
| @message.message_detail_attributes = {content: params[:content]} | |||||
| @message.email_notify = @board.course.email_notify && params[:email_notify] ? 1 : 0 | |||||
| @message.save! | |||||
| Attachment.associate_container(params[:attachment_ids], @message.id, @message.class.name) | |||||
| if @board.course.email_notify && params[:email_notify] | |||||
| notify_course_students @message, @board.course | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| def destroy | |||||
| begin | |||||
| return normal_status(403, "您没有权限进行该操作") if current_user.course_identity(@message.board.course) >= 5 || @message.author != current_user | |||||
| @message.destroy! | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| def bulk_send | |||||
| return normal_status(403) unless current_user.teacher_or_admin?(@board.course) | |||||
| ids = params[:ids] | |||||
| course_ids = params[:to_course_ids] | |||||
| begin | |||||
| ids.each do |id| | |||||
| @message = Message.find_by_id id | |||||
| if @message.try(:parent_id).nil? # TODO 暂时只支持目录下的跟节点发送 | |||||
| course_ids.each do |course_id| | |||||
| course = Course.find course_id | |||||
| new_message = Message.create!(board: course.course_board, | |||||
| subject: @message.subject, | |||||
| author: current_user, | |||||
| message_detail_attributes: { | |||||
| content: @message.try(:message_detail).try(:content) | |||||
| } | |||||
| ) | |||||
| @message.copy_attachments_to_new_message(new_message, current_user) | |||||
| end | |||||
| end | |||||
| end | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| raise ActiveRecord::Rollback | |||||
| end | |||||
| end | |||||
| def bulk_move | |||||
| # 课堂的目录之间移动,有子栏目的才显示此项 | |||||
| return normal_status(403) unless current_user.teacher_of_course?(@board.course) | |||||
| Message.bulk_move_to_other_board(params[:ids], params[:to_board_id]) | |||||
| end | |||||
| def bulk_public | |||||
| @messages = @board.messages.root_nodes.by_ids Array(params[:ids]) | |||||
| @messages.update_all(is_public: true) | |||||
| end | |||||
| private | |||||
| def validate_sort_type | |||||
| normal_status(2, "参数sort_type暂时只支持 'time', 'hot'两种") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip) | |||||
| end | |||||
| def find_message | |||||
| begin | |||||
| @message = Message.find params[:id] | |||||
| rescue Exception => e | |||||
| uid_logger_error(e.message) | |||||
| tip_exception(e.message) | |||||
| end | |||||
| end | |||||
| def message_params | |||||
| params.require(:message).permit(:subject, :sticky) | |||||
| end | |||||
| def notify_course_students message, course | |||||
| course.students.includes(:user).each do |student| | |||||
| UserMailer.course_message_email(student&.user&.mail, message.id).deliver_later if student&.user&.mail | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,138 +0,0 @@ | |||||
| class PartnersController < ApplicationController | |||||
| skip_before_action :check_sign | |||||
| include Base::PaginateHelper | |||||
| include Admins::RenderHelper | |||||
| layout 'college' | |||||
| before_action :require_login, :check_partner_present!, :check_permission! | |||||
| before_action :check_admin_manager_group_permission!, except: [:customers] | |||||
| helper_method :current_partner, :manager_permission? | |||||
| def customers | |||||
| customers = CustomerQuery.call(current_partner, current_user, params) | |||||
| @customers = paginate(customers.includes(:school)) | |||||
| load_customer_extra_statistic_data | |||||
| end | |||||
| def partner_manager_groups | |||||
| @manager_groups = current_partner.partner_manager_groups.includes(users: :user_extension).to_a | |||||
| end | |||||
| def manager_group | |||||
| name = params[:manager_group_name].to_s.strip | |||||
| if params[:manager_group_id].present? | |||||
| # 重命名 | |||||
| @manager_group = current_partner.partner_manager_groups.find(params[:manager_group_id]) | |||||
| return render_error('不能修改管理者权限组名称') if @manager_group.admin? | |||||
| @manager_group.update!(name: name) | |||||
| else | |||||
| # 新建 | |||||
| @manager_group = current_partner.partner_manager_groups.create!(name: name) | |||||
| end | |||||
| end | |||||
| def remove_manager_group | |||||
| manager_group = current_partner.partner_manager_groups.find(params[:manager_group_id]) | |||||
| return render_error('不能删除管理者权限组') if manager_group.admin? | |||||
| manager_group.destroy! | |||||
| render_delete_success | |||||
| end | |||||
| def partner_managers | |||||
| user_ids = Array.wrap(params[:user_ids]) | |||||
| @manager_group = current_partner.partner_manager_groups.find(params[:manager_group_id]) | |||||
| ActiveRecord::Base.transaction do | |||||
| User.where(id: user_ids).pluck(:id).each do |user_id| | |||||
| next if current_partner.partner_managers.exists?(partner_manager_group: @manager_group, user_id: user_id) | |||||
| current_partner.partner_managers.create!(partner_manager_group: @manager_group, user_id: user_id) | |||||
| end | |||||
| end | |||||
| @manager_group.reload | |||||
| end | |||||
| def remove_partner_manager | |||||
| partner_manager = current_partner.partner_managers.find(params[:manager_id]) | |||||
| return render_error('不能删除自己') if partner_manager.user_id == current_user.id && partner_manager.partner_manager_group.admin? | |||||
| partner_manager.destroy! | |||||
| render_delete_success | |||||
| end | |||||
| def customer_manager_group | |||||
| customer = current_partner.customers.find(params[:customer_id]) | |||||
| if params[:manager_group_id].present? | |||||
| manager_group = current_partner.partner_manager_groups.find(params[:manager_group_id]) | |||||
| customer.update!(partner_manager_group: manager_group) | |||||
| else | |||||
| customer.update!(partner_manager_group_id: nil) | |||||
| end | |||||
| render_ok | |||||
| end | |||||
| private | |||||
| def current_partner | |||||
| @_current_partner ||= Partner.find(params[:id].presence || params[:partner_id]) | |||||
| end | |||||
| def check_partner_present! | |||||
| return if current_partner.present? | |||||
| redirect_to '/404' | |||||
| end | |||||
| def manager_permission? | |||||
| admin_or_business? || current_user.partner_managers.exists?(partner_id: current_partner.id) | |||||
| end | |||||
| def check_permission! | |||||
| return if manager_permission? | |||||
| redirect_to '/403' | |||||
| end | |||||
| def check_admin_manager_group_permission! | |||||
| return if admin_or_business? | |||||
| return if current_partner.admin_partner_manager_group.partner_managers.exists?(user: current_user) | |||||
| render_forbidden | |||||
| end | |||||
| def load_customer_extra_statistic_data | |||||
| school_ids = @customers.map(&:school_id) | |||||
| teacher_map = UserExtension.where(school_id: school_ids, identity: 0).group(:school_id).count | |||||
| student_map = UserExtension.where(school_id: school_ids, identity: 1).group(:school_id).count | |||||
| course_map = Course.where(school_id: school_ids, is_delete: 0).where.not(id: 1309).group(:school_id).count | |||||
| shixun_map = Shixun.visible.joins('left join user_extensions on user_extensions.user_id = shixuns.user_id') | |||||
| .where(user_extensions: { school_id: school_ids }).group('user_extensions.school_id').count | |||||
| shixun_report_map = StudentWork.where(work_status: [1, 2]).where('myshixun_id != 0') | |||||
| .joins('left join user_extensions on user_extensions.user_id = student_works.user_id') | |||||
| .where(user_extensions: { school_id: school_ids }) | |||||
| .group('user_extensions.school_id').count | |||||
| course_time_map = Course.where(school_id: school_ids, is_delete: 0) | |||||
| .where.not(id: 1309).group(:school_id).maximum(:updated_at) | |||||
| @customers.each do |customer| | |||||
| customer._extra_data = { | |||||
| teacher_count: teacher_map[customer.school_id], | |||||
| student_count: student_map[customer.school_id], | |||||
| course_count: course_map[customer.school_id], | |||||
| shixun_count: shixun_map[customer.school_id], | |||||
| shixun_report_count: shixun_report_map[customer.school_id], | |||||
| course_time: course_time_map[customer.school_id] | |||||
| } | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,5 +0,0 @@ | |||||
| class RepertoiresController < ApplicationController | |||||
| def index | |||||
| render_ok(repertoires: Repertoire.select(:id, :name).order(:created_at).as_json) | |||||
| end | |||||
| end | |||||
| @@ -1,9 +0,0 @@ | |||||
| class SyncForgeController < ApplicationController | |||||
| skip_before_action :user_setup | |||||
| skip_before_action :check_sign | |||||
| def create | |||||
| SyncForgeJob.perform_later(params[:sync_params]) | |||||
| end | |||||
| end | |||||
| @@ -1,11 +0,0 @@ | |||||
| class TagDisciplinesController < ApplicationController | |||||
| before_action :require_login | |||||
| def create | |||||
| sub_discipline = SubDiscipline.find_by!(id: params[:sub_discipline_id]) | |||||
| tip_exception("重复的知识点") if sub_discipline.tag_disciplines.exists?(name: params[:name].to_s.strip) | |||||
| tag_discipline = TagDiscipline.create!(name: params[:name].to_s.strip, sub_discipline: sub_discipline, user_id: current_user.id, | |||||
| position: sub_discipline.tag_disciplines.pluck(:position).max + 1) | |||||
| render_ok({tag_discipline_id: tag_discipline.id}) | |||||
| end | |||||
| end | |||||
| @@ -1,74 +0,0 @@ | |||||
| class TemTestsController < ApplicationController | |||||
| before_action :set_tem_test, only: [:show, :edit, :update, :destroy] | |||||
| # GET /tem_tests | |||||
| # GET /tem_tests.json | |||||
| def index | |||||
| @tem_tests = TemTest.all | |||||
| end | |||||
| # GET /tem_tests/1 | |||||
| # GET /tem_tests/1.json | |||||
| def show | |||||
| end | |||||
| # GET /tem_tests/new | |||||
| def new | |||||
| @tem_test = TemTest.new | |||||
| end | |||||
| # GET /tem_tests/1/edit | |||||
| def edit | |||||
| end | |||||
| # POST /tem_tests | |||||
| # POST /tem_tests.json | |||||
| def create | |||||
| @tem_test = TemTest.new(tem_test_params) | |||||
| respond_to do |format| | |||||
| if @tem_test.save | |||||
| format.html { redirect_to @tem_test, notice: 'Tem test was successfully created.' } | |||||
| format.json { render :show, status: :created, location: @tem_test } | |||||
| else | |||||
| format.html { render :new } | |||||
| format.json { render json: @tem_test.errors, status: :unprocessable_entity } | |||||
| end | |||||
| end | |||||
| end | |||||
| # PATCH/PUT /tem_tests/1 | |||||
| # PATCH/PUT /tem_tests/1.json | |||||
| def update | |||||
| respond_to do |format| | |||||
| if @tem_test.update(tem_test_params) | |||||
| format.html { redirect_to @tem_test, notice: 'Tem test was successfully updated.' } | |||||
| format.json { render :show, status: :ok, location: @tem_test } | |||||
| else | |||||
| format.html { render :edit } | |||||
| format.json { render json: @tem_test.errors, status: :unprocessable_entity } | |||||
| end | |||||
| end | |||||
| end | |||||
| # DELETE /tem_tests/1 | |||||
| # DELETE /tem_tests/1.json | |||||
| def destroy | |||||
| @tem_test.destroy | |||||
| respond_to do |format| | |||||
| format.html { redirect_to tem_tests_url, notice: 'Tem test was successfully destroyed.' } | |||||
| format.json { head :no_content } | |||||
| end | |||||
| end | |||||
| private | |||||
| # Use callbacks to share common setup or constraints between actions. | |||||
| def set_tem_test | |||||
| @tem_test = TemTest.find(params[:id]) | |||||
| end | |||||
| # Never trust parameters from the scary internet, only allow the white list through. | |||||
| def tem_test_params | |||||
| params.require(:tem_test).permit(:name, :email) | |||||
| end | |||||
| end | |||||
| @@ -1,5 +0,0 @@ | |||||
| class TemplatesController < ApplicationController | |||||
| def show | |||||
| @template = EcTemplate.find_by_name!(params[:name]) | |||||
| end | |||||
| end | |||||
| @@ -1,37 +0,0 @@ | |||||
| class TidingsController < ApplicationController | |||||
| include PaginateHelper | |||||
| before_action :require_login | |||||
| after_action :update_onclick_time!, only: [:index] | |||||
| def index | |||||
| tidings = current_user.tidings.visible | |||||
| @onclick_time = current_user.click_time | |||||
| tiding_types = | |||||
| case params[:type] | |||||
| when 'notice' then 'System' | |||||
| when 'apply' then 'Apply' | |||||
| when 'course' then %w(HomeworkCommon Exercise Poll GraduationTask GraduationTopic) | |||||
| when 'project' then 'Project' | |||||
| when 'interaction' then %w(Comment Mentioned Praise Fan) | |||||
| when 'project_package' then %w(Created Destroyed Bidding BiddingEnd BiddingWon BiddingLost) | |||||
| end | |||||
| tidings = tidings.where(tiding_type: tiding_types) if tiding_types.present? | |||||
| tidings = tidings.where(container_type: 'JoinCourse', status: 0) if params[:type] == 'course_apply' | |||||
| # @course_apply_count = tidings.where("created_at > '#{@onclick_time}'").where(container_type: 'JoinCourse', status: 0).count | |||||
| @course_apply_count = tidings.where(container_type: 'JoinCourse', status: 0).count | |||||
| tidings = tidings.where(container_type: 'ProjectPackage') if params[:type] == 'project_package' | |||||
| @count = tidings.count | |||||
| @tidings = paginate(tidings.order(created_at: :desc), per_page: 10) | |||||
| end | |||||
| private | |||||
| def update_onclick_time! | |||||
| current_user.onclick_time.touch(:onclick_time) | |||||
| end | |||||
| end | |||||
| @@ -1,22 +0,0 @@ | |||||
| class TrialAppliesController < ApplicationController | |||||
| before_action :require_user_login | |||||
| def create | |||||
| Users::ApplyTrailService.call(current_user, create_params) | |||||
| render_ok | |||||
| rescue Users::ApplyTrailService::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| private | |||||
| def create_params | |||||
| params.permit(:phone, :code, :reason).merge(remote_ip: request.remote_ip) | |||||
| end | |||||
| def require_user_login | |||||
| return if User.current.logged? | |||||
| render_unauthorized | |||||
| end | |||||
| end | |||||
| @@ -1,72 +0,0 @@ | |||||
| class TrustieHacksController < ApplicationController | |||||
| before_action :require_admin, :except => [:index, :entry] | |||||
| before_action :require_login, :except => [:index] | |||||
| before_action :find_hackathon | |||||
| before_action :find_hack, :except => [:create, :index, :edit_hackathon, :update_hackathon] | |||||
| def index | |||||
| ## 分页参数 | |||||
| page = params[:page] || 1 | |||||
| limit = params[:limit] || 16 | |||||
| search = params[:search] | |||||
| hacks = @hackathon.trustie_hacks | |||||
| if search | |||||
| hacks = hacks.where("name like ?", "%#{search}%") | |||||
| end | |||||
| @hackathon_users_count = hacks.blank? ? 0 : hacks.sum(:hack_users_count) | |||||
| @hacks_count = hacks.count | |||||
| @hacks = hacks.page(page).per(limit) | |||||
| end | |||||
| def edit;end | |||||
| def create | |||||
| @hackathon.trustie_hacks.create!(name: params[:name], description: params[:description]) | |||||
| render_ok | |||||
| end | |||||
| def update | |||||
| @hack.update_attributes(name: params[:name], description: params[:description]) | |||||
| render_ok | |||||
| end | |||||
| def destroy | |||||
| @hack.destroy | |||||
| render_ok | |||||
| end | |||||
| def edit_hackathon | |||||
| end | |||||
| def update_hackathon | |||||
| @hackathon.update_attributes(name: params[:name], description: params[:description]) | |||||
| render_ok | |||||
| end | |||||
| # 报名入口 | |||||
| def entry | |||||
| if @hack.hack_users.exists?(user_id: current_user.id) | |||||
| render_error('已经报名,请勿重复操作') | |||||
| else | |||||
| @hack.hack_users.create(user_id: current_user.id) | |||||
| render_ok | |||||
| end | |||||
| end | |||||
| private | |||||
| def find_hackathon | |||||
| @hackathon = TrustieHackathon.first || | |||||
| TrustieHackathon.create!(name: params[:name], description: params[:description]) | |||||
| end | |||||
| def find_hack | |||||
| @hack = TrustieHack.find params[:id] | |||||
| end | |||||
| end | |||||
| @@ -1,6 +1,6 @@ | |||||
| class UsersController < ApplicationController | class UsersController < ApplicationController | ||||
| before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd] | |||||
| before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects] | |||||
| before_action :check_user_exist, only: [:show, :homepage_info] | before_action :check_user_exist, only: [:show, :homepage_info] | ||||
| before_action :require_login, only: %i[me list projects] | before_action :require_login, only: %i[me list projects] | ||||
| skip_before_action :check_sign, only: [:attachment_show] | skip_before_action :check_sign, only: [:attachment_show] | ||||
| @@ -113,7 +113,7 @@ class UsersController < ApplicationController | |||||
| end | end | ||||
| def projects | def projects | ||||
| scope = Projects::ListMyQuery.call(params.merge(category: params[:category],is_public: params[:status]), current_user) | |||||
| scope = Projects::ListMyQuery.call(params.merge(category: params[:category],is_public: params[:status]), @user) | |||||
| @total_count = scope.size | @total_count = scope.size | ||||
| @projects = paginate(scope) | @projects = paginate(scope) | ||||
| end | end | ||||
| @@ -1,27 +0,0 @@ | |||||
| class UsersForPartnersController < ApplicationController | |||||
| include Base::PaginateHelper | |||||
| before_action :check_partner_manager_permission! | |||||
| def index | |||||
| params[:sort_by] = params[:sort_by].presence || 'created_on' | |||||
| params[:sort_direction] = params[:sort_direction].presence || 'desc' | |||||
| users = Admins::UserQuery.call(search_params) | |||||
| @users = paginate users.includes(user_extension: :school) | |||||
| end | |||||
| private | |||||
| def search_params | |||||
| params.permit(:name, :sort_by, :sort_direction) | |||||
| end | |||||
| def check_partner_manager_permission! | |||||
| partner = Partner.find(params[:partner_id]) | |||||
| return if admin_or_business? | |||||
| return if partner.admin_partner_manager_group.partner_managers.exists?(user: current_user) | |||||
| render_forbidden | |||||
| end | |||||
| end | |||||
| @@ -1,11 +0,0 @@ | |||||
| class Wechats::JsSdkSignaturesController < ApplicationController | |||||
| def create | |||||
| timestamp = Time.now.to_i | |||||
| noncestr = ('A'..'z').to_a.sample(8).join | |||||
| signature = Wechat::OfficialAccount.js_sdk_signature(params[:url], noncestr, timestamp) | |||||
| render_ok(appid: Wechat::OfficialAccount.appid, timestamp: timestamp, noncestr: noncestr, signature: signature) | |||||
| rescue Wechat::Error => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| end | |||||
| @@ -1,15 +0,0 @@ | |||||
| class ApplyAddDepartment < ApplicationRecord | |||||
| belongs_to :user | |||||
| belongs_to :school | |||||
| belongs_to :department | |||||
| has_many :applied_messages, as: :applied | |||||
| has_many :tidings, as: :container, dependent: :destroy | |||||
| after_create :send_notify | |||||
| private | |||||
| def send_notify | |||||
| tidings.create!(user_id: 1, trigger_user_id: user_id, belong_container: school, tiding_type: 'Apply', status: 0) | |||||
| end | |||||
| end | |||||
| @@ -1,22 +0,0 @@ | |||||
| class ApplyAddSchool < ApplicationRecord | |||||
| belongs_to :school | |||||
| belongs_to :user | |||||
| has_many :applied_messages, as: :applied | |||||
| has_many :tidings, as: :container, dependent: :destroy | |||||
| after_create :send_notify | |||||
| # after_destroy :after_delete_apply | |||||
| private | |||||
| def send_notify | |||||
| Tiding.create!(user_id: 1, status: 0, container_id: id, container_type: 'ApplyAddSchools', | |||||
| trigger_user_id: user_id, belong_container: school, tiding_type: 'Apply') | |||||
| end | |||||
| # def after_delete_apply | |||||
| # | |||||
| # end | |||||
| end | |||||
| @@ -1,7 +1,7 @@ | |||||
| class AttachmentGroupSetting < ActiveRecord::Base | class AttachmentGroupSetting < ActiveRecord::Base | ||||
| belongs_to :attachment | belongs_to :attachment | ||||
| belongs_to :course_group | |||||
| belongs_to :course | |||||
| # belongs_to :course_group | |||||
| # belongs_to :course | |||||
| scope :none_published, -> {where("attachment_group_settings.publish_time IS NULL OR attachment_group_settings.publish_time > ?", Time.now)} | scope :none_published, -> {where("attachment_group_settings.publish_time IS NULL OR attachment_group_settings.publish_time > ?", Time.now)} | ||||
| @@ -1,16 +0,0 @@ | |||||
| class Attendance < ApplicationRecord | |||||
| belongs_to :user | |||||
| default_scope { order(created_at: :desc) } | |||||
| def next_gold | |||||
| # 超过1天即没有连续的签到则又从10个金币开始累加 | |||||
| return 50 if Util.days_between(Time.zone.now, created_at) > 1 | |||||
| [[score.to_i, 50].max + 10, 100].min | |||||
| end | |||||
| def today? | |||||
| Util.days_between(Time.current, created_at).zero? | |||||
| end | |||||
| end | |||||
| @@ -1,2 +0,0 @@ | |||||
| class Career < ApplicationRecord | |||||
| end | |||||
| @@ -1,150 +0,0 @@ | |||||
| class Challenge < ApplicationRecord | |||||
| # difficulty: 关卡难度: 1.简单 2.中等 3.困难 | |||||
| # show_type: 效果展示:-1.无效果 1.图片 2.apk/exe 3.txt 4.html 5.mp3 6.mp4 | |||||
| belongs_to :shixun, :touch => true, counter_cache: true | |||||
| belongs_to :user | |||||
| has_many :challenge_samples, :dependent => :destroy | |||||
| has_many :test_sets, :dependent => :destroy | |||||
| has_many :challenge_tags, :dependent => :destroy | |||||
| has_many :games, :dependent => :destroy | |||||
| has_many :challenge_chooses, :dependent => :destroy | |||||
| has_many :homework_challenge_settings, :dependent => :destroy | |||||
| has_many :praise_treads, as: :praise_tread_object, dependent: :destroy | |||||
| has_one :praise_tread_cache, as: :object, dependent: :destroy | |||||
| has_many :tidings | |||||
| # 参考答案 | |||||
| has_many :challenge_answers, :dependent => :destroy | |||||
| has_many :exercise_bank_shixun_challenges, :dependent => :destroy | |||||
| # 回复 | |||||
| has_many :discusses, :dependent => :destroy | |||||
| # acts_as_attachable | |||||
| scope :base_attrs, -> { select([:id, :subject, :position, :shixun_id, :st, :score, :path, :task_pass, :modify_time, | |||||
| :web_route, :answer, :exec_time, :praises_count]) } | |||||
| scope :choose_type, -> { where(st: 1) } | |||||
| scope :practice_type, -> { where(st: 0) } | |||||
| scope :fields_for_list, -> { select([:id, :subject, :st, :score, :position, :shixun_id]) } | |||||
| validates :task_pass, length: { maximum: 35000, too_long: "不能超过35000个字符" } | |||||
| after_commit :create_diff_record | |||||
| def next_challenge | |||||
| position = self.position + 1 | |||||
| Challenge.where(:position => position, :shixun_id => self.shixun).first | |||||
| end | |||||
| # 用户关卡是否通关 | |||||
| def has_passed?(user_id) | |||||
| self.games.present? && self.games.select{|game| game.user_id == user_id && game.status == 2}.length > 0 | |||||
| end | |||||
| ## 选择题总分 | |||||
| def choose_score | |||||
| self.score | |||||
| #self.challenge_chooses.pluck(:score).sum | |||||
| end | |||||
| def challenge_difficulty | |||||
| case difficulty | |||||
| when 1 then "简单" | |||||
| when 2 then "中等" | |||||
| when 3 then "困难" | |||||
| else '' | |||||
| end | |||||
| end | |||||
| # 关卡总分 | |||||
| def all_score | |||||
| self.score | |||||
| # if self.st == 1 | |||||
| # self.choose_score | |||||
| # else | |||||
| # self.score | |||||
| # end | |||||
| end | |||||
| # 开启挑战 | |||||
| def open_game user_id, shixun | |||||
| game = self.games.where(user_id: user_id).first | |||||
| if game.present? | |||||
| shixun.task_pass || game.status != 3 ? "/tasks/#{game.identifier}" : "" | |||||
| else | |||||
| "/api/shixuns/#{shixun.identifier}/shixun_exec" | |||||
| end | |||||
| end | |||||
| # # 开启挑战 | |||||
| # def open_game(user_id, shixun) | |||||
| # | |||||
| # | |||||
| # game = self.games.select([:status, :identifier]).where(user_id: user_id).first | |||||
| # game = self.games.select{|game| game.user_id == user_id} | |||||
| # if game.present? | |||||
| # shixun.task_pass || game.status != 3 ? "/tasks/#{game.identifier}" : "" | |||||
| # else | |||||
| # "/api/shixuns/#{shixun.identifier}/shixun_exec" | |||||
| # end | |||||
| # end | |||||
| ## 用户关卡状态 0: 不能开启实训; 1:直接开启; 2表示已完成 | |||||
| def user_tpi_status user_id | |||||
| # todo: 以前没加索引导致相同关卡,同一用户有多个games | |||||
| # 允许跳关则直接开启 | |||||
| game = games.where(user_id: user_id).take | |||||
| if game.blank? | |||||
| position == 1 ? 1 : 0 | |||||
| else | |||||
| if game.status == 3 | |||||
| shixun.task_pass ? 1 : 0 | |||||
| elsif game.status == 2 | |||||
| 2 | |||||
| else | |||||
| 1 | |||||
| end | |||||
| end | |||||
| end | |||||
| def tags_show | |||||
| if self.challenge_tags.nil? | |||||
| "--" | |||||
| else | |||||
| self.try(:challenge_tags).map(&:name).join(";") | |||||
| end | |||||
| end | |||||
| ## 选择题答案 | |||||
| def choose_answer | |||||
| result = [] | |||||
| self.challenge_chooses.each do |choose| | |||||
| result << {:position => choose.position, :answer => (choose.answer.blank? ? choose.standard_answer : choose.answer)} | |||||
| end | |||||
| end | |||||
| # 关卡用户通关数 | |||||
| def user_passed_count | |||||
| games.where(status: 2).count | |||||
| end | |||||
| # 关卡用户正在挑战的人数 | |||||
| def playing_count | |||||
| games.where(status: [0, 1]).count | |||||
| end | |||||
| def last_challenge | |||||
| Challenge.find_by(position: position - 1, shixun_id: shixun_id) | |||||
| end | |||||
| # 关卡评测文件 | |||||
| private | |||||
| def create_diff_record | |||||
| return unless task_pass_previously_changed? | |||||
| CreateDiffRecordJob.perform_later(User.current.id, id, 'Challenge', 'task_pass', task_pass_before_last_save, task_pass) | |||||
| end | |||||
| end | |||||
| @@ -1,11 +0,0 @@ | |||||
| class ChallengeAnswer < ApplicationRecord | |||||
| default_scope { order("challenge_answers.level asc") } | |||||
| belongs_to :challenge | |||||
| has_many :game_answers, :dependent => :destroy | |||||
| validates :contents, length: { maximum: 25000 , too_long: "不能超过25000个字符"} | |||||
| def view_answer_time(user_id) | |||||
| game_answers.where(user_id: user_id).last&.view_time | |||||
| end | |||||
| end | |||||
| @@ -1,9 +0,0 @@ | |||||
| class ChallengeChoose < ApplicationRecord | |||||
| default_scope {order("challenge_chooses.position asc")} | |||||
| belongs_to :challenge, optional: true | |||||
| has_many :challenge_tags, :dependent => :destroy | |||||
| has_many :challenge_questions, dependent: :destroy | |||||
| validates :subject, length: { maximum: 25000, too_long: "不能超过25000个字符" } | |||||
| end | |||||
| @@ -1,6 +0,0 @@ | |||||
| class ChallengeQuestion < ApplicationRecord | |||||
| belongs_to :challenge_choose | |||||
| validates :option_name, length: { maximum: 500, too_long: "不能超过500个字符" } | |||||
| end | |||||
| @@ -1,4 +0,0 @@ | |||||
| class ChallengeSample < ApplicationRecord | |||||
| belongs_to :challenge | |||||
| end | |||||
| @@ -1,6 +0,0 @@ | |||||
| class ChallengeTag < ApplicationRecord | |||||
| include Searchable::Dependents::ChallengeTag | |||||
| belongs_to :challenge, counter_cache: true | |||||
| belongs_to :challenge_choose, optional: true | |||||
| end | |||||
| @@ -1,15 +0,0 @@ | |||||
| class ChallengeWorkScore < ApplicationRecord | |||||
| belongs_to :user | |||||
| belongs_to :student_work | |||||
| belongs_to :challenge | |||||
| has_many :tidings, as: :container, dependent: :destroy | |||||
| validates :comment, length: { maximum: 500, too_long: "不能超过500个字符" } | |||||
| def create_tiding trigger_user_id | |||||
| tidings << Tiding.new(user_id: student_work.user_id, trigger_user_id: trigger_user_id, container_id: id, | |||||
| container_type: "ChallengeWorkScore", parent_container_id: student_work_id, | |||||
| parent_container_type: "StudentWork", belong_container_id: student_work&.homework_common&.course_id, | |||||
| belong_container_type: "Course", viewed: 0, tiding_type: "HomeworkCommon") | |||||
| end | |||||
| end | |||||
| @@ -1,4 +0,0 @@ | |||||
| class Commit < ApplicationRecord | |||||
| belongs_to :project, foreign_key: :project_id | |||||
| end | |||||
| @@ -1,4 +0,0 @@ | |||||
| class CommitIssue < ApplicationRecord | |||||
| belongs_to :issue, foreign_key: :issue_id | |||||
| end | |||||
| @@ -1,12 +0,0 @@ | |||||
| class Compose < ApplicationRecord | |||||
| #组织 | |||||
| belongs_to :user | |||||
| has_many :compose_projects | |||||
| has_many :compose_users | |||||
| validates :title, presence: {message: "组织名称不能为空"}, uniqueness: {message: "组织名称已存在"} | |||||
| scope :compose_includes, ->{includes(:compose_projects, :compose_users, :user)} | |||||
| end | |||||
| @@ -1,4 +0,0 @@ | |||||
| class ComposeProject < ApplicationRecord | |||||
| #组织的项目记录表 | |||||
| belongs_to :compose | |||||
| end | |||||
| @@ -1,4 +0,0 @@ | |||||
| class ComposeUser < ApplicationRecord | |||||
| belongs_to :compose | |||||
| belongs_to :user | |||||
| end | |||||
| @@ -1,9 +0,0 @@ | |||||
| class Cooperation < ApplicationRecord | |||||
| def user_type_text | |||||
| case user_type.to_i | |||||
| when 1 then '高校合作' | |||||
| when 2 then '企业合作' | |||||
| when 3 then '实训投稿' | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,455 +0,0 @@ | |||||
| class Course < ApplicationRecord | |||||
| include Searchable::Course | |||||
| has_many :boards, dependent: :destroy | |||||
| belongs_to :teacher, class_name: 'User', foreign_key: :tea_id # 定义一个方法teacher,该方法通过tea_id来调用User表 | |||||
| belongs_to :school, class_name: 'School', foreign_key: :school_id #定义一个方法school,该方法通过school_id来调用School表 | |||||
| belongs_to :course_list, optional: true | |||||
| belongs_to :laboratory, optional: true | |||||
| # 所属实践课程 | |||||
| belongs_to :subject, optional: true | |||||
| has_many :informs, as: :container, dependent: :destroy | |||||
| has_many :course_infos, dependent: :destroy | |||||
| # 课堂左侧导航栏的模块 | |||||
| has_many :course_modules, dependent: :destroy | |||||
| has_many :none_hidden_course_modules, -> { not_hidden }, class_name: "CourseModule" | |||||
| has_many :board_course_modules, -> { board_module }, class_name: "CourseModule" | |||||
| has_many :attachment_course_modules, -> { attachment_module }, class_name: "CourseModule" | |||||
| has_many :common_course_modules, -> { common_homework_module }, class_name: "CourseModule" | |||||
| has_many :group_course_modules, -> { group_homework_module }, class_name: "CourseModule" | |||||
| has_many :shixun_course_modules, -> { shixun_homework_module }, class_name: "CourseModule" | |||||
| # 课堂模块的二级目录 | |||||
| has_many :course_second_categories, dependent: :destroy | |||||
| # 课堂分班 | |||||
| has_many :course_groups, dependent: :destroy | |||||
| # 答辩组 | |||||
| has_many :graduation_groups, dependent: :destroy | |||||
| has_many :course_members, dependent: :destroy | |||||
| has_many :students, -> { course_students }, class_name: 'CourseMember' | |||||
| has_many :teacher_course_members, -> { teachers_and_admin }, class_name: 'CourseMember' | |||||
| has_many :teacher_users, through: :teacher_course_members, source: :user | |||||
| has_many :course_messages, dependent: :destroy | |||||
| has_many :homework_commons, dependent: :destroy | |||||
| has_many :normal_homeworks, -> { normals }, class_name: 'HomeworkCommon' | |||||
| has_many :group_homeworks, -> { groups }, class_name: 'HomeworkCommon' | |||||
| has_many :practice_homeworks, -> { practices }, class_name: 'HomeworkCommon' | |||||
| has_many :homework_group_settings | |||||
| has_many :graduation_works, dependent: :destroy | |||||
| # 实训作业的二级目录(已弃用) | |||||
| has_many :course_homework_categories, dependent: :destroy | |||||
| has_many :exercises, dependent: :destroy | |||||
| #课堂的试卷 | |||||
| has_many :exercise_group_settings, :dependent => :destroy | |||||
| # 课堂的问卷 | |||||
| has_many :polls, dependent: :destroy | |||||
| has_many :poll_group_settings, :dependent => :destroy | |||||
| # 毕业设计 | |||||
| has_many :graduation_topics, dependent: :destroy | |||||
| has_many :graduation_tasks, dependent: :destroy | |||||
| has_many :student_graduation_topics, :dependent => :destroy | |||||
| has_many :teacher_course_groups, :dependent => :destroy | |||||
| # 资源 | |||||
| has_many :attachments, as: :container, dependent: :destroy | |||||
| has_many :attachment_group_settings, :dependent => :destroy | |||||
| # 课堂学生,弃用 | |||||
| has_many :student, :class_name => 'StudentsForCourse', :source => :user | |||||
| # 课堂动态 | |||||
| has_one :course_act, class_name: 'CourseActivity', as: :course_act, dependent: :destroy | |||||
| has_many :course_activities | |||||
| has_many :tidings, as: :container, dependent: :destroy | |||||
| # 开放课堂 | |||||
| has_many :course_stages, -> { order("course_stages.position ASC") }, dependent: :destroy | |||||
| has_many :course_stage_shixuns, dependent: :destroy | |||||
| has_many :shixuns, through: :course_stage_shixuns | |||||
| # 老版的members弃用 现用course_members | |||||
| has_many :members | |||||
| # 视频 | |||||
| has_many :course_videos, dependent: :destroy | |||||
| has_many :videos, through: :course_videos | |||||
| # 直播 | |||||
| has_many :live_links, dependent: :destroy | |||||
| validate :validate_sensitive_string | |||||
| scope :hidden, ->(is_hidden = true) { where(is_hidden: is_hidden) } | |||||
| scope :ended, ->(is_end = true) { where(is_end: is_end) } | |||||
| scope :processing, -> { where(is_end: false) } | |||||
| scope :not_deleted, -> { where(is_delete: 0) } | |||||
| scope :not_excellent, -> { where(excellent: 0) } | |||||
| scope :deleted, ->(is_delete = 1) { where(is_delete: is_delete) } | |||||
| scope :by_user, ->(user) { joins(:course_members).where('course_members.user_id = ?', user.id).order(updated_at: :desc) } | |||||
| scope :by_keywords, lambda { |keywords| | |||||
| where("name LIKE ?", "%#{keywords.split(" ").join('|')}%") unless keywords.blank? | |||||
| } | |||||
| scope :started, -> { where("start_date is null or start_date <= '#{Date.today}'") } | |||||
| # acts_as_taggable | |||||
| # 课程权限判断 | |||||
| ADMIN = 0 # 超级管理员 | |||||
| BUSINESS = 1 # 运营人员 | |||||
| CREATOR = 2 # 课程创建者 | |||||
| PROFESSOR = 3 # 课程老师 | |||||
| ASSISTANT_PROFESSOR = 4 # 课程助教 | |||||
| STUDENT = 5 # 学生 | |||||
| NORMAL = 6 # 普通用户 | |||||
| Anonymous = 7 # 普未登录 | |||||
| validates :name, presence: true, length: { maximum: 60, too_long: "不能超过60个字符" } | |||||
| before_save :set_laboratory | |||||
| after_create :create_board_sync, :act_as_course_activity, :send_tiding | |||||
| def course_member? user_id, role | |||||
| course_members.where(user_id: user_id, role: role).exists? | |||||
| end | |||||
| def course_group_module? | |||||
| course_modules.exists?(module_type: "course_group", hidden: 0) | |||||
| end | |||||
| # 作业对应的子目录/父目录名称 | |||||
| def category_info type | |||||
| course_module = course_modules.find_by(module_type: type) | |||||
| { category_id: course_module&.id, category_name: course_module&.module_name } | |||||
| end | |||||
| # 未分班的学生数 | |||||
| def none_group_count | |||||
| course_members.where(role: 4, course_group_id: 0).size | |||||
| end | |||||
| def course_member(user_id) | |||||
| course_members.find_by(user_id: user_id, is_active: 1) | |||||
| end | |||||
| def course_student(user_id) | |||||
| course_members.find_by(user_id: user_id, role: %i(STUDENT)) | |||||
| end | |||||
| def user_group_name(user_id) | |||||
| students.find_by(user_id: user_id)&.course_group_name | |||||
| end | |||||
| def teacher_group(user_id) | |||||
| data = | |||||
| if teacher_course_groups.exists?(user_id: user_id) | |||||
| teacher_course_groups.joins(:course_group).where(user_id: user_id) | |||||
| .pluck('course_groups.id', 'course_groups.name') | |||||
| else | |||||
| course_groups.pluck(:id, :name) | |||||
| end | |||||
| data.map { |arr| { group_id: arr.first, group_name: arr.last } } | |||||
| end | |||||
| #当前老师的班级id | |||||
| def teacher_course_ids(user_id) | |||||
| course_teacher_member = teacher_course_groups.get_user_groups(user_id).select(:course_group_id) #获取当前老师的分班 | |||||
| if course_teacher_member.blank? | |||||
| if none_group_count > 0 #有未分班的,则发布到未发布分班 | |||||
| un_group_ids = [0] | |||||
| else | |||||
| un_group_ids = [] | |||||
| end | |||||
| course_groups.pluck(:id) + un_group_ids #所有分班和未分班 | |||||
| else | |||||
| course_teacher_member.pluck(:course_group_id).reject(&:blank?).uniq #当前用户所在的班级,老师可能有多个班级 | |||||
| end | |||||
| end | |||||
| # 查询老师分班的所有学生 | |||||
| def teacher_group_user_ids user_id | |||||
| teachers = teacher_course_groups.where(user_id: user_id) | |||||
| if teachers.exists? | |||||
| students.where(course_group_id: teachers.pluck(:course_group_id)).pluck(:user_id) | |||||
| else | |||||
| students.pluck(:user_id) | |||||
| end | |||||
| end | |||||
| # 创建课程模块 | |||||
| def create_course_modules(course_module_types) | |||||
| course_modules.destroy_all if course_modules.present? | |||||
| all_course_module_types.each do |type| | |||||
| name = get_name_by_type(type) | |||||
| position = get_position_by_type(type) | |||||
| hidden = course_module_types.include?(type) ? 0 : 1 | |||||
| CourseModule.create(course_id: id, module_type: type, position: position, hidden: hidden, module_name: name) | |||||
| end | |||||
| end | |||||
| # 更新课程模块 | |||||
| def update_course_modules(course_module_types) | |||||
| all_course_module_types.each do |type| | |||||
| hidden_value = course_module_types.include?(type) ? 0 : 1 | |||||
| course_module = course_modules.where(module_type: type).first | |||||
| course_module.update_attribute(:hidden, hidden_value) if course_module.present? | |||||
| end | |||||
| end | |||||
| def all_course_module_types | |||||
| %w[activity announcement online_learning shixun_homework common_homework group_homework exercise attachment course_group graduation poll board statistics video] | |||||
| end | |||||
| def get_course_module_by_type(type) | |||||
| #CourseModule.where(course_id: course_id, module_type: type).first | |||||
| self.course_modules.where(module_type: type).first | |||||
| end | |||||
| # 创建课程讨论区 | |||||
| def create_board_sync | |||||
| boards.create(name: '讨论区', description: name, project_id: -1) | |||||
| end | |||||
| def delete! | |||||
| update_attribute(:is_delete, true) | |||||
| end | |||||
| def attachment_count | |||||
| Attachment.where(container: self).count | |||||
| end | |||||
| # 课堂某角色的成员数量:[1, 2, 3] 是教师身份、4 学生身份 | |||||
| def course_member_count(roles) | |||||
| course_members.where(role: roles).size | |||||
| end | |||||
| # 课堂老师 | |||||
| def teachers | |||||
| course_members.where(role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR]) | |||||
| end | |||||
| def teachers_without_assistant_professor | |||||
| course_members.where(role: %i[CREATOR PROFESSOR]) | |||||
| end | |||||
| # 更新课程的访问人数 | |||||
| def update_visits(new_visits) | |||||
| update_attributes(visits: new_visits) | |||||
| end | |||||
| # 老师负责的分班id | |||||
| def charge_group_ids user | |||||
| member = course_member(user.id) | |||||
| group_ids = if member.present? | |||||
| member.teacher_course_groups.size > 0 ? member.teacher_course_groups.pluck(:course_group_id) : course_groups.pluck(:id) | |||||
| elsif user.admin_or_business? | |||||
| course_groups.pluck(:id) | |||||
| else | |||||
| [] | |||||
| end | |||||
| end | |||||
| # 生成邀请码 | |||||
| CODES = %W(2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z) | |||||
| def generate_invite_code | |||||
| return invite_code if invite_code.present? && invite_code.size >= 5 | |||||
| code = CODES.sample(5).join | |||||
| while Course.exists?(invite_code: code) do | |||||
| code = CODES.sample(5).join | |||||
| end | |||||
| update_attribute(:invite_code, code) | |||||
| code | |||||
| end | |||||
| # 课堂主讨论区 | |||||
| def course_board | |||||
| board = boards.find_by(parent_id: 0) | |||||
| return board if board.present? | |||||
| create_board_sync | |||||
| Board.find_by(parent_id: 0, course_id: id) | |||||
| end | |||||
| # 是否是课堂的成员(未实现,暂时返回true) | |||||
| def member?(user) | |||||
| true | |||||
| end | |||||
| # 是否具有分班权限,返回分班的id | |||||
| def group_course_power(user_id) | |||||
| teacher_course_groups.where(user_id: user_id).pluck(:course_group_id) | |||||
| end | |||||
| #课程动态公共表记录 | |||||
| def act_as_course_activity | |||||
| self.course_act << CourseActivity.new(user_id: tea_id, course_id: id) | |||||
| end | |||||
| # 当前老师分班下的所有学生 | |||||
| def user_group_students(user_id) | |||||
| group_ids = teacher_course_groups.where(user_id: user_id).pluck(:course_group_id) | |||||
| course_members.where(course_group_id: group_ids) | |||||
| end | |||||
| def self_duplicate | |||||
| DuplicateCourseService.call(self, User.current) | |||||
| end | |||||
| def update_quotes attachment | |||||
| if attachment.copy_from | |||||
| attachments = Attachment.find_by_sql("select * from attachments where copy_from = #{attachment.copy_from} or id = #{attachment.copy_from}") | |||||
| else | |||||
| attachments = Attachment.find_by_sql("select * from attachments where copy_from = #{attachment.id} or id = #{attachment.copy_from}") | |||||
| end | |||||
| attachment.quotes = get_qute_number attachment | |||||
| attachment.save | |||||
| attachments.each do |att| | |||||
| att.quotes = attachment.quotes | |||||
| att.save | |||||
| end | |||||
| end | |||||
| def get_qute_number attachment | |||||
| if attachment.copy_from | |||||
| result = Attachment.find_by_sql("select count(*) as number from attachments where copy_from = #{attachment.copy_from}") | |||||
| else | |||||
| result = Attachment.find_by_sql("select count(*) as number from attachments where copy_from = #{attachment.id}") | |||||
| end | |||||
| if result.nil? || result.count <= 0 | |||||
| 0 | |||||
| else | |||||
| result[0].number | |||||
| end | |||||
| end | |||||
| #获取试卷/问卷已发布的班级id,名称和人数。当为统一设置时,显示全部,否则只显示当前已发布的班级信息 | |||||
| def get_ex_published_course(common_ids) | |||||
| teacher_power_courses = [] | |||||
| publish_groups = course_groups.where(id: common_ids) | |||||
| if common_ids.include?(0) | |||||
| teacher_power_courses << {course_name:"未分班", course_id: 0, student_count: none_group_count} | |||||
| end | |||||
| if publish_groups.present? | |||||
| publish_groups.each do |group| | |||||
| teacher_power_courses << {course_name: group&.name,course_id: group&.id, student_count: group&.course_members_count} | |||||
| end | |||||
| end | |||||
| teacher_power_courses | |||||
| end | |||||
| def create_stages subject | |||||
| if subject | |||||
| subject.stages.each do |stage| | |||||
| new_stage = CourseStage.create!(course_id: id, name: stage.name, description: stage.description, position: stage.position) | |||||
| stage.stage_shixuns.each do |stage_shixun| | |||||
| CourseStageShixun.create!(course_id: id, course_stage_id: new_stage.id, shixun_id: stage_shixun.shixun_id, position: stage_shixun.position) | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| def learning? user_id | |||||
| Myshixun.where(user_id: user_id, shixun_id: shixuns).exists? | |||||
| end | |||||
| def my_subject_progress myshixuns | |||||
| my_challenge_count = Game.where(myshixun_id: myshixuns.pluck(:id), status: 2).pluck(:challenge_id).uniq.size | |||||
| course_challeng_count = shixuns.pluck(:challenges_count).sum | |||||
| count = course_challeng_count == 0 ? 0 : ((my_challenge_count.to_f / course_challeng_count).round(2) * 100).to_i | |||||
| end | |||||
| # 课堂实训作业的评测次数 | |||||
| def evaluate_count | |||||
| course_user_ids = students.pluck(:user_id) | |||||
| shixun_ids = homework_commons.joins(:homework_commons_shixun).where(homework_type: 4).pluck(:shixun_id) | |||||
| return 0 if shixun_ids.blank? | |||||
| Game.joins(:challenge).where(challenges: {shixun_id: shixun_ids}, games: {user_id: course_user_ids}).sum(:evaluate_count) | |||||
| end | |||||
| def max_activity_time | |||||
| course_acts.pluck(:updated_at).max | |||||
| end | |||||
| # 课堂作业数 | |||||
| def course_homework_count type | |||||
| homework_commons.select{|homework| homework.homework_type == type}.size | |||||
| end | |||||
| private | |||||
| #创建课程后,给该用户发送消息 | |||||
| def send_tiding | |||||
| self.tidings << Tiding.new(user_id: tea_id, trigger_user_id: 0, belong_container_id: id, | |||||
| belong_container_type: 'Course', tiding_type: 'System') | |||||
| end | |||||
| def get_name_by_type(type) | |||||
| case type | |||||
| when 'activity' then '动态' | |||||
| when 'announcement' then '公告栏' | |||||
| when 'online_learning' then '课程学习' | |||||
| when 'shixun_homework' then '实训作业' | |||||
| when 'common_homework' then '普通作业' | |||||
| when 'group_homework' then '分组作业' | |||||
| when 'graduation' then '毕业设计' | |||||
| when 'exercise' then '试卷' | |||||
| when 'poll' then '问卷' | |||||
| when 'attachment' then '资源' | |||||
| when 'video' then '视频直播' | |||||
| when 'board' then '讨论' | |||||
| when 'course_group' then '分班' | |||||
| when 'statistics' then '统计' | |||||
| else '' | |||||
| end | |||||
| end | |||||
| def get_position_by_type(type) | |||||
| case type | |||||
| when 'activity' then 1 | |||||
| when 'announcement' then 2 | |||||
| when 'online_learning' then 3 | |||||
| when 'shixun_homework' then 4 | |||||
| when 'common_homework' then 5 | |||||
| when 'group_homework' then 6 | |||||
| when 'graduation' then 7 | |||||
| when 'exercise' then 8 | |||||
| when 'poll' then 9 | |||||
| when 'attachment' then 10 | |||||
| when 'video' then 11 | |||||
| when 'board' then 12 | |||||
| when 'course_group' then 13 | |||||
| when 'statistics' then 14 | |||||
| else 100 | |||||
| end | |||||
| end | |||||
| def set_laboratory | |||||
| return unless new_record? # 新记录才需要标记 | |||||
| self.laboratory = Laboratory.current if laboratory_id.blank? | |||||
| end | |||||
| def validate_sensitive_string | |||||
| raise("课堂名称包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(name) | |||||
| end | |||||
| end | |||||
| @@ -1,54 +0,0 @@ | |||||
| class CourseActivity < ApplicationRecord | |||||
| belongs_to :course_act, polymorphic: true | |||||
| belongs_to :course | |||||
| belongs_to :user | |||||
| belongs_to :exercise | |||||
| belongs_to :poll | |||||
| belongs_to :course_message | |||||
| belongs_to :homework_common | |||||
| # after_create :add_course_lead | |||||
| def container_name | |||||
| case course_act_type | |||||
| when "HomeworkCommon" | |||||
| course_act&.name | |||||
| when "Exercise" | |||||
| course_act&.exercise_name | |||||
| when "Poll" | |||||
| course_act&.poll_name | |||||
| when "Message" | |||||
| course_act&.subject | |||||
| else | |||||
| "" | |||||
| end | |||||
| end | |||||
| # 发布新课导语 | |||||
| # 导语要放置在课程创建信息之后 | |||||
| def add_course_lead | |||||
| # 避免空数据迁移报错问题 | |||||
| if self.course_act_type == "Course" | |||||
| sample = PlatformSample.where(:samples_type => "courseGuide").first | |||||
| if sample.present? && sample.contents.present? | |||||
| content = sample.contents | |||||
| elsif Message.find(12440) | |||||
| lead_message = Message.find(12440) | |||||
| content = lead_message.content | |||||
| end | |||||
| if content | |||||
| # message的status状态为0为正常,为1表示创建课程时发送的message | |||||
| # author_id 默认为课程使者创建 | |||||
| message = Message.create(subject: "新课导语", | |||||
| board_id: course.course_board.try(:id), | |||||
| author_id: 1, | |||||
| sticky: true, | |||||
| status: true, | |||||
| message_detail_attributes: {content: content} | |||||
| ) | |||||
| # 更新的目的是为了排序,因为该条动态的时间可能与课程创建的动态创建时间一致 | |||||
| message.course_acts.first.update_attribute(:updated_at, message.course_acts.first.updated_at + 1) if message.course_acts.first | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,34 +0,0 @@ | |||||
| class CourseGroup < ApplicationRecord | |||||
| default_scope { order("course_groups.position ASC") } | |||||
| belongs_to :course, counter_cache: true | |||||
| has_many :course_members | |||||
| has_many :exercise_group_settings,:dependent => :destroy | |||||
| has_many :attachment_group_settings, :dependent => :destroy | |||||
| has_many :homework_group_reviews, :dependent => :destroy | |||||
| has_many :teacher_course_groups, :dependent => :destroy | |||||
| has_many :homework_group_settings, :dependent => :destroy | |||||
| scope :by_group_ids, lambda { |ids| where(id: ids)} | |||||
| validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } | |||||
| validates_uniqueness_of :name, scope: :course_id, message: "不能创建相同名称的分班" | |||||
| after_create :generate_invite_code | |||||
| # 延迟生成邀请码 | |||||
| def invite_code | |||||
| return generate_invite_code | |||||
| end | |||||
| # 生成邀请码 | |||||
| CODES = %W(2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z) | |||||
| def generate_invite_code | |||||
| code = read_attribute(:invite_code) | |||||
| if !code || code.size < 6 | |||||
| code = CODES.sample(6).join | |||||
| return generate_invite_code if CourseGroup.where(invite_code: code).present? | |||||
| update_attribute(:invite_code, code) | |||||
| end | |||||
| code | |||||
| end | |||||
| end | |||||
| @@ -1,3 +0,0 @@ | |||||
| class CourseHomeworkCategory < ApplicationRecord | |||||
| belongs_to :course | |||||
| end | |||||
| @@ -1,3 +0,0 @@ | |||||
| class CourseInfo < ApplicationRecord | |||||
| belongs_to :course | |||||
| end | |||||
| @@ -1,15 +0,0 @@ | |||||
| class CourseList < ApplicationRecord | |||||
| has_many :courses | |||||
| has_many :question_banks | |||||
| has_many :homework_banks | |||||
| has_many :exercise_banks | |||||
| has_many :gtask_banks | |||||
| has_many :gtopic_banks | |||||
| belongs_to :user | |||||
| validate :validate_sensitive_string | |||||
| def validate_sensitive_string | |||||
| raise("课程名称包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(name) | |||||
| end | |||||
| end | |||||
| @@ -1,159 +0,0 @@ | |||||
| class CourseMember < ApplicationRecord | |||||
| # role 1:创建者 2:老师 3:助教 4:学生 | |||||
| enum role: { CREATOR: 1, PROFESSOR: 2, ASSISTANT_PROFESSOR: 3, STUDENT: 4 } | |||||
| # is_active: true:当前活跃身份(多重身份的用户) | |||||
| belongs_to :course, counter_cache: true | |||||
| belongs_to :user | |||||
| belongs_to :course_group, counter_cache: true, optional: true | |||||
| belongs_to :graduation_group, optional: true | |||||
| has_many :teacher_course_groups, dependent: :destroy | |||||
| scope :teachers_and_admin, -> { where(role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR]) } | |||||
| scope :students, ->(course) { where(course_id: course.id, role: %i[STUDENT])} | |||||
| scope :course_find_by_ids, lambda { |k,ids| where("#{k}": ids)} | |||||
| scope :course_students, -> {where(role: %i[STUDENT])} | |||||
| #用户的身份查询 | |||||
| scope :course_user_role, lambda { |k| where(role: k)} | |||||
| # 未分班 | |||||
| scope :ungroup_students, -> { where(course_group_id: 0, role: 4) } | |||||
| # after_destroy :delete_works | |||||
| # after_create :work_operation | |||||
| def delete_works | |||||
| if self.role == "STUDENT" | |||||
| course = self.course | |||||
| student_works = StudentWork.joins(:homework_common).where(user_id: self.user_id, homework_commons: {course_id: course.id}) | |||||
| student_works.update_all(is_delete: 1) | |||||
| exercise_users = ExerciseUser.joins(:exercise).where(user_id: self.user_id, exercises: {course_id: course.id}) | |||||
| exercise_users.update_all(is_delete: 1) | |||||
| poll_users = PollUser.joins(:poll).where(user_id: self.user_id, polls: {course_id: course.id}) | |||||
| poll_users.update_all(is_delete: 1) | |||||
| course.graduation_works.where(user_id: self.user_id).update_all(is_delete: 1) | |||||
| end | |||||
| end | |||||
| def work_operation | |||||
| if self.role == "STUDENT" | |||||
| recover_works | |||||
| create_exercise_users | |||||
| create_graduation_works | |||||
| create_poll_users | |||||
| create_student_works | |||||
| end | |||||
| end | |||||
| # 加入班级时还原作品(如果有已删除作品的话) | |||||
| def recover_works | |||||
| course = self.course | |||||
| student_works = StudentWork.joins(:homework_common).where(user_id: self.user_id, homework_commons: {course_id: course.id}) | |||||
| student_works.update_all(is_delete: 0) | |||||
| exercise_users = ExerciseUser.joins(:exercise).where(user_id: self.user_id, exercises: {course_id: course.id}) | |||||
| exercise_users.update_all(is_delete: 0) | |||||
| poll_users = PollUser.joins(:poll).where(user_id: self.user_id, polls: {course_id: course.id}) | |||||
| poll_users.update_all(is_delete: 0) | |||||
| graduation_works = course.graduation_works.where(user_id: self.user_id) | |||||
| graduation_works.update_all(is_delete: 0) | |||||
| end | |||||
| # 加入班级时创建作业的作品(如果没有作品才创建) | |||||
| def create_student_works | |||||
| course = self.course | |||||
| homework_commons = course.homework_commons.where(homework_type: %i[normal group practice]) | |||||
| str = "" | |||||
| homework_commons.each do |homework| | |||||
| next if homework.student_works.where(user_id: self.user_id).any? | |||||
| str += "," if str != "" | |||||
| str += "(#{homework.id}, #{user_id}, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" | |||||
| end | |||||
| if str != "" | |||||
| sql = "insert into student_works (homework_common_id, user_id, created_at, updated_at) values" + str | |||||
| ActiveRecord::Base.connection.execute sql | |||||
| end | |||||
| end | |||||
| # 加入班级时创建已发布试卷的作品(如果没有作品才创建) | |||||
| def create_exercise_users | |||||
| course = self.course | |||||
| exercises = course.exercises | |||||
| str = "" | |||||
| exercises.each do |exercise| | |||||
| next if exercise.exercise_users.where(user_id: self.user_id).any? | |||||
| str += "," if str != "" | |||||
| str += "(#{user_id}, #{exercise.id}, 0, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" | |||||
| end | |||||
| if str != "" | |||||
| sql = "insert into exercise_users (user_id, exercise_id, commit_status, created_at, updated_at) values" + str | |||||
| ActiveRecord::Base.connection.execute sql | |||||
| end | |||||
| end | |||||
| # 加入班级时创建已发布问卷的作品(如果没有作品才创建) | |||||
| def create_poll_users | |||||
| course = self.course | |||||
| polls = course.polls | |||||
| str = "" | |||||
| polls.each do |poll| | |||||
| next if poll.poll_users.where(user_id: self.user_id).any? | |||||
| str += "," if str != "" | |||||
| str += "(#{user_id}, #{poll.id}, 0, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" | |||||
| end | |||||
| if str != "" | |||||
| sql = "insert into poll_users (user_id, poll_id, commit_status, created_at, updated_at) values" + str | |||||
| ActiveRecord::Base.connection.execute sql | |||||
| end | |||||
| end | |||||
| # 创建毕设任务作品(如果没有作品才创建) | |||||
| def create_graduation_works | |||||
| course = self.course | |||||
| tasks = course.graduation_tasks | |||||
| str = "" | |||||
| tasks.each do |task| | |||||
| next if task.graduation_works.where(user_id: self.user_id).any? | |||||
| str += "," if str != "" | |||||
| str += "(#{task.id}, #{user_id}, #{course_id}, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" | |||||
| end | |||||
| if str != "" | |||||
| sql = "insert into graduation_works (graduation_task_id, user_id, course_id, created_at, updated_at) values" + str | |||||
| ActiveRecord::Base.connection.execute sql | |||||
| end | |||||
| end | |||||
| # 分班名称 | |||||
| def course_group_name | |||||
| self.course_group_id == 0 ? "未分班" : course_group.try(:name) | |||||
| end | |||||
| # 学生的分班老师 | |||||
| def member_teachers | |||||
| teacher_groups = course.teacher_course_groups | |||||
| if teacher_groups.count > 0 | |||||
| member_ids = teacher_groups.where(course_group_id: self.try(:course_group_id)).pluck(:course_member_id).compact | |||||
| none_group_teachers = teacher_groups.pluck(:course_member_id).compact.size > 0 ? teacher_groups.pluck(:course_member_id).compact.join(',') : -1 | |||||
| teachers = course.teachers.where("course_members.id not in (#{none_group_teachers}) or | |||||
| course_members.id in (#{member_ids.size > 0 ? member_ids.join(',') : -1})") | |||||
| else | |||||
| teachers = course.teachers | |||||
| end | |||||
| teachers | |||||
| end | |||||
| end | |||||
| @@ -1,28 +0,0 @@ | |||||
| class CourseModule < ApplicationRecord | |||||
| default_scope { order("course_modules.position ASC") } | |||||
| belongs_to :course | |||||
| # 二级目录 | |||||
| has_many :course_second_categories | |||||
| validates :module_name, length: { maximum: 20, too_long: "不能超过20个字符" } | |||||
| scope :not_hidden, -> { where(hidden: 0) } | |||||
| scope :graduation_module, -> { where(module_type: "graduation") } | |||||
| scope :graduation_module_not_hidden, -> { graduation_module.where(hidden: 0) } | |||||
| scope :board_module, -> { where(module_type: 'board') } | |||||
| scope :attachment_module, -> { includes(:course_second_categories).where(module_type: 'attachment') } | |||||
| scope :common_homework_module, -> { where(module_type: 'common_homework') } | |||||
| scope :group_homework_module, -> { where(module_type: 'group_homework') } | |||||
| scope :shixun_homework_module, -> { where(module_type: 'shixun_homework') } | |||||
| scope :search_by_module_type, -> (type) {where(module_type:type)} | |||||
| # 课堂模块的子目录 | |||||
| def course_second_categories | |||||
| if module_type == "graduation" && CourseSecondCategory.where(course_module_id: self.id).count == 0 | |||||
| CourseSecondCategory.create!(course_module_id: self.id, course_id: self.course_id, name: "毕设选题", category_type: "graduation", position: 1) | |||||
| CourseSecondCategory.create!(course_module_id: self.id, course_id: self.course_id, name: "毕设任务", category_type: "graduation", position: 2) | |||||
| end | |||||
| CourseSecondCategory.where(course_module_id: self.id) | |||||
| end | |||||
| end | |||||
| @@ -1,15 +0,0 @@ | |||||
| class CourseSecondCategory < ApplicationRecord | |||||
| default_scope { order("course_second_categories.position ASC") } | |||||
| belongs_to :course | |||||
| belongs_to :course_module | |||||
| has_many :homework_commons | |||||
| validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } | |||||
| def category_type_str | |||||
| category_type == "graduation" && name == "毕设选题" ? "graduation_topics" : ( | |||||
| category_type == "graduation" && name == "毕设任务" ? "graduation_tasks" : category_type | |||||
| ) | |||||
| end | |||||
| end | |||||
| @@ -1,9 +0,0 @@ | |||||
| class CourseStage < ApplicationRecord | |||||
| belongs_to :course | |||||
| has_many :course_stage_shixuns, -> { order("course_stage_shixuns.position ASC") }, dependent: :destroy | |||||
| has_many :shixuns, :through => :course_stage_shixuns | |||||
| validates :name, length: { maximum: 60 , too_long: "不能超过60个字符"} | |||||
| validates :description, length: { maximum: 1000, too_long: "不能超过1000个字符" } | |||||
| end | |||||
| @@ -1,5 +0,0 @@ | |||||
| class CourseStageShixun < ApplicationRecord | |||||
| belongs_to :course | |||||
| belongs_to :course_stage, counter_cache: :shixuns_count | |||||
| belongs_to :shixun | |||||
| end | |||||
| @@ -1,4 +0,0 @@ | |||||
| class CourseVideo < ApplicationRecord | |||||
| belongs_to :course | |||||
| belongs_to :video | |||||
| end | |||||
| @@ -1,11 +0,0 @@ | |||||
| class Customer < ApplicationRecord | |||||
| default_scope { order(created_at: :desc) } | |||||
| belongs_to :school | |||||
| belongs_to :partner_manager_group, optional: true | |||||
| has_many :partner_customers, dependent: :destroy | |||||
| has_many :partners, through: :partner_customers | |||||
| has_many :users | |||||
| end | |||||
| @@ -1,19 +0,0 @@ | |||||
| class Department < ApplicationRecord | |||||
| belongs_to :school | |||||
| has_many :department_members, dependent: :destroy | |||||
| has_many :member_users, through: :department_members, source: :user | |||||
| has_many :user_extensions, dependent: :nullify | |||||
| has_many :apply_add_departments, dependent: :destroy | |||||
| scope :without_deleted, -> { where(is_delete: false) } | |||||
| def member?(user) | |||||
| department_members.exists?(user_id: user.id) | |||||
| end | |||||
| def soft_delete! | |||||
| update!(is_delete: true) | |||||
| end | |||||
| end | |||||
| @@ -1,4 +0,0 @@ | |||||
| class DepartmentMember < ApplicationRecord | |||||
| belongs_to :user | |||||
| belongs_to :department | |||||
| end | |||||
| @@ -1,12 +0,0 @@ | |||||
| class Discipline < ApplicationRecord | |||||
| default_scope { order(position: :asc) } | |||||
| has_many :sub_disciplines, -> { order("sub_disciplines.position ASC") }, dependent: :destroy | |||||
| has_many :shixun_sub_disciplines, -> { where("shixun = 1") }, class_name: "SubDiscipline" | |||||
| has_many :subject_sub_disciplines, -> { where("subject = 1") }, class_name: "SubDiscipline" | |||||
| has_many :question_sub_disciplines, -> { where("question = 1") }, class_name: "SubDiscipline" | |||||
| validates_presence_of :name | |||||
| end | |||||
| @@ -1,3 +0,0 @@ | |||||
| class Experience < ApplicationRecord | |||||
| belongs_to :user | |||||
| end | |||||
| @@ -1,3 +0,0 @@ | |||||
| class Forum < ApplicationRecord | |||||
| has_many :memos, dependent: :destroy | |||||
| end | |||||
| @@ -11,7 +11,7 @@ class Issue < ApplicationRecord | |||||
| belongs_to :issue_status, foreign_key: :status_id,optional: true | belongs_to :issue_status, foreign_key: :status_id,optional: true | ||||
| has_many :commit_issues | has_many :commit_issues | ||||
| has_many :attachments, as: :container, dependent: :destroy | has_many :attachments, as: :container, dependent: :destroy | ||||
| has_many :memos | |||||
| # has_many :memos | |||||
| has_many :journals, :as => :journalized, :dependent => :destroy | has_many :journals, :as => :journalized, :dependent => :destroy | ||||
| has_many :journal_details, through: :journals | has_many :journal_details, through: :journals | ||||
| has_many :issue_tags_relates, dependent: :destroy | has_many :issue_tags_relates, dependent: :destroy | ||||
| @@ -1,4 +0,0 @@ | |||||
| class ItemAnalysis < ApplicationRecord | |||||
| belongs_to :item_bank, touch: true | |||||
| validates :analysis, length: { maximum: 5000, too_long: "不能超过5000个字符" } | |||||
| end | |||||
| @@ -1,45 +0,0 @@ | |||||
| class ItemBank < ApplicationRecord | |||||
| # difficulty: 1 简单 2 适中 3 困难 | |||||
| enum item_type: { SINGLE: 0, MULTIPLE: 1, JUDGMENT: 2, COMPLETION: 3, SUBJECTIVE: 4, PRACTICAL: 5, PROGRAM: 6 } | |||||
| # item_type: 0 单选 1 多选 2 判断 3 填空 4 简答 5 实训 6 编程 | |||||
| belongs_to :user | |||||
| belongs_to :sub_discipline, optional: true | |||||
| has_one :item_analysis, dependent: :destroy | |||||
| has_many :item_choices, dependent: :destroy | |||||
| has_many :item_baskets, dependent: :destroy | |||||
| has_many :tag_discipline_containers, as: :container, dependent: :destroy | |||||
| has_many :tag_disciplines, through: :tag_discipline_containers | |||||
| belongs_to :container, polymorphic: true, optional: true | |||||
| validates :name, presence: true, length: { maximum: 1000, too_long: "不能超过1000个字符" } | |||||
| def analysis | |||||
| item_analysis&.analysis | |||||
| end | |||||
| def apply? | |||||
| !public && ApplyAction.exists?(container_type: "ItemBank", container_id: id, status: 0) | |||||
| end | |||||
| def type_string | |||||
| case item_type | |||||
| when "SINGLE" then "单选题" | |||||
| when "MULTIPLE" then "多选题" | |||||
| when "JUDGMENT" then "判断题" | |||||
| when "COMPLETION" then "填空题" | |||||
| when "SUBJECTIVE" then "简答题" | |||||
| when "PRACTICAL" then "实训题" | |||||
| when "PROGRAM" then "编程题" | |||||
| end | |||||
| end | |||||
| def difficulty_string | |||||
| case difficulty | |||||
| when 1 then "简单" | |||||
| when 2 then "适中" | |||||
| when 3 then "困难" | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,7 +0,0 @@ | |||||
| class ItemBasket < ApplicationRecord | |||||
| enum item_type: { SINGLE: 0, MULTIPLE: 1, JUDGMENT: 2, COMPLETION: 3, SUBJECTIVE: 4, PRACTICAL: 5, PROGRAM: 6 } | |||||
| belongs_to :item_bank | |||||
| belongs_to :user, optional: true | |||||
| belongs_to :examination_intelligent_setting, optional: true | |||||
| end | |||||
| @@ -1,5 +0,0 @@ | |||||
| class ItemChoice < ApplicationRecord | |||||
| belongs_to :item_bank, touch: true | |||||
| validates :choice_text, presence: true, length: { maximum: 500, too_long: "不能超过500个字符" } | |||||
| end | |||||
| @@ -1,5 +1,5 @@ | |||||
| class LiveLink < ApplicationRecord | class LiveLink < ApplicationRecord | ||||
| belongs_to :course | |||||
| # belongs_to :course | |||||
| belongs_to :user | belongs_to :user | ||||
| has_many :tidings, as: :container, dependent: :destroy | has_many :tidings, as: :container, dependent: :destroy | ||||
| @@ -1,6 +1,6 @@ | |||||
| class Member < ApplicationRecord | class Member < ApplicationRecord | ||||
| belongs_to :user | belongs_to :user | ||||
| belongs_to :course, optional: true | |||||
| # belongs_to :course, optional: true | |||||
| belongs_to :project, optional: true | belongs_to :project, optional: true | ||||
| has_many :member_roles, dependent: :destroy | has_many :member_roles, dependent: :destroy | ||||
| @@ -1,72 +0,0 @@ | |||||
| class Memo < ApplicationRecord | |||||
| include Searchable::Memo | |||||
| belongs_to :forum, touch: true | |||||
| has_many :memo_tag_repertoires, dependent: :destroy | |||||
| has_many :tag_repertoires, :through => :memo_tag_repertoires | |||||
| has_many :praise_treads, as: :praise_tread_object, dependent: :destroy | |||||
| has_one :praise_tread_cache, as: :object, dependent: :destroy | |||||
| belongs_to :author, class_name: 'User', foreign_key: 'author_id' | |||||
| belongs_to :parent, class_name: 'Memo', foreign_key: 'parent_id' | |||||
| has_many :descendants, foreign_key: :root_id, class_name: 'Memo' | |||||
| has_many :children, foreign_key: :parent_id, class_name: 'Memo' | |||||
| has_many :attachments, as: :container, dependent: :destroy | |||||
| has_many :tidings, as: :container, dependent: :destroy | |||||
| validate :validate_sensitive_string | |||||
| scope :field_for_list, lambda{ | |||||
| select([:id, :subject, :author_id, :sticky, :updated_at, :language, :reward, :all_replies_count, :viewed_count, :forum_id]) | |||||
| } | |||||
| scope :user_posts, -> (user_id){ where(root_id: nil, author_id: user_id, forum_id: [3, 5]) } | |||||
| scope :field_for_recommend, -> { select([:id, :subject, :language, :forum_id, :all_replies_count]) } | |||||
| scope :memo_replies, -> (id) { where(root_id: id) } | |||||
| scope :hot, -> { order("all_replies_count desc, updated_at desc") } | |||||
| scope :posts, -> { where(root_id: nil, forum_id: [3, 5]) } | |||||
| validates :content, length: { maximum: 10000, too_long: "不能超过10000个字符" } | |||||
| after_create :send_tiding | |||||
| # 帖子的回复 | |||||
| def reply_for_memo | |||||
| Memo.where(parent_id: id) | |||||
| end | |||||
| # 子回复 | |||||
| def children_of_reply | |||||
| Memo.where(parent_id: id).includes(:author).reorder("created_at asc") | |||||
| end | |||||
| # 主贴的名称 | |||||
| def main_subject | |||||
| memo = Memo.find_by(root_id: id) | |||||
| Rails.logger.info("###############memo: #{memo&.subject}") | |||||
| memo ? memo.subject : subject | |||||
| end | |||||
| private | |||||
| def send_tiding | |||||
| tiding_attr = { | |||||
| trigger_user_id: author_id, viewed: 0, tiding_type: 'Comment', | |||||
| parent_container_type: 'Memo', belong_container_id: forum_id, belong_container_type: 'Forum' | |||||
| } | |||||
| if parent_id.present? | |||||
| tiding_attr.merge!(user_id: parent.author_id, parent_container_id: root_id) | |||||
| else | |||||
| # 新帖子给超级管理员发消息 | |||||
| tiding_attr.merge!(user_id: 1, parent_container_id: id) | |||||
| end | |||||
| self.tidings << Tiding.new(tiding_attr) | |||||
| end | |||||
| def validate_sensitive_string | |||||
| raise("标题包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(subject) | |||||
| raise("内容包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(content) | |||||
| end | |||||
| end | |||||
| @@ -1,4 +0,0 @@ | |||||
| class MemoTagRepertoire < ApplicationRecord | |||||
| belongs_to :memo | |||||
| belongs_to :tag_repertoire | |||||
| end | |||||
| @@ -1,5 +1,5 @@ | |||||
| class MessageDetail < ApplicationRecord | class MessageDetail < ApplicationRecord | ||||
| belongs_to :message, :touch => true | |||||
| # belongs_to :message, :touch => true | |||||
| validates :content, length: { maximum: 10000, too_long: "内容不能超过10000个字符" } | validates :content, length: { maximum: 10000, too_long: "内容不能超过10000个字符" } | ||||
| end | end | ||||
| @@ -1,7 +0,0 @@ | |||||
| # status: 0 创建镜像; 1 修改镜像ID; 2 修改镜像name 3 删除镜像 4.从主节点同步镜像到子节点(子节点发生异常), 5. 修改镜像别名, 6. 修改镜像的状态 | |||||
| # user_id: -1时,证明是非人为因素造成,中间层异常导致 | |||||
| class MirrorOperationRecord < ActiveRecord::Base | |||||
| default_scope { order(created_at: :desc) } | |||||
| belongs_to :mirror_repository | |||||
| end | |||||
| @@ -1,16 +0,0 @@ | |||||
| class MirrorRepository < ApplicationRecord | |||||
| has_many :shixun_mirror_repositories, :dependent => :destroy | |||||
| has_many :shixun, :through => :shixun_mirror_repositories | |||||
| has_many :mirror_scripts, :dependent => :destroy | |||||
| scope :published_mirror, -> { where(status: [1,2,3,5]) } | |||||
| scope :published_main_mirror, -> { published_mirror.where(main_type: 1) } | |||||
| scope :published_small_mirror, -> { published_mirror.where(main_type: 0) } | |||||
| scope :small_mirror, -> { where(main_type: 0) } | |||||
| def deletable? | |||||
| status != 1 && !shixun_mirror_repositories.exists? | |||||
| end | |||||
| end | |||||
| @@ -1,4 +0,0 @@ | |||||
| class MirrorScript < ApplicationRecord | |||||
| belongs_to :mirror_repository | |||||
| end | |||||
| @@ -1,2 +0,0 @@ | |||||
| class ModuleSetting < ApplicationRecord | |||||
| end | |||||
| @@ -1,118 +0,0 @@ | |||||
| class Myshixun < ApplicationRecord | |||||
| include ApplicationHelper | |||||
| has_many :games, :dependent => :destroy | |||||
| has_many :student_works | |||||
| has_one :shixun_modify, :dependent => :destroy | |||||
| belongs_to :user | |||||
| belongs_to :user_extension, foreign_key: :user_id | |||||
| belongs_to :shixun, counter_cache: true | |||||
| has_one :last_executable_task, -> { where(status: [0, 1]).reorder(created_at: :asc) }, class_name: 'Game' | |||||
| has_one :last_task, -> { all }, class_name: 'Game' | |||||
| validates_uniqueness_of :shixun_id, :scope => :user_id, :message => "shixun_id and user_id unique error" | |||||
| scope :finished, lambda { where(status: 1) } | |||||
| scope :search_myshixun_user, ->(user_id){where(user_id:user_id)} | |||||
| def owner | |||||
| self.user | |||||
| rescue ActiveRecord::RecordNotFound | |||||
| end | |||||
| def output_times | |||||
| games.map(&:evaluate_count).sum.to_i | |||||
| end | |||||
| def repo_path | |||||
| "#{self.repo_name}.git" | |||||
| end | |||||
| def repo_save_path | |||||
| self.repo_name.split('/').last | |||||
| end | |||||
| def is_complete? | |||||
| self.status == 1 | |||||
| end | |||||
| # 判断TPM的代码是否被修改了 | |||||
| # 判断依据是看tpm的最新提交记录和tpi数据库中存储的commit_id是否一致 | |||||
| def repository_is_modified shixun_repo_path | |||||
| myshixun_commit_id = self.commit_id | |||||
| if myshixun_commit_id.blank? | |||||
| myshixun_commit_id = GitService.commits(repo_path: self.repo_path).last["id"] | |||||
| self.update_column(:commit_id, myshixun_commit_id) | |||||
| end | |||||
| shixun_commit_id = GitService.commits(repo_path: shixun_repo_path).first["id"] | |||||
| Rails.logger.warn("###############shixun_commit_id is #{shixun_commit_id}") | |||||
| Rails.logger.warn("###############myshixun_commit_id is #{self.commit_id}") | |||||
| result = myshixun_commit_id != shixun_commit_id ? true :false | |||||
| return result | |||||
| end | |||||
| def mirror_name | |||||
| self.shixun.mirror_repositories.map(&:type_name).blank? ? "" : self.shixun.mirror_repositories.map(&:type_name) | |||||
| end | |||||
| def main_mirror | |||||
| self.shixun.mirror_repositories.published_main_mirror.try(:first) | |||||
| end | |||||
| # 当前任务:一个实训中只可能一个未完成任务(status 0或1只会存在一条记录) | |||||
| # status:0 可以测评的; 1 正在测评的; 2评测通过的; 3未开启的 | |||||
| # 如果都完成,则当前任务为最后一个任务 | |||||
| def current_task games | |||||
| current_game = games.select{|game| game.status == 1 || game.status == 0}.last | |||||
| if current_game.blank? | |||||
| current_game = games.last | |||||
| end | |||||
| current_game | |||||
| end | |||||
| # 挑战至第几关(已完成关卡数+1) | |||||
| def exec_count | |||||
| gcount = self.games.select{|game| game.status == 2}.size | |||||
| gcount = gcount < self.games.size ? (gcount + 1) : gcount | |||||
| end | |||||
| # 个人实训得分 | |||||
| def total_score | |||||
| self.games.select{|game| game.status == 2 && game.final_score > 0}.pluck(:final_score).sum.to_i | |||||
| end | |||||
| # 个人通关数 | |||||
| def passed_count | |||||
| self.games.select{|game| game.status == 2}.size | |||||
| end | |||||
| # 指定时间前完成的关卡数 | |||||
| def time_passed_count time | |||||
| time.present? ? self.games.select{|game| game.status == 2 && game.end_time < time}.size : 0 | |||||
| end | |||||
| # 查看答案的关卡数,只统计通关前看的关卡 | |||||
| def view_answer_count | |||||
| answer_ids = user.grades.joins("join games on grades.container_id = games.id").where("container_type = 'Answer' and games.status=2 and games.end_time > grades.created_at").pluck(:container_id) | |||||
| self.games.select{|game| game.status == 2 && game.answer_open != 0 && answer_ids.include?(game.id)}.size | |||||
| end | |||||
| # 通关时间 | |||||
| def passed_time | |||||
| self.status == 1 ? self.games.select{|game| game.status == 2}.map(&:end_time).max : "--" | |||||
| end | |||||
| # 耗时 | |||||
| def total_spend_time | |||||
| game_spend_time total_cost_time | |||||
| end | |||||
| # 通关总耗时 | |||||
| def total_cost_time | |||||
| self.games.select{|game| game.status == 2}.map(&:cost_time).sum.to_i | |||||
| end | |||||
| end | |||||
| @@ -1,2 +0,0 @@ | |||||
| class OldMessageDetail < ApplicationRecord | |||||
| end | |||||
| @@ -1,15 +0,0 @@ | |||||
| # 字段说明: | |||||
| # code:-1表示评测未通过,0表示评测成功,实质是status的值 | |||||
| # mes: | |||||
| # out_put: | |||||
| # test_set_position: 测试集序号(排序) | |||||
| # actual_output: | |||||
| # result: | |||||
| # is_public:测试集是否是公开 | |||||
| # query_index:评测次数 | |||||
| # compile_success: | |||||
| # text_scor: | |||||
| # sec_key:每次评测的唯一标识 | |||||
| class Output < ApplicationRecord | |||||
| belongs_to :game | |||||
| end | |||||
| @@ -1,34 +0,0 @@ | |||||
| class ProgramBank < ApplicationRecord | |||||
| def oj_language | |||||
| result = case language | |||||
| when '1' | |||||
| then 'C' | |||||
| when '2' | |||||
| then 'C++' | |||||
| when '3' | |||||
| then 'Python' | |||||
| when '4' | |||||
| then 'Java' | |||||
| end | |||||
| result | |||||
| end | |||||
| def strip_description | |||||
| strip_html description | |||||
| end | |||||
| def oj_sub_discipline_id | |||||
| result = case language | |||||
| when '1' | |||||
| then 3 | |||||
| when '2' | |||||
| then 4 | |||||
| when '3' | |||||
| then 5 | |||||
| when '4' | |||||
| then 2 | |||||
| end | |||||
| result | |||||
| end | |||||
| end | |||||
| @@ -1,2 +0,0 @@ | |||||
| class ProgramBankTest < ApplicationRecord | |||||
| end | |||||
| @@ -1,8 +0,0 @@ | |||||
| # TODO: 已废弃 | |||||
| class Relationship < ApplicationRecord | |||||
| belongs_to :follower, class_name: "User" | |||||
| belongs_to :followed, class_name: "User" | |||||
| validates :follower_id, presence: true | |||||
| validates :followed_id, presence: true | |||||
| end | |||||
| @@ -1,6 +0,0 @@ | |||||
| class Repertoire < ApplicationRecord | |||||
| has_many :sub_repertoires, ->{order(updated_at: :desc)}, :dependent => :destroy | |||||
| has_many :tag_repertoires, through: :sub_repertoires | |||||
| has_many :user_interests, dependent: :delete_all | |||||
| end | |||||
| @@ -1,3 +0,0 @@ | |||||
| class RunCodeMessage < ApplicationRecord | |||||
| belongs_to :game | |||||
| end | |||||
| @@ -1,44 +1,44 @@ | |||||
| class School < ApplicationRecord | class School < ApplicationRecord | ||||
| has_many :departments, dependent: :destroy | has_many :departments, dependent: :destroy | ||||
| has_many :shixun_schools, :dependent => :destroy | |||||
| has_many :shixuns, :through => :shixun_schools | |||||
| has_many :ec_school_users, :dependent => :destroy | |||||
| has_many :users, :through => :ec_school_users | |||||
| has_many :ec_major_schools, :dependent => :destroy | |||||
| has_many :ec_majors, :through => :ec_major_schools | |||||
| has_many :school_daily_reports, dependent: :destroy | |||||
| has_many :courses | |||||
| # has_many :shixun_schools, :dependent => :destroy | |||||
| # has_many :shixuns, :through => :shixun_schools | |||||
| # | |||||
| # has_many :ec_school_users, :dependent => :destroy | |||||
| # has_many :users, :through => :ec_school_users | |||||
| # | |||||
| # has_many :ec_major_schools, :dependent => :destroy | |||||
| # has_many :ec_majors, :through => :ec_major_schools | |||||
| # | |||||
| # has_many :school_daily_reports, dependent: :destroy | |||||
| # has_many :courses | |||||
| has_many :customers, dependent: :destroy | has_many :customers, dependent: :destroy | ||||
| has_one :partner, dependent: :destroy | |||||
| has_many :apply_add_departments, dependent: :destroy | |||||
| # has_one :partner, dependent: :destroy | |||||
| # | |||||
| # has_many :apply_add_departments, dependent: :destroy | |||||
| has_many :user_extensions, dependent: :nullify | has_many :user_extensions, dependent: :nullify | ||||
| after_create do | after_create do | ||||
| SyncTrustieJob.perform_later("school", 1) if allow_sync_to_trustie? #同步到trustie | SyncTrustieJob.perform_later("school", 1) if allow_sync_to_trustie? #同步到trustie | ||||
| end | end | ||||
| # 学校管理员 | |||||
| def manager?(user) | |||||
| ec_school_users.exists?(user_id: user.id) | |||||
| end | |||||
| # 专业管理员 | |||||
| def major_manager?(user) | |||||
| relations = ec_major_schools.not_template.joins(:ec_major_school_users) | |||||
| relations.exists?(ec_major_school_users: { user_id: user.id }) | |||||
| end | |||||
| # 课程管理员 | |||||
| def course_manager?(user) | |||||
| relations = ec_major_schools.not_template.joins(ec_years: :ec_course_users) | |||||
| relations.exists?(ec_course_users: { user_id: user.id }) | |||||
| end | |||||
| # # 学校管理员 | |||||
| # def manager?(user) | |||||
| # ec_school_users.exists?(user_id: user.id) | |||||
| # end | |||||
| # | |||||
| # # 专业管理员 | |||||
| # def major_manager?(user) | |||||
| # relations = ec_major_schools.not_template.joins(:ec_major_school_users) | |||||
| # relations.exists?(ec_major_school_users: { user_id: user.id }) | |||||
| # end | |||||
| # | |||||
| # # 课程管理员 | |||||
| # def course_manager?(user) | |||||
| # relations = ec_major_schools.not_template.joins(ec_years: :ec_course_users) | |||||
| # relations.exists?(ec_course_users: { user_id: user.id }) | |||||
| # end | |||||
| def manage_permission?(user) | def manage_permission?(user) | ||||
| manager?(user) || major_manager?(user) || course_manager?(user) | manager?(user) || major_manager?(user) || course_manager?(user) | ||||
| @@ -1,12 +0,0 @@ | |||||
| class TagDiscipline < ApplicationRecord | |||||
| belongs_to :sub_discipline | |||||
| belongs_to :user, optional: true | |||||
| has_many :tag_discipline_containers, dependent: :destroy | |||||
| validates_presence_of :name | |||||
| validates :name, length: { maximum: 15, too_long: "不能超过15个字符" } | |||||
| def discipline | |||||
| sub_discipline&.discipline | |||||
| end | |||||
| end | |||||
| @@ -1,5 +0,0 @@ | |||||
| class TagDisciplineContainer < ApplicationRecord | |||||
| belongs_to :tag_discipline | |||||
| belongs_to :container, polymorphic: true, optional: true, touch: true | |||||
| end | |||||