Merge remote-tracking branch 'origin/develop' into develop

dev_daiao
杨树明 5 years ago
commit 8c032e4c4d

@ -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({ searchForm.find('.school-select').select2({
theme: 'bootstrap4', 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(){ $(document).on('turbolinks:load', function(){
if ($('body.admins-shixun-feedback-messages-index-page').length > 0) { if ($('body.admins-shixun-feedback-messages-index-page').length > 0) {
$(".content-img img").addClass("w-100").addClass("preview-image");
var baseOptions = { var baseOptions = {
autoclose: true, autoclose: true,
language: 'zh-CN', language: 'zh-CN',
format: 'yyyy-mm-dd 00:00:00', format: 'yyyy-mm-dd 00:00:00',
startDate: '2017-04-01' startDate: '2017-04-01'
} };
var defineDateRangeSelect = function(element){ var defineDateRangeSelect = function(element){
var options = $.extend({inputs: $(element).find('.start-date, .end-date')}, baseOptions); 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('.start-date').datepicker().on('changeDate', function(e){
$(element).find('.end-date').datepicker('setStartDate', e.date); $(element).find('.end-date').datepicker('setStartDate', e.date);
}) });
}; };
defineDateRangeSelect('.grow-date-input-daterange'); 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,9 @@
class Admins::ShixunModifyRecordsController < Admins::BaseController
def index
records = Admins::ShixunModifyRecordQuery.call(params)
@records = paginate records.includes(:diff_record_content)
end
end

@ -18,9 +18,9 @@ class AttachmentsController < ApplicationController
pdf_attachment = params[:disposition] || "attachment" pdf_attachment = params[:disposition] || "attachment"
if pdf_attachment == "inline" if pdf_attachment == "inline"
send_file absolute_path(local_path(@file)),filename: @file.filename, disposition: 'inline',type: 'application/pdf' send_file absolute_path(local_path(@file)),filename: @file.title, disposition: 'inline',type: 'application/pdf'
else else
send_file(absolute_path(local_path(@file)), filename: @file.filename,stream:false, type: @file.content_type.presence || 'application/octet-stream') send_file(absolute_path(local_path(@file)), filename: @file.title,stream:false, type: @file.content_type.presence || 'application/octet-stream')
end end
update_downloads(@file) update_downloads(@file)
end end

@ -1,13 +1,14 @@
class HackUserLastestCodesController < ApplicationController class HackUserLastestCodesController < ApplicationController
before_action :require_login, except: [:listen_result] 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] :listen_result, :result, :submit_records, :restore_initial_code]
before_action :update_user_hack_status, only: [:code_debug, :code_submit] 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] before_action :require_manager_identity, only: [:update_code]
def show def show
@my_hack.update_attribute(:submit_status, 0) if @my_hack.submit_status == 1 @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 end
def update_code def update_code
@ -20,6 +21,11 @@ class HackUserLastestCodesController < ApplicationController
@my_hack.update_attribute(:code, @hack.code) @my_hack.update_attribute(:code, @hack.code)
end end
# 同步代码
def sync_code
@my_hack.update_attributes(code: @hack.code, modify_time: @hack.modify_time)
end
# 调试代码 # 调试代码
def code_debug def code_debug
exec_mode = "debug" exec_mode = "debug"

@ -1,7 +1,7 @@
class HacksController < ApplicationController class HacksController < ApplicationController
before_action :require_login, except: [:index] before_action :require_login, except: [:index]
before_action :find_hack, only: [:edit, :update, :publish, :start, :update_set, :delete_set] 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] before_action :require_auth_identity, only: [:update, :edit, :publish, :update_set, :delete_set]
@ -15,7 +15,7 @@ class HacksController < ApplicationController
user_hack.identifier user_hack.identifier
else else
user_identifier = generate_identifier HackUserLastestCode, 12 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} identifier: user_identifier, language: @hack.language}
@hack.hack_user_lastest_codes.create!(user_code) @hack.hack_user_lastest_codes.create!(user_code)
user_identifier user_identifier
@ -47,10 +47,8 @@ class HacksController < ApplicationController
hack.identifier = generate_identifier Hack, 8 hack.identifier = generate_identifier Hack, 8
hack.save! 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_sets.create!(hack_sets_params)
hack.hack_codes.create!(hack_code_params) hack.hack_codes.create!(hack_code_params.merge(modify_time: Time.now))
end end
render_ok({identifier: hack.identifier}) render_ok({identifier: hack.identifier})
rescue Exception => e rescue Exception => e
@ -69,6 +67,9 @@ class HacksController < ApplicationController
# 新建 # 新建
@hack.hack_sets.create!(hack_sets_params) @hack.hack_sets.create!(hack_sets_params)
# 更新代码 # 更新代码
if params[:hack_codes][:code] != @hack.code
hack_code_params = hack_code_params.merge(modify_time: Time.now)
end
@hack.hack_codes.create!(hack_code_params) @hack.hack_codes.create!(hack_code_params)
end end
render_ok render_ok
@ -109,6 +110,8 @@ class HacksController < ApplicationController
def edit;end def edit;end
def new;end
private private
# 实名认证老师,管理员与运营人员权限 # 实名认证老师,管理员与运营人员权限
def require_teacher_identity def require_teacher_identity

@ -1416,7 +1416,7 @@ class PollsController < ApplicationController
if user_poll_answer_ids.count >1 if user_poll_answer_ids.count >1
u_answer = answer_content.pluck(:answer_text).join(";") u_answer = answer_content.pluck(:answer_text).join(";")
else else
u_answer = answer_content.first.answer_text u_answer = answer_content.first&.answer_text
end end
elsif user_poll_vote_texts.count > 0 elsif user_poll_vote_texts.count > 0
if user_poll_vote_texts.count > 1 if user_poll_vote_texts.count > 1

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

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

@ -27,12 +27,21 @@ class Attachment < ApplicationRecord
validates_length_of :description, maximum: 100 validates_length_of :description, maximum: 100
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
def diskfile def diskfile
File.join(File.join(Rails.root, "files"), disk_directory.to_s, disk_filename.to_s) File.join(File.join(Rails.root, "files"), disk_directory.to_s, disk_filename.to_s)
end end
def title def title
filename title = filename
if container.is_a?(StudentWork) && author_id != User.current.id
course = container&.homework_common&.course
unless User.current.teacher_of_course?(course)
title = "#{Time.now.strftime('%Y%m%d%H%M%S')}_#{DCODES.sample(8).join}" + File.extname(filename)
end
end
title
end end
def downloads_count def downloads_count

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

@ -3,6 +3,8 @@ class Hack < ApplicationRecord
# diffcult: 难度 1简单2中等 3困难 # diffcult: 难度 1简单2中等 3困难
# 编程题 # 编程题
validates_length_of :name, maximum: 60 validates_length_of :name, maximum: 60
validates :description, presence: { message: "描述不能为空" }
validates :name, presence: { message: "名称不能为空" }
# 测试集 # 测试集
has_many :hack_sets, ->{order("position asc")}, :dependent => :destroy has_many :hack_sets, ->{order("position asc")}, :dependent => :destroy
# 代码 # 代码

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

@ -25,6 +25,7 @@ class CreateDiffRecordService < ApplicationService
index = 0 index = 0
fragment_size = 1 fragment_size = 1
Diffy::Diff.new(before, after).each do |line| Diffy::Diff.new(before, after).each do |line|
unless line.include?("\\ 文件尾没有 newline 字符")
unless line =~ /^[\+-]/ unless line =~ /^[\+-]/
if arr.empty? && index < fragment_size if arr.empty? && index < fragment_size
content += line content += line
@ -41,6 +42,7 @@ class CreateDiffRecordService < ApplicationService
content += line content += line
arr.clear arr.clear
end end
end
content content
end end
end end

@ -27,7 +27,8 @@
<li><%= sidebar_item(admins_shixun_settings_path, '实训配置', icon: 'cog', controller: 'admins-shixun_settings') %></li> <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_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_myshixuns_path, '学员实训列表', icon: 'server', controller: 'admins-myshixuns') %></li>
<li><%= sidebar_item(admins_shixun_recycles_path, '实训回收站', icon: 'recycle', controller: 'admins-myshixuns') %></li> <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 %> <% end %>
</li> </li>

@ -15,7 +15,7 @@
<td><%= (@params_page.to_i - 1) * 20 + index + 1 %></td> <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 %> <% 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"><%= 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><%= discuss.user.show_real_name %></td>
<td><%= format_time discuss.created_at %></td> <td><%= format_time discuss.created_at %></td>
</tr> </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 } %>

@ -5,8 +5,13 @@ json.hack do
json.code @my_hack.code json.code @my_hack.code
json.pass_count @hack.pass_num json.pass_count @hack.pass_num
json.submit_count @hack.submit_num json.submit_count @hack.submit_num
json.modify_code @modify
end end
json.test_case do json.test_case do
json.input @hack.input_test_case json.input @hack.input_test_case
end end
json.user do
json.partial! 'users/user', user: current_user
end

@ -11,3 +11,6 @@ json.hack_sets do
json.(set, :id, :input, :output, :position) json.(set, :id, :input, :output, :position)
end end
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

@ -15,6 +15,7 @@ json.shixuns_list do
json.shixun_name shixun.name json.shixun_name shixun.name
json.shixun_hidden shixun.hidden json.shixun_hidden shixun.hidden
json.identifier shixun.identifier 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.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) json.shixun_status stage_shixun_status(subject.status, shixun.status, shixun.hidden)
end end

@ -11,7 +11,7 @@ json.update_user_name @is_evaluation ? "匿名" : @work.update_user.try(:real_na
json.update_atta @homework.late_duration && @is_author json.update_atta @homework.late_duration && @is_author
json.attachments @attachments do |atta| json.attachments @attachments do |atta|
json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: false} json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: false, }
end end
unless @is_evaluation unless @is_evaluation

@ -59,6 +59,7 @@ Rails.application.routes.draw do
get :result get :result
get :submit_records get :submit_records
post :restore_initial_code post :restore_initial_code
post :sync_code
end end
collection do collection do
@ -1056,6 +1057,7 @@ Rails.application.routes.draw do
resources :shixun_recycles, only: [:index, :destroy] do resources :shixun_recycles, only: [:index, :destroy] do
post :resume, on: :member post :resume, on: :member
end end
resources :shixun_modify_records, only: [:index]
resources :department_applies,only: [:index,:destroy] do resources :department_applies,only: [:index,:destroy] do
collection do collection do
post :merge post :merge

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -132,7 +132,9 @@ class Trainingjobsetting extends Component {
CalculateMax: 100,//总分值 CalculateMax: 100,//总分值
borredszf:"ml10 color-grey-9", borredszf:"ml10 color-grey-9",
borredszfl:true, borredszfl:true,
borredszfls:'' borredszfls:'',
total_scoretwo:0,
total_score:0,
} }
// console.log("获取到的值") // console.log("获取到的值")
// console.log("Trainingjobsetting") // console.log("Trainingjobsetting")
@ -302,7 +304,10 @@ class Trainingjobsetting extends Component {
proportion: result.data.shixun_evaluation === 0 ? "均分比例" : result.data.shixun_evaluation === 1 ? "经验值比例" : result.data.shixun_evaluation === 2 ? "自定义分值" : "", proportion: result.data.shixun_evaluation === 0 ? "均分比例" : result.data.shixun_evaluation === 1 ? "经验值比例" : result.data.shixun_evaluation === 2 ? "自定义分值" : "",
publicwork: result.data.work_public, publicwork: result.data.work_public,
challenge_settings: result.data.challenge_settings, challenge_settings: result.data.challenge_settings,
code_review: result.data.code_review code_review: result.data.code_review,
total_scoretwo:result.data.total_score,
total_score:result.data.total_score,
}) })
this.props.Getdataback(result, result.data); this.props.Getdataback(result, result.data);
@ -646,6 +651,7 @@ class Trainingjobsetting extends Component {
if (this.state.completionefficiencyscore === true) { if (this.state.completionefficiencyscore === true) {
latedeductiontwos = this.state.latedeductiontwo; latedeductiontwos = this.state.latedeductiontwo;
} }
//从这里开始记得等于0的时候还要做判断
if (challenge_scoredata.length > 0) { if (challenge_scoredata.length > 0) {
var len = 0; var len = 0;
for (var k = 0; k < challenge_scoredata.length; k++) { for (var k = 0; k < challenge_scoredata.length; k++) {
@ -680,6 +686,16 @@ class Trainingjobsetting extends Component {
} }
}else{
try {
if(parseFloat(this.state.CalculateMax)!==parseFloat(0)){
this.props.showNotification(`分值之和必须等于总分值:${this.state.CalculateMax}`);
this.scrollToAnchor("zongfentimeid");
return;
}
}catch (e) {
}
} }
var url = `/homework_commons/${homeworkid}/update_settings.json`; var url = `/homework_commons/${homeworkid}/update_settings.json`;
@ -707,7 +723,9 @@ class Trainingjobsetting extends Component {
shixun_evaluation: this.state.proportion === "均分比例" ? 0 : this.state.proportion === "经验值比例" ? 1 : this.state.proportion === "自定义分值" ? 2 : 0, shixun_evaluation: this.state.proportion === "均分比例" ? 0 : this.state.proportion === "经验值比例" ? 1 : this.state.proportion === "自定义分值" ? 2 : 0,
challenge_settings: array, challenge_settings: array,
score_open: this.state.publicwork, score_open: this.state.publicwork,
total_score:this.state.CalculateMax total_score:this.state.CalculateMax,
total_scoretwo:this.state.CalculateMax,//记录总分值点击取消的时候还原总分值
} }
} else { } else {
// //非统一配置 // //非统一配置
@ -738,7 +756,8 @@ class Trainingjobsetting extends Component {
shixun_evaluation: this.state.proportion === "均分比例" ? 0 : this.state.proportion === "经验值比例" ? 1 : this.state.proportion === "自定义分值" ? 2 : 0, shixun_evaluation: this.state.proportion === "均分比例" ? 0 : this.state.proportion === "经验值比例" ? 1 : this.state.proportion === "自定义分值" ? 2 : 0,
challenge_settings: array, challenge_settings: array,
score_open: this.state.publicwork, score_open: this.state.publicwork,
total_score:this.state.CalculateMax total_score:this.state.CalculateMax,
total_scoretwo:this.state.CalculateMax
} }
} }
@ -1193,8 +1212,7 @@ class Trainingjobsetting extends Component {
} }
//总比分 //总比分
Totalscorecalculation = (value) => { Totalscorecalculation = (value) => {
debugger
this.setState({ this.setState({
CalculateMax: value, CalculateMax: value,
}) })
@ -2150,6 +2168,9 @@ class Trainingjobsetting extends Component {
}) })
this.refs.targetElementTrainingjobsetting.scrollIntoView(); this.refs.targetElementTrainingjobsetting.scrollIntoView();
this.getTrainingjobsetting(false); this.getTrainingjobsetting(false);
this.setState({
CalculateMax:this.state.total_scoretwo,
})
} }
rulesCheckInfo = (rules) => { rulesCheckInfo = (rules) => {

@ -179,7 +179,6 @@ class DeveloperHome extends React.PureComponent {
componentDidMount() { componentDidMount() {
// 是否是我的,如果是我的 显示编辑按钮 // 是否是我的,如果是我的 显示编辑按钮
const { isMySource } = this.props; const { isMySource } = this.props;
console.log(this.props); console.log(this.props);
if (isMySource) { if (isMySource) {
this.handleFilterSearch({come_from: 'mine'}); this.handleFilterSearch({come_from: 'mine'});

@ -7,6 +7,7 @@
*/ */
import React from 'react'; import React from 'react';
import { TPMIndexHOC } from '../tpm/TPMIndexHOC'; import { TPMIndexHOC } from '../tpm/TPMIndexHOC';
import { SnackbarHOC } from 'educoder';
import DeveloperHome from './DeveloperHome'; import DeveloperHome from './DeveloperHome';
const App = (props) => { const App = (props) => {
@ -15,4 +16,4 @@ const App = (props) => {
); );
} }
export default TPMIndexHOC(App); export default SnackbarHOC()(TPMIndexHOC(App));

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2019-11-20 10:35:40 * @Date: 2019-11-20 10:35:40
* @LastEditors: tangjiang * @LastEditors: tangjiang
* @LastEditTime: 2019-12-04 19:56:43 * @LastEditTime: 2019-12-05 18:07:32
*/ */
import 'quill/dist/quill.core.css'; import 'quill/dist/quill.core.css';
import 'quill/dist/quill.bubble.css'; import 'quill/dist/quill.bubble.css';
@ -18,6 +18,7 @@ import AddTestDemo from './AddTestDemo';
import QuillEditor from '../../../quillEditor'; import QuillEditor from '../../../quillEditor';
import actions from '../../../../../redux/actions'; import actions from '../../../../../redux/actions';
import CONST from '../../../../../constants'; import CONST from '../../../../../constants';
import { fromStore, toStore } from 'educoder'; // 保存和读取store值
const scrollIntoView = require('scroll-into-view'); const scrollIntoView = require('scroll-into-view');
const {jcLabel} = CONST; const {jcLabel} = CONST;
const FormItem = Form.Item; const FormItem = Form.Item;
@ -110,6 +111,8 @@ class EditTab extends React.Component {
// 改变描述信息 // 改变描述信息
handleChangeDescription = (value) => { handleChangeDescription = (value) => {
// console.log('获取的编辑器内容为: ', value); // console.log('获取的编辑器内容为: ', value);
// 描述信息变化时将信息保存至store中
toStore('oj_description', value);
this.props.validateOjDescription(value); this.props.validateOjDescription(value);
} }
// 改变难易度 // 改变难易度

@ -47,7 +47,7 @@ const five_min = 5 * 60 * 1000;
倒计时为0时出现重启按钮 倒计时为0时出现重启按钮
*/ */
const isSSHInIframe = false; const isSSHInIframe = false;
class WebSSHTimer extends React.PureComponent { class WebSSHTimer extends Component {
constructor(props) { constructor(props) {
super(props) super(props)
@ -165,7 +165,6 @@ class WebSSHTimer extends React.PureComponent {
}) })
} }
componentDidUpdate(prevProps, prevState, snapshot) { componentDidUpdate(prevProps, prevState, snapshot) {
console.log('======',prevProps, this.state, this.startTimeRemain);
// 仅初始化一次 // 仅初始化一次
if (prevProps.showTimerProp === false && this.props.showTimerProp === true) { if (prevProps.showTimerProp === false && this.props.showTimerProp === true) {
if (this.intervalHandler) { if (this.intervalHandler) {
@ -199,8 +198,8 @@ class WebSSHTimer extends React.PureComponent {
// } // }
} else if (e.data.tp === "sshWorking") { } else if (e.data.tp === "sshWorking") {
this.startTimeRemain = 60; // this.startTimeRemain = 60;
this.forceUpdate() // this.forceUpdate();
} }
}); });
// } else { // } else {

@ -244,7 +244,9 @@ class TPIMonaco extends Component {
// 重要setState(因获取代码、重置代码等接口引起的调用)调用引起的变化才需要setValue // 重要setState(因获取代码、重置代码等接口引起的调用)调用引起的变化才需要setValue
editor_monaco.setValue(this.props.repositoryCode) editor_monaco.setValue(this.props.repositoryCode)
} }
// 代码没变也需要layout可能从命令行自动切回了代码tab // 代码没变也需要layout可能从命令行自动切回了代码tab
editor_monaco.layout();
// Clears the editor's undo history. // Clears the editor's undo history.
// TODO // TODO

@ -136,7 +136,7 @@ class AccountBasic extends Component {
} }
handleSubmit = () => { handleSubmit = () => {
this.props.form.validateFieldsAndScroll((err, values) => { this.props.form.validateFieldsAndScroll({ force: true }, (err, values) => {
console.log(values); console.log(values);
let {basicInfo}=this.props; let {basicInfo}=this.props;
if(!err ){ if(!err ){
@ -390,13 +390,13 @@ class AccountBasic extends Component {
this.props.showNotification("请先选择正确的单位或者学校!"); this.props.showNotification("请先选择正确的单位或者学校!");
} }
} }
checkNameLength = (rule, value, callback) => { // checkNameLength = (rule, value, callback) => {
if (value && value.length <= MAX_NAME_LENGTH) { // if (value && value.length <= MAX_NAME_LENGTH) {
callback(); // callback();
return; // return;
} // }
callback(`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`); // callback(`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`);
} // }
// 切换职称 // 切换职称
changeJob=(e)=>{ changeJob=(e)=>{
this.setState({ this.setState({
@ -410,7 +410,51 @@ class AccountBasic extends Component {
}) })
} }
} }
//昵称
handleSubmitName(rule, value, callback){
if (value) {
let iconRule1 = /[`~!@#$%^&*()\-+=<>?:"{}|,.\/;'\\[\]·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/im;
// 判断是否含有emoji表情
let iconRule2 = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
// 如果为true字符串含有emoji表情 false不含
const iconRule2s =iconRule2.test(value);
// 如果为true字符串含有特殊符号 false不
const iconRule1s =iconRule1.test(value);
if (iconRule2s===true|| iconRule1s===true) {
callback('2-20位中英文、数字及下划线');
}
else if(value.length<2){
callback('2-20位中英文、数字及下划线');
}else if(value.length>=21){
callback('2-20位中英文、数字及下划线');
}
}
callback();
}
// 姓名
handleSubmitNames(rule, value, callback){
if (value) {
let iconRule1 = /[`~!@#$%^&()_\-+=<>?:"{}|,.\/;'\\[\]·~@#¥%……&()——\-+={}|《》?:“”【】、;‘’,。、]/im;
// 判断是否含有emoji表情
let iconRule2 = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
// 如果为true字符串含有emoji表情 false不含
const iconRule2s =iconRule2.test(value);
// 如果为true字符串含有特殊符号 false不
const iconRule1s =iconRule1.test(value);
if (iconRule2s===true|| iconRule1s===true) {
callback('2-10位中英文、数字');
}
else if(value.length<2){
callback('2-10位中英文、数字');
}else if(value.length>=11){
callback('2-10位中英文、数字');
}
}
callback();
}
render() { render() {
let{ let{
nameLength, nameLength,
@ -527,7 +571,10 @@ class AccountBasic extends Component {
// initialValue: this.state.cityDefaultValue, // initialValue: this.state.cityDefaultValue,
required: true, required: true,
message: '请输入您的昵称', message: '请输入您的昵称',
}], },
{ validator: this.handleSubmitName },
],
validateTrigger: 'onSubmit', // 设置进行表单验证的时机为onSubmit
})( })(
<Input placeholder={`请输入您的昵称,最大限制${MAX_NICKNAME_LENGTH}个字符`} className="exercicenewinputysl" onInput={this.changeNickName} maxLength={MAX_NICKNAME_LENGTH} addonAfter ={ <Input placeholder={`请输入您的昵称,最大限制${MAX_NICKNAME_LENGTH}个字符`} className="exercicenewinputysl" onInput={this.changeNickName} maxLength={MAX_NICKNAME_LENGTH} addonAfter ={
<span className="color-grey-6 font-13">{String(nameLength)}/{MAX_NICKNAME_LENGTH}</span> <span className="color-grey-6 font-13">{String(nameLength)}/{MAX_NICKNAME_LENGTH}</span>
@ -554,8 +601,11 @@ class AccountBasic extends Component {
// initialValue: this.state.cityDefaultValue, // initialValue: this.state.cityDefaultValue,
required: true, required: true,
message: `请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`, message: `请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`,
validator: this.checkNameLength },
}], { validator: this.handleSubmitNames },
],
validateTrigger: 'onSubmit', // 设置进行表单验证的时机为onSubmit
})( })(
<Input placeholder={`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`} className="yslgraduainputedit" disabled={!showRealName && this.state.forDisable == true } addonAfter={ <Input placeholder={`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`} className="yslgraduainputedit" disabled={!showRealName && this.state.forDisable == true } addonAfter={
<i className={showRealName?"iconfont icon-xianshi font-18 color-blue":"iconfont icon-yincang font-18 color-blue"} <i className={showRealName?"iconfont icon-xianshi font-18 color-blue":"iconfont icon-yincang font-18 color-blue"}

@ -450,6 +450,28 @@ class RealNameCertificationModal extends Component{
department_id: arr[0].id, department_id: arr[0].id,
}) })
} }
// 姓名
handleSubmitNames(rule, value, callback){
if (value) {
let iconRule1 = /[`~!@#$%^&()_\-+=<>?:"{}|,.\/;'\\[\]·~@#¥%……&()——\-+={}|《》?:“”【】、;‘’,。、]/im;
// 判断是否含有emoji表情
let iconRule2 = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
// 如果为true字符串含有emoji表情 false不含
const iconRule2s =iconRule2.test(value);
// 如果为true字符串含有特殊符号 false不
const iconRule1s =iconRule1.test(value);
if (iconRule2s===true|| iconRule1s===true) {
callback('2-10位中英文、数字');
}
else if(value.length<2){
callback('2-10位中英文、数字');
}else if(value.length>=11){
callback('2-10位中英文、数字');
}
}
callback();
}
render(){ render(){
const { course_lists, checkBoxValues, searchValue, loading, imageUrl, imageUrl2, const { course_lists, checkBoxValues, searchValue, loading, imageUrl, imageUrl2,
@ -669,8 +691,10 @@ class RealNameCertificationModal extends Component{
// initialValue: this.state.cityDefaultValue, // initialValue: this.state.cityDefaultValue,
required: true, required: true,
message: `请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`, message: `请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`,
validator: this.checkNameLength
}], },
{ validator: this.handleSubmitNames },
],
})( })(
<Input placeholder={`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`} className="yslgraduainputedit" disabled={!showRealName && this.state.forDisable == true } addonAfter={ <Input placeholder={`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`} className="yslgraduainputedit" disabled={!showRealName && this.state.forDisable == true } addonAfter={
<i className={showRealName?"iconfont icon-xianshi font-18 color-blue":"iconfont icon-yincang font-18 color-blue"} <i className={showRealName?"iconfont icon-xianshi font-18 color-blue":"iconfont icon-yincang font-18 color-blue"}

Loading…
Cancel
Save