Merge branch 'dev_aliyun' into dev_cxt

chromesetting
cxt 5 years ago
commit 93e8fa2bde

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

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

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

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

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

@ -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,7 +1,7 @@
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_teacher_identity, only: [:create, :update_set, :edit, :update]
before_action :require_auth_identity, only: [:update, :edit, :publish, :update_set, :delete_set]
@ -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,8 @@ class HacksController < ApplicationController
def edit;end
def new;end
private
# 实名认证老师,管理员与运营人员权限
def require_teacher_identity
@ -199,7 +202,7 @@ class HacksController < ApplicationController
end
def start_hack_auth
return true if @hack == 1
return true if @hack.status == 1
require_auth_identity
end

@ -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?
@ -635,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)
@ -826,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)
@ -1101,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]
@ -1137,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]
@ -1211,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
@ -1582,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
@ -1653,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

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

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

@ -6,7 +6,7 @@ class Weapps::CoursesController < Weapps::BaseController
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
@ -107,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|
@ -150,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,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

@ -3,4 +3,5 @@ module CustomRegexp
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,7 +21,7 @@ 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)}
@ -35,7 +35,7 @@ class Attachment < ApplicationRecord
def title
title = filename
if container.is_a?(StudentWork) && author_id != User.current.id
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)

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

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

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

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

@ -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,30 +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 %>">
<%= render 'admins/courses/shared/td', course: course %>
<%= render partial: 'admins/courses/shared/td', locals: {course: course, no: index} %>
</tr>
<% end %>
<% else %>

@ -1,3 +1,4 @@
<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') %>

@ -1 +1,3 @@
$("#course-item-<%= @course.id %>").html("<%= j render partial: "admins/courses/shared/td",locals: {course: @course} %>")
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 %>

@ -1,6 +1,7 @@
<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="6%">统计链接</th>
@ -9,14 +10,14 @@
<th width="4%" title="同步显示主站下该单位的课堂">同步课堂</th>
<th width="4%" title="同步显示主站下该单位用户创建的实践课程">同步实践课程</th>
<th width="4%" title="同步显示主站下该单位用户创建的实训">同步实训</th>
<th width="20%">操作</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 %>

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

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

@ -3,11 +3,12 @@
<table class="table table-hover text-center shixun-authorization-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="8%">头像</th>
<th width="8%">创建者</th>
<th width="28%" class="text-left">实训名称</th>
<th width="8%">审核情况</th>
<th width="12%">任务数</th>
<th width="8%">任务数</th>
<th width="16%">时间</th>
<% if is_processed %>
<th width="12%">拒绝原因</th>
@ -19,12 +20,13 @@
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% applies.each_with_index do |apply, index| %>
<% user = apply.user %>
<% shixun = shixun_map[apply.container_id] %>
<% content_review = shixun.shixun_reviews.select{|sr| sr.review_type == 'Content'}.first %>
<% perference_review = shixun.shixun_reviews.select{|sr| sr.review_type == 'Performance'}.first %>
<tr class="shixun-authorization-item shixun-authorization-<%= apply.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td>
<%= link_to "/users/#{user.login}", class: 'shixun-authorization-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />

@ -15,7 +15,7 @@
<td><%= (@params_page.to_i - 1) * 20 + index + 1 %></td>
<% identifier = Game.find_by(challenge_id: discuss.challenge_id, user_id: discuss.user_id)&.identifier %>
<td class="text-left"><%= link_to discuss.dis.name, "/tasks/#{identifier}", target: '_blank'%></td>
<td class="text-left"><%= content_safe discuss.content %></td>
<td class="text-left content-img"><%= content_safe discuss.content %></td>
<td><%= discuss.user.show_real_name %></td>
<td><%= format_time discuss.created_at %></td>
</tr>

@ -0,0 +1,25 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('实训修改记录') %>
<% end %>
<div class="box search-form-container shixun-modify-record-list-form">
<%= form_tag(admins_shixun_modify_records_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<div class="form-group col-12 col-md-4">
<label for="user_name">用户名:</label>
<%= text_field_tag :user_name, params[:user_name], class: 'form-control flex-1', placeholder: '真实姓名搜索' %>
</div>
<div class="form-group col-12 col-md-auto">
<label for="status">时间范围:</label>
<% data_arrs = [['最近一周', 'weekly'], ['最近一个月', 'monthly']] %>
<%= select_tag(:date, options_for_select(data_arrs, params[:date]), class: 'form-control') %>
</div>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
</div>
<div class="box admin-list-container shixun-modify-record-list-container">
<%= render partial: 'admins/shixun_modify_records/shared/list', locals: { records: @records } %>
</div>

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

@ -0,0 +1,36 @@
<% if records.present? %>
<% records.each do |record| %>
<div class="card mb-5">
<div class="card-header font-16">
<span><%= record.user.real_name %></span>
<span class="ml-3"><%= format_time record.created_at %></span>
</div>
<div class="mt-2 mb-3 ml-3 font-14">
<span>实训名称:<%= record.container&.shixun&.name %></span>
<% if record.container_type == "Challenge" %>
<span class="ml-3">/</span>
<span class="ml-3">关卡名:<%= record.container&.subject %></span>
<% end %>
</div>
<div class="diff font-12">
<ul>
<% record.diff_record_content&.content&.split("\n").each do |line| %>
<% if line =~ /^[\+]/ %>
<li class="ins"><ins><%= line %></ins></li>
<% elsif line =~ /^[\-]/ %>
<li class="del"><del><%= line %></del></li>
<% else %>
<li class="unchanged"><span><%= line %></span></li>
<% end %>
<% end %>
</ul>
</div>
</div>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
<%= render partial: 'admins/shared/paginate', locals: { objects: records } %>

@ -1,16 +1,18 @@
<table class="table table-hover text-center shixuns-list-table">
<thead class="thead-light">
<th width="4%">序号</th>
<th width="8%">ID</th>
<th width="32%" class="text-left">实训名称</th>
<th width="20%">子站源</th>
<th width="16%">子站源</th>
<th width="10%">创建者</th>
<th width="20%"><%= sort_tag('创建于', name: 'created_at', path: admins_shixun_recycles_path) %></th>
<th width="10%">操作</th>
</thead>
<tbody>
<% if shixuns.present? %>
<% shixuns.each do |shixun| %>
<% shixuns.each_with_index do |shixun, index| %>
<tr id="shixun_recycle_item_<%= shixun.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td><%= shixun.identifier %></td>
<td class="text-left"><span><%= link_to overflow_hidden_span(shixun.name), "/shixuns/#{shixun.identifier}", :target => "_blank", :title => shixun.name %></span></td>
<td><%= shixun.laboratory&.school&.name %></td>

@ -65,6 +65,12 @@
<span class="only_view">只看已隐藏文件目录</span>
</label>
</div>
<div class="mr-5">
<label for="vip">
<%= check_box_tag :vip, !@sort_json[:vip],@sort_json[:vip], class:"shixun-settings-select" %>
<span class="only_view">只看vip</span>
</label>
</div>
</div>
</div>
<% end %>

@ -1,12 +1,13 @@
<table class="table text-center shixun-settings-list-table">
<thead class="thead-light">
<th width="8%">ID</th>
<th width="4%">序号</th>
<th width="7%">ID</th>
<th width="12%" class="text-left">实训名称</th>
<th width="8%">技术平台</th>
<th width="8%">权限</th>
<th width="15%">技术体系</th>
<th width="8%">上传图片</th>
<th width="8%">小程序封面</th>
<th width="13%">技术体系</th>
<th width="7%">上传图片</th>
<th width="7%">小程序封面</th>
<th width="5%">创建者</th>
<th width="5%">关闭</th>
<th width="4%">复制</th>
@ -14,7 +15,7 @@
<th>
操作
<div class="setting-chosen">
ssh/隐藏/首页/跳关/隐藏目录
ssh/隐藏/首页/跳关/隐藏目录/vip
</div>
</th>
</thead>

@ -1,3 +1,4 @@
<td class="shixun-line-no"><%= page_no %></td>
<td><%= shixun.identifier %></td>
<td class="text-left">
<span>
@ -47,6 +48,7 @@
<%= check_box_tag :homepage_show,!shixun.homepage_show,shixun.homepage_show,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},class:"shixun-setting-form",title:"首页" %>
<%= check_box_tag :task_pass,!shixun.task_pass,shixun.task_pass,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},class:"shixun-setting-form" ,title:"跳关"%>
<%= check_box_tag :code_hidden,!shixun.code_hidden,shixun.code_hidden,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},class:"shixun-setting-form" ,title:"隐藏目录"%>
<%= check_box_tag :vip,!shixun.vip,shixun.vip,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},class:"shixun-setting-form" ,title:"vip"%>
</td>
<script>

@ -3,9 +3,10 @@
<table class="table table-hover text-center subject-authorization-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="8%">头像</th>
<th width="10%">创建者</th>
<th width="28%" class="text-left">实践课程名称</th>
<th width="24%" class="text-left">实践课程名称</th>
<th width="6%">阶段数</th>
<th width="6%">实训数</th>
<th width="6%">关卡数</th>
@ -20,10 +21,11 @@
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% applies.each_with_index do |apply, index| %>
<% user = apply.user %>
<% subject = subject_map[apply.container_id] %>
<tr class="subject-authorization-item subject-authorization-<%= apply.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td>
<%= link_to "/users/#{user.login}", class: 'subject-authorization-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />

@ -1,11 +1,12 @@
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="14%" class="text-left">名称</th>
<th width="6%">阶段数</th>
<th width="6%">实训数</th>
<th width="8%">技术体系</th>
<th width="8%">等级体系</th>
<th width="5%">阶段数</th>
<th width="5%">实训数</th>
<th width="7%">技术体系</th>
<th width="7%">等级体系</th>
<th width="8%">封面</th>
<th width="7%">创建者</th>
<th width="10%">单位</th>
@ -17,8 +18,9 @@
</thead>
<tbody>
<% if subjects.present? %>
<% subjects.each do |subject| %>
<% subjects.each_with_index do |subject, index| %>
<tr class="subject-item-<%= subject.id %>">
<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-show-badge" style="<%= subject.homepage_show? ? '' : 'display:none' %>">首页</span>

@ -1,3 +1,4 @@
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td><%= apply.id %></td>
<td class="text-left"><%= overflow_hidden_span apply.name %></td>
<td class="text-left">

@ -1,9 +1,10 @@
<table class="table table-hover text-center unit-applies-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="8%">ID</th>
<th width="20%" class="text-left">单位名称</th>
<th width="12%" class="text-left">地区</th>
<th width="8%" class="text-left">地区</th>
<th width="20%" class="text-left">详细地址</th>
<th width="10%">申请者</th>
<th width="15%"><%= sort_tag('创建于', name: 'created_at', path: admins_unit_applies_path) %></th>
@ -12,9 +13,9 @@
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% applies.each_with_index do |apply, index| %>
<tr class="unit-apply-<%= apply.id %>">
<%= render partial: "admins/unit_applies/shared/apply_item", locals: {apply: apply} %>
<%= render partial: "admins/unit_applies/shared/apply_item", locals: {apply: apply, index: index} %>
</tr>
<% end %>
<% else %>

@ -1,20 +1,22 @@
<table class="table table-hover text-center user-statistic-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="14%" class="text-left">姓名</th>
<th width="22%" class="text-left">单位部门</th>
<th width="10%">学习关卡数<%#= sort_tag('学习关卡数', name: 'study_challenge_count', path: admins_user_statistics_path) %></th>
<th width="10%">完成关卡数<%#= sort_tag('完成关卡数', name: 'finish_challenge_count', path: admins_user_statistics_path) %></th>
<th width="10%"><%= sort_tag('学习实训数', name: 'study_shixun_count', path: admins_user_statistics_path) %></th>
<th width="10%"><%= sort_tag('完成实训数', name: 'finish_shixun_count', path: admins_user_statistics_path) %></th>
<th width="10%">评测次数</th>
<th width="9%">完成关卡数<%#= sort_tag('完成关卡数', name: 'finish_challenge_count', path: admins_user_statistics_path) %></th>
<th width="9%"><%= sort_tag('学习实训数', name: 'study_shixun_count', path: admins_user_statistics_path) %></th>
<th width="9%"><%= sort_tag('完成实训数', name: 'finish_shixun_count', path: admins_user_statistics_path) %></th>
<th width="9%">评测次数</th>
<th width="14%">实战时间</th>
</tr>
</thead>
<tbody>
<% if users.present? %>
<% users.each do |user| %>
<% users.each_with_index do |user, index| %>
<tr class="user-statistic-item-<%= user.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left">
<%= link_to "/users/#{user.login}", target: '_blank' do %>
<%= overflow_hidden_span user.real_name, width: 100 %>

@ -1,8 +1,9 @@
<table class="table table-hover users-list-table">
<thead class="thead-light">
<tr>
<th width="10%" class="text-left">真实姓名</th>
<th width="15%">邮件地址</th>
<th width="4%">序号</th>
<th width="8%" class="text-left">真实姓名</th>
<th width="13%">邮件地址</th>
<th width="10%">手机号码</th>
<th width="14%">单位</th>
<th width="7%">角色</th>
@ -15,8 +16,9 @@
</thead>
<tbody>
<% if users.present? %>
<% users.each do |user| %>
<% users.each_with_index do |user, index| %>
<tr class="user-item-<%= user.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left">
<%= link_to "/users/#{user.login}", target: '_blank' do %>
<%= overflow_hidden_span user.real_name, width: 100 %>

@ -3,12 +3,13 @@
<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="13%">视频大小</th>
<th width="13%" class="text-left">播放链接</th>
<th width="16%">时间</th>
<th width="12%">时间</th>
<% if is_processed %>
<th width="16%">拒绝原因</th>
<th width="8%">状态</th>
@ -19,10 +20,11 @@
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |v| %>
<% applies.each_with_index do |v, index| %>
<% video = v.video %>
<% user = video.user %>
<tr class="video-applies-item video-applies-<%= v.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,3 +1,8 @@
json.(@hack_user, :id, :status, :error_line, :error_msg, :expected_output,
:input, :output, :execute_time, :execute_memory)
json.language @hack_user.hack.language
:input, :output, :execute_time, :execute_memory, :created_at, :code)
json.language @hack_user.hack.language
json.name @hack_user.hack.name
json.myproblem_identifier @my_hack.identifier
json.user do
json.partial! 'users/user', user: current_user
end

@ -1,12 +1,19 @@
json.hack do
json.(@hack, :difficult, :time_limit, :description, :score, :identifier)
json.(@hack, :name, :difficult, :time_limit, :description, :score, :identifier)
json.language @hack.language
json.username @hack.user.real_name
json.code @my_hack.code
json.pass_count @hack.pass_num
json.submit_count @hack.submit_num
json.modify_code @modify
end
json.test_case do
json.input @hack.input_test_case
end
json.user do
json.partial! 'users/user', user: current_user
json.hack_manager @hack.manager?(current_user)
end

@ -1,4 +1,4 @@
json.array! @my_hack.hack_user_codes do |hack_user|
json.array! @records do |hack_user|
json.(hack_user, :id, :created_at, :status, :execute_time, :execute_memory)
json.language hack_user.hack.language
end

@ -1,5 +1,5 @@
# 编程内容
json.(@hack, :name, :description, :language, :difficult, :category, :time_limit, :open_or_not)
json.(@hack, :name, :description, :language, :difficult, :category, :time_limit, :open_or_not, :status)
# 代码
json.language @hack.language
@ -11,3 +11,6 @@ json.hack_sets do
json.(set, :id, :input, :output, :position)
end
end
json.user do
json.partial! 'users/user', user: current_user
end

@ -0,0 +1,3 @@
json.user do
json.partial! 'users/user', user: current_user
end

@ -22,6 +22,6 @@ json.question do
end
end
if question_votes.find_vote_text.present?
json.vote_text question_votes.pluck(:vote_text).reject(&:blank?) #问题的回答是否有用户手动输入的内容
json.vote_text question_votes.pluck(:vote_text) #问题的回答是否有用户手动输入的内容
end
end

@ -10,6 +10,7 @@ json.setting do
json.course_banner_url (setting.course_banner_url || default_setting.course_banner_url)&.[](1..-1)
json.competition_banner_url (setting.competition_banner_url || default_setting.competition_banner_url)&.[](1..-1)
json.moop_cases_banner_url (setting.moop_cases_banner_url || default_setting.moop_cases_banner_url)&.[](1..-1)
json.oj_banner_url (setting.oj_banner_url || default_setting.oj_banner_url)&.[](1..-1)
json.navbar setting.navbar || default_setting.navbar

@ -15,6 +15,7 @@ json.shixuns_list do
json.shixun_name shixun.name
json.shixun_hidden shixun.hidden
json.identifier shixun.identifier
json.challenges_count shixun.challenges_count
json.complete_status stage_myshixun_status(myshixuns.select{|ms| ms.shixun_id == shixun.id}.first)
json.shixun_status stage_shixun_status(subject.status, shixun.status, shixun.hidden)
end

@ -59,6 +59,7 @@ Rails.application.routes.draw do
get :result
get :submit_records
post :restore_initial_code
post :sync_code
end
collection do
@ -928,6 +929,10 @@ Rails.application.routes.draw do
delete :delete_course_students
end
end
resources :homework_commons do
post :update_settings, on: :member
end
end
resources :users_for_partners, only: [:index]
@ -1054,6 +1059,7 @@ Rails.application.routes.draw do
resources :shixun_recycles, only: [:index, :destroy] do
post :resume, on: :member
end
resources :shixun_modify_records, only: [:index]
resources :department_applies,only: [:index,:destroy] do
collection do
post :merge

@ -0,0 +1,27 @@
class MigrateExerciseSingleQuestionScore < ActiveRecord::Migration[5.2]
def change
# # 删除判断、单选题中生成多条记录但exercise_choice_id不同的数据
# sql = %Q(delete from exercise_answers where (exercise_question_id, user_id) in
# (select * from (select exercise_question_id, user_id from exercise_answers join exercise_questions eq on exercise_question_id = eq.id where eq.question_type in (0, 2) group by exercise_question_id, user_id having count(*) > 1) a)
# and id not in (select * from (select min(exercise_answers.id) from exercise_answers join exercise_questions eq on exercise_question_id = eq.id where eq.question_type in (0, 2) group by exercise_question_id, user_id having count(*) > 1 order by exercise_answers.id) b))
# ActiveRecord::Base.connection.execute sql
#
# # 更新成绩
# exercise_answers = ExerciseAnswer.joins(:exercise_question).where(score: -1, exercise_questions: {question_type: [0, 2]})
# exercise_answers.includes(:exercise_choice, exercise_question: :exercise_standard_answers).find_each do |answer|
#
# question = answer.exercise_question
# exercise_user = ExerciseUser.find_by(exercise_id: question.exercise_id, user_id: answer.user_id)
#
# if exercise_user && exercise_user.commit_status == 1
# user_choice_position = answer.exercise_choice&.choice_position
# if user_choice_position && (user_choice_position.to_i == question.exercise_standard_answers.take&.exercise_choice_id.to_i)
# answer.update!(score: question.question_score)
# score = exercise_user.score.to_f + question.question_score
# objective_score = exercise_user.objective_score + question.question_score
# exercise_user.update!(score: score, objective_score: objective_score)
# end
# end
# end
end
end

@ -0,0 +1,6 @@
class AddModifyTimeForHackCodes < ActiveRecord::Migration[5.2]
def change
add_column :hack_codes, :modify_time, :timestamp
add_column :hack_user_lastest_codes, :modify_time, :timestamp
end
end

@ -0,0 +1,6 @@
class AddIndexForHackCodes < ActiveRecord::Migration[5.2]
def change
HackCode.destroy_all
add_index :hack_codes, [:hack_id, :language], unique: true
end
end

@ -0,0 +1,5 @@
class AddVipToShixun < ActiveRecord::Migration[5.2]
def change
add_column :shixuns, :vip, :boolean, default: 0
end
end

File diff suppressed because one or more lines are too long

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

Loading…
Cancel
Save