Merge branch 'dev_daiao' into dev_jupyter

chromesetting
daiao 5 years ago
commit 24fac643cc

@ -26,6 +26,15 @@ $(document).on('turbolinks:load', function() {
});
});
// 清空
searchForm.on('click', '.clear-btn', function () {
searchForm.find('select[name="status"]').val('');
searchForm.find('.school-select').val('').trigger('change');
searchForm.find('input[name="keyword"]').val('');
searchForm.find('#homepage_show').attr('checked', false);
searchForm.find('input[type="submit"]').trigger('click');
});
// ************** 学校选择 *************
searchForm.find('.school-select').select2({
theme: 'bootstrap4',

@ -65,7 +65,7 @@ $(document).on('turbolinks:load', function() {
},
matcher: matcherFunc
});
}
};
$.ajax({
url: '/api/schools/for_option.json',
@ -171,5 +171,19 @@ $(document).on('turbolinks:load', function() {
data: json
})
});
$(".laboratory-list-container").on("change", '.laboratory-sync-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/laboratories/" + s_id,
type: "PUT",
dataType:'script',
data: json
});
});
}
});

@ -107,7 +107,7 @@ $(document).on('turbolinks:load', function() {
},
templateResult: function (item) {
if(!item.id || item.id === '') return item.text;
var ele = '<span>'
var ele = '<span>';
ele += '<span>' + item.name + '</span>';
ele += '<span class="font-12"> -- ' + item.creator_name + '</span>';
ele += '<span class="font-12"> -- ' + item.status_text+ '</span>';
@ -116,10 +116,9 @@ $(document).on('turbolinks:load', function() {
return $(ele);
},
templateSelection: function(item){
if (item.id) {
}
var ele = '<span>' + (item.name || item.text) + '<span class="font-12"> -- ' + item.creator_name + '</span></span>'
return $(ele);
if(!item.id || item.id === '') return item.text;
var ele = '<span>' + (item.name || item.text) + '<span class="font-12"> -- ' + item.creator_name + '</span></span>';
return $(ele);
}
});

@ -0,0 +1,11 @@
$(document).on('turbolinks:load', function () {
if ($('body.admins-projects-index-page').length > 0) {
var $form = $('.search-form');
// 清空
$form.on('click', '.clear-btn', function () {
$form.find('input[name="search"]').val('');
$form.find('input[type="submit"]').trigger('click');
});
}
});

@ -1,12 +1,14 @@
$(document).on('turbolinks:load', function(){
if ($('body.admins-shixun-feedback-messages-index-page').length > 0) {
$(".content-img img").addClass("w-20").addClass("preview-image");
var baseOptions = {
autoclose: true,
language: 'zh-CN',
format: 'yyyy-mm-dd 00:00:00',
startDate: '2017-04-01'
}
};
var defineDateRangeSelect = function(element){
var options = $.extend({inputs: $(element).find('.start-date, .end-date')}, baseOptions);
@ -14,9 +16,9 @@ $(document).on('turbolinks:load', function(){
$(element).find('.start-date').datepicker().on('changeDate', function(e){
$(element).find('.end-date').datepicker('setStartDate', e.date);
})
});
};
defineDateRangeSelect('.grow-date-input-daterange');
}
})
});

@ -0,0 +1,12 @@
$(document).on('turbolinks:load', function () {
if ($('body.admins-shixun-modify-records-index-page').length > 0) {
var $form = $('.search-form');
// 清空
$form.on('click', '.clear-btn', function () {
$form.find('select[name="date"]').val('weekly');
$form.find('input[name="user_name"]').val('');
$form.find('input[type="submit"]').trigger('click');
});
}
});

@ -0,0 +1,14 @@
.diff{overflow:auto;}
.diff ul{background:#fff;overflow:auto;font-size:13px;list-style:none;margin:0;padding:0 1rem;display:table;width:100%;}
.diff del, .diff ins{display:block;text-decoration:none;}
.diff li{padding:0; display:table-row;margin: 0;height:1em;}
.diff li.ins{background:#dfd; color:#080}
.diff li.del{background:#fee; color:#b00}
.diff li:hover{background:#ffc}
/* try 'whitespace:pre;' if you don't want lines to wrap */
.diff del, .diff ins, .diff span{white-space:pre-wrap;font-family:courier;}
.diff del strong{font-weight:normal;background:#fcc;}
.diff ins strong{font-weight:normal;background:#9f9;}
.diff li.diff-comment { display: none; }
.diff li.diff-block-info { background: none repeat scroll 0 0 gray; }

@ -0,0 +1,7 @@
.admins-shixun-feedback-messages-index-page {
.content-img {
img {
height: 60px;
}
}
}

@ -1,7 +1,8 @@
class AdminConstraint
def matches?(request)
return false unless request.session[:user_id]
user = User.find request.session[:user_id]
laboratory = Laboratory.first
return false unless request.session[:"#{laboratory.try(:identifier).split('.').first}_user_id"]
user = User.find request.session[:"#{laboratory.try(:identifier).split('.').first}_user_id"]
user && user.admin?
end
end

@ -38,6 +38,8 @@ class AccountsController < ApplicationController
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
end
return normal_status(-1, "8~16位密码支持字母数字和符号") unless params[:password] =~ CustomRegexp::PASSWORD
code = generate_identifier User, 8, pre
login = pre + code
@user = User.new(admin: false, login: login, mail: email, phone: phone, type: "User")
@ -114,6 +116,7 @@ class AccountsController < ApplicationController
end
return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
return normal_status(-1, "8~16位密码支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD
user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation]
ActiveRecord::Base.transaction do
@ -123,7 +126,7 @@ class AccountsController < ApplicationController
sucess_status
rescue Exception => e
uid_logger_error(e.message)
tip_exception("密码重置失败")
tip_exception(e.message)
end
end

@ -29,9 +29,7 @@ class Admins::CoursesController < Admins::BaseController
end
def update
if @course.update_attributes(setting_params)
render_ok
else
unless @course.update_attributes!(setting_params)
redirect_to admins_courses_path
flash[:danger] = "更新失败"
end

@ -6,6 +6,7 @@ class Admins::DailySchoolStatisticsController < Admins::BaseController
total_count, statistics = Admins::SchoolDailyStatisticService.call(params)
@statistics = paginate statistics, total_count: total_count
@params_page = params[:page] || 1
respond_to do |format|
format.html { load_statistic_total }

@ -61,6 +61,14 @@ class Admins::LaboratoriesController < Admins::BaseController
@laboratory = current_laboratory
end
def update
@laboratory = current_laboratory
unless @laboratory.update_attributes!(setting_params)
redirect_to admins_laboratories_path
flash[:danger] = "更新失败"
end
end
private
def current_laboratory
@ -70,4 +78,8 @@ class Admins::LaboratoriesController < Admins::BaseController
def create_params
params.permit(:school_id)
end
def setting_params
params.permit(:sync_course, :sync_subject, :sync_shixun)
end
end

@ -16,7 +16,7 @@ class Admins::LaboratorySettingsController < Admins::BaseController
def form_params
params.permit(:identifier, :name,
:nav_logo, :login_logo, :tab_logo,
:nav_logo, :login_logo, :tab_logo, :oj_banner,
:subject_banner, :course_banner, :competition_banner, :moop_cases_banner,
:footer, navbar: %i[name link hidden])
end

@ -6,6 +6,7 @@ class Admins::MyshixunsController < Admins::BaseController
myshixuns = Admins::MyshixunQuery.call(params)
@myshixuns = paginate myshixuns.includes(:last_executable_task, :last_task, shixun: :user, user: { user_extension: :school })
@params_page = params[:page] || 1
myshixun_ids = @myshixuns.map(&:id)
@finish_game_count = Game.where(myshixun_id: myshixun_ids, status: 2).group(:myshixun_id).count

@ -10,6 +10,7 @@ class Admins::SchoolStatisticsController < Admins::BaseController
@grow_summary = service.grow_summary
total_count, statistics = service.call
@params_page = params[:page] || 1
@statistics = paginate statistics, total_count: total_count
end

@ -0,0 +1,9 @@
class Admins::ShixunModifyRecordsController < Admins::BaseController
def index
records = Admins::ShixunModifyRecordQuery.call(params)
@records = paginate records.includes(:diff_record_content)
end
end

@ -15,7 +15,8 @@ class Admins::ShixunSettingsController < Admins::BaseController
hidden: params[:hidden].present? ? params[:hidden] : false,
homepage_show: params[:homepage_show].present? ? params[:homepage_show] : false,
task_pass: params[:task_pass].present? ? params[:task_pass] : false,
code_hidden: params[:code_hidden].present? ? params[:code_hidden] : false
code_hidden: params[:code_hidden].present? ? params[:code_hidden] : false,
vip: params[:vip].present? ? params[:vip] : false
}
@shixuns_type_check = MirrorRepository.pluck(:type_name,:id)
@ -126,6 +127,6 @@ class Admins::ShixunSettingsController < Admins::BaseController
end
def setting_params
params.permit(:use_scope,:excute_time,:close,:status,:can_copy,:webssh,:hidden,:homepage_show,:task_pass,:code_hidden,:page_no, :id,tag_repertoires:[])
params.permit(:use_scope,:excute_time,:close,:status,:can_copy,:webssh,:hidden,:homepage_show,:task_pass,:code_hidden,:vip,:page_no,:id,tag_repertoires:[])
end
end

@ -18,9 +18,9 @@ class AttachmentsController < ApplicationController
pdf_attachment = params[:disposition] || "attachment"
if pdf_attachment == "inline"
send_file absolute_path(local_path(@file)),filename: @file.filename, disposition: 'inline',type: 'application/pdf'
send_file absolute_path(local_path(@file)),filename: @file.title, disposition: 'inline',type: 'application/pdf'
else
send_file(absolute_path(local_path(@file)), filename: @file.filename,stream:false, type: @file.content_type.presence || 'application/octet-stream')
send_file(absolute_path(local_path(@file)), filename: @file.title,stream:false, type: @file.content_type.presence || 'application/octet-stream')
end
update_downloads(@file)
end
@ -68,6 +68,9 @@ class AttachmentsController < ApplicationController
@attachment.author_id = current_user.id
@attachment.disk_directory = month_folder
@attachment.cloud_url = remote_path
@attachment.container_id = conversion_container_id(params[:container_id], params[:container_type])
@attachment.container_type = params[:container_type]
@attachment.attachtype = params[:attachtype]
@attachment.save!
else
logger.info "文件已存在id = #{@attachment.id}, filename = #{@attachment.filename}"
@ -91,6 +94,22 @@ class AttachmentsController < ApplicationController
end
end
# 多文件删除
def destroy_files
files = Attachment.where(id: params[:id])
begin
files.each do |file|
file_path = absolute_path(local_path(file))
file.destroy!
delete_file(file_path)
end
render_ok
rescue => e
uid_logger_error(e.message)
tip_exception(e.message)
end
end
private
def find_file
@file =
@ -196,4 +215,12 @@ class AttachmentsController < ApplicationController
end
end
end
def conversion_container_id id, type
if id.is_a?(String) && type == 'Shixun'
Shixun.find_by_identifier(id).id
else
id
end
end
end

@ -125,7 +125,7 @@ class Competitions::CompetitionsController < Competitions::BaseController
end
@all_records = @competition.competition_teams.joins(:competition_scores).where(competition_scores: {competition_stage_id: @stage&.id.to_i})
.select("competition_teams.*, score, cost_time").order("score desc, cost_time desc")
.select("competition_teams.*, score, cost_time").order("score desc, cost_time asc")
current_team_ids = @competition.team_members.where(user_id: current_user.id).pluck(:competition_team_id).uniq
@user_ranks = @all_records.select{|com_team| current_team_ids.include?(com_team.id)}
@ -213,7 +213,7 @@ class Competitions::CompetitionsController < Competitions::BaseController
if personal
row_cells_column << record_user.real_name
row_cells_column << record_user.school_name
row_cells_column << record_user.student_id.present? ? (record_user.student_id.to_s + "\t") : "--"
row_cells_column << (record_user.student_id.present? ? (record_user.student_id.to_s + "\t") : "--")
else
row_cells_column << record.name
row_cells_column << record.teachers_name

@ -1299,8 +1299,10 @@ class CoursesController < ApplicationController
begin
@all_members = @course.students
search = params[:search] ? "#{params[:search].strip}" : "" #用户名或学生学号id搜索
group_id = params[:group_id] #分班的班级id
@all_members = @all_members.where(course_group_id: group_id.map(&:to_i)) unless group_id.blank?
if params[:group_id].present?
group_ids = params[:group_id].is_a?(String) ? [params[:group_id].to_i] : params[:group_id].map(&:to_i)
@all_members = @all_members.where(course_group_id: group_ids)
end
unless search.blank?
@all_members = @all_members.joins(user: [:user_extension]).where('concat(users.lastname, users.firstname) like ? or user_extensions.student_id like ?',"%#{search}%","%#{search}%")
end

@ -4,85 +4,83 @@ class ExerciseAnswersController < ApplicationController
include ExercisesHelper
def create #每一次答案的点击,请求一次,实训题不在这里回答
ActiveRecord::Base.transaction do
begin
q_type = @exercise_question.question_type #试卷的类型
choice_id = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : ""
answer_text = params[:answer_text].present? ? params[:answer_text].strip : "" #为字符串
if q_type < Exercise::SUBJECTIVE && (q_type != Exercise::MULTIPLE) && choice_id.blank?
normal_status(-1,"请选择序号")
else
ea = @exercise_question.exercise_answers.search_answer_users("user_id",current_user.id) #试卷的当前用户的答案
if q_type == Exercise::SINGLE || q_type == Exercise::JUDGMENT #选择题(单选)/判断题
if ea.exists?
ea.first.update_attribute(:exercise_choice_id,choice_id )
else
answer_option = {
:user_id => current_user.id,
:exercise_question_id => @exercise_question.id,
:exercise_choice_id => choice_id,
:answer_text => ""
}
ex_a = ExerciseAnswer.new(answer_option)
ex_a.save!
end
elsif q_type == Exercise::MULTIPLE #多选题的
choice_ids = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : []
ea_ids = ea.pluck(:exercise_choice_id)
common_answer_ids = choice_ids & ea_ids #已经存在的试卷选项id
new_ids = choice_ids - common_answer_ids # 新增的id
old_ids = ea_ids - common_answer_ids #没有选择的,则删掉
if new_ids.size > 0
new_ids.each do |e|
answer_option = {
:user_id => current_user.id,
:exercise_question_id => @exercise_question.id,
:exercise_choice_id => e,
:answer_text => ""
}
ex_a = ExerciseAnswer.new(answer_option)
ex_a.save!
end
end
if old_ids.size > 0
ea_answer = ea.search_answer_users("exercise_choice_id",old_ids)
ea_answer.destroy_all
end
elsif q_type == Exercise::COMPLETION #填空题
answer_option = {
:user_id => current_user.id,
:exercise_question_id => @exercise_question.id,
:exercise_choice_id => choice_id,
:answer_text => answer_text
}
ea_answer = ea.search_answer_users("exercise_choice_id",choice_id)
if ea.present? && ea_answer.present?
ea_answer.update(answer_option)
else
ex_new = ExerciseAnswer.new(answer_option)
ex_new.save!
end
elsif q_type == Exercise::SUBJECTIVE #简答题
begin
q_type = @exercise_question.question_type #试卷的类型
choice_id = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : ""
answer_text = params[:answer_text].present? ? params[:answer_text].strip : "" #为字符串
if q_type < Exercise::SUBJECTIVE && (q_type != Exercise::MULTIPLE) && choice_id.blank?
normal_status(-1,"请选择序号")
else
ea = @exercise_question.exercise_answers.search_answer_users("user_id",current_user.id) #试卷的当前用户的答案
if q_type == Exercise::SINGLE || q_type == Exercise::JUDGMENT #选择题(单选)/判断题
if ea.exists?
ea.first.update_attribute(:exercise_choice_id,choice_id )
else
answer_option = {
:user_id => current_user.id,
:exercise_question_id => @exercise_question.id
:user_id => current_user.id,
:exercise_question_id => @exercise_question.id,
:exercise_choice_id => choice_id,
:answer_text => ""
}
if ea.present? #已经回答了的,
ea.first.update_attribute("answer_text",answer_text)
else
answer_option.merge!(answer_text:answer_text)
ex_a = ExerciseAnswer.new(answer_option)
ex_a.save!
end
elsif q_type == Exercise::MULTIPLE #多选题的
choice_ids = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : []
ea_ids = ea.pluck(:exercise_choice_id)
common_answer_ids = choice_ids & ea_ids #已经存在的试卷选项id
new_ids = (choice_ids - common_answer_ids).uniq # 新增的id
old_ids = (ea_ids - common_answer_ids).uniq #没有选择的,则删掉
if new_ids.size > 0
new_ids.each do |e|
answer_option = {
:user_id => current_user.id,
:exercise_question_id => @exercise_question.id,
:exercise_choice_id => e,
:answer_text => ""
}
ex_a = ExerciseAnswer.new(answer_option)
ex_a.save!
end
end
normal_status(0,"回答成功")
if old_ids.size > 0
ea_answer = ea.search_answer_users("exercise_choice_id",old_ids)
ea_answer.destroy_all
end
elsif q_type == Exercise::COMPLETION #填空题
answer_option = {
:user_id => current_user.id,
:exercise_question_id => @exercise_question.id,
:exercise_choice_id => choice_id,
:answer_text => answer_text
}
ea_answer = ea.search_answer_users("exercise_choice_id",choice_id)
if ea.present? && ea_answer.present?
ea_answer.update(answer_option)
else
ex_new = ExerciseAnswer.new(answer_option)
ex_new.save!
end
elsif q_type == Exercise::SUBJECTIVE #简答题
answer_option = {
:user_id => current_user.id,
:exercise_question_id => @exercise_question.id
}
if ea.present? #已经回答了的,
ea.first.update_attribute("answer_text",answer_text)
else
answer_option.merge!(answer_text:answer_text)
ex_a = ExerciseAnswer.new(answer_option)
ex_a.save!
end
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception("页面调用失败!")
raise ActiveRecord::Rollback
normal_status(0,"回答成功")
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception("页面调用失败!")
raise ActiveRecord::Rollback
end
end

@ -47,26 +47,26 @@ class FilesController < ApplicationController
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
# 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_all(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
# 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)
@ -140,7 +140,7 @@ class FilesController < ApplicationController
def public_with_course_and_project
@attachments = Attachment.publiced.simple_columns
.contains_course_and_project
.includes(:author => :user_extension)
.includes(:container, author: :user_extension)
.by_filename_or_user_name(params[:search])
.ordered(sort: 0, sort_type: 'created_on')
@ -361,15 +361,16 @@ class FilesController < ApplicationController
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
elsif params[:delay_publish].to_i == 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

@ -1,13 +1,14 @@
class HackUserLastestCodesController < ApplicationController
before_action :require_login, except: [:listen_result]
before_action :find_my_hack, only: [:show, :code_debug, :code_submit, :update_code,
before_action :find_my_hack, only: [:show, :code_debug, :code_submit, :update_code, :sync_code,
: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: [:update_code, :restore_initial_code]
before_action :require_auth_identity, only: [:update_code, :restore_initial_code, :sync_code]
before_action :require_manager_identity, only: [:update_code]
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
@ -15,10 +16,14 @@ class HackUserLastestCodesController < ApplicationController
render_ok
end
# 复初始代码
# 复初始代码
def restore_initial_code
@my_hack.update_attribute(:code, @hack.code)
render_ok
end
# 同步代码
def sync_code
@my_hack.update_attributes(code: @hack.code, modify_time: @hack.modify_time)
end
# 调试代码
@ -55,12 +60,15 @@ class HackUserLastestCodesController < ApplicationController
end
# 提交记录
def submit_records;end
def submit_records
@records = @my_hack.hack_user_codes.created_order
end
# 提交记录详情
def record_detail
@hack_user = HackUserCode.find params[:id]
@my_hack = @hack_user.hack_user_lastest_code
end
# 接收中间件返回结果接口

@ -1,8 +1,8 @@
class HacksController < ApplicationController
before_action :require_login, except: [:index]
before_action :find_hack, only: [:edit, :update, :publish, :start, :update_set, :delete_set]
before_action :require_teacher_identity, only: [:create, :update_set]
before_action :require_auth_identity, only: [:update, :edit, :publish, :update_set, :delete_set]
before_action :find_hack, only: [:edit, :update, :publish, :start, :update_set, :delete_set, :destroy]
before_action :require_teacher_identity, only: [:create]
before_action :require_auth_identity, only: [:update, :edit, :publish, :update_set, :delete_set, :destroy]
# 开启编程,如果第一次开启,创建一条记录,如果已经开启过的话,直接返回标识即可
@ -15,7 +15,7 @@ class HacksController < ApplicationController
user_hack.identifier
else
user_identifier = generate_identifier HackUserLastestCode, 12
user_code = {user_id: current_user.id, code: @hack.code,
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
@ -47,10 +47,10 @@ class HacksController < ApplicationController
hack.identifier = generate_identifier Hack, 8
hack.save!
# 创建测试集与代码
logger.info("hack_sets_params:#{hack_sets_params}")
logger.info("hack_code_params:#{hack_code_params}")
hack.hack_sets.create!(hack_sets_params)
hack.hack_codes.create!(hack_code_params)
hack_codes = hack.hack_codes.new(hack_code_params)
hack_codes.modify_time = Time.now
hack_codes.save!
end
render_ok({identifier: hack.identifier})
rescue Exception => e
@ -69,7 +69,8 @@ class HacksController < ApplicationController
# 新建
@hack.hack_sets.create!(hack_sets_params)
# 更新代码
@hack.hack_codes.create!(hack_code_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)
end
render_ok
rescue Exception => e
@ -109,6 +110,13 @@ class HacksController < ApplicationController
def edit;end
def new;end
def destroy
@hack.destroy
render_ok
end
private
# 实名认证老师,管理员与运营人员权限
def require_teacher_identity
@ -199,7 +207,7 @@ class HacksController < ApplicationController
end
def start_hack_auth
return true if @hack == 1
return true if @hack.status == 1
require_auth_identity
end

@ -20,8 +20,8 @@ class HomeController < ApplicationController
shixuns = shixuns.where(homepage_show: true)
subjects = subjects.where(homepage_show: true)
else
shixuns = shixuns.where(laboratory_shixuns: { homepage: true })
subjects = subjects.where(laboratory_subjects: { homepage: true })
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)

@ -294,7 +294,7 @@ class HomeworkCommonsController < ApplicationController
HomeworksService.new.update_myshixun_work_score work, myshixun, games, @homework, challenge_settings
normal_status("更新成功")
else
normal_status("开启挑战,暂不能更新成绩")
normal_status("开启挑战,暂不能更新成绩")
end
rescue Exception => e
uid_logger(e.message)
@ -453,7 +453,9 @@ class HomeworkCommonsController < ApplicationController
# 课堂结束后不能再更新
unless @course.is_end
UpdateHomeworkPublishSettingService.call(@homework, publish_params)
# 作业未发布时unified_setting参数不能为空
=begin
if @homework.publish_time.nil? || @homework.publish_time > Time.now
tip_exception("缺少统一设置的参数") if params[:unified_setting].nil?
if params[:unified_setting] || @course.course_groups_count == 0
@ -549,6 +551,7 @@ class HomeworkCommonsController < ApplicationController
@homework.end_time = @homework.max_group_end_time
end
end
=end
# 补交设置
tip_exception("缺少allow_late参数") if params[:allow_late].nil?
@ -582,8 +585,8 @@ class HomeworkCommonsController < ApplicationController
tip_exception("缺少answer_open_evaluation参数") if params[:answer_open_evaluation].nil?
tip_exception("缺少work_efficiency参数") if params[:work_efficiency].nil?
tip_exception("缺少eff_score参数") if params[:work_efficiency] && params[:eff_score].blank?
tip_exception("效率分不能小于等于0") if params[:eff_score] && params[:eff_score].to_f <= 0
tip_exception("效率分不能大于总分值") if params[:eff_score] && params[:eff_score].to_f.round(2) > params[:total_score].to_f.round(2)
tip_exception("效率分不能小于等于0") if params[:work_efficiency] && params[:eff_score] && params[:eff_score].to_f <= 0
tip_exception("效率分不能大于总分值") if params[:work_efficiency] && params[:eff_score] && params[:eff_score].to_f.round(2) > params[:total_score].to_f.round(2)
tip_exception("缺少shixun_evaluation参数") if params[:shixun_evaluation].blank?
tip_exception("缺少challenge_settings参数") if params[:challenge_settings].blank?
# tip_exception("缺少challenge_id参数") if params[:challenge_settings][:challenge_id].blank?
@ -591,6 +594,10 @@ class HomeworkCommonsController < ApplicationController
# tip_exception("challenge_id参数的长度与challenge_score参数的长度不匹配") if
# params[:challenge_settings][:challenge_score].length != params[:challenge_settings][:challenge_id].length
sum_challenge_score = params[:challenge_settings].pluck(:challenge_score).reject(&:blank?).map{|score| score.to_f}.sum
total_score = params[:work_efficiency] ? (params[:eff_score].to_f + sum_challenge_score) : sum_challenge_score
tip_exception("分值之和必须等于总分值:#{params[:total_score]}") if params[:total_score].to_f.round(2) != total_score.to_f.round(2)
current_eff_score = @homework.eff_score.to_f.round(2)
@homework.total_score = params[:total_score]
@homework.work_efficiency = params[:work_efficiency]
@ -631,7 +638,7 @@ class HomeworkCommonsController < ApplicationController
@homework.save!
if score_change && @homework.end_or_late_none_group
UpdateShixunWorkScoreJob.perform_now(@homework.id)
UpdateShixunWorkScoreJob.perform_later(@homework.id)
elsif update_eff_score && (@homework.end_or_late_none_group || @homework.max_efficiency > 0)
# 更新所有学生的效率分(作业允许补交且补交已截止 或者 作业不允许补交且提交已截止 或者作业已计算过效率分)
HomeworksService.new.update_student_eff_score HomeworkCommon.find_by(id: @homework.id)
@ -822,12 +829,16 @@ class HomeworkCommonsController < ApplicationController
end
end
HomeworkCommonPushNotifyJob.perform_later(@homework.id, publish_group_ids) if send_tiding
normal_status(0, "更新成功")
else
tip_exception("课堂已结束不能再更新")
end
# rescue ActiveRecord::RecordInvalid
# render_error("保存失败")
# rescue ApplicationService::Error => ex
# uid_logger(ex.message)
# render_error(ex.message)
# raise ActiveRecord::Rollback
rescue Exception => e
uid_logger(e.backtrace)
tip_exception(e.message)
@ -1097,7 +1108,7 @@ class HomeworkCommonsController < ApplicationController
else
homework.unified_setting = false
# 创建作业分班设置homework_group_setting
create_homework_group_settings(homework)
homework.create_homework_group_settings
# 选中的分班设置的发布时间改为当前时间,截止时间改为传的截止时间参数
if params[:detail]
@ -1133,7 +1144,7 @@ class HomeworkCommonsController < ApplicationController
# 发消息
HomeworkCommonPushNotifyJob.perform_later(homework.id, tiding_group_ids)
else
create_homework_group_settings(homework)
homework.create_homework_group_settings
none_publish_settings = homework.homework_group_settings.where(course_group_id: publish_groups).none_published
if params[:detail]
@ -1207,7 +1218,7 @@ class HomeworkCommonsController < ApplicationController
# 分组设置
if !params[:group_ids].blank?
# 确保之前是统一设置或者有新创建的分班的数据一致性
create_homework_group_settings(homework)
homework.create_homework_group_settings
homework.unified_setting = false if homework.unified_setting && end_groups.length != @course.course_groups_count
@ -1578,15 +1589,6 @@ class HomeworkCommonsController < ApplicationController
end
def create_homework_group_settings homework
if homework.homework_group_settings.size != @course.course_groups.size
@course.course_groups.where.not(id: homework.homework_group_settings.pluck(:course_group_id)).each do |group|
homework.homework_group_settings << HomeworkGroupSetting.new(course_group_id: group.id, course_id: @course.id,
publish_time: homework.publish_time, end_time: homework.end_time)
end
end
end
def get_new_code_reviews_result homework
if homework.code_reviews_new_results?
# 获取最新的查询id
@ -1649,4 +1651,8 @@ class HomeworkCommonsController < ApplicationController
homework_bank
end
def publish_params
params.permit(:unified_setting, :publish_time, :end_time, group_settings: [:publish_time, :end_time, group_id: []])
end
end

@ -216,7 +216,8 @@ class MyshixunsController < ApplicationController
begin
shixun_tomcat = edu_setting('tomcat_webssh')
uri = "#{shixun_tomcat}/bridge/webssh/getConnectInfo"
params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh),
# 由于中间层采用混合云的方式因为local参数表示在有文件生成的实训是在本地生成还是在其他云端生成评测文件
params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh), local: @myshixun.shixun.show_type != -1,
containers:(Base64.urlsafe_encode64(shixun_container_limit @myshixun.shixun))}
res = uri_post uri, params
if res && res['code'].to_i != 0

@ -6,119 +6,117 @@ class PollVotesController < ApplicationController
def create #每一次答案的点击,请求一次
ActiveRecord::Base.transaction do
begin
question_votes = @poll_question.poll_votes
question_type = @poll_question.question_type
question_answer_id = params[:poll_answer_id] ? params[:poll_answer_id] : nil #该答案的id
question_answer_text = params[:vote_text].present? ? params[:vote_text] : nil #其他选项的内容
user_votes = question_votes.find_current_vote("user_id",current_user.id) #当前用户的答案,可能有多个
# 当前用户的当前答案,如果已存在,当再次点击的时候,取消答案,即删除该答案
current_vote_text = nil
begin
question_votes = @poll_question.poll_votes
question_type = @poll_question.question_type
question_answer_id = params[:poll_answer_id] ? params[:poll_answer_id] : -1 #该答案的id
question_answer_text = params[:vote_text].present? ? params[:vote_text] : nil #其他选项的内容
user_votes = question_votes.find_current_vote("user_id",current_user.id) #当前用户的答案,可能有多个
# 当前用户的当前答案,如果已存在,当再次点击的时候,取消答案,即删除该答案
current_vote_text = nil
# if user_votes.find_vote_text.present?
# current_vote_text = user_votes.find_vote_text.first
# end
# if user_votes.find_vote_text.present?
# current_vote_text = user_votes.find_vote_text.first
# end
vote_answer_params = {
:user_id => current_user.id,
:poll_question_id => @poll_question.id,
:poll_answer_id => question_answer_id,
:vote_text => question_answer_text
}
#begin
if question_type == 1
if user_votes.present? #用户曾经回答过的,答案选择不一样,否则新建
current_user_answer = user_votes.first
if current_user_answer&.poll_answer_id != question_answer_id #如果说更换了答案,则以前的答案删除,并新建记录
current_user_answer.destroy
PollVote.create(vote_answer_params)
else
vote_answer_params = {
:user_id => current_user.id,
:poll_question_id => @poll_question.id,
:poll_answer_id => question_answer_id,
:vote_text => question_answer_text
}
#begin
if question_type == 1
if user_votes.present? #用户曾经回答过的,答案选择不一样,否则新建
current_user_answer = user_votes.first
if current_user_answer&.poll_answer_id != question_answer_id #如果说更换了答案,则以前的答案删除,并新建记录
current_user_answer.destroy
PollVote.create(vote_answer_params)
else
if question_answer_text.present?
current_user_answer.update_attribute("vote_text", question_answer_text)
end
if question_answer_text.present?
current_user_answer.update_attribute("vote_text", question_answer_text)
end
else
PollVote.create(vote_answer_params)
end
elsif question_type == 2 #多选题的话答案应该是1个以上
question_answer_ids = params[:poll_answer_id] ? params[:poll_answer_id] : [] #该答案的id
if question_answer_ids.present?
if question_answer_text.present? #有文字输入,但是不存在其他选项的
ques_vote_id = question_answer_ids.map(&:to_i).max
if user_votes.find_vote_text.present?
current_vote_text = user_votes.find_vote_text.first
current_vote_text.update_attribute("vote_text", question_answer_text)
else
answer_option = {
:user_id => current_user.id,
:poll_question_id => @poll_question.id,
:poll_answer_id => ques_vote_id,
:vote_text => question_answer_text
}
PollVote.create(answer_option)
end
# if current_vote_text.present? #已有其他输入文字的选项
# current_vote_text.update_attribute("vote_text", question_answer_text)
# else
#
# end
else
PollVote.create(vote_answer_params)
end
elsif question_type == 2 #多选题的话答案应该是1个以上
question_answer_ids = params[:poll_answer_id] ? params[:poll_answer_id] : [] #该答案的id
if question_answer_ids.present?
if question_answer_text.present? #有文字输入,但是不存在其他选项的
ques_vote_id = question_answer_ids.map(&:to_i).max
if user_votes.find_vote_text.present?
current_vote_text = user_votes.find_vote_text.first
current_vote_text.update_attribute("vote_text", question_answer_text)
else
answer_option = {
:user_id => current_user.id,
:poll_question_id => @poll_question.id,
:poll_answer_id => ques_vote_id,
:vote_text => question_answer_text
}
PollVote.create(answer_option)
end
# if current_vote_text.present? #已有其他输入文字的选项
# current_vote_text.update_attribute("vote_text", question_answer_text)
# else
#
# end
end
ea_ids = user_votes.pluck(:poll_answer_id)
common_answer_ids = question_answer_ids & ea_ids #已经存在的试卷选项id
new_ids = question_answer_ids - common_answer_ids # 新增的id
old_ids = ea_ids - common_answer_ids #没有选择的,则删掉
if new_ids.size > 0
new_ids.each do |e|
answer_option = {
:user_id => current_user.id,
:poll_question_id => @poll_question.id,
:poll_answer_id => e,
:vote_text => nil
}
ex_a = PollVote.new(answer_option)
ex_a.save!
end
end
if old_ids.size > 0
ea_answer = user_votes.find_current_vote("poll_answer_id",old_ids)
ea_answer.destroy_all
ea_ids = user_votes.pluck(:poll_answer_id)
common_answer_ids = question_answer_ids & ea_ids #已经存在的试卷选项id
new_ids = question_answer_ids - common_answer_ids # 新增的id
old_ids = ea_ids - common_answer_ids #没有选择的,则删掉
if new_ids.size > 0
new_ids.each do |e|
answer_option = {
:user_id => current_user.id,
:poll_question_id => @poll_question.id,
:poll_answer_id => e,
:vote_text => nil
}
ex_a = PollVote.new(answer_option)
ex_a.save!
end
else
user_votes.destroy_all
end
else #主观题的输入
# current_vote_text = user_votes.find_vote_text
if user_votes.present?
user_votes.first.update_attribute("vote_text", question_answer_text)
# if question_answer_text.present?
# user_votes.first.update_attribute("vote_text", question_answer_text)
# else
# user_votes.destroy_all
# end
else
PollVote.create(vote_answer_params)
if old_ids.size > 0
ea_answer = user_votes.find_current_vote("poll_answer_id",old_ids)
ea_answer.destroy_all
end
else
user_votes.destroy_all
end
@current_question_number = @poll_question.question_number
@current_question_necessary = @poll_question.is_necessary
#问答记录存在,且有值,才会有返回值。
@current_question_status = 0
new_user_votes = question_votes.where(user_id: current_user.id)
if new_user_votes.present?
vote_answer_id = new_user_votes.pluck(:poll_answer_id).reject(&:blank?).size
vote_text_count = new_user_votes.pluck(:vote_text).reject(&:blank?).size
if vote_text_count > 0 || vote_answer_id > 0
@current_question_status = 1
end
else #主观题的输入
# current_vote_text = user_votes.find_vote_text
if user_votes.present?
user_votes.first.update_attribute("vote_text", question_answer_text)
# if question_answer_text.present?
# user_votes.first.update_attribute("vote_text", question_answer_text)
# else
# user_votes.destroy_all
# end
else
PollVote.create(vote_answer_params)
end
end
@current_question_number = @poll_question.question_number
@current_question_necessary = @poll_question.is_necessary
#问答记录存在,且有值,才会有返回值。
@current_question_status = 0
new_user_votes = question_votes.where(user_id: current_user.id)
if new_user_votes.present?
vote_answer_id = new_user_votes.pluck(:poll_answer_id).reject(&:blank?).size
vote_text_count = new_user_votes.pluck(:vote_text).reject(&:blank?).size
if vote_text_count > 0 || vote_answer_id > 0
@current_question_status = 1
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception("页面调用失败!")
raise ActiveRecord::Rollback
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception("页面调用失败!")
raise ActiveRecord::Rollback
end
end

@ -1409,23 +1409,29 @@ class PollsController < ApplicationController
poll_questions.each do |q|
user_poll_votes = u_user.poll_votes.find_current_vote("poll_question_id",q.id)
if user_poll_votes.present?
user_poll_answer_ids = user_poll_votes.pluck(:poll_answer_id).reject(&:blank?)
user_poll_vote_texts = user_poll_votes.pluck(:vote_text).reject(&:blank?)
if user_poll_answer_ids.count > 0
answer_content = q.poll_answers.find_answer_by_custom("id",user_poll_answer_ids)
if user_poll_answer_ids.count >1
u_answer = answer_content.pluck(:answer_text).join(";")
if q.question_type < 3
user_poll_answer_ids = user_poll_votes.pluck(:poll_answer_id).reject(&:blank?)
if user_poll_answer_ids.count > 0
answer_content = q.poll_answers.find_answer_by_custom("id",user_poll_answer_ids)
if user_poll_answer_ids.count >1
u_answer = answer_content.pluck(:answer_text).join(";")
else
u_answer = answer_content.first&.answer_text
end
else
u_answer = answer_content.first.answer_text
u_answer = "--"
end
elsif user_poll_vote_texts.count > 0
if user_poll_vote_texts.count > 1
u_answer = user_poll_vote_texts.join(";")
else
user_poll_vote_texts = user_poll_votes.pluck(:vote_text).reject(&:blank?)
if user_poll_vote_texts.count > 0
if user_poll_vote_texts.count > 1
u_answer = user_poll_vote_texts.join(";")
else
u_answer = user_poll_vote_texts.first
end
else
u_answer = user_poll_vote_texts.first
u_answer = "--"
end
else
u_answer = "--"
end
else
u_answer = "--"

@ -26,22 +26,7 @@ class ShixunsController < ApplicationController
## 获取课程列表
def index
## 我的实训
@shixuns =
if params[:order_by] == 'mine'
tip_exception(401, "..") unless current_user.logged?
current_user.my_shixuns
else
Shixun.unhidden
end
## 云上实验室过滤
unless current_laboratory.main_site?
@shixuns = @shixuns.joins(:laboratory_shixuns).where(laboratory_shixuns: { laboratory_id: current_laboratory.id })
else
not_shixun_ids = Shixun.joins(:laboratory_shixuns).where("laboratory_shixuns.laboratory_id != #{current_laboratory.id}")
@shixuns = @shixuns.where.not(id: not_shixun_ids)
end
@shixuns = current_laboratory.shixuns.unhidden
## 方向
if params[:tag_level].present? && params[:tag_id].present?
@ -379,76 +364,107 @@ class ShixunsController < ApplicationController
end
def create
# 评测脚本的一些操作
main_type, sub_type = params[:main_type], params[:small_type]
mirror = MirrorScript.where(:mirror_repository_id => main_type)
identifier = generate_identifier Shixun, 8
@shixun = Shixun.new(shixun_params)
@shixun.identifier = identifier
@shixun.user_id = current_user.id
@shixun.reset_time, @shixun.modify_time = Time.now, Time.now
if sub_type.blank?
shixun_script = mirror.first.try(:script)
else
main_mirror = MirrorRepository.find(main_type).type_name
sub_mirror = MirrorRepository.where(id: sub_type).pluck(:type_name)
if main_mirror == "Java" && sub_mirror.include?("Mysql")
shixun_script = mirror.last.try(:script)
else
shixun_script = mirror.first.try(:script)
shixun_script = modify_shixun_script @shixun, shixun_script
end
begin
@shixun = CreateShixunService.call(current_user, shixun_params, params)
rescue => e
logger_error("shixun_create_error: #{e.message}")
tip_exception("创建实训失败!")
end
end
ActiveRecord::Base.transaction do
begin
@shixun.save!
# shixun_info关联ß
ShixunInfo.create!(shixun_id: @shixun.id, evaluate_script: shixun_script, description: params[:description])
# 实训的公开范围
if params[:scope_partment].present?
arr = []
ids = School.where(:name => params[:scope_partment]).pluck(:id).uniq
ids.each do |id|
arr << { :school_id => id, :shixun_id => @shixun.id }
end
ShixunSchool.create!(arr)
def update
# 镜像方面
mirror_ids = MirrorRepository.where(id: params[:main_type])
.or( MirrorRepository.where(id: params[:sub_type])).pluck(:id).uniq
old_mirror_ids = @shixun.shixun_mirror_repositories
.where(mirror_repository_id: params[:main_type])
.or(@shixun.shixun_mirror_repositories.where(mirror_repository_id: params[:sub_type]))
.pluck(:mirror_repository_id).uniq
new_mirror_id = (mirror_ids - old_mirror_ids).map{|id| {mirror_repository_id: id}} # 转换成数组hash方便操作
logger.info("##########new_mirror_id: #{new_mirror_id}")
logger.info("##########old_mirror_ids: #{old_mirror_ids}")
logger.info("##########mirror_ids: #{mirror_ids}")
# 服务配置方面
service_create_params = service_config_params[:shixun_service_configs]
.select{|config| !old_mirror_ids.include?(config[:mirror_repository_id]) &&
MirrorRepository.find(config[:mirror_repository_id]).name.present?}
service_update_params = service_config_params[:shixun_service_configs]
.select{|config| old_mirror_ids.include?(config[:mirror_repository_id])}
logger.info("#########service_create_params: #{service_create_params}")
logger.info("#########service_update_params: #{service_update_params}")
begin
ActiveRecord::Base.transaction do
@shixun.update_attributes(shixun_params)
@shixun.shixun_info.update_attributes(shixun_info_params)
# 镜像变动
@shixun.shixun_mirror_repositories.where.not(mirror_repository_id: old_mirror_ids).destroy_all
@shixun.shixun_mirror_repositories.create!(new_mirror_id)
# 镜像变动要更换服务配置
@shixun.shixun_service_configs.where.not(mirror_repository_id: old_mirror_ids).destroy_all
@shixun.shixun_service_configs.create!(service_create_params)
service_update_params&.map do |service|
smr = @shixun.shixun_service_configs.find_by(mirror_repository_id: service[:mirror_repository_id])
smr.update_attributes(service)
end
# 实训合作者
@shixun.shixun_members.create!(user_id: current_user.id, role: 1)
# 镜像-实训关联表
ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i) if main_type.present?
# 实训主镜像服务配置
ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i)
if sub_type.present?
sub_type.each do |mirror|
ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
# 实训子镜像服务配置
name = MirrorRepository.find_by(id: mirror).try(:name) #查看镜像是否有名称,如果没有名称就不用服务配置
ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror) if name.present?
# 添加第二仓库(管理员权限)
if current_user.admin_or_business?
if params[:is_secret_repository]
add_secret_repository if @shixun.shixun_secret_repository.blank?
else
# 如果有仓库,就要删
if @shixun.shixun_secret_repository&.repo_name
@shixun.shixun_secret_repository.lock!
GitService.delete_repository(repo_path: @shixun.shixun_secret_repository.repo_path)
@shixun.shixun_secret_repository.destroy
end
end
end
end
rescue => e
uid_logger_error(e.message)
tip_exception("基本信息更新失败:#{e.message}")
end
end
# 创建版本库
repo_path = repo_namespace(User.current.login, @shixun.identifier)
GitService.add_repository(repo_path: repo_path)
# todo: 为什么保存的时候要去除后面的.git呢??
@shixun.update_column(:repo_name, repo_path.split(".")[0])
# 实训权限设置
def update_permission_setting
# 查找需要增删的高校id
school_id = School.where(:name => params[:scope_partment]).pluck(:id)
old_school_ids = @shixun.shixun_schools.pluck(:school_id)
school_params = (school_id - old_school_ids).map{|id| {school_id: id}}
begin
ActiveRecord::Base.transaction do
@shixun.update_attributes!(shixun_params)
@shixun.shixun_schools.where.not(school_id: school_id).destroy_all if school_id.present?
@shixun.shixun_schools.create!(school_params)
end
rescue => e
uid_logger_error("实训权限设置失败--------#{e.message}")
tip_exception("实训权限设置失败")
end
end
# 将实训标志为该云上实验室建立
Laboratory.current.laboratory_shixuns.create!(shixun: @shixun, ownership: true)
rescue Exception => e
uid_logger_error(e.message)
tip_exception("实训创建失败")
raise ActiveRecord::Rollback
# 实训学习页面设置
def update_learn_setting
begin
ActiveRecord::Base.transaction do
@shixun.update_attributes!(shixun_params)
end
rescue => e
uid_logger_error("实训学习页面设置失败--------#{e.message}")
tip_exception("实训学习页面设置失败")
end
end
# Jupyter数据集
def jupyter_data_sets
page = params[:page] || 1
limit = params[:limit] || 10
data_sets = @shixun.jupyter_data_sets
@data_count = data_sets.count
@data_sets= data_sets.page(page).per(limit)
end
def apply_shixun_mirror
form_params = params.permit(*%i[language runtime run_method attachment_id])
form = ApplyShixunMirrorForm.new(form_params)
@ -477,61 +493,6 @@ class ShixunsController < ApplicationController
tip_exception("申请失败")
end
def update
ActiveRecord::Base.transaction do
begin
@shixun.shixun_mirror_repositories.destroy_all
if params[:main_type].present?
ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => params[:main_type].to_i)
end
if params[:small_type].present?
params[:small_type].each do |mirror|
ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
end
end
@shixun.update_attributes(shixun_params)
@shixun.shixun_info.update_attributes(shixun_info_params)
@shixun.shixun_schools.delete_all
# scope_partment: 高校的名称
if params[:scope_partment].present?
arr = []
ids = School.where(:name => params[:scope_partment]).pluck(:id).uniq
ids.each do |id|
arr << { :school_id => id, :shixun_id => @shixun.id }
end
ShixunSchool.create!(arr)
end
# 超级管理员和运营人员才能保存 中间层服务器pod信息的配置
# 如果镜像改动了,则也需要更改
mirror = @shixun.shixun_service_configs.map(&:mirror_repository_id).sort
new_mirror = params[:shixun_service_configs].map{|c| c[:mirror_repository_id]}.sort
if current_user.admin? || current_user.business? || (mirror != new_mirror)
@shixun.shixun_service_configs.destroy_all
service_config_params[:shixun_service_configs].each do |config|
name = MirrorRepository.find_by_id(config[:mirror_repository_id])&.name
# 不保存没有镜像的配置
@shixun.shixun_service_configs.create!(config) if name.present?
end
end
# 添加第二仓库
if params[:is_secret_repository]
add_secret_repository if @shixun.shixun_secret_repository.blank?
else
# 如果有仓库,就要删
if @shixun.shixun_secret_repository&.repo_name
@shixun.shixun_secret_repository.lock!
GitService.delete_repository(repo_path: @shixun.shixun_secret_repository.repo_path)
@shixun.shixun_secret_repository.destroy
end
end
rescue Exception => e
uid_logger_error("实训保存失败--------#{e.message}")
tip_exception("实训保存失败")
raise ActiveRecord::Rollback
end
end
end
# 永久关闭实训
def close
@ -1036,10 +997,9 @@ class ShixunsController < ApplicationController
private
def shixun_params
raise("实训名称不能为空") if params[:shixun][:name].blank?
params.require(:shixun).permit(:name, :trainee, :webssh, :can_copy, :use_scope, :vnc, :test_set_permission,
:task_pass, :multi_webssh, :opening_time, :mirror_script_id, :code_hidden,
:hide_code, :forbid_copy, :vnc_evaluate, :code_edit_permission)
:hide_code, :forbid_copy, :vnc_evaluate, :code_edit_permission, :is_jupyter)
end
def validate_review_shixun_params
@ -1048,8 +1008,6 @@ private
end
def shixun_info_params
raise("实训描述不能为空") if params[:shixun_info][:description].blank?
raise("评测脚本不能为空") if params[:shixun_info][:evaluate_script].blank?
params.require(:shixun_info).permit(:description, :evaluate_script)
end

@ -25,15 +25,9 @@ class SubjectsController < ApplicationController
# 最热排序
if reorder == "myshixun_count"
if current_laboratory.main_site?
not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{current_laboratory.id}").pluck(:id)
not_subject_ids = not_subject_ids.length > 0 ? "(" + not_subject_ids.join(",") + ")" : "(-1)"
laboratory_join = " AND subjects.id not in #{not_subject_ids} "
else
subject_ids = Subject.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: current_laboratory.id }).pluck(:id)
subject_ids = subject_ids.length > 0 ? "(" + subject_ids.join(",") + ")" : "(-1)"
laboratory_join = " AND subjects.id in #{subject_ids} "
end
subject_ids = current_laboratory.subjects.pluck(:id)
subject_ids = subject_ids.length > 0 ? "(" + subject_ids.join(",") + ")" : "(-1)"
laboratory_join = " AND subjects.id in #{subject_ids} "
if select
@subjects = Subject.find_by_sql("SELECT subjects.id, subjects.user_id, subjects.name, subjects.stages_count, subjects.repertoire_id, subjects.status,
@ -49,6 +43,7 @@ class SubjectsController < ApplicationController
GROUP BY subjects.id ORDER BY myshixun_member_count DESC")
end
else
@subjects = current_laboratory.subjects
# 我的路径
if reorder == "mine"
tip_exception(401, "..") unless current_user.logged?
@ -57,19 +52,11 @@ class SubjectsController < ApplicationController
(select distinct(shixun_id) from myshixuns where user_id=#{current_user.id})").map(&:subject_id)
manage_subject_id = SubjectMember.where(user_id: current_user.id).pluck(:subject_id)
total_subject_id = (mine_subject_id + manage_subject_id).uniq
@subjects = Subject.where(id: total_subject_id)
@subjects = @subjects.where(id: total_subject_id)
elsif reorder == "publish_time"
@subjects = Subject.unhidden
else
@subjects = Subject.visible.unhidden
end
# 云上实验室过滤
unless current_laboratory.main_site?
@subjects = @subjects.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: current_laboratory.id })
@subjects = @subjects.unhidden
else
not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{current_laboratory.id}")
@subjects = @subjects.where.not(id: not_subject_ids)
@subjects = @subjects.visible.unhidden
end
# 类型
@ -217,7 +204,7 @@ class SubjectsController < ApplicationController
def add_shixun_to_stage
identifier = generate_identifier Shixun, 8
ActiveRecord::Base.transaction do
@shixun = Shixun.create!(name: params[:name], user_id: current_user.id, identifier: identifier)
@shixun = Shixun.create!(name: params[:name], user_id: current_user.id, identifier: identifier, is_jupyter: params[:is_jupyter])
# 添加合作者
@shixun.shixun_members.create!(user_id: current_user.id, role: 1)
# 创建长字段

@ -1,5 +1,6 @@
class Users::AuthenticationAppliesController < Users::BaseAccountController
before_action :private_user_resources!
before_action :check_account, only: [:create]
def create
Users::ApplyAuthenticationService.call(observed_user, create_params)

@ -1,5 +1,6 @@
class Users::ProfessionalAuthAppliesController < Users::BaseAccountController
before_action :private_user_resources!
before_action :check_account, only: [:create]
def create
Users::ApplyProfessionalAuthService.call(observed_user, create_params)

@ -1,14 +1,6 @@
class Users::ShixunsController < Users::BaseController
def index
shixuns = Users::ShixunService.new(observed_user, query_params).call
## 云上实验室过滤
if current_laboratory.main_site?
not_shixun_ids = Shixun.joins(:laboratory_shixuns).where("laboratory_shixuns.laboratory_id != #{current_laboratory.id}")
shixuns = shixuns.where.not(id: not_shixun_ids)
else
shixuns = shixuns.joins(:laboratory_shixuns).where(laboratory_shixuns: { laboratory_id: current_laboratory.id })
end
shixuns = Users::ShixunService.new(observed_user, query_params, current_laboratory).call
@count = shixuns.count
@shixuns = paginate(shixuns.includes(:first_tag_repertoire), special: observed_user.is_teacher?)

@ -2,13 +2,7 @@ class Users::SubjectsController < Users::BaseController
def index
subjects = Users::SubjectService.new(observed_user, query_params).call
## 云上实验室过滤
if current_laboratory.main_site?
not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{current_laboratory.id}")
subjects = subjects.where.not(id: not_subject_ids)
else
subjects = subjects.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: current_laboratory.id })
end
subjects = subjects.where(id: current_laboratory.subjects)
@count = subjects.count
@subjects = paginate(subjects.includes(:user, :repertoire), special: observed_user.is_teacher?)

@ -6,7 +6,9 @@ class Weapps::CodeSessionsController < Weapps::BaseController
logged = false
result = Wechat::Weapp.jscode2session(params[:code])
Rails.logger.info("###########result: #{result}")
Rails.logger.info("###########result: #{result['session_key']}")
Rails.logger.info("###########result: #{result['unionid']}")
# 能根据 code 拿到 unionid
open_user = OpenUsers::Wechat.find_by(uid: result['unionid'])
if open_user.present? && open_user.user

@ -1,11 +1,12 @@
class Weapps::CoursesController < Weapps::BaseController
before_action :require_login
before_action :set_course, :user_course_identity, except: [:create]
before_action :check_account, only: [:create]
before_action :teacher_allowed, only: [:edit, :update]
before_action :teacher_or_admin_allowed, only: [:change_member_roles, :delete_course_teachers]
def create
return render_error("只有老师身份才能创建课堂") unless current_user.is_teacher?
# return render_error("只有老师身份才能创建课堂") unless current_user.is_teacher?
course = Course.new(tea_id: current_user.id)
Weapps::CreateCourseService.call(course, course_params)
render_ok
@ -106,7 +107,7 @@ class Weapps::CoursesController < Weapps::BaseController
# 批量修改角色
def change_member_roles
@course = current_course
tip_exception("请至少选择一个角色") if params[:roles].blank?
tip_exception("请至少选择一个角色") if params[:roles].reject(&:blank?).blank?
tip_exception("不能具有老师、助教两种角色") if params[:roles].include?("PROFESSOR") && params[:roles].include?("ASSISTANT_PROFESSOR")
params[:user_ids].each do |user_id|
@ -149,13 +150,13 @@ class Weapps::CoursesController < Weapps::BaseController
new_student.is_active = 0 if correspond_teacher_exist
new_student.save!
CourseAddStudentCreateWorksJob.perform_later(@course.id, user_id)
CourseAddStudentCreateWorksJob.perform_later(@course.id, [user_id])
# StudentJoinCourseNotifyJob.perform_later(current_user.id, course.id)
elsif !params[:roles].include?("STUDENT") && student_member.present?
# 删除学生身份时激活老师身份
teacher_member.update_attributes!(is_active: 1) if student_member.is_active && teacher_member.present?
student_member.destroy!
CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, user_id)
CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, [user_id])
# CourseDeleteStudentNotifyJob.perform_later(@course.id, [params[:user_id]], current_user.id)
elsif params[:roles].include?("STUDENT") && student_member.present? && !params[:roles].include?("PROFESSOR") && !params[:roles].include?("ASSISTANT_PROFESSOR")
# 学生身份存在且学生没有教师身份时更新is_active

@ -0,0 +1,38 @@
class Weapps::HomeworkCommonsController < Weapps::BaseController
before_action :require_login
before_action :find_homework, :user_course_identity
before_action :teacher_allowed
def update_settings
begin
# 课堂结束后不能再更新
unless @course.is_end
UpdateHomeworkPublishSettingService.call(@homework, publish_params)
render_ok
else
tip_exception("课堂已结束不能再更新")
end
rescue Exception => e
uid_logger(e.backtrace)
tip_exception(e.message)
raise ActiveRecord::Rollback
end
end
private
def teacher_allowed
return render_forbidden unless @user_course_identity < Course::STUDENT
end
def find_homework
@homework = HomeworkCommon.find_by!(id: params[:id])
@course = @homework.course
@homework_detail_manual = @homework.homework_detail_manual
end
def publish_params
params.permit(:unified_setting, :publish_time, :end_time, group_settings: [:publish_time, :end_time, group_id: []])
end
end

@ -3,7 +3,7 @@ class Users::ApplyAuthenticationForm
attr_accessor :name, :show_realname, :id_number, :gender, :upload_image, :attachment_ids
validates :name, presence: true
validates :name, presence: true, length: { minimum: 2, maximum: 10 }, format: { with: CustomRegexp::LASTNAME, message: "2-10位中英文、数字" }
validate :validate_ID_number
validate :validate_attachment_ids

@ -5,8 +5,8 @@ class Users::UpdateAccountForm
attr_accessor :nickname, :name, :show_realname, :gender, :location, :location_city,
:identity, :student_id, :technical_title, :school_id, :department_id
validates :nickname, presence: true, length: { maximum: 20 }
validates :name, presence: true, length: { maximum: 10 }
validates :nickname, presence: true, length: { minimum: 2, maximum: 20 }, format: { with: CustomRegexp::NICKNAME, message: "2-20位中英文、数字及下划线" }
validates :name, presence: true, length: { minimum: 2, maximum: 10 }, format: { with: CustomRegexp::LASTNAME, message: "2-10位中英文、数字" }
validates :gender, presence: true, numericality: { only_integer: true }, inclusion: { in: [0, 1] }
validates :location, presence: true
validates :location_city, presence: true

@ -3,5 +3,5 @@ class Users::UpdatePasswordForm
attr_accessor :password, :old_password
validates :password, presence: true
validates :password, presence: true, length: { minimum: 8, maximum: 16 }, format: { with: CustomRegexp::PASSWORD, message: "8~16位密码支持字母数字和符号" }
end

@ -1,4 +1,7 @@
module CustomRegexp
PHONE = /1\d{10}/
EMAIL = /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
EMAIL = /\A[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/
LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/
NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
end

@ -21,18 +21,27 @@ class Attachment < ApplicationRecord
scope :contains_only_project, -> { where(container_type: 'Project') }
scope :contains_course_and_project, -> { contains_only_course.or(contains_only_project) }
scope :mine, -> (author_id) { where(author_id: author_id) }
scope :simple_columns, -> { select(:id, :filename, :filesize, :created_on, :cloud_url, :author_id, :content_type) }
scope :simple_columns, -> { select(:id, :filename, :filesize, :created_on, :cloud_url, :author_id, :content_type, :container_type, :container_id) }
scope :search_by_container, -> (ids) {where(container_id: ids)}
scope :unified_setting, -> {where("unified_setting = ? ", 1)}
validates_length_of :description, maximum: 100
DCODES = %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)
def diskfile
File.join(File.join(Rails.root, "files"), disk_directory.to_s, disk_filename.to_s)
end
def title
filename
title = filename
if container && container.is_a?(StudentWork) && author_id != User.current.id
course = container&.homework_common&.course
unless User.current.teacher_of_course?(course)
title = "#{Time.now.strftime('%Y%m%d%H%M%S')}_#{DCODES.sample(8).join}" + File.extname(filename)
end
end
title
end
def downloads_count

@ -165,7 +165,7 @@ class Competition < ApplicationRecord
def get_module_name type
case type
when 'home' then '首页'
when 'home' then '赛制介绍'
when 'enroll' then '报名'
when 'inform' then '通知公告'
when 'chart' then '排行榜'

@ -3,6 +3,8 @@ class Hack < ApplicationRecord
# diffcult: 难度 1简单2中等 3困难
# 编程题
validates_length_of :name, maximum: 60
validates :description, presence: { message: "描述不能为空" }
validates :name, presence: { message: "名称不能为空" }
# 测试集
has_many :hack_sets, ->{order("position asc")}, :dependent => :destroy
# 代码
@ -39,4 +41,9 @@ class Hack < ApplicationRecord
hack_sets.first&.input
end
# 管理员
def manager?(user)
user_id == user.id || user.admin_or_business?
end
end

@ -1,6 +1,7 @@
class HackSet < ApplicationRecord
validates :input, presence: { message: "测试集输入不能为空" }
#validates :input, presence: { message: "测试集输入不能为空" }
validates :output, presence: { message: "测试集输出不能为空" }
validates_uniqueness_of :input, scope: [:hack_id, :input], message: "多个测试集的输入不能相同"
# 编程题测试集
belongs_to :hack
end

@ -1,4 +1,7 @@
class HackUserCode < ApplicationRecord
# 用户编程题的信息
belongs_to :hack
belongs_to :hack_user_lastest_code
scope :created_order, ->{ order("created_at desc")}
end

@ -285,6 +285,15 @@ class HomeworkCommon < ApplicationRecord
homework_challenge_settings.find_by(challenge_id: challenge_id)&.score.to_f
end
def create_homework_group_settings
if homework_group_settings.size != course.course_groups.size
course.course_groups.where.not(id: homework_group_settings.pluck(:course_group_id)).each do |group|
homework_group_settings << HomeworkGroupSetting.new(course_group_id: group.id, course_id: course.id,
publish_time: publish_time, end_time: end_time)
end
end
end
def update_homework_work_score
if unified_setting
works = student_works

@ -47,11 +47,31 @@ class Laboratory < ApplicationRecord
end
def shixuns
main_site? ? Shixun.all : Shixun.joins(:laboratory_shixuns).where(laboratory_shixuns: { laboratory_id: id })
if main_site?
not_shixun_ids = Shixun.joins(:laboratory_shixuns).where("laboratory_shixuns.laboratory_id != #{Laboratory.current.id}")
Shixun.where.not(id: not_shixun_ids.pluck(:shixun_id))
elsif sync_shixun
laboratory_shixun_ids = laboratory_shixuns.pluck(:shixun_id)
school_shixun_ids = Shixun.joins("join user_extensions on shixuns.user_id=user_extensions.user_id").where(user_extensions: { school_id: school_id }).pluck(:id)
shixun_ids = laboratory_shixun_ids + school_shixun_ids
Shixun.where(id: shixun_ids.uniq)
else
Shixun.joins(:laboratory_shixuns).where(laboratory_shixuns: { laboratory_id: id })
end
end
def subjects
main_site? ? Subject.all : Subject.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: id })
if main_site?
not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{Laboratory.current.id}")
Subject.where.not(id: not_subject_ids.pluck(:subject_id))
elsif sync_subject
laboratory_subject_ids = laboratory_subjects.pluck(:subject_id)
school_subject_ids = Subject.joins("join user_extensions on subjects.user_id=user_extensions.user_id").where(user_extensions: { school_id: school_id }).pluck(:id)
subject_ids = laboratory_subject_ids + school_subject_ids
Subject.where(id: subject_ids.uniq)
else
Subject.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: id })
end
end
def all_courses

@ -42,6 +42,10 @@ class LaboratorySetting < ApplicationRecord
image_url('_moop_cases_banner')
end
def oj_banner_url
image_url('_oj_banner')
end
def default_navbar
self.class.default_config[:navbar]
end

@ -9,6 +9,7 @@ class Shixun < ApplicationRecord
# webssh 0不开启webssh1开启练习模式; 2开启评测模式
# trainee 实训的难度
# vnc: VCN实训是否用于评测
validates_presence_of :name, message: "实训名称不能为空"
has_many :challenges, -> {order("challenges.position asc")}, dependent: :destroy
has_many :challenge_tags, through: :challenges
has_many :myshixuns, :dependent => :destroy
@ -54,6 +55,8 @@ class Shixun < ApplicationRecord
has_many :laboratory_shixuns, dependent: :destroy
belongs_to :laboratory, optional: true
# Jupyter数据集,附件
has_many :jupyter_data_sets, ->{where(attachtype: 2)}, class_name: 'Attachment', as: :container, dependent: :destroy
scope :search_by_name, ->(keyword) { where("name like ? or description like ? ",
"%#{keyword}%", "%#{keyword}%") }

@ -1,7 +1,7 @@
class ShixunInfo < ApplicationRecord
belongs_to :shixun
validates_uniqueness_of :shixun_id
validates_presence_of :shixun_id
validates_presence_of :shixun_id, :description
after_commit :create_diff_record

@ -2,4 +2,5 @@ class ShixunMirrorRepository < ApplicationRecord
belongs_to :shixun
belongs_to :mirror_repository
validates_uniqueness_of :shixun_id, :scope => :mirror_repository_id
validates_presence_of :shixun_id, :mirror_repository_id
end

@ -1,4 +1,6 @@
class ShixunServiceConfig < ApplicationRecord
belongs_to :shixun
belongs_to :mirror_repository
validates_presence_of :shixun_id, :mirror_repository_id
end

@ -21,7 +21,7 @@ class User < ApplicationRecord
VALID_EMAIL_REGEX = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/i
VALID_PHONE_REGEX = /^1\d{10}$/
# 身份证
VALID_NUMBER_REGEX = /^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
VALID_NUMBER_REGEX = /(^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^([A-Z]\d{6,10}(\(\w{1}\))?)$)/
LOGIN_LENGTH_LIMIT = 30
MAIL_LENGTH_LMIT = 60

@ -0,0 +1,33 @@
class Admins::ShixunModifyRecordQuery < ApplicationQuery
attr_reader :params
def initialize(params)
@params = params
end
def call
if params[:user_name].blank? || params[:date].blank?
records = DiffRecord.none
else
records = DiffRecord.joins(:user).where("concat(users.lastname, users.firstname) like ?", "%#{params[:user_name].strip}%")
if time_range.present?
records = records.where(created_at: time_range)
end
end
records.order("diff_records.created_at desc")
end
private
def time_range
@_time_range ||= begin
case params[:date]
when 'weekly' then 1.weeks.ago..Time.now
when 'monthly' then 1.months.ago..Time.now
when 'quarterly' then 3.months.ago..Time.now
when 'yearly' then 1.years.ago..Time.now
else ''
end
end
end
end

@ -51,6 +51,7 @@ class Admins::ShixunSettingsQuery < ApplicationQuery
all_shixuns = all_shixuns.where(homepage_show: params[:homepage_show]) if params[:homepage_show]
all_shixuns = all_shixuns.where(task_pass: params[:task_pass]) if params[:task_pass]
all_shixuns = all_shixuns.where(code_hidden: params[:code_hidden]) if params[:code_hidden]
all_shixuns = all_shixuns.where(vip: params[:vip]) if params[:vip]
custom_sort(all_shixuns, params[:sort_by], params[:sort_direction])
end

@ -75,13 +75,12 @@ class Admins::CheckShixunMirrorsService < ApplicationService
def bridge_images
@_bridge_images ||= begin
url = EduSetting.get('cloud_bridge')
url = "#{EduSetting.get('cloud_bridge')}/bridge/docker/images"
res = Faraday.get(url)
res_body = JSON.parse(res.body)
res = JSON.parse(res.body)
raise Error, '拉取镜像信息异常' if res && res['code'] != 0
raise Error, '拉取镜像信息异常' if res_body && res_body['code'].to_i != 0
res_body
res
rescue => e
Rails.logger.error("get response failed ! #{e.message}")
raise Error, '实训云平台繁忙繁忙等级84'

@ -43,6 +43,7 @@ class Admins::SaveLaboratorySettingService < ApplicationService
save_image_file(params[:course_banner], '_course_banner')
save_image_file(params[:competition_banner], '_competition_banner')
save_image_file(params[:moop_cases_banner], '_moop_cases_banner')
save_image_file(params[:oj_banner], '_oj_banner')
end
def save_image_file(file, type)

@ -3,6 +3,12 @@ class ApplicationService
Error = Class.new(StandardError)
def regix_emoji content
" " if content.blank?
regex = /[^a-zA-Z0-9\u4E00-\u9FFF]/
content.gsub(regex, '')
end
private
def strip(str)

@ -25,21 +25,23 @@ class CreateDiffRecordService < ApplicationService
index = 0
fragment_size = 1
Diffy::Diff.new(before, after).each do |line|
unless line =~ /^[\+-]/
if arr.empty? && index < fragment_size
content += line
index += 1
else
index = 0
arr << line
arr.shift if arr.size > fragment_size
unless line.include?("\\ 文件尾没有 newline 字符")
unless line =~ /^[\+-]/
if arr.empty? && index < fragment_size
content += line
index += 1
else
index = 0
arr << line
arr.shift if arr.size > fragment_size
end
next
end
next
end
content += arr.join('') if arr.present?
content += line
arr.clear
content += arr.join('') if arr.present?
content += line
arr.clear
end
end
content
end

@ -17,7 +17,8 @@ class Oauth::CreateOrFindQqAccountService < ApplicationService
new_user = true
# 新用户
login = User.generate_login('Q')
@user = User.new(login: login, nickname: params.dig('info', 'nickname').force_encoding('UTF-8'), type: 'User', status: User::STATUS_ACTIVE)
#nickname = regix_emoji params.dig('info', 'nickname')
@user = User.new(login: login, type: 'User', status: User::STATUS_ACTIVE)
end
ActiveRecord::Base.transaction do
@ -31,7 +32,7 @@ class Oauth::CreateOrFindQqAccountService < ApplicationService
Util.download_file(params.dig('info', 'image'), avatar_path)
end
new_open_user = OpenUsers::QQ.create!(user: user, uid: params['uid'], extra: params.dig('extra', 'raw_info'))
new_open_user = OpenUsers::QQ.create!(user: user, uid: params['uid'])
Rails.cache.write(new_open_user.can_bind_cache_key, 1, expires_in: 1.hours) if new_user # 方便后面进行账号绑定
end

@ -24,15 +24,10 @@ class Oauth::CreateOrFindWechatAccountService < ApplicationService
new_user = true
# 新用户
login = User.generate_login('w')
cd = CharDet.detect(result['nickname'])
Rails.logger.info "encoding: #{cd['encoding']} confidence: #{cd['confidence']}"
decode_content =
if cd["encoding"] == 'GB18030' && cd['confidence'] > 0.8
result['nickname'].encode('UTF-8', 'GBK', {:invalid => :replace, :undef => :replace, :replace => ' '})
else
result['nickname'].force_encoding('UTF-8')
end
@user = User.new(login: login, nickname: decode_content, type: 'User', status: User::STATUS_ACTIVE)
# result['nickname'] = regix_emoji(result['nickname'])
@user = User.new(login: login, type: 'User', status: User::STATUS_ACTIVE)
#@user = User.new(login: login, nickname: result['nickname'], type: 'User', status: User::STATUS_ACTIVE)
end
ActiveRecord::Base.transaction do
@ -47,7 +42,7 @@ class Oauth::CreateOrFindWechatAccountService < ApplicationService
Util.download_file(result['headimgurl'], avatar_path)
end
new_open_user= OpenUsers::Wechat.create!(user: user, uid: result['unionid'], extra: result)
new_open_user= OpenUsers::Wechat.create!(user: user, uid: result['unionid'])
Rails.cache.write(new_open_user.can_bind_cache_key, 1, expires_in: 1.hours) if new_user # 方便后面进行账号绑定
end

@ -40,23 +40,11 @@ class SearchService < ApplicationService
def extra_options
case params[:type].to_s.strip
when 'shixun' then
if Laboratory.current.main_site?
not_shixun_ids = Shixun.joins(:laboratory_shixuns).where("laboratory_shixuns.laboratory_id != #{Laboratory.current.id}")
shixun_ids = Shixun.where.not(id: not_shixun_ids).pluck(:id)
else
shixun_ids = Laboratory.current.shixuns.pluck(:id)
end
{ where: { id: shixun_ids } }
{ where: { id: Laboratory.current.shixuns.pluck(:id) } }
when 'subject' then
if Laboratory.current.main_site?
not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{Laboratory.current.id}")
subject_ids = Subject.where.not(id: not_subject_ids).pluck(:id)
else
subject_ids = Laboratory.current.subjects.pluck(:id)
end
{ where: { id: subject_ids } }
{ where: { id: Laboratory.current.subjects.pluck(:id) } }
when 'course' then
{ where: { laboratory_id: Laboratory.current.id } }
{ where: { id: Laboratory.current.all_courses.pluck(:id) } }
else
{}
end

@ -14,16 +14,18 @@ class ShixunSearchService < ApplicationService
# 状态:已发布/未发布
status = params[:status] || "all"
@shixuns = laboratory.shixuns.none_closed
# 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭)
if type == "mine"
@shixuns = User.current.shixuns.none_closed
@shixuns = @shixuns.where(id: User.current.shixuns)
else
if User.current.admin? || User.current.business?
@shixuns = Shixun.none_closed.where(hidden: 0)
if User.current.admin? || User.current.business? || !User.current.school_id
@shixuns = @shixuns.where(hidden: 0)
else
none_shixun_ids = ShixunSchool.where("school_id != #{User.current.school_id}").pluck(:shixun_id)
@shixuns = Shixun.where.not(id: none_shixun_ids).none_closed.where(hidden: 0)
@shixuns = @shixuns.where.not(id: none_shixun_ids).where(hidden: 0)
end
end
@ -36,17 +38,6 @@ class ShixunSearchService < ApplicationService
@shixuns = @shixuns.where(trainee: params[:diff])
end
## 云上实验室过滤
if laboratory.main_site?
not_shixun_ids = Shixun.joins(:laboratory_shixuns).where("laboratory_shixuns.laboratory_id != #{laboratory.id}")
@shixuns = @shixuns.where.not(id: not_shixun_ids)
else
@shixuns = @shixuns.joins(:laboratory_shixuns).where(laboratory_shixuns: { laboratory_id: laboratory.id })
end
# laboratory = Laboratory.find_by_subdomain(subdomain)
# @shixuns = @shixuns.where(id: laboratory.shixuns) if laboratory
Shixun.search(keyword, search_options)
end

@ -0,0 +1,104 @@
class CreateShixunService < ApplicationService
attr_reader :user, :params, :permit_params
def initialize(user, permit_params, params)
@user = user
@params = params
@permit_params = permit_params
end
def call
shixun = Shixun.new(permit_params)
identifier = Util::UUID.generate_identifier(Shixun, 8)
shixun.identifier= identifier
shixun.user_id = user.id
main_mirror = MirrorRepository.find params[:main_type]
sub_mirrors = MirrorRepository.where(id: params[:sub_type])
ActiveRecord::Base.transaction do
shixun.save!
# 获取脚本内容
shixun_script = get_shixun_script(shixun, main_mirror, sub_mirrors)
# 创建额外信息
ShixunInfo.create!(shixun_id: shixun.id, evaluate_script: shixun_script, description: params[:description])
# 创建合作者
shixun.shixun_members.create!(user_id: user.id, role: 1)
# 创建镜像
ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => main_mirror.id)
# 创建主服务配置
ShixunServiceConfig.create!(:shixun_id => shixun.id, :mirror_repository_id => main_mirror.id)
# 创建子镜像相关数据(实训镜像关联表,子镜像服务配置)
sub_mirrors.each do |sub|
ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id)
# 实训子镜像服务配置
name = sub.name #查看镜像是否有名称,如果没有名称就不用服务配置
ShixunServiceConfig.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id) if name.present?
end
# 创建版本库
repo_path = repo_namespace(user.login, shixun.identifier)
GitService.add_repository(repo_path: repo_path)
shixun.update_column(:repo_name, repo_path.split(".")[0])
# 如果是云上实验室,创建相关记录
if !Laboratory.current.main_site?
Laboratory.current.laboratory_shixuns.create!(shixun: shixun, ownership: true)
end
return shixun
end
end
private
def get_shixun_script shixun, main_mirror, sub_mirrors
if !shixun.is_jupyter?
mirror = main_mirror.mirror_scripts
if main_mirror.blank?
modify_shixun_script shixun, mirror.first&.(:script)
else
sub_name = sub_mirrors.pluck(:type_name)
if main_mirror.type_name == "Java" && sub_name.include?("Mysql")
mirror.last.try(:script)
else
shixun_script = mirror.first&.script
modify_shixun_script shixun, shixun_script
end
end
end
end
def modify_shixun_script shixun, script
if script.present?
source_class_name = []
challenge_program_name = []
shixun.challenges.map(&:exec_path).each do |exec_path|
challenge_program_name << "\"#{exec_path}\""
if shixun.main_mirror_name == "Java"
if exec_path.nil? || exec_path.split("src/")[1].nil?
source = "\"\""
else
source = "\"#{exec_path.split("src/")[1].split(".java")[0]}\""
end
logger.info("----source: #{source}")
source_class_name << source.gsub("/", ".") if source.present?
elsif shixun.main_mirror_name.try(:first) == "C#"
if exec_path.nil? || exec_path.split(".")[1].nil?
source = "\"\""
else
source = "\"#{exec_path.split(".")[0]}.exe\""
end
source_class_name << source if source.present?
end
end
script = if script.include?("sourceClassName") && script.include?("challengeProgramName")
script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{source_class_name.reject(&:blank?).join(" ")}\)")
else
script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)")
end
end
return script
end
# 版本库目录空间
def repo_namespace(user, shixun_identifier)
"#{user}/#{shixun_identifier}.git"
end
end

@ -12,21 +12,12 @@ class SubjectSearchService < ApplicationService
# 全部实训/我的实训
type = params[:type] || "all"
if type == "mine"
@subjects = User.current.subjects.visible.unhidden
else
@subjects = Subject.visible.unhidden
end
@subjects = laboratory.subjects
# laboratory = Laboratory.find_by_subdomain(subdomain)
# @subjects = @subjects.where(id: laboratory.subjects) if laboratory
## 云上实验室过滤
if laboratory.main_site?
not_subject_ids = Subject.joins(:laboratory_subjects).where("laboratory_subjects.laboratory_id != #{laboratory.id}")
@subjects = @subjects.where.not(id: not_subject_ids)
if type == "mine"
@subjects = @subjects.where(id: User.current.subjects).visible.unhidden
else
@subjects = @subjects.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: laboratory.id })
@subjects = @subjects.visible.unhidden
end
Subject.search(keyword, search_options)

@ -0,0 +1,116 @@
class UpdateHomeworkPublishSettingService < ApplicationService
attr_reader :homework, :params
def initialize(homework, params)
@params = params
@homework = homework
end
def call
puts params
course = homework.course
# 作业未发布时unified_setting参数不能为空
if homework.publish_time.nil? || homework.publish_time > Time.now
tip_exception("缺少统一设置的参数") if params[:unified_setting].nil?
if params[:unified_setting] || course.course_groups_count == 0
tip_exception("发布时间不能为空") if params[:publish_time].blank?
tip_exception("截止时间不能为空") if params[:end_time].blank?
tip_exception("发布时间不能早于当前时间") if params[:publish_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S")
tip_exception("截止时间不能早于当前时间") if params[:end_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S")
tip_exception("截止时间不能早于发布时间") if params[:publish_time] > params[:end_time]
tip_exception("截止时间不能晚于课堂结束时间(#{course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
course.end_date.present? && params[:end_time] > course.end_date.end_of_day
homework.unified_setting = 1
homework.homework_group_settings.destroy_all
homework.publish_time = params[:publish_time]
# 截止时间为空时取发布时间后一个月
homework.end_time = params[:end_time]
else
tip_exception("分班发布设置不能为空") if params[:group_settings].blank?
# 创建作业的分班设置
homework.create_homework_group_settings
setting_group_ids = []
params[:group_settings].each do |setting|
tip_exception("分班id不能为空") if setting[:group_id].length == 0
tip_exception("发布时间不能为空") if setting[:publish_time].blank?
tip_exception("截止时间不能为空") if setting[:end_time].blank?
tip_exception("发布时间不能早于当前时间") if setting[:publish_time].to_time <= Time.now
tip_exception("截止时间不能早于当前时间") if setting[:end_time].to_time <= Time.now
tip_exception("截止时间不能早于发布时间") if setting[:publish_time].to_time > setting[:end_time].to_time
tip_exception("截止时间不能晚于课堂结束时间(#{course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
course.end_date.present? && setting[:end_time] > course.end_date.end_of_day
publish_time = setting[:publish_time] == "" ? Time.now : setting[:publish_time]
# 截止时间为空时取发布时间后一个月
end_time = setting[:end_time]
HomeworkGroupSetting.where(homework_common_id: homework.id, course_group_id: setting[:group_id]).
update_all(publish_time: publish_time, end_time: end_time)
setting_group_ids << setting[:group_id]
end
# 未设置的分班发布时间和截止时间都为nil
HomeworkGroupSetting.where.not(course_group_id: setting_group_ids).where(homework_common_id: homework.id).
update_all(publish_time: nil, end_time: nil)
# 记录已发布需要发消息的分班
publish_group_ids = HomeworkGroupSetting.where(homework_common_id: homework.id).group_published.pluck(:course_group_id)
homework.unified_setting = 0
homework.publish_time = homework.min_group_publish_time
homework.end_time = homework.max_group_end_time
end
# 如果作业立即发布则更新状态、发消息
if homework.publish_time <= Time.now and homework_detail_manual.comment_status == 0
homework_detail_manual.comment_status = 1
send_tiding = true
end
# 作业在"提交中"状态时
else
if homework.end_time > Time.now && homework.unified_setting
tip_exception("截止时间不能为空") if params[:end_time].blank?
tip_exception("截止时间不能早于当前时间") if params[:end_time].to_time <= Time.now
tip_exception("截止时间不能晚于课堂结束时间(#{course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
course.end_date.present? && params[:end_time].to_time > course.end_date.end_of_day
homework.end_time = params[:end_time]
elsif !homework.unified_setting
homework.create_homework_group_settings
tip_exception("分班发布设置不能为空") if params[:group_settings].reject(&:blank?).blank?
params[:group_settings].each do |setting|
group_settings = HomeworkGroupSetting.where(homework_common_id: homework.id, course_group_id: setting[:group_id])
tip_exception("分班id不能为空") if setting[:group_id].length == 0
tip_exception("发布时间不能为空") if setting[:publish_time].blank?
tip_exception("截止时间不能为空") if setting[:end_time].blank?
# 如果该发布规则 没有已发布的分班则需判断发布时间
tip_exception("发布时间不能早于等于当前时间") if setting[:publish_time].to_time <= Time.now && group_settings.group_published.count == 0
tip_exception("截止时间不能早于等于当前时间") if setting[:end_time].to_time <= Time.now && group_settings.none_end.count > 0
tip_exception("截止时间不能早于发布时间") if setting[:publish_time].to_time > setting[:end_time].to_time
tip_exception("截止时间不能晚于课堂结束时间(#{course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
course.end_date.present? && setting[:end_time].to_time > course.end_date.end_of_day
group_settings.none_published.update_all(publish_time: setting[:publish_time])
group_settings.none_end.update_all(end_time: setting[:end_time])
end
homework.end_time = homework.max_group_end_time
end
end
homework.save!
HomeworkCommonPushNotifyJob.perform_later(homework.id, publish_group_ids) if send_tiding
end
private
def tip_exception(status = -1, message)
raise Educoder::TipException.new(status, message)
end
end

@ -1,12 +1,14 @@
class Users::ShixunService
attr_reader :user, :params
attr_reader :user, :params, :laboratory
def initialize(user, params)
def initialize(user, params, laboratory)
@user = user
@params = params
@laboratory = laboratory
end
def call
shixuns = category_scope_shixuns
shixuns = user_policy_filter(shixuns)
@ -19,12 +21,12 @@ class Users::ShixunService
def category_scope_shixuns
case params[:category]
when 'study' then
user.study_shixuns
user.study_shixuns.where(shixuns: {id: laboratory.shixuns})
when 'manage' then
user.shixuns
laboratory.shixuns.where(id: user.shixuns)
else
ids = user.study_shixuns.pluck(:id) + user.shixuns.pluck(:id)
Shixun.where(id: ids)
laboratory.shixuns.where(id: ids)
end
end

@ -1,56 +1,31 @@
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="4%">ID</th>
<th width="10%" class="text-left">课堂名称</th>
<th width="6%">成员</th>
<th width="5%">成员</th>
<th width="4%">资源</th>
<th width="4%">普通作业</th>
<th width="4%">分组作业</th>
<th width="4%">实训作业</th>
<th width="4%">试卷</th>
<th width="7%">评测次数</th>
<th width="6%">评测次数</th>
<th width="4%">私有</th>
<th width="6%">状态</th>
<th width="10%">单位</th>
<th width="7%">创建者</th>
<th width="10%"><%= sort_tag('创建时间', name: 'created_at', path: admins_courses_path) %></th>
<th width="4%">首页</th>
<th width="6%">邮件通知</th>
<th width="6%">操作</th>
<th width="5%">邮件通知</th>
<th width="5%">操作</th>
</tr>
</thead>
<tbody>
<% if courses.present? %>
<% courses.each do |course| %>
<% courses.each_with_index do |course, index| %>
<tr class="course-item-<%= course.id %>">
<td><%= course.id %></td>
<td class="text-left">
<%= link_to(course.name, "/courses/#{course.id}", target: '_blank') %>
</td>
<td><%= course.course_members_count %></td>
<td><%= get_attachment_count(course, 0) %></td>
<td><%= course.course_homework_count(1) %></td>
<td><%= course.course_homework_count(3) %></td>
<td><%= course.course_homework_count(4) %></td>
<td><%= course.exercises_count %></td>
<td><%= course.evaluate_count %></td>
<td><%= course.is_public == 1 ? "--" : "√" %></td>
<td><%= course.is_end ? "已结束" : "正在进行" %></td>
<td><%= course.school&.name %></td>
<td><%= course.teacher&.real_name %></td>
<td><%= course.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td>
<%= check_box_tag :homepage_show,!course.homepage_show,course.homepage_show,remote:true,data:{id:course.id},class:"course-setting-form" %>
</td>
<td>
<%= check_box_tag :email_notify,!course.email_notify,course.email_notify,remote:true,data:{id:course.id},class:"course-setting-form" %>
</td>
<td class="action-container">
<% if course.is_delete == 0 %>
<%= delete_link '删除', admins_course_path(course, element: ".course-item-#{course.id}"), class: 'delete-course-action' %>
<% end %>
</td>
<%= render partial: 'admins/courses/shared/td', locals: {course: course, no: index} %>
</tr>
<% end %>
<% else %>

@ -0,0 +1,28 @@
<td><%= list_index_no((params[:page] || 1).to_i, no) %></td>
<td><%= course.id %></td>
<td class="text-left">
<%= link_to(course.name, "/courses/#{course.id}", target: '_blank') %>
</td>
<td><%= course.course_members_count %></td>
<td><%= get_attachment_count(course, 0) %></td>
<td><%= course.course_homework_count(1) %></td>
<td><%= course.course_homework_count(3) %></td>
<td><%= course.course_homework_count(4) %></td>
<td><%= course.exercises_count %></td>
<td><%= course.evaluate_count %></td>
<td><%= course.is_public == 1 ? "--" : "√" %></td>
<td><%= course.is_end ? "已结束" : "正在进行" %></td>
<td><%= course.school&.name %></td>
<td><%= course.teacher&.real_name %></td>
<td><%= course.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td>
<%= check_box_tag :homepage_show,!course.homepage_show,course.homepage_show,remote:true,data:{id:course.id},class:"course-setting-form" %>
</td>
<td>
<%= check_box_tag :email_notify,!course.email_notify,course.email_notify,remote:true,data:{id:course.id},class:"course-setting-form" %>
</td>
<td class="action-container">
<% if course.is_delete == 0 %>
<%= delete_link '删除', admins_course_path(course, element: ".course-item-#{course.id}"), class: 'delete-course-action' %>
<% end %>
</td>

@ -0,0 +1,3 @@
var index = $("#course-item-<%= @course.id %>").children(":first").html();
$("#course-item-<%= @course.id %>").html("<%= j render partial: "admins/courses/shared/td",locals: {course: @course, no: 1} %>");
$("#course-item-<%= @course.id %>").children(":first").html(index);

@ -1,15 +1,17 @@
<table class="table table-hover text-center customer-list-table">
<thead class="thead-light">
<tr>
<th width="50%" class="text-left">客户名称</th>
<th width="10%">序号</th>
<th width="40%" class="text-left">客户名称</th>
<th width="30%"><%= sort_tag('添加时间', name: 'created_at', path: admins_partner_customers_path(current_partner)) %></th>
<th width="20%">操作</th>
</tr>
</thead>
<tbody>
<% if customers.present? %>
<% customers.each do |customer| %>
<% customers.each_with_index do |customer, index| %>
<tr class="customer-item-<%= customer.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left"><%= customer.school&.name %></td>
<td><%= customer.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td>

@ -1,8 +1,8 @@
<table class="table table-hover daily-school-statistic-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="12%" class="text-left">单位名称</th>
<th width="10%"><%= sort_tag('教师总数', name: 'teacher_count', path: admins_daily_school_statistics_path) %></th>
<th width="10%"><%= sort_tag('学生总数', name: 'student_count', path: admins_daily_school_statistics_path) %></th>
<th width="10%"><%= sort_tag('课堂总数', name: 'course_count', path: admins_daily_school_statistics_path) %></th>
@ -16,13 +16,14 @@
</th>
<th width="11%"><%= sort_tag('实训作业总数', name: 'homework_count', path: admins_daily_school_statistics_path) %></th>
<th width="11%"><%= sort_tag('其它作业总数', name: 'other_homework_count', path: admins_daily_school_statistics_path) %></th>
<th width="13%"><%= sort_tag('动态时间', name: 'nearly_course_time', path: admins_daily_school_statistics_path) %></th>
<th width="9%"><%= sort_tag('动态时间', name: 'nearly_course_time', path: admins_daily_school_statistics_path) %></th>
</tr>
</thead>
<tbody>
<% if statistics.present? %>
<% statistics.each do |statistic| %>
<% statistics.each_with_index do |statistic, index| %>
<tr>
<td><%= list_index_no(@params_page.to_i, index) %></td>
<td class="text-left">
<%= link_to statistic[:name], "/colleges/#{statistic[:id]}/statistics",
target: '_blank', data: { toggle: 'tooltip', title: '点击查看学校统计概况' } %>

@ -1,18 +1,20 @@
<table class="table table-hover text-center department_applies-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="8%">ID</th>
<th width="22%" class="text-left">部门名称</th>
<th width="20%" class="text-left">单位名称</th>
<th width="15%">创建者</th>
<th width="11%">创建者</th>
<th width="15%"><%= sort_tag('创建于', name: 'created_at', path: admins_department_applies_path) %></th>
<th width="20%">操作</th>
</tr>
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% applies.each_with_index do |apply, index| %>
<tr class="department-apply-<%= apply.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td><%= apply.id %></td>
<td class="text-left"> <%= apply.name %></td>
<td class="text-left"> <%= apply.school.try(:name) %></td>

@ -1,4 +1,6 @@
$('.modal.admin-add-department-member-modal').modal('hide');
$.notify({ message: '操作成功' });
$('.department-list-table .department-item-<%= current_department.id %>').html("<%= j(render partial: 'admins/departments/shared/department_item', locals: { department: current_department }) %>")
var index = $(".department-item-<%= current_department.id %>").children(":first").html();
$('.department-list-table .department-item-<%= current_department.id %>').html("<%= j(render partial: 'admins/departments/shared/department_item', locals: { department: current_department, index: 1 }) %>");
$(".department-item-<%= current_department.id %>").children(":first").html(index);

@ -1,3 +1,4 @@
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<% not_list = defined?(:users_count) %>
<td class="text-left"><%= overflow_hidden_span department.name, width: 150 %></td>

@ -1,10 +1,11 @@
<table class="table table-hover text-center department-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="14%" class="text-left">部门名称</th>
<th width="14%" class="text-left">单位名称</th>
<th width="6%">用户数</th>
<th width="10%">已职业认证</th>
<th width="6%">已职业认证</th>
<th width="20%">部门管理员</th>
<th width="8%">统计链接</th>
<th width="8%">云主机数</th>
@ -14,9 +15,9 @@
</thead>
<tbody>
<% if departments.present? %>
<% departments.each do |department| %>
<% departments.each_with_index do |department, index| %>
<tr class="department-item-<%= department.id %>">
<%= render 'admins/departments/shared/department_item', department: department %>
<%= render partial: 'admins/departments/shared/department_item', locals: {department: department, index: index} %>
</tr>
<% end %>
<% else %>

@ -1,4 +1,6 @@
$('.modal.admin-edit-department-modal').modal('hide');
$.notify({ message: '操作成功' });
$('.department-list-table .department-item-<%= current_department.id %>').html("<%= j(render partial: 'admins/departments/shared/department_item', locals: { department: current_department }) %>")
var index = $(".department-item-<%= current_department.id %>").children(":first").html();
$('.department-list-table .department-item-<%= current_department.id %>').html("<%= j(render partial: 'admins/departments/shared/department_item', locals: {department: current_department, index: 1}) %>");
$(".department-item-<%= current_department.id %>").children(":first").html(index);

@ -3,6 +3,7 @@
<table class="table table-hover text-center identity-authentication-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<% unless is_processed %>
<th width="4%">
<%= check_box_tag('all-check', 1, false, id: nil, class: 'batch-all-check-box',
@ -13,7 +14,7 @@
<th width="10%">姓名</th>
<th width="14%">身份证号</th>
<th width="20%">学校/单位</th>
<th width="12%">职称</th>
<th width="8%">职称</th>
<% unless is_processed %>
<th width="8%">
照片
@ -33,9 +34,10 @@
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% applies.each_with_index do |apply, index| %>
<% user = apply.user %>
<tr class="identity-authentication-item identity-authentication-<%= apply.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<% unless is_processed %>
<td><%= check_box_tag('ids[]', apply.id, false, id: nil, class: 'batch-check-box') %></td>
<% end %>

@ -1,4 +1,5 @@
<% school = laboratory.school %>
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left"><%= school&.name || 'EduCoder主站' %></td>
<td class="text-left">
<% if laboratory.identifier %>
@ -31,7 +32,17 @@
<td><%= laboratory.created_at.strftime('%Y-%m-%d %H:%M') %></td>
<td>
<% if school.present? && laboratory.id != 1 %>
<%= check_box_tag :sync_course,!laboratory.sync_course,laboratory.sync_course,remote:true,data:{id:laboratory.id},class:"laboratory-sync-course" %>
<%= check_box_tag :sync_course,!laboratory.sync_course,laboratory.sync_course,remote:true,data:{id:laboratory.id},class:"laboratory-sync-form" %>
<% end %>
</td>
<td>
<% if school.present? && laboratory.id != 1 %>
<%= check_box_tag :sync_subject,!laboratory.sync_subject,laboratory.sync_subject,remote:true,data:{id:laboratory.id},class:"laboratory-sync-form" %>
<% end %>
</td>
<td>
<% if school.present? && laboratory.id != 1 %>
<%= check_box_tag :sync_shixun,!laboratory.sync_shixun,laboratory.sync_shixun,remote:true,data:{id:laboratory.id},class:"laboratory-sync-form" %>
<% end %>
</td>
<td class="action-container">

@ -1,20 +1,23 @@
<table class="table table-hover text-center laboratory-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="14%" class="text-left">单位名称</th>
<th width="16%" class="text-left">域名</th>
<th width="10%">统计链接</th>
<th width="6%">统计链接</th>
<th width="22%">管理员</th>
<th width="14%"><%= sort_tag('创建时间', name: 'id', path: admins_laboratories_path) %></th>
<th width="6%" title="同步显示显示主站下该单位的课堂">同步课堂</th>
<th width="20%">操作</th>
<th width="10%"><%= sort_tag('创建时间', name: 'id', path: admins_laboratories_path) %></th>
<th width="4%" title="同步显示主站下该单位的课堂">同步课堂</th>
<th width="4%" title="同步显示主站下该单位用户创建的实践课程">同步实践课程</th>
<th width="4%" title="同步显示主站下该单位用户创建的实训">同步实训</th>
<th width="16%">操作</th>
</tr>
</thead>
<tbody>
<% if laboratories.present? %>
<% laboratories.each do |laboratory| %>
<% laboratories.each_with_index do |laboratory, index| %>
<tr class="laboratory-item laboratory-item-<%= laboratory.id %>">
<%= render 'admins/laboratories/shared/laboratory_item', laboratory: laboratory %>
<%= render partial: 'admins/laboratories/shared/laboratory_item', locals: {laboratory: laboratory, index: index} %>
</tr>
<% end %>
<% else %>

@ -0,0 +1,3 @@
var index = $(".laboratory-item-<%= @laboratory.id %>").children(":first").html();
$(".laboratory-item-<%= @laboratory.id %>").html("<%= j render partial: "admins/laboratories/shared/laboratory_item",locals: {laboratory: @laboratory, index: 1} %>");
$(".laboratory-item-<%= @laboratory.id %>").children(":first").html(index);

@ -1 +1,3 @@
$("#laboratory-item-<%= @laboratory.id %>").html("<%= j render partial: 'admins/laboratories/shared/laboratory_item', locals: {laboratory: @laboratory} %>")
var index = $(".laboratory-item-<%= @laboratory.id %>").children(":first").html();
$("#laboratory-item-<%= @laboratory.id %>").html("<%= j render partial: 'admins/laboratories/shared/laboratory_item', locals: {laboratory: @laboratory, index: 1} %>");
$(".laboratory-item-<%= @laboratory.id %>").children(":first").html(index);

@ -129,6 +129,16 @@
<label for="moop_cases_banner" class="banner-item-upload" data-toggle="tooltip" data-title="选择图片"></label>
</div>
</div>
<div class="col-12 col-md-4 banner-item">
<%- oj_banner = setting.oj_banner_url -%>
<div class="banner-item-top">开发者社区</div>
<div class="banner-item-bottom <%= oj_banner ? 'has-img' : '' %>">
<img class="banner-item-img oj-banner-img" src="<%= oj_banner %>" style="<%= oj_banner.present? ? '' : 'display: none' %>"/>
<%= file_field_tag(:oj_banner, accept: 'image/*', style: 'display: none', value: params[:oj_banner]) %>
<label for="oj_banner" class="banner-item-upload" data-toggle="tooltip" data-title="选择图片"></label>
</div>
</div>
</div>
</div>

@ -1,21 +1,22 @@
<table class="table text-center laboratory-shixun-list-table">
<thead class="thead-light">
<tr>
<th width="28%" class="text-left">实训名称</th>
<th width="4%">序号</th>
<th width="26%" class="text-left">实训名称</th>
<th width="12%">技术平台</th>
<th width="14%" class="text-left">技术体系</th>
<th width="10%">封面</th>
<th width="8%">创建者</th>
<th width="8%">状态</th>
<th width="6%">状态</th>
<th width="8%">执行时间</th>
<th width="16%">操作</th>
</tr>
</thead>
<tbody>
<% if laboratory_shixuns.present? %>
<% laboratory_shixuns.each do |laboratory_shixun| %>
<% laboratory_shixuns.each_with_index do |laboratory_shixun, index| %>
<tr class="laboratory-shixun-item-<%= laboratory_shixun.id %>">
<%= render partial: 'admins/laboratory_shixuns/shared/td', locals: { laboratory_shixun: laboratory_shixun } %>
<%= render partial: 'admins/laboratory_shixuns/shared/td', locals: { laboratory_shixun: laboratory_shixun, index: index } %>
</tr>
<% end %>
<% else %>

@ -1,5 +1,6 @@
<%- shixun = laboratory_shixun.shixun -%>
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left">
<%= link_to "/shixuns/#{shixun.identifier}", target: '_blank' do %>
<%= shixun.name %>

@ -1,7 +1,8 @@
<table class="table text-center laboratory-subject-list-table">
<thead class="thead-light">
<tr>
<th width="28%" class="text-left">课程名称</th>
<th width="4%">序号</th>
<th width="24%" class="text-left">课程名称</th>
<th width="12%">技术体系</th>
<th width="10%">等级体系</th>
<th width="10%">封面</th>
@ -13,10 +14,11 @@
</thead>
<tbody>
<% if laboratory_subjects.present? %>
<% laboratory_subjects.each do |laboratory_subject| %>
<% laboratory_subjects.each_with_index do |laboratory_subject, index| %>
<tr class="laboratory-subject-item-<%= laboratory_subject.id %>">
<%- subject = laboratory_subject.subject -%>
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left">
<%= link_to(subject.name, "/paths/#{subject.id}", target: '_blank') %>
<span class="badge badge-pill badge-success homepage-badge" style="<%= laboratory_subject.homepage? ? '' : 'display:none' %>">首页</span>

@ -1,4 +1,6 @@
$('.modal.admin-add-laboratory-user-modal').modal('hide');
$.notify({ message: '操作成功' });
$('.laboratory-list-table .laboratory-item-<%= current_laboratory.id %>').html("<%= j(render partial: 'admins/laboratories/shared/laboratory_item', locals: { laboratory: current_laboratory }) %>")
var index = $(".laboratory-item-<%= current_laboratory.id %>").children(":first").html();
$('.laboratory-list-table .laboratory-item-<%= current_laboratory.id %>').html("<%= j(render partial: 'admins/laboratories/shared/laboratory_item', locals: {laboratory: current_laboratory, index: 1}) %>");
$(".laboratory-item-<%= current_laboratory.id %>").children(":first").html(index);

@ -3,11 +3,12 @@
<table class="table table-hover text-center library_applies-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="8%">头像</th>
<th width="14%">姓名</th>
<th width="26%" class="text-left">教学案例</th>
<th width="26%" class="text-left">案例描述</th>
<th width="16%">时间</th>
<th width="12%">时间</th>
<% if is_processed %>
<th width="16%">拒绝原因</th>
<th width="8%">状态</th>
@ -18,10 +19,11 @@
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% applies.each_with_index do |apply, index| %>
<% user = apply.library.user %>
<% library = apply.library %>
<tr class="library_applies-item library_applies-<%= apply.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td>
<%= link_to "/users/#{user.login}", class: 'professional-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />

@ -1,9 +1,10 @@
<table class="table table-hover text-center myshixun-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="6%">ID</th>
<th width="10%">标识</th>
<th width="22%" class="text-left">实训名称</th>
<th width="18%" class="text-left">实训名称</th>
<th width="10%">实训老师</th>
<th width="6%">完成</th>
<th width="6%">经验值</th>
@ -14,8 +15,9 @@
</thead>
<tbody>
<% if myshixuns.present? %>
<% myshixuns.each do |myshixun| %>
<% myshixuns.each_with_index do |myshixun, index| %>
<tr class="myshixun-item-<%= myshixun.id %>">
<td><%= list_index_no(@params_page.to_i, index) %></td>
<td><%= myshixun.id %></td>
<td><%= myshixun.identifier %></td>
<td class="text-left">

@ -1,15 +1,17 @@
<table class="table table-hover text-center partner-list-table">
<thead class="thead-light">
<tr>
<th width="50%" class="text-left">名称</th>
<th width="10%">序号</th>
<th width="40%" class="text-left">名称</th>
<th width="30%"><%= sort_tag('添加时间', name: 'created_at', path: admins_partners_path) %></th>
<th width="20%">操作</th>
</tr>
</thead>
<tbody>
<% if partners.present? %>
<% partners.each do |partner| %>
<% partners.each_with_index do |partner, index| %>
<tr class="partner-item-<%= partner.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left">
<%= link_to partner.school&.name || partner.name, customers_partner_path(partner), target: '_blank' %>
</td>

@ -3,6 +3,7 @@
<table class="table table-hover text-center professional-authentication-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<% unless is_processed %>
<th width="4%">
<%= check_box_tag('all-check', 1, false, id: nil, class: 'batch-all-check-box',
@ -12,7 +13,7 @@
<th width="8%">头像</th>
<th width="14%">姓名</th>
<th width="20%">学校/单位</th>
<th width="12%">职称</th>
<th width="8%">职称</th>
<% unless is_processed %>
<th width="14%">
照片
@ -31,9 +32,10 @@
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% applies.each_with_index do |apply, index| %>
<% user = apply.user %>
<tr class="professional-authentication-item professional-authentication-<%= apply.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<% unless is_processed %>
<td><%= check_box_tag('ids[]', apply.id, false, id: nil, class: 'batch-check-box') %></td>
<% end %>

@ -3,11 +3,12 @@
<table class="table table-hover text-center library_applies-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="8%">头像</th>
<th width="14%">姓名</th>
<th width="26%" class="text-left">众包需求</th>
<th width="26%" class="text-left">需求描述</th>
<th width="16%">时间</th>
<th width="12%">时间</th>
<% if is_processed %>
<th width="16%">拒绝原因</th>
<th width="8%">状态</th>
@ -18,10 +19,11 @@
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% applies.each_with_index do |apply, index| %>
<% package = apply.project_package %>
<% user = package.creator %>
<tr class="project-package-item project-package-applies-<%= apply.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td>
<%= link_to "/users/#{user.login}", class: 'professional-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />

@ -1,6 +1,7 @@
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="4%">ID</th>
<th width="15%" class="text-left">项目名称</th>
<th width="6%">公开</th>
@ -11,14 +12,15 @@
<th width="6%">里程碑</th>
<th width="10%">成员</th>
<th width="10%">管理员</th>
<th width="15%"><%= sort_tag('创建时间', name: 'created_at', path: admins_projects_path) %></th>
<th width="11%"><%= sort_tag('创建时间', name: 'created_at', path: admins_projects_path) %></th>
<th width="10%">操作</th>
</tr>
</thead>
<tbody>
<% if projects.present? %>
<% projects.each do |project| %>
<% projects.each_with_index do |project, index| %>
<tr class="project-item-<%= project.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td><%= project.id %></td>
<td class="text-left">
<%= link_to(project.name, "/projects/#{project.id}", target: '_blank') %>

@ -20,7 +20,8 @@
<table class="table table-hover text-center daily-school-statistic-list-table">
<thead class="thead-light">
<tr>
<th width="24%" class="text-left">单位名称</th>
<th width="4%">序号</th>
<th width="20%" class="text-left">单位名称</th>
<th width="12%"><%= sort_tag('新增教师', name: 'teacher_increase_count', path: admins_school_statistics_path) %></th>
<th width="12%"><%= sort_tag('新增学生', name: 'student_increase_count', path: admins_school_statistics_path) %></th>
<th width="12%"><%= sort_tag('新增课堂', name: 'course_increase_count', path: admins_school_statistics_path) %></th>
@ -32,8 +33,9 @@
</thead>
<tbody>
<% if statistics.present? %>
<% statistics.each do |statistic| %>
<% statistics.each_with_index do |statistic, index| %>
<tr>
<td><%= list_index_no(@params_page.to_i, index) %></td>
<td class="text-left">
<%= link_to statistic.school_name, "/colleges/#{statistic.school_id}/statistics",
target: '_blank', data: { toggle: 'tooltip', title: '点击查看学校统计概况' } %>

@ -4,7 +4,7 @@
<div class="box search-form-container school-list-form">
<%= form_tag(admins_schools_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '部门名称检索') %>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '单位名称检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %>

@ -1,6 +1,7 @@
<table class="table table-hover text-center school-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="6%">ID</th>
<th width="6%">LOGO</th>
<th width="8%">标识码</th>
@ -11,13 +12,14 @@
<th width="6%"><%= sort_tag('用户数', name: 'users_count', path: admins_schools_path) %></th>
<th width="6%">部门数</th>
<th width="12%"><%= sort_tag('创建时间', name: 'created_at', path: admins_schools_path) %></th>
<th width="14%">操作</th>
<th width="10%">操作</th>
</tr>
</thead>
<tbody>
<% if schools.present? %>
<% schools.each do |school| %>
<% schools.each_with_index do |school, index| %>
<tr class="school-item-<%= school.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td><%= school.id %></td>
<td>
<% if Util::FileManage.exists?(school) %>

@ -27,8 +27,9 @@
<li><%= sidebar_item(admins_shixun_settings_path, '实训配置', icon: 'cog', controller: 'admins-shixun_settings') %></li>
<li><%= sidebar_item(admins_mirror_repositories_path, '镜像管理', icon: 'cubes', controller: 'admins-mirror_repositories') %></li>
<li><%= sidebar_item(admins_myshixuns_path, '学员实训列表', icon: 'server', controller: 'admins-myshixuns') %></li>
<li><%= sidebar_item(admins_shixun_recycles_path, '实训回收站', icon: 'recycle', controller: 'admins-myshixuns') %></li>
<% end %>
<li><%= sidebar_item(admins_shixun_modify_records_path, '实训修改记录', icon: 'eraser', controller: 'admins-shixun_modify_records') %></li>
<li><%= sidebar_item(admins_shixun_recycles_path, '实训回收站', icon: 'recycle', controller: 'admins-shixun_recycles') %></li>
<% end %>
</li>
<li>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save