Merge branch 'dev_aliyun' into dev_cxt

dev_aliyun_beta
cxt 6 years ago
commit e2a5fd80d5

@ -32,8 +32,11 @@ $(document).on('turbolinks:load', function(){
// flash alert提示框自动关闭
if($('.admin-alert-container .alert').length > 0){
setTimeout(function(){
$('.admin-alert-container .alert').alert('close');
$('.admin-alert-container .alert:not(.alert-danger)').alert('close');
}, 2000);
setTimeout(function(){
$('.admin-alert-container .alert.alert-danger').alert('close');
}, 5000);
}
});

@ -1,6 +1,7 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-identity-authentications-index-page').length > 0) {
var $searchFrom = $('.identity-authentication-list-form');
$searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@ -12,6 +13,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
$searchFrom.find('select[name="status"]').val('pending');
}
});
}

@ -0,0 +1,19 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-mirror-repositories-edit-page, body.admins-mirror-repositories-update-page').length > 0) {
var $form = $('form.edit-mirror');
$form.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
"mirror_repository[type_name]": {
required: true
}
}
});
$form.submit(function(e){
if(!$form.valid()){ e.preventDefault(); }
});
}
});

@ -0,0 +1,4 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-mirror-repositories-index-page').length > 0) {
}
});

@ -0,0 +1,32 @@
$(document).on('turbolinks:load', function() {
$('.admin-modal-container').on('show.bs.modal', '.modal.admin-choose-mirror-modal', function(){
var $modal = $('.modal.admin-choose-mirror-modal');
var $form = $modal.find('form.admin-choose-mirror-form');
var validateForm = function(){
var checkedValue = $form.find('input[name="mirror_number"]:checked').val();
if(checkedValue == undefined){
$modal.find('.error').html('必须选择一种镜像保存!');
return false;
}
return true;
}
$modal.on('click', '.submit-btn', function(){
$form.find('.error').html('');
var url = $form.attr('action');
if (validateForm()) {
$.ajax({
method: 'POST',
dataType: 'script',
url: url,
data: $form.serialize(),
}).done(function(){
$modal.modal('hide');
});
}
});
})
});

@ -0,0 +1,89 @@
$(document).on('turbolinks:load', function() {
var $modal = $('.modal.admin-replace-mirror-modal');
if ($modal.length > 0) {
var $form = $modal.find('form.admin-replace-mirror-form');
var $mirrorIdInput = $modal.find('.modal-body input[name="mirror_id"]');
var $mirrorSelect = $modal.find('.new-mirror-select');
var setMirror = function(id, name){
$mirrorIdInput.val(id);
$form.find('.mirror-id-container').html(id);
$form.find('.mirror-name-container').html(name);
}
$form.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
new_mirror_id: {
required: true
},
},
messages: {
new_mirror_id: {
required: '请选择新镜像'
}
}
});
// modal ready fire
$modal.on('show.bs.modal', function (event) {
var $link = $(event.relatedTarget);
var mirrorId = $link.data('id');
var mirrorName = $link.data('name');
setMirror(mirrorId, mirrorName);
$mirrorSelect.select2('val', ' ');
});
$modal.on('hide.bs.modal', function () {
setMirror('', '');
$mirrorSelect.select2('val', ' ');
$('#new_mirror_id-error').remove();
});
$mirrorSelect.select2({
theme: 'bootstrap4',
placeholder: '输入要合并的镜像名',
minimumInputLength: 1,
ajax: {
url: '/admins/mirror_repositories/for_select',
dataType: 'json',
data: function(params){
return { keyword: params.term };
},
processResults: function(data){
return { results: data.mirrors }
}
},
templateResult: function (item) {
if(!item.id || item.id === '') return item.text;
return item.name;
},
templateSelection: function(item){
if (item.id) {
$('#new_mirror_id-error').remove();
$('#new_mirror_id').val(item.id);
}
return item.name || item.text;
}
});
$modal.on('click', '.submit-btn', function(){
$form.find('.error').html('');
if ($form.valid()) {
var url = $form.data('url');
$.ajax({
method: 'POST',
dataType: 'script',
url: url,
data: $form.serialize(),
}).done(function(){
$modal.modal('hide');
});
}
});
}
});

@ -1,6 +1,7 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-professional-authentications-index-page').length > 0) {
var $searchFrom = $('.professional-authentication-list-form');
$searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@ -12,6 +13,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
$searchFrom.find('select[name="status"]').val('pending');
}
});
}

@ -1,6 +1,7 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-shixun-authorizations-index-page').length > 0) {
var $searchFrom = $('.shixun-authorization-list-form');
$searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@ -12,6 +13,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
$searchFrom.find('select[name="status"]').val('pending');
}
});
}

@ -1,6 +1,7 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-subject-authorizations-index-page').length > 0) {
var $searchFrom = $('.subject-authorization-list-form');
$searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@ -12,6 +13,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
$searchFrom.find('select[name="status"]').val('pending');
}
});
}

@ -47,4 +47,9 @@ label.error {
.flex-1 {
flex: 1;
}
}
.font-12 { font-size: 12px !important; }
.font-14 { font-size: 14px !important; }
.font-16 { font-size: 16px !important; }
.font-18 { font-size: 18px !important; }

@ -0,0 +1,11 @@
class Admins::ChooseMirrorRepositoriesController < Admins::BaseController
def new
@mirror = MirrorRepository.find(params[:mirror_id])
@new_mirror = MirrorOperationRecord.where(mirror_repository_id: @mirror.id, status: 1, user_id: -1).first
end
def create
mirror = MirrorRepository.find(params[:mirror_id])
Admins::ChooseMirrorService.call(mirror, current_user, params[:mirror_number])
end
end

@ -0,0 +1,96 @@
class Admins::MirrorRepositoriesController < Admins::BaseController
before_action :check_shixun_mirrors!, only: [:index]
def index
mirrors = MirrorRepository.all
mirrors = mirrors.reorder(status: :desc, main_type: :desc, type_name: :asc)
@mirrors = paginate mirrors.includes(:mirror_scripts)
@error_mirror_names = MirrorRepository.where(status: 5).pluck(:name)
end
def new
@mirror = MirrorRepository.new
end
def create
@mirror = MirrorRepository.new
Admins::SaveMirrorRepositoryService.call(@mirror, current_user, form_params)
flash[:success] = '保存成功'
redirect_to edit_admins_mirror_repository_path(@mirror)
rescue ActiveRecord::RecordInvalid
flash.now[:danger] = '保存失败'
render 'new'
rescue Admins::SaveMirrorRepositoryService::Error => ex
flash.now[:danger] = ex.message
render 'new'
end
def edit
@mirror = current_mirror
end
def update
@mirror = current_mirror
Admins::SaveMirrorRepositoryService.call(current_mirror, current_user, form_params)
flash[:success] = '保存成功'
redirect_to edit_admins_mirror_repository_path(current_mirror)
rescue ActiveRecord::RecordInvalid
flash.now[:danger] = '保存失败'
render 'edit'
rescue Admins::SaveMirrorRepositoryService::Error => ex
flash.now[:danger] = ex.message
render 'edit'
end
def destroy
return render_js_error('该状态下不允许删除') unless current_mirror.deletable?
current_mirror.destroy!
render_delete_success
end
def for_select
mirrors = MirrorRepository.all
keyword = params[:keyword].to_s.strip
mirrors = mirrors.where('name LIKE ?', "%#{keyword}%") if keyword.present?
@mirrors = paginate mirrors
render_ok(count: @mirrors.total_count, mirrors: @mirrors.as_json(only: %i[id name]))
end
def merge
origin_mirror = MirrorRepository.find(params[:mirror_id])
mirror = MirrorRepository.find(params[:new_mirror_id])
ActiveRecord::Base.transaction do
origin_mirror.update!(name: mirror.name, mirrorID: mirror.mirrorID)
mirror.destroy!
end
end
private
def current_mirror
@_current_mirror ||= MirrorRepository.find(params[:id])
end
def form_params
columns = %i[type_name main_type time_limit resource_limit cpu_limit memory_limit description status]
params.require(:mirror_repository).permit(*columns)
end
def check_shixun_mirrors!
return unless request.format.html?
Admins::CheckShixunMirrorsService.call
rescue Admins::CheckShixunMirrorsService::Error => e
internal_server_error(e.message)
end
end

@ -74,6 +74,7 @@ class ChallengesController < ApplicationController
ChallengeTag.create(:name => tag, :challenge_choose_id => @challenge_choose.id, :challenge_id => @challenge.id)
end
end
@challenge.update_column(:score, @challenge.challenge_chooses.sum(:score))
end
rescue Exception => e
raise ActiveRecord::Rollback
@ -95,6 +96,7 @@ class ChallengesController < ApplicationController
@challenge.update_column(:modify_time, Time.now)
end
@challenge_choose.update_attributes(chooce_params)
@challenge.update_column(:score, @challenge.challenge_chooses.sum(:score))
# 单选多选题的更新
category = @challenge_choose.standard_answer.length > 1 ? 2 : 1
@challenge_choose.update_column(:category, category)
@ -208,6 +210,9 @@ class ChallengesController < ApplicationController
# 测试集的
@shixun.myshixuns.update_all(:system_tip => 0)
end
if params[:challenge][:show_type].to_i == -1
@challenge.update_attributes(picture_path: nil, web_route: nil, expect_picture_path: nil, original_picture_path: nil)
end
# 关卡评测执行文件如果被修改,需要修改脚本内容
script = modify_shixun_script @shixun, @shixun.evaluate_script
@shixun.shixun_info.update_column(:evaluate_script, script)

@ -1,36 +1,34 @@
module Admins::RenderHelper
extend ActiveSupport::Concern
def render_by_format(hash)
format = request.format.symbol
hash.key?(format) ? hash[format].call : hash[:html].call
end
def render_forbidden
respond_to do |format|
format.html { redirect_to '/403' }
format.json { super }
end
render_by_format(html: -> { redirect_to '/403' },
json: -> { render status: 403, json: { messages: I18n.t('error.forbidden') } } )
end
def render_not_found
respond_to do |format|
format.html { render 'admins/shared/404' }
format.js { render_js_error('资源未找到') }
format.json { render status: 404, json: { message: '资源未找到' } }
end
render_by_format(html: -> { render 'admins/shared/404' },
js: -> { render_js_error('资源未找到') },
json: -> { render status: 404, json: { message: '资源未找到' } })
end
def render_unprocessable_entity(message)
respond_to do |format|
format.html { render 'admins/shared/422' }
format.js { render_js_error(message) }
format.json { render status: 422, json: { message: message } }
end
render_by_format(html: -> { render 'admins/shared/422' },
js: -> { render_js_error(message) },
json: -> { render status: 422, json: { message: message } })
end
alias_method :render_error, :render_unprocessable_entity
def internal_server_error
respond_to do |format|
format.html { render 'admins/shared/500' }
format.js { render_js_error('系统错误') }
format.json { render status: 500, json: { message: '系统错误' } }
end
def internal_server_error(message = '系统错误')
@message = message
render_by_format(html: -> { render 'admins/shared/500' },
js: -> { render_js_error(message) },
json: -> { render status: 500, json: { message: message } })
end
def render_js_template(template, **opts)

@ -171,6 +171,7 @@ class FilesController < ApplicationController
begin
attachment_ids.each do |attachment_id|
ori = Attachment.find_by_id(attachment_id)
# 同一个资源可以多次发送到课堂
@course.attachments.each do |att|
@exist = false
if att.id == ori.id || (!att.copy_from.nil? && !ori.copy_from.nil? && att.copy_from == ori.copy_from) || att.copy_from == ori.id || att.id == ori.copy_from

@ -739,7 +739,7 @@ class GamesController < ApplicationController
experience = 0
game_status = @game.status
had_done = @game.had_done
game_challenge = Challenge.select([:id, :score, :position, :shixun_id, :web_route]).find(@game.challenge_id)
game_challenge = Challenge.select([:id, :score, :position, :shixun_id, :web_route, :show_type]).find(@game.challenge_id)
if params[:resubmit].blank? # 非重新评测
if game_status == 2 # 通关
@ -765,9 +765,10 @@ class GamesController < ApplicationController
testset_detail max_query_index.to_i, game_challenge
# 处理生成图片类型文件
picture = (@game.picture_path.nil? ? 0 : @game.id)
picture = (game_challenge.show_type.to_i == -1 || @game.picture_path.nil?) ? 0 : @game.id
# 针对web类型的实训
web_route = game_challenge.try(:web_route)
mirror_name = @shixun.mirror_name
e_record = EvaluateRecord.where(:identifier => sec_key).first

@ -101,8 +101,9 @@ class SubjectsController < ApplicationController
@tags = ChallengeTag.where(challenge_id: challenge_ids).pluck(:name).uniq
# 用户获取的实训标签
# @user_tags = @subject.shixuns.map(&:user_tags_name).flatten.uniq
@user_tags = user_shixun_tags challenge_ids, @user.id
@my_subject_progress = @subject.my_subject_progress
# 用户进展
user_subject_progress(challenge_ids)
end
def new
@ -269,7 +270,7 @@ class SubjectsController < ApplicationController
page = params[:page] || 1
member_ids = @subject.subject_members.map(&:user_id).join(',')
condition = "%#{params[:search].strip}%".gsub(" ","")
@users = User.where("id not in (?) and status = 1 and LOWER(concat(lastname, firstname, login, mail)) LIKE ?", member_ids, "#{condition}")
@users = User.where("id not in (?) and status = 1 and LOWER(concat(lastname, ifnull(firstname, ''), login)) LIKE ?", member_ids, "#{condition}")
@users = @users.page(page).per(10)
@users = @users.includes(:user_extension)
@ -436,4 +437,33 @@ class SubjectsController < ApplicationController
tip_exception("403", "")
end
end
# 用户进展和获取的标签
def user_subject_progress challenge_ids
pass_games = Game.select(:id, :cost_time, :challenge_id).where(status: 2, user_id: current_user.id, challenge_id: challenge_ids) if current_user.logged?
@all_score = Challenge.where(id: challenge_ids).sum(:score)
# 如果没有通关的,没必要再继续统计了
if pass_games.blank?
@my_score = 0
@learned = 0
@time = 0
@user_tags = []
else
pass_challenge_ids = pass_games.map(&:challenge_id)
subject_challenge_count = @subject.shixuns.sum(:challenges_count)
# 用户通关获得的标签
@user_tags = ChallengeTag.where(challenge_id: pass_challenge_ids).pluck(:name)
# 用户学习进度
@learned =
subject_challenge_count == 0 ? 0 :
((pass_challenge_ids.size.to_f / subject_challenge_count).round(2) * 100).to_i
# 用户通关分数
@my_score = Challenge.where(id: pass_challenge_ids).pluck(:score).sum
@time = pass_games.map(&:cost_time).sum
end
end
end

@ -0,0 +1,23 @@
module Admins::MirrorRepositoriesHelper
def mirror_type_tag(mirror)
case mirror.main_type
when '1' then '<i class="fa fa-star text-success font-16" aria-hidden="true" data-toggle="tooltip" data-title="主类别"></i>'.html_safe
when '0' then '<i class="fa fa-star text-secondary font-16" aria-hidden="true" data-toggle="tooltip" data-title="子类别"></i>'.html_safe
end
end
def mirror_status_tag(mirror)
case mirror.status
when 0
'<i class="fa fa-check-circle text-secondary font-16" data-toggle="tooltip" data-title="未发布"></i>'.html_safe
when 1
'<i class="fa fa-check-circle text-success font-16" data-toggle="tooltip" data-title="已发布"></i>'.html_safe
when 2, 3
'<i class="fa fa-exclamation-circle text-danger font-16" data-toggle="tooltip" data-title="被修改"></i>'.html_safe
when 4
'<i class="fa fa-times-circle text-danger font-18" data-toggle="tooltip" data-title="被删除"></i>'.html_safe
when 5
'<i class="fa fa-exclamation-circle text-warning font-16" data-toggle="tooltip" data-title="子节点异常"></i>'.html_safe
end
end
end

@ -40,16 +40,18 @@ class Challenge < ApplicationRecord
## 选择题总分
def choose_score
self.challenge_chooses.pluck(:score).sum
self.score
#self.challenge_chooses.pluck(:score).sum
end
# 关卡总分
def all_score
if self.st == 1
self.choose_score
else
self.score
end
self.score
# if self.st == 1
# self.choose_score
# else
# self.score
# end
end
# 开启挑战

@ -31,7 +31,7 @@ class Game < ApplicationRecord
# 根据得分比例来算实际得分(试卷、实训作业)
def real_score score
((final_score < 0 ? 0 : final_score).to_f / challenge.all_score) * score
((final_score < 0 ? 0 : final_score).to_f / challenge.score) * score
end
# 判断实训是否全部通关

@ -0,0 +1,7 @@
# status: 0 创建镜像; 1 修改镜像ID 2 修改镜像name 3 删除镜像 4.从主节点同步镜像到子节点(子节点发生异常), 5. 修改镜像别名, 6. 修改镜像的状态
# user_id: -1时证明是非人为因素造成中间层异常导致
class MirrorOperationRecord < ActiveRecord::Base
default_scope { order(created_at: :desc) }
belongs_to :mirror_repository
end

@ -8,4 +8,8 @@ class MirrorRepository < ApplicationRecord
scope :published_mirror, -> { where(status: 1) }
scope :published_main_mirror, -> { published_mirror.where(main_type: 1) }
scope :published_small_mirror, -> { published_mirror.where(main_type: 0) }
def deletable?
status != 1 && !shixun_mirror_repositories.exists?
end
end

@ -192,11 +192,7 @@ class Shixun < ApplicationRecord
# 实训关卡的总分(由于大部分是实践题,因此没关联查choose表)
# 提前加载问题由于选择题比较少所以几乎不会触发选择题的查询所以没必要提前载入choose_score
def all_score
sum = 0
challenges.each do |challenge|
sum += challenge.st == 0 ? challenge.score : challenge.choose_score
end
sum
self.challenges.pluck(:score).sum
end
### fork 数量

@ -83,7 +83,7 @@ class Subject < ApplicationRecord
def my_subject_progress
my_challenge_count = Game.joins(:challenge).where(user_id: User.current.id, status: 2, challenges: {shixun_id: shixuns.published_closed}).
pluck(:challenge_id).uniq.size
pluck(:challenge_id).uniq.size
count = self.subject_challenge_count == 0 ? 0 : ((my_challenge_count.to_f / self.subject_challenge_count).round(2) * 100).to_i
end

@ -0,0 +1,89 @@
class Admins::CheckShixunMirrorsService < ApplicationService
Error = Class.new(StandardError)
def call
bridge_images
ActiveRecord::Base.transaction do
check_sync_mirrors!
check_mirrors!
end
end
private
def mirrors
bridge_images['images']
end
def sync_mirrors
bridge_images['imagesNotSync']
end
def check_mirrors!
return if mirrors.blank?
image_names = []
mirrors.each do |data|
mirror = JSON.parse(data)
name_repository = MirrorRepository.find_by(name: mirror['imageName'])
id_repository = MirrorRepository.find_by(mirrorID: mirror['imageID'])
image_names << mirror['imageName']
if name_repository.blank? && id_repository.present? # 镜像名称被修改
id_repository.update_column(:status, 2)
MirrorOperationRecord.create!(mirror_repository_id: id_repository.id, mirror_id: mirror['imageID'],
mirror_name: mirror['imageName'], status: 2, user_id: -1)
elsif name_repository.blank? # 镜像不存在、创建镜像
new_repository = MirrorRepository.create!(mirrorID: mirror['imageID'], name: mirror['imageName'])
MirrorOperationRecord.create!(mirror_repository_id: new_repository.id, mirror_id: mirror['imageID'],
mirror_name: mirror['imageName'], status: 0, user_id: -1)
elsif name_repository.mirrorID != mirror['imageID'] # 镜像ID被修改
name_repository.update_column(:status, 2)
MirrorOperationRecord.create!(mirror_repository_id: name_repository.id, mirror_id: mirror['imageID'],
mirror_name: mirror['imageName'], status: 1, user_id: -1)
end
end
# 判断中间层镜像是否被删除
MirrorRepository.find_each do |mirror|
next if mirror&.name.blank? || image_names.index(mirror.name)
mirror.update_column(:status, 4)
MirrorOperationRecord.create!(mirror_repository_id: mirror.id, mirror_id: mirror&.mirrorID,
mirror_name: mirror.name, status: 3, user_id: -1)
end
end
def check_sync_mirrors!
return if sync_mirrors.blank?
sync_mirrors.each do |data|
mirror = JSON.parse(data)
repository = MirrorRepository.find_by(name: mirror['imageName'])
next if repository.blank? || repository.status != 1
repository.update_column(:status, 5)
MirrorOperationRecord.create!(mirror_repository_id: repository.id, mirror_id: mirror['imageID'],
mirror_name: mirror['imageName'], status: 4, user_id: -1)
end
end
def bridge_images
@_bridge_images ||= begin
url = EduSetting.get('cloud_bridge')
res = Faraday.get(url)
raise Error, '拉取镜像信息异常' if res && res['code'].nonzero?
res
rescue => e
Rails.logger.error("get response failed ! #{e.message}")
raise Error, '实训云平台繁忙繁忙等级84'
end
end
end

@ -0,0 +1,21 @@
class Admins::ChooseMirrorService < ApplicationService
attr_reader :mirror, :user, :number
def initialize(mirror, user, mirror_number)
@mirror = mirror
@user = user
@number = mirror_number
end
def call
if mirror.mirrorID == number
mirror.update_column(:status, 1)
return
end
old_number = mirror.mirrorID
mirror.update!(mirrorID: number, status: 1)
MirrorOperationRecord.create!(mirror_repository_id: mirror.id, mirror_id: number, mirror_name: mirror.name,
status: 1, user_id: user.id, old_tag: old_number, new_tag: mirror.mirrorID)
end
end

@ -0,0 +1,37 @@
class Admins::SaveMirrorRepositoryService < ApplicationService
Error = Class.new(StandardError)
attr_reader :mirror, :user, :params
def initialize(mirror, user, params)
@mirror = mirror
@user = user
@params = params
end
def call
mirror.assign_attributes(params)
raise Error, '镜像别名重复' if MirrorRepository.where.not(id: mirror.id).exists?(type_name: params[:type_name])
ActiveRecord::Base.transaction do
record_operation! if mirror.persisted?
mirror.save!
end
end
private
def record_operation!
if mirror.type_name_changed?
MirrorOperationRecord.create!(mirror_repository_id: mirror.id, status: 5,
user_id: user.id, old_tag: mirror.type_name_in_database,
new_tag: mirror.type_name)
elsif mirror.status_changed?
MirrorOperationRecord.create!(mirror_repository_id: mirror.id, status: 5,
user_id: user.id, old_tag: mirror.status_in_database,
new_tag: mirror.status)
end
end
end

@ -0,0 +1,5 @@
$.notify({ message: '操作成功' },{ type: 'success' });
setTimeout(function(){
window.location.reload();
}, 500)

@ -0,0 +1,2 @@
$('.admin-modal-container').html("<%= j( render partial: 'admins/mirror_repositories/shared/choose_mirror_modal', locals: { mirror: @mirror, new_mirror: @new_mirror } ) %>");
$('.modal.admin-choose-mirror-modal').modal('show');

@ -0,0 +1,8 @@
<%
define_admin_breadcrumbs do
add_admin_breadcrumb('镜像管理', admins_mirror_repositories_path)
add_admin_breadcrumb('镜像详情')
end
%>
<%= render partial: 'admins/mirror_repositories/shared/form', locals: { mirror: @mirror, form_action: 'update' } %>

@ -0,0 +1,23 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('镜像管理') %>
<% end %>
<div class="box search-form-container mirror-repository-list-form">
<form class="flex-1"></form>
<%= link_to '新建', new_admins_mirror_repository_path, class: 'btn btn-primary' %>
</div>
<% if @error_mirror_names.present? %>
<div class="box pb-0">
以下镜像异常:
<% @error_mirror_names.each do |mirror_name| %>
<span class="ml-2 text-danger"><%= mirror_name %></span>
<% end %>
</div>
<% end %>
<div class="box mirror-repository-list-container">
<%= render partial: 'admins/mirror_repositories/shared/list', locals: { mirrors: @mirrors } %>
</div>
<%= render 'admins/mirror_repositories/shared/replace_mirror_modal' %>

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

@ -0,0 +1,5 @@
$.notify({ message: '操作成功' },{ type: 'success' });
setTimeout(function(){
window.location.reload();
}, 500)

@ -0,0 +1,8 @@
<%
define_admin_breadcrumbs do
add_admin_breadcrumb('镜像管理', admins_mirror_repositories_path)
add_admin_breadcrumb('新建镜像')
end
%>
<%= render partial: 'admins/mirror_repositories/shared/form', locals: { mirror: @mirror, form_action: 'create' } %>

@ -0,0 +1,42 @@
<div class="modal fade admin-choose-mirror-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">更新镜像仓库</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<%= form_tag(admins_choose_mirror_repositories_path(mirror_id: mirror.id), method: :post, class: 'admin-choose-mirror-form') do %>
<div class="form-group row">
<div class="col-md-2"></div>
<div class="col-md-5">ID</div>
<div class="col-md-5">名称</div>
</div>
<div class="form-group row">
<div class="col-md-2">旧镜像</div>
<div class="col-md-5 form-check">
<input class="form-check-input" type="radio" name="mirror_number" id="old-mirror-check" value="<%= mirror.mirrorID %>">
<label class="form-check-label" for="old-mirror-check"><%= mirror.mirrorID %></label>
</div>
<div class="col-md-5"><%= mirror.name %></div>
</div>
<div class="form-group row">
<div class="col-md-2">新镜像</div>
<div class="col-md-5 form-check">
<input class="form-check-input" type="radio" name="mirror_number" id="new-mirror-check" value="<%= new_mirror.mirror_id %>">
<label class="form-check-label" for="new-mirror-check"><%= new_mirror.mirror_id %></label>
</div>
<div class="col-md-5"><%= new_mirror.mirror_name %></div>
</div>
<div class="mt-2 error text-danger"></div>
<% end %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -0,0 +1,42 @@
<div class="box edit-mirror-repository-container">
<%= simple_form_for([:admins, mirror], url: { action: form_action }, html: { class: 'edit-mirror col-md-12' }, defaults: { wrapper_html: { class: 'col-md-4' } }) do |f| %>
<% unless mirror.new_record? %>
<div class="row">
<%= f.input :mirrorID, label: '镜像ID', input_html: { readonly: true, class: 'form-control-plaintext' } %>
<%= f.input :name, label: '镜像名称', input_html: { readonly: true, class: 'form-control-plaintext' } %>
</div>
<% end %>
<div class="row">
<%= f.input :type_name, as: :string, label: '镜像别名 *' %>
<div class="form-group select optional col-md-4">
<%= f.label :main_type, label: '类别' %>
<%= f.select :main_type, [['主类别', 1],['小类别', 0]], {}, class: 'form-control optional' %>
</div>
</div>
<div class="row">
<%= f.input :time_limit, as: :integer, label: '评测时限(S)' %>
<%= f.input :resource_limit, as: :integer, label: '磁盘限制(K)' %>
</div>
<div class="row">
<%= f.input :cpu_limit, as: :integer, label: 'CPU限制(核)' %>
<%= f.input :memory_limit, as: :integer, label: '内存限制(M)' %>
</div>
<div class="row">
<%= f.input :description, as: :text, label: '描述', wrapper_html: { class: 'col-md-8' } %>
</div>
<div class="row">
<%= f.input :status, as: :radio_buttons, label: '状态', collection: [%w(未发布 0), %w(已发布 1)], wrapper_html: { class: 'col-md-4' } %>
</div>
<div class="row">
<%= f.button :submit, value: '保存', class: 'btn-primary mr-3 px-4', 'data-disable-with': '保存中...' %>
<%= link_to '取消', admins_mirror_repositories_path, class: 'btn btn-secondary px-4' %>
</div>
<% end %>
</div>

@ -0,0 +1,54 @@
<table class="table table-hover text-center mirror-repository-list-table">
<thead class="thead-light">
<tr>
<th width="6%">ID</th>
<th width="6%">类别</th>
<th width="12%" class="text-left">镜像别名</th>
<th width="16%" class="text-left">镜像名称</th>
<th width="22%" class="text-left">镜像描述</th>
<th width="14%">修改时间</th>
<th width="6%">脚本</th>
<th width="6%">状态</th>
<th width="12%">操作</th>
</tr>
</thead>
<tbody>
<% if mirrors.present? %>
<% mirrors.each do |mirror| %>
<tr class="mirror-repository-item-<%= mirror.id %>">
<td><%= mirror.id %></td>
<td><%= mirror_type_tag(mirror) %></td>
<td class="text-left"><%= display_text(mirror.type_name) %></td>
<td class="text-left"><%= overflow_hidden_span mirror.name, width: 150 %></td>
<td class="text-left"><%= overflow_hidden_span mirror.description, width: 240 %></td>
<td><%= mirror.updated_at.strftime('%Y-%m-%d %H:%M') %></td>
<td>
<% if mirror.main_type == "1" %>
<%= link_to "/users/modify_script?mirror_id=#{mirror.id}", target: '_blank' do %>
<i class="fa fa-file-text <%= mirror.mirror_scripts.blank? ? 'text-danger' : 'text-success' %>" aria-hidden="true" data-toggle="tooltip" data-title="脚本模板"></i>
<% end %>
<% end %>
</td>
<td><%= mirror_status_tag mirror %></td>
<td class="action-container">
<%= link_to '编辑', edit_admins_mirror_repository_path(mirror), class: 'action edit-action' %>
<% if mirror.status == 2 %>
<%= link_to '同步', new_admins_choose_mirror_repository_path(mirror_id: mirror.id), remote: true, class: 'action sync-action' %>
<% end %>
<%= javascript_void_link '替换', class: 'action replace-action', data: { toggle: 'modal', target: '.admin-replace-mirror-modal', id: mirror.id, name: mirror.name } %>
<% if mirror.deletable? %>
<%= delete_link '删除', admins_mirror_repository_path(mirror, element: ".mirror-repository-item-#{mirror.id}"), class: 'delete-mirror-repository-action' %>
<% end %>
</td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: mirrors } %>

@ -0,0 +1,33 @@
<div class="modal fade admin-replace-mirror-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">镜像替换</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form class="admin-replace-mirror-form" data-url="<%= merge_admins_mirror_repositories_path %>">
<%= hidden_field_tag(:mirror_id, nil) %>
<div class="form-group d-flex">
<div>被替换镜像:</div>
<div class="ml-2">ID<span class="mx-1 text-info mirror-id-container"></span></div>
<div class="ml-2">名称:<span class="mx-1 text-info mirror-name-container"></span></div>
</div>
<div class="form-group d-flex">
<label for="new_mirror_id" class="col-form-label">选择新镜像:</label>
<div class="d-flex flex-column-reverse w-75">
<select id="new_mirror_id" name="new_mirror_id" class="form-control new-mirror-select"></select>
</div>
</div>
<div class="error text-danger"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -2,5 +2,5 @@
<div class="global-error-code">
<span>500</span>
</div>
<div class="global-error-text">系统错误</div>
<div class="global-error-text"><%= @message %></div>
</div>

@ -1,5 +1,5 @@
<div class="paginate-container">
<% if objects.size.nonzero? %>
<% if objects && objects.size.nonzero? %>
<div class="paginate-total"><%= page_entries_info objects %></div>
<% end %>
<%= paginate objects, views_prefix: 'admins', remote: true %>

@ -20,6 +20,12 @@
<% end %>
</li>
<li>
<%= sidebar_item_group('#shixun-submenu', '实训管理', icon: 'window-restore') do %>
<li><%= sidebar_item(admins_mirror_repositories_path, '镜像管理', icon: 'cubes', controller: 'admins-mirror_repositories') %></li>
<% end %>
</li>
<!-- <li>-->
<%#= sidebar_item_group('#course-submenu', '课堂+', icon: 'mortar-board') do %>
<!-- <li><%#= sidebar_item('#', '课程列表', icon: 'calendar', controller: '') %></li>-->

@ -131,7 +131,7 @@
<div class="form-row mt-4">
<%= f.button :submit, value: '保存', class: 'btn-primary mr-3 px-4' %>
<%= link_to '取消', 'javascript:history.go(-1)', class: 'btn btn-secondary px-4' %>
<%= link_to '取消', admins_users_path, class: 'btn btn-secondary px-4' %>
</div>
<% end %>
</div>

@ -13,7 +13,7 @@ if @challenges.present?
json.position challenge.position
json.st challenge.st
json.name challenge.subject
json.score challenge.all_score
json.score challenge.score
json.passed_count challenge.user_passed_count
json.playing_count challenge.playing_count
json.name_url shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier)

@ -20,10 +20,20 @@ if question.question_type <= 2 #当为选择题或判断题时,只显示选
#TODO: 旧版本来一个题只有一个标准答案的新版又做成了一个题有多个标准答案exercise_choice_id存放的是标准答案的位置..
standard_answer_b = standard_answers_array.join("").include?(a.choice_position.to_s)
user_answer_b = user_answer.include?(a.id)
choice_text = a.choice_text
if question.question_type == 2
if choice_text == "对"
choice_text = "正确"
end
if choice_text == "错"
choice_text = "错误"
end
end
json.c_position (index+1) if ex_choice_random_boolean #当选项随机时,选项位置以此为准,否则不出现
json.choice_id a.id
# json.choice_text (edit_type.present? || question.question_type == 2) ? a.choice_text : "#{(index+65).chr}.#{a.choice_text}"
json.choice_text a.choice_text
json.choice_text choice_text
json.choice_position a.choice_position
if exercise_type == 1 || exercise_type == 4 #1为教师编辑/预览 试卷或问题2为空白试卷即标准答案和用户答案都不显示3为用户开始答题的显示4为老师评阅试卷或学生在截止后查看试卷
json.standard_boolean standard_answer_b
@ -36,6 +46,14 @@ if question.question_type <= 2 #当为选择题或判断题时,只显示选
if exercise_type == 1 || exercise_type == 4 #1为老师4为试卷截止且答案公开的情况
json.standard_answer standard_answers_array
if question.question_type == 2 #返回答案的文字
standard_text = standard_answers_array.first.to_i == 1 ? "正确" : "错误"
else
array_text_answer = []
standard_answers_array.each{|a| array_text_answer.push((a+64).chr)}
standard_text = array_text_answer.join("")
end
json.standard_answer_show standard_text
end
if exercise_type == 3 || exercise_type == 4
json.user_answer user_answer

@ -14,8 +14,8 @@ end
# 我的进展
json.progress do
json.my_score @subject.my_subject_score
json.all_score @subject.all_score
json.learned @subject.my_subject_progress
json.time @subject.my_consume_time
json.my_score @my_score
json.all_score @all_score
json.learned @learned
json.time @time
end

@ -50,12 +50,11 @@ Rails.application.configure do
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = false
config.assets.debug = true
# Suppress logger output for asset requests.
config.assets.quiet = true
config.assets.compile = true
# config.assets.prefix = '/dev-assets'
# Raises error for missing translations

@ -799,6 +799,13 @@ Rails.application.routes.draw do
post :refuse
end
end
resources :mirror_repositories, only: [:index, :new, :create, :edit, :update, :destroy] do
collection do
post :merge
get :for_select
end
end
resources :choose_mirror_repositories, only: [:new, :create]
end
#git 认证回调

@ -0,0 +1,10 @@
class ModifyChallnegeScoreForChoose < ActiveRecord::Migration[5.2]
def change
challenges = Challenge.where(st: 1)
challenges.find_each do |c|
puts(c.id)
score = c.challenge_chooses.sum(:score)
c.update_column(:score, score)
end
end
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

@ -446,8 +446,8 @@ table.text-file{}
/*-------------------------------实训路径-------------------------------*/
.path-head{width: 100%;height: 300px;background-image: url("/images/educoder/path.png");
background-color: #081C4B;
background-size: cover;
background-color: #000a4f;
/*background-size: cover;*/
background-position: center;
background-repeat: no-repeat;
}

@ -236,8 +236,7 @@ $(function(){
if(dragging) {
clickX = e.pageX || e.originalEvent.touches[0].pageX;;
if(clickX > leftOffset+0&&clickX<leftOffset+1600) {
console.log('resize')
//console.log(1);
// console.log('resize')
lab.css('left', clickX - 7 - leftOffset + 'px');
$("#game_left_contents").width( clickX-leftOffset + 'px');
nextW2 = clickX-leftOffset;
@ -314,10 +313,16 @@ $(function(){
window.top.__updateWebsshRows && window.top.__updateWebsshRows(rows)
}
window.refresh_editor_monaco = function(height) {
console.log('refresh_editor_monaco')
if (window.editor_monaco) {
height && $('#codetab_con_1').height(height)
window.editor_monaco.layout();
}
// if ($('#game_operate_action').width() < 720) {
// $('#game_operate_action .time_limit').hide()
// } else {
// $('#game_operate_action .time_limit').show()
// }
}
// end;
//解決IE瀏覽器大小改變時webssh佈局變亂。

@ -203,12 +203,12 @@ function generateNewIndexJsp() {
<script>
(function() {
var _host = '/react/build/'
/*
/**/
if (window.location.host == 'pre-newweb.educoder.net') {
_host = 'https://testali-cdn.educoder.net/react/build/'
} else if (window.location.host == 'www.educoder.net') {
_host = 'https://ali-newweb.educoder.net/react/build/'
}*/
_host = 'https://ali-cdn.educoder.net/react/build/'
}
document.write('<script type="text/javascript" src="' + _host + 'js/js_min_all.js"><\\/script>');
document.write('<script type="text/javascript" src="' + _host + 'static/js/main.${matchResult[1]}.js"><\\/script>');
})()

@ -1,10 +1,10 @@
const isDev = window.location.port == 3007;
export const TEST_HOST = "http://pre-newweb.educoder.net"
export const TEST_HOST = "https://pre-newweb.educoder.net"
export function getImageUrl(path) {
// https://www.educoder.net
// https://testbdweb.trustie.net
// const local = 'http://localhost:3000'
const local = 'http://pre-newweb.educoder.net'
const local = 'https://pre-newweb.educoder.net'
if (isDev) {
return `${local}/${path}`
}
@ -12,7 +12,7 @@ export function getImageUrl(path) {
}
export function setImagesUrl(path){
const local = 'http://pre-newweb.educoder.net'
const local = 'https://pre-newweb.educoder.net'
let firstStr=path.substr(0,1);
// console.log(firstStr);
if(firstStr=="/"){
@ -31,7 +31,7 @@ export function getUrl(path, goTest) {
// testbdweb.educoder.net testbdweb.trustie.net
// const local = goTest ? 'https://testeduplus2.educoder.net' : 'http://localhost:3000'
// const local = 'https://testeduplus2.educoder.net'
const local = 'http://pre-newweb.educoder.net'
const local = 'https://pre-newweb.educoder.net'
if (isDev) {
return `${local}${path?path:''}`
}

@ -271,15 +271,19 @@ class CommonWorkAppraise extends Component{
{work_members.map((item, index) => {
return <React.Fragment>
{isAdmin ?
<a className={`color-blue ${index == 0 ? '' : 'ml10'}`} href="javascript:void(0)"
<a className={`color-blue ${index == 0 ? '' : 'ml12'}`} href="javascript:void(0)"
onClick={() => this.props.toWorkDetailPage(this.props.match.params, null, item.work_id)}
>
{item.user_name}
</a> : <span className={`${index == 0 ? '' : 'ml10'}`} >{item.user_name}</span>}
</a> : <span className={`${index == 0 ? '' : 'ml12'}`} >{item.user_name}</span>}
{item.is_leader && <LeaderIcon small={true} ></LeaderIcon>}
</React.Fragment>
})}
</div>
<div className="font-12 color-grey-9">
<span >温馨提示</span>
点击其他组员的姓名可以快速评阅TA的作品
</div>
</div>
</div>

@ -430,7 +430,7 @@ class CommonWorkList extends Component{
}
_getRequestParams() {
const { search, arg_work_status, arg_teacher_comment, arg_course_group, order, page } = this.state
const { search, arg_work_status, arg_teacher_comment, arg_course_group, order, page, arg_member_work } = this.state
return {
page,
search,
@ -441,6 +441,7 @@ class CommonWorkList extends Component{
limit: PAGE_SIZE,
b_order: orderMap[order],
group_id:arg_course_group,
member_work: arg_member_work
}
}
fetchData = () => {
@ -488,6 +489,11 @@ class CommonWorkList extends Component{
this.fetchList()
})
}
memberWorkChange = (values, isAllChecked) => {
this.setState({arg_member_work: isAllChecked ? '' : values[0], page: 1}, () => {
this.fetchList()
})
}
funorder = (order) => {
this.setState({ order }, () => {
this.fetchList()
@ -581,10 +587,21 @@ class CommonWorkList extends Component{
return { label: `${item.name}(${item.count})`, value: item.id }
})
// 1:组长, 0:组员,“” 不限
const member_works = [{
name: '组长', id: 1
}, {
name: '组员', id: 0
}]
const options_member_work = member_works.map((item) => {
return { label: `${item.name}`, value: item.id }
})
const isAdmin = this.props.isAdmin()
const isStudent = this.props.isStudent()
const isAdminOrStudent = this.props.isAdminOrStudent()
const isGroup = this.props.isGroup();
// work_group
let StudentData;
@ -679,6 +696,7 @@ class CommonWorkList extends Component{
<CheckAllGroup options={options_teacher_comment} label={'你的评阅:'} onChange={this.teacherCommentOptionChange}></CheckAllGroup>
<CheckAllGroup options={options_status} label={'作品状态:'} onChange={this.statusOptionChange}></CheckAllGroup>
{options_course_group.length > 1 && <CheckAllGroup options={options_course_group} label={'分班情况:'} onChange={this.courseGroupOptionChange} checkboxGroupStyle={{width: '980px'}}></CheckAllGroup>}
{isGroup && <CheckAllGroup options={options_member_work} label={'组内角色:'} onChange={this.memberWorkChange}></CheckAllGroup>}
{/* value={search} */}

@ -1,12 +1,14 @@
import React,{Component} from "React";
import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal,Tooltip} from "antd";
import {Link} from 'react-router-dom';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import { WordsBtn, getUploadActionUrl, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll } from 'educoder';
import axios from 'axios';
import Modals from '../../modals/Modals';
import _ from 'lodash'
import { WordsBtn, getUploadActionUrl, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll } from 'educoder';
import Modals from '../../modals/Modals';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import LeaderIcon from './common/LeaderIcon'
const Search = Input.Search;
const CheckboxGroup = Checkbox.Group;
@ -735,8 +737,12 @@ render(){
disabled={item.commit_status || item.user_id == this.props.current_user.user_id ===true?true:false} className="fl "
></Checkbox>
<Tooltip placement="bottom" title={item.user_nam}><div className={"fl ml5 fonthidden"} style={{width: '70px'}}>{item.user_name}</div></Tooltip>
<div className={"fl ml20 color-grey-9"}>{item.group_name}</div>
<div className={"fl ml20 color-grey-9"}>{item.student_id}</div>
<div className={"fl ml20 color-grey-9 overflowHidden1"} style={{ maxWidth: '147px' }}
title={item.group_name && item.group_name.length > 9 ? item.group_name : ''}
>{item.group_name}</div>
<div className={"fl ml20 color-grey-9 overflowHidden1"} style={{ maxWidth: '84px' }}
title={item.student_id && item.student_id.length > 12 ? item.student_id : ''}
>{item.student_id}</div>
<div className={"fl ml20"}>{item.commit_status===true?<span className={"color-orange"}>已提交</span> :""}</div>
</div>
)
@ -753,6 +759,8 @@ render(){
text-overflow:ellipsis;
white-space:nowrap
}
.members .leaderIcon {
}
`}</style>
<div className={"members fl"}>
@ -764,11 +772,21 @@ render(){
display:item.user_name===undefined?"none":""
}}>
<Tooltip placement="bottom" title={item.user_nam}>
<div className={"fl ml5 fonthidden"} style={{width: '50px'}}>{item.user_name}</div>
<div className={"fl ml5 fonthidden"} style={{width: '68px'}}>
{item.user_name}{ (item.is_leader || !this.isEdit && key==0) && <LeaderIcon className="leaderIcon" small={true}></LeaderIcon>}
</div>
</Tooltip>
<div className={"fl ml40 color-grey-9"}>{item.group_name}</div>
<div className={"fl ml40 color-grey-9"}>{item.student_id}</div>
{item.user_id != this.props.current_user.user_id ?<div className={"fr"}><i className={"iconfont icon-shanchudiao fl "} style={{marginTop:'-4px'}} onClick={()=>this.delecttask_status(item.user_id)}></i></div>:""}
<div className={"fl ml40 color-grey-9 overflowHidden1"} style={{ maxWidth: '147px' }}
title={item.group_name && item.group_name.length > 9 ? item.group_name : ''}
>{item.group_name}</div>
<div className={"fl ml40 color-grey-9 overflowHidden1"} style={{ maxWidth: '84px' }}
title={item.student_id && item.student_id.length > 12 ? item.student_id : ''}
>{item.student_id}</div>
{item.user_id != this.props.current_user.user_id ?
<div className={"fr"}><i className={"iconfont icon-shanchudiao fl "}
style={{marginTop:'-4px'}} onClick={()=>this.delecttask_status(item.user_id)}></i></div>:""}
</div>
)
})}

@ -2,8 +2,10 @@ import React,{Component} from "React";
export default function LeaderIcon(props = {}) {
let icon = null;
const { className, style } = props;
const _className = `font-8 blueFull Actionbtn ${className}`
if (props.small) {
icon = <div className="font-8 blueFull Actionbtn" style={{
icon = <div className={_className} style={{
height: '14px',
'line-height': '14px',
width: '24px',
@ -12,7 +14,7 @@ export default function LeaderIcon(props = {}) {
'margin-left': '2px',
'vertical-align': 'middle', }}>组长</div>
} else {
icon = <div className="font-8 blueFull Actionbtn" style={{ height: '16px', 'line-height': '16px', width: '30px'}}>组长</div>
icon = <div className={_className} style={{ height: '16px', 'line-height': '16px', transform: 'scale(0.833)'}}>组长</div>
}
return icon

@ -1,5 +1,5 @@
import React,{ Component } from "react";
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form,Row, Col } from "antd";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import './myysleduinforms.css'
import axios from 'axios';
@ -165,18 +165,25 @@ class Bullsubdirectory extends Component{
{
whethertoeditysl === false?
<div>
<div className="" >
<div className="fudonyingxiangysl"><div className="ysltitbt fl"><span >{myname}</span></div>
{
this.props.isAdmin() === true ?
(this.props.yslbool===false?
<i className="iconfont icon-bianji1 newbianji1 fr pr25 yslbianji" onClick={()=>this.bianji(true)}></i>
:
""
)
:""
}
<div>
<div className="fudonyingxiangysl">
<div style={{marginRight:"60px"}}>
<span className="ysltitbt">{myname}</span>
</div>
<div>
<span className="fr pr25 yslbianji">
{
this.props.isAdmin() === true ?
(this.props.yslbool===false?
<i className="iconfont icon-bianji1 newbianji1" onClick={()=>this.bianji(true)}></i>
:
""
)
:""
}
</span>
</div>
<div className="yslclear"></div>
</div>
<div id="MakedownHTML"className={"markdown-body fonttext yslmtopcg yslminHeigth markdownysltext"} dangerouslySetInnerHTML={{__html: markdownToHTML(mydescription).replace(/▁/g, "▁▁▁")}}/>
</div>

@ -68,7 +68,6 @@
}
.fudonyingxiangysl{
width: 100%;
height: 66px;
}
.yslbianji{
padding-top: 31px;
@ -79,3 +78,5 @@
.ysldashed{
border:1px dashed #EEE;
}
.yslclear{ clear: both;
}

@ -961,6 +961,9 @@ class GraduationTaskssettinglist extends Component{
.linbox{
height: 26px;
}
.ant-table-tbody>tr>td, .ant-table-thead>tr>th{
padding: 16px 10px
}
`
}
</style>

@ -45,6 +45,7 @@ class CreateGroupByImportModal extends Component{
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification(response.data.message)
this.props.createGroupImportSuccess && this.props.createGroupImportSuccess()
this.setVisible(false)
} else {

@ -35,6 +35,7 @@ const buildColumns = (that) => {
dataIndex: 'login',
key: 'login',
align:'center',
width:"10%",
className:"color-grey-6",
render: (login, record) => {
return <span className="color-dark overflowHidden1" style={{maxWidth: '160px'}}
@ -57,9 +58,10 @@ const buildColumns = (that) => {
dataIndex: 'student_id',
key: 'student_id',
align:'center',
width:"10%",
className:"color-grey-6",
render: (student_id, record) => {
return <span className="color-dark overflowHidden1 "title={student_id && student_id.length > 10 ? student_id : ''}
return <span className="color-dark overflowHidden1 " title={student_id && student_id.length > 10 ? student_id : ''}
style={{maxWidth: '160px'}} >{student_id}</span>
}
}];
@ -69,7 +71,7 @@ const buildColumns = (that) => {
dataIndex: 'course_group_name',
key: 'course_group_name',
align:'center',
width:"50%",
width:"40%",
className:"color-grey-6"
})
}
@ -232,6 +234,9 @@ class studentsList extends Component{
off('updateNavSuccess', this.updateNavSuccess)
}
}
createGroupImportSuccess = () => {
this.props.updataleftNavfun()
}
updateNavSuccess = () => {
this.fetchCourseGroups()
}
@ -554,7 +559,9 @@ class studentsList extends Component{
firstRowRight={
<React.Fragment>
{ isSuperAdmin && <React.Fragment>
<CreateGroupByImportModal ref="createGroupByImportModal" {...this.props}></CreateGroupByImportModal>
<CreateGroupByImportModal ref="createGroupByImportModal" {...this.props}
createGroupImportSuccess={this.createGroupImportSuccess}
></CreateGroupByImportModal>
<WordsBtn style="blue" className="mr30" onClick={()=> this.refs['createGroupByImportModal'].setVisible(true)}>导入创建分班</WordsBtn>
</React.Fragment> }
{ isAdmin && isParent && <WordsBtn style="blue" className="mr30" onClick={()=>this.addDir()}>添加分班</WordsBtn> }

@ -42,6 +42,7 @@ function buildColumns(that) {
title: '序号',
dataIndex: 'name',
key: 'index',
width: 78,
render: (content, item, index) => {
return index + 1
// return item.isApply == true ? '' : <a href="javascript:;">{(that.state.page - 1) * 20 + index + 1
@ -74,6 +75,7 @@ function buildColumns(that) {
dataIndex: 'role',
key: 'role',
sorter: showSorter,
width: 86,
// 'ascend' | 'descend'
defaultSortOrder: 'ascend',
sortDirections: sortDirections,
@ -160,16 +162,16 @@ function buildColumns(that) {
},
})
}
if(isAdminOrTeacher && hasGraduationModule) {
columns.unshift({
title: '',
dataIndex: 'course_member_id',
key: 'course_member_id',
render: (content, item, index) => {
return content ? <Checkbox value={content}></Checkbox> : ''
}
})
}
// if(isAdminOrTeacher && hasGraduationModule) {
// columns.unshift({
// title: '',
// dataIndex: 'course_member_id',
// key: 'course_member_id',
// render: (content, item, index) => {
// return content ? <Checkbox value={content}></Checkbox> : ''
// }
// })
// }
return columns
}

@ -45,10 +45,11 @@ class CoursesNew extends Component {
fetching:false,
boolxinjian:false,
checkboxgroup:undefined,
addonAfteronelenone:0,
addonAfteronelentwo:0,
checkbofrup:[{module_type:"shixun_homework",module_name:"实训作业"},{module_type:"common_homework",module_name:"普通作业"},{module_type:"group_homework",module_name:"分组作业"}
,{module_type:"exercise",module_name:"试卷"},{module_type:"poll",module_name:"问卷"},{module_type:"graduation",module_name:"毕业设计"}
,{module_type:"board",module_name:"讨论"},{module_type:"attachment",module_name:"资源"},{module_type:"course_group",module_name:"分班"}],
checkbofrups:[],
}
}
componentDidMount() {
@ -66,8 +67,8 @@ class CoursesNew extends Component {
this.props.form.setFieldsValue({
course: data.course_list_name,
classroom: data.name,
period: data.class_period,
credit: data.credit,
period: data.class_period===undefined?'':data.class_period===null?'':data.class_period===null?'':data.class_period==="null"?'':data.class_period+"",
credit: data.credit===undefined?'':data.credit===null?'':data.credit===null?'':data.credit==="null"?'':data.credit+"",
checkboxgroup: data.course_module_types,
Realnamecertification: data.authentication,
Professionalcertification:data.professional_certification,
@ -81,7 +82,9 @@ class CoursesNew extends Component {
is_public: data.is_public === 1 ? true : false,
Realnamecertification: data.authentication,
Professionalcertification:data.professional_certification,
// checkbofrups:data.course_modules,
addonAfteronelenone: data.class_period===undefined?'':data.class_period===null?'':data.class_period===null?'':data.class_period==="null"?'':data.class_period,
addonAfteronelentwo:data.credit===undefined?'':data.credit===null?'':data.credit===null?'':data.credit==="null"?'':data.credit,
});
// try {
// if(data.course_modules===undefined||data.course_modules.length===0){
@ -94,6 +97,9 @@ class CoursesNew extends Component {
// checkbofrups:this.state.checkbofrup,
// });
// }
this.handleSearchschool(data.school);
}).catch((error) => {
console.log(error);
@ -469,10 +475,20 @@ class CoursesNew extends Component {
const optionschool = this.state.searchlistscholl===undefined?"":this.state.searchlistscholl===null?"":this.state.searchlistscholl==="[]"?"":this.state.searchlistscholl.map(z => <Option key={z} value={z}>{z}</Option>);
// console.log(this.props.current_user.user_school)
// form合并了
console.log("获取到的数据");
console.log(this.state);
console.log(this.props);
console.log(this.props.current_user);
// console.log("获取到的数据");
// console.log(this.state);
// console.log(this.props);
// console.log(this.props.current_user);
var addonAfterone=this.props.form&&this.props.form.getFieldValue('period');
var addonAfteronelen=0;
if(addonAfterone){
addonAfteronelen=String(addonAfterone).length;
}
var addonAftertwo=this.props.form&&this.props.form.getFieldValue('credit');
var addonAfteronelens=0;
if(addonAftertwo){
addonAfteronelens=String(addonAftertwo).length;
}
return (
<React.Fragment>
@ -630,6 +646,23 @@ class CoursesNew extends Component {
}
`}
</style>
<style>{
`
.yslzxueshi .ant-input{
border-right: none !important;
height: 40px !important;
width: 236px !important
}
.yslzxueshi .ant-input-group {
width: 280px !important;
}
.yslzxueshi .ant-input-group-addon{
width: 44px !important;
background-color: #fafafa!important;
}
`
}</style>
<Form.Item
label="总学时"
hasFeedback
@ -637,15 +670,15 @@ class CoursesNew extends Component {
{getFieldDecorator("period",
{
rules:[{
required:false,
pattern: new RegExp(/^[0-9]\d*$/, "g"),
message: ''
}],
getValueFromEvent: (event) => {
return event.target.value.replace(/\D/g,'')
}}
pattern: new RegExp(/^[0-9]+([.]{1}[0-9]+){0,1}$/, "g"),
message: '必须是数值'
},
{
max:5,
message: '不能超过5个字符',
}]}
)(
<Input id="period" className="greyInput " placeholder="例如30"/>
<Input id="period" className="yslzxueshi " placeholder="例如30" addonAfter={String(addonAfteronelen)+"/5"} maxLength={5}/>
)}
</Form.Item>
@ -656,15 +689,16 @@ class CoursesNew extends Component {
{getFieldDecorator("credit",
{
rules:[{
required:false,
pattern: new RegExp(/^[0-9]\d*$/, "g"),
message: ''
}],
getValueFromEvent: (event) => {
return event.target.value.replace(/\D/g,'')
}}
pattern: new RegExp(/^[0-9]+([.]{1}[0-9]+){0,1}$/, "g"),
message: '必须是数值'
},
{
max:5,
message: '不能超过5个字符',
}
]}
)(
<Input id="credit" className={"greyInput "} placeholder="例如3"/>
<Input id="credit" className="yslzxueshi" placeholder="例如3" addonAfter={String(addonAfteronelen)+"/5"} maxLength={5}/>
)}
</Form.Item>
<Form.Item
@ -696,7 +730,6 @@ class CoursesNew extends Component {
label="课堂模块"
hasFeedback
>
{getFieldDecorator("checkboxgroup", {
initialValue: [
"shixun_homework", "common_homework", "group_homework", "exercise", "attachment", "course_group",

@ -27,7 +27,9 @@ function disabledDateTime() {
disabledMinutes: () => range(1, 30).concat(range(31, 60)),
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
// function disabledDate(current) {
// console.log(current);
// return current && current < moment().endOf('day').subtract(1, 'days');
@ -49,13 +51,15 @@ class Goldsubject extends Component {
fetching:false,
subject_id:"",
start_date:"",
addonAfteronelenone:"",
addonAfteronelentwo:"",
Whethertocreateanewclassroom:true,
checkbofrup:[
{module_type:"announcement",module_name:"公告栏"},{module_type:"online_learning",module_name:"在线学习"}
,{module_type:"shixun_homework",module_name:"实训作业"},{module_type:"common_homework",module_name:"普通作业"}
,{module_type:"exercise",module_name:"试卷"},{module_type:"poll",module_name:"问卷"}
,{module_type:"attachment",module_name:"资源"},{module_type:"board",module_name:"讨论"},{module_type:"course_group",module_name:"分班"},],
checkbofrups:[],
}
}
// disabledEndDate= endValue => {
@ -121,8 +125,8 @@ class Goldsubject extends Component {
this.props.form.setFieldsValue({
course: data.course_list_name,
classroom: data.name,
period: data.class_period,
credit: data.credit,
period: data.class_period===undefined?'':data.class_period===null?'':data.class_period===null?'':data.class_period==="null"?'':data.class_period+"",
credit: data.credit===undefined?'':data.credit===null?'':data.credit===null?'':data.credit==="null"?'':data.credit+"",
checkboxgroup: data.course_module_types,
Realnamecertification: data.authentication,
Professionalcertification:data.professional_certification,
@ -140,22 +144,13 @@ class Goldsubject extends Component {
Professionalcertification:data.professional_certification,
name: data.name,
class_period: data.class_period,
credit: parseFloat(data.credit),
addonAfteronelenone: data.class_period===undefined?'':data.class_period===null?'':data.class_period===null?'':data.class_period==="null"?'':data.class_period,
credit: parseFloat(data.credit),
addonAfteronelentwo:data.credit===undefined?'':data.credit===null?'':data.credit===null?'':data.credit==="null"?'':data.credit,
course_module_types: data.course_module_types,
school:data.school,
Whethertocreateanewclassroom:false,
});
// try {
// if(data.course_modules===undefined||data.course_modules.length===0){
// this.setState({
// checkbofrups:this.state.checkbofrup,
// });
// }
// }catch (e) {
// this.setState({
// checkbofrups:this.state.checkbofrup,
// });
// }
this.handleSearchschool(data.school);
}).catch((error) => {
console.log(error);
@ -607,7 +602,7 @@ class Goldsubject extends Component {
this.applyForAddOrgForm.setVisible(true)
}
render() {
let {datatime,datatimetwo,school,searchlistscholl,Whethertocreateanewclassroom} = this.state;
let {datatime,datatimetwo,school,searchlistscholl,Whethertocreateanewclassroom,addonAfteronelenone,addonAfteronelentwo} = this.state;
const {getFieldDecorator} = this.props.form;
const propsWithoutForm = Object.assign({}, this.props)
delete propsWithoutForm.form
@ -619,6 +614,18 @@ class Goldsubject extends Component {
// console.log(this.state);
// console.log(this.props);
// console.log(this.props.current_user);
var addonAfterone=this.props.form&&this.props.form.getFieldValue('period');
var addonAfteronelen=0;
if(addonAfterone){
addonAfteronelen=String(addonAfterone).length;
}
var addonAftertwo=this.props.form&&this.props.form.getFieldValue('credit');
var addonAfteronelens=0;
if(addonAftertwo){
addonAfteronelens=String(addonAftertwo).length;
}
console.log(addonAfteronelenone);
console.log(addonAfteronelentwo);
return (
<React.Fragment>
@ -786,6 +793,23 @@ class Goldsubject extends Component {
}
`}
</style>
<style>{
`
.yslzxueshi .ant-input{
border-right: none !important;
height: 40px !important;
width: 236px !important
}
.yslzxueshi .ant-input-group {
width: 280px !important;
}
.yslzxueshi .ant-input-group-addon{
width: 44px !important;
background-color: #fafafa!important;
}
`
}</style>
<Form.Item
label="总学时"
hasFeedback
@ -793,18 +817,17 @@ class Goldsubject extends Component {
{getFieldDecorator("period",
{
rules:[{
required:false,
pattern: new RegExp(/^[0-9]\d*$/, "g"),
message: ''
}],
getValueFromEvent: (event) => {
return event.target.value.replace(/\D/g,'')
}}
pattern: new RegExp(/^[0-9]+([.]{1}[0-9]+){0,1}$/, "g"),
message: '必须是数值'
},
{
max:5,
message: '不能超过5个字符',
}]}
)(
<Input id="period" className="greyInput " placeholder="例如30"/>
<Input id="period" placeholder="例如30" className="yslzxueshi" addonAfter={String(addonAfteronelen)+"/5"} maxLength={5}/>
)}
</Form.Item>
<Form.Item
label="学分"
hasFeedback
@ -812,15 +835,16 @@ class Goldsubject extends Component {
{getFieldDecorator("credit",
{
rules:[{
required:false,
pattern: new RegExp(/^[0-9]\d*$/, "g"),
message: ''
}],
getValueFromEvent: (event) => {
return event.target.value.replace(/\D/g,'')
}}
pattern: new RegExp(/^[0-9]+([.]{1}[0-9]+){0,1}$/, "g"),
message: '必须是数值'
},
{
max:5,
message: '不能超过5个字符',
}
]}
)(
<Input id="credit" className={"greyInput "} placeholder="例如3"/>
<Input id="credit" placeholder="例如3" className="yslzxueshi" addonAfter={String(addonAfteronelens)+"/5"} maxLength={5}/>
)}
</Form.Item>
<Form.Item
@ -850,7 +874,8 @@ class Goldsubject extends Component {
label="结束时间"
>
{getFieldDecorator("endtime", {
rules: [{type: 'object',required: true, message: "结束时间不能为空"}],
rules: [{type: 'object',
required: true, message: "结束时间不能为空"}],
})(
<span className="fl mt5">
<DatePicker

@ -52,11 +52,18 @@ class ActionView extends Component {
componentDidMount() {
// request
window._tpiWidthResize = () => {
if (window.$('#actionView').width() < 580) {
window.$('.time_limit').hide()
} else {
window.$('.time_limit').show()
}
const _w = window.$('#actionView').width();
// if (_w < 446) {
// window.$('#time-consuming').hide()
// // window.$('#time-consuming').hide()
// } else if (_w < 746) {
// // 文字放出来之前是 580
// window.$('#time-consuming').show()
// window.$('.time_limit').hide()
// } else {
// window.$('#time-consuming').show()
// window.$('.time_limit').show()
// }
}
}
@ -70,24 +77,50 @@ class ActionView extends Component {
return (
<div className="-flex -layout-h" id="game_operate_action">
<style>{`
#game_operate_action {
width: 100%;
}
.time_limit {
margin-right: 16px;
margin-right: 0px;
}
.spliter {
border-right: 1px solid;
padding-right: 8px;
margin-right: 8px;
height: 14px;
display: inline-block;
position: relative;
top: 3px;
}
#time-consuming {
flex: auto;
overflow: hidden;
white-space: nowrap;
}
#game_operate_action .act_btn {
flex: 0 0 90px;
}
`}</style>
<span className="mt10 -flex c_grey ml15" id="time-consuming">
{!!time_limit &&
<span className="time_limit">{`本关最大执行时间:${real_time_limit}`}</span>}
<span className="time_limit">{`本关最大执行时间:${real_time_limit}`}
{!gameBuilding && record && <span className="spliter"></span>}
</span>}
{!gameBuilding && record ?
<Tooltip title={ "本次评测耗时(编译、运行总时间)" }>
<span>{ record } </span>
</Tooltip>
// <Tooltip title={ "本次评测耗时(编译、运行总时间)" }></Tooltip>
<span>本次评测耗时(编译运行总时间){ record } </span>
: ""}
</span>
{/*将第一个按钮改为visibility方式隐藏不然加载时测评按钮会出现没有垂直居中的情况*/}
<Tooltip title={ "倒计时为0时服务将被关闭" }>
<Button size="small" className={classes.button + ' actionViewfirstButton'} onClick={()=>this.showWebDisplay(challenge)}
style={{ visibility: challenge.showWebDisplayButton ? '': 'hidden'}}
style={{ visibility: challenge.showWebDisplayButton ? '': 'hidden',
minWidth: challenge.showWebDisplayButton ? '': '1px',
width: challenge.showWebDisplayButton ? '': '1px',
flex: `0 0 ${challenge.showWebDisplayButton ? '110px': '1px'}`
}}
id="showWebDisplayButton"
// style={{ display: challenge.showWebDisplayButton ? 'flex': 'none'}}
>
@ -98,7 +131,7 @@ class ActionView extends Component {
{
!gameBuilding &&
(game && !!game.prev_game) ?
<Link to={`/tasks/${game.prev_game}`} className={classes.buttonText}>
<Link to={`/tasks/${game.prev_game}`} className={classes.buttonText + ' act_btn'}>
<Button size="small" className={classes.button}>
上一关
</Button>
@ -108,7 +141,7 @@ class ActionView extends Component {
{/*未发布的都能跳转*/}
{ !gameBuilding &&
((game && (game.status === 2 || shixun.status < 2) || shixun && shixun.task_pass ) && !!game.next_game) ?
<Link to={`/tasks/${game.next_game}`} className={classes.buttonText}>
<Link to={`/tasks/${game.next_game}`} className={classes.buttonText + ' act_btn'}>
<Button size="small" className={classes.button}>
下一关
</Button>
@ -117,11 +150,11 @@ class ActionView extends Component {
<div id="code_test">
<div id="code_test" className="act_btn">
{
st === 1 && game.status === 2 ?
<Tooltip title={ "已通关的选择题任务无法再次测评" }>
<a href="javascript:void(0)" className="shixun-task-btn mr15 gray"
<a href="javascript:void(0)" className="shixun-task-btn mr15 gray "
>
<i className="fa fa-play-circle font-16"></i>
测评
@ -130,7 +163,7 @@ class ActionView extends Component {
:
gameBuilding ?
<a href="javascript:void(0)" className="shixun-task-btn mr15 gray"
<a href="javascript:void(0)" className="shixun-task-btn mr15 gray "
>
<i className="fa fa-play-circle font-16"></i>
测评

@ -14,13 +14,16 @@
min-width: 280px;
}
#time-consuming .time_limit {
display: none;
}
.actionViewfirstButton {
display: none !important;
}
}
@media (max-width: 800px) {
#time-consuming .time_limit {
display: none;
}
}
@media (max-width: 628px) {
.-header-right { display: none }
.exitBtn span { display: none }

@ -297,43 +297,49 @@ class DetailCardsEditAndAdd extends Component{
contentViewScrolladd=(e)=>{
const {ChooseShixunList}=this.state;
//滑动到底判断
if(e.currentTarget.scrollHeight-e.currentTarget.scrollTop===e.currentTarget.clientHeight){
// console.log("到达底部");
this.setState({
hometypepvisible:true
})
let pathId=this.props.pathid;
let {search,page,type,ChooseShixunListshixun_list}=this.state;
let newpage=page+1;
let newChooseShixunListshixun_list=ChooseShixunListshixun_list;
let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage
if(search!="" && search!=undefined){
url+="&search="+search;
}
if(type!=0){
url+="&type="+type;
}
axios.get(url).then((result)=>{
if(result.status===200){
let list =result.data.shixun_list;
for(var i=0; i<list.length; i++){
newChooseShixunListshixun_list.push(list[i])
}
this.setState({
ChooseShixunList:result.data,
hometypepvisible:false,
type:type,
search:search,
page:newpage,
ChooseShixunListshixun_list:newChooseShixunListshixun_list
})
}
}).catch((error)=>{
console.log(error);
})
if(ChooseShixunList.shixun_list.length===0){
return
}else{
// console.log("到达底部");
this.setState({
hometypepvisible:true
})
let pathId=this.props.pathid;
let {search,page,type,ChooseShixunListshixun_list}=this.state;
let newpage=page+1;
let newChooseShixunListshixun_list=ChooseShixunListshixun_list;
let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage
if(search!="" && search!=undefined){
url+="&search="+search;
}
if(type!=0){
url+="&type="+type;
}
axios.get(url).then((result)=>{
if(result.status===200){
let list =result.data.shixun_list;
for(var i=0; i<list.length; i++){
newChooseShixunListshixun_list.push(list[i])
}
this.setState({
ChooseShixunList:result.data,
hometypepvisible:false,
type:type,
search:search,
page:newpage,
ChooseShixunListshixun_list:newChooseShixunListshixun_list
})
}
}).catch((error)=>{
console.log(error);
})
}
}

@ -338,50 +338,59 @@ class DetailCardsEditAndEdit extends Component{
contentViewScrolledit=(e)=>{
//滑动到底判断
const {ChooseShixunList}=this.state;
if(e.currentTarget.scrollHeight-e.currentTarget.scrollTop===e.currentTarget.clientHeight){
this.setState({
hometypepvisible:true
})
// console.log("到达底部");
let {page,type,search,ChooseShixunListshixun_list}=this.state;
if(ChooseShixunList.shixun_list.length===0){
return
}else{
this.setState({
hometypepvisible:true
})
// console.log("到达底部");
let newpage=page+1;
let {page,type,search,ChooseShixunListshixun_list}=this.state;
let pathId=this.props.pathid;
let newpage=page+1;
let newChooseShixunListshixun_list=ChooseShixunListshixun_list;
let pathId=this.props.pathid;
let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage
let newChooseShixunListshixun_list=ChooseShixunListshixun_list;
if(search!="" && search!=undefined){
url+="&search="+search;
}
let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage
if(type!=0){
url+="&type="+type;
}
axios.get(url).then((result)=>{
if(result.status===200){
if(search!="" && search!=undefined){
url+="&search="+search;
}
if(type!=0){
url+="&type="+type;
}
axios.get(url).then((result)=>{
if(result.status===200){
let list =result.data.shixun_list;
for(var i=0; i<list.length; i++){
newChooseShixunListshixun_list.push(list[i])
}
this.setState({
ChooseShixunList:result.data,
hometypepvisible:false,
type:type,
page:newpage,
search:search,
ChooseShixunListshixun_list:newChooseShixunListshixun_list
})
}
}).catch((error)=>{
console.log(error);
})
}
let list =result.data.shixun_list;
for(var i=0; i<list.length; i++){
newChooseShixunListshixun_list.push(list[i])
}
this.setState({
ChooseShixunList:result.data,
hometypepvisible:false,
type:type,
page:newpage,
search:search,
ChooseShixunListshixun_list:newChooseShixunListshixun_list
})
}
}).catch((error)=>{
console.log(error);
})
}

@ -475,7 +475,10 @@ export default class TPMevaluation extends Component {
}
handpathoptionvalue=(value)=>{
this.setState({
pathoptionvalue:value
pathoptionvalue:value,
shixunfileexpectpicturepath:undefined,
shixunfilestandardpicturepath:undefined,
shixunfilepicturepath:undefined
})
}
showrepositoryurltip=(type)=>{
@ -640,19 +643,20 @@ export default class TPMevaluation extends Component {
let id = this.props.match.params.shixunId;
let{checkpointId}=this.state;
let url = "/shixuns/"+id+"/challenges/"+checkpointId+".json";
let newchallenge={
path:shixunfilepath,
exec_path:shixunfilepathplay,
show_type:pathoptionvalue,
original_picture_path:pathoptionvalue===-1?undefined:shixunfileexpectpicturepath===undefined?null:shixunfileexpectpicturepath,
expect_picture_path:pathoptionvalue===-1?undefined:shixunfilestandardpicturepath===undefined?null:shixunfilestandardpicturepath,
picture_path:pathoptionvalue===-1?undefined:shixunfilepicturepath===undefined?null:shixunfilepicturepath,
test_set_score:newscorevalue,
test_set_average:markvalue,
web_route:web_route===null?undefined:web_route
}
axios.put(url,{
tab:1,
challenge:{
path:shixunfilepath,
exec_path:shixunfilepathplay,
show_type:pathoptionvalue,
original_picture_path:shixunfileexpectpicturepath,
expect_picture_path:shixunfilestandardpicturepath,
picture_path:shixunfilepicturepath,
test_set_score:newscorevalue,
test_set_average:markvalue,
web_route:web_route===null?undefined:web_route
},
challenge:newchallenge,
test_set:evaluationlist
}
).then((response) => {

@ -26,6 +26,8 @@ class InfosBanner extends Component{
let {username}= this.props.match.params;
let {pathname}=this.props.location;
moduleName=pathname.split("/")[3];
console.log(is_current)
return(
<div className="bannerPanel mb60">
<div className="educontent">
@ -113,6 +115,14 @@ class InfosBanner extends Component{
onClick={() => this.setState({moduleName: 'videos'})}
to={`/users/${username}/videos`}>视频</Link>
</li>}
{((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
&& <li className={`${moduleName == 'videos' ? 'active' : '' }`}>
<Link
onClick={() => this.setState({moduleName: 'videos'})}
to={`/users/${username}/videos`}>题库</Link>
</li>}
</div>
</div>
</div>

@ -1,6 +1,6 @@
/*global __webpack_public_path__ */
if (window._enableCDN && window.location.host == 'pre-newweb.educoder.net') {
__webpack_public_path__ = 'http://testali-cdn.educoder.net/react/build/'
} else if (window._enableCDN && window.location.host == 'www.educoder.net') {
__webpack_public_path__ = 'https://ali-newweb.educoder.net/react/build/'
if ( window.location.host == 'pre-newweb.educoder.net') {
__webpack_public_path__ = 'https://testali-cdn.educoder.net/react/build/'
} else if ( window.location.host == 'www.educoder.net') {
__webpack_public_path__ = 'https://ali-cdn.educoder.net/react/build/'
}

@ -448,8 +448,8 @@ table.text-file{}
/*-------------------------------实训路径-------------------------------*/
.path-head{width: 100%;height: 300px;background-image: url("/images/educoder/path.png");
background-color: #081C4B;
background-size: cover;
background-color: #000a4f;
/*background-size: cover;*/
background-position: center;
background-repeat: no-repeat;
}

Loading…
Cancel
Save