diff --git a/app/controllers/admins/shixuns_controller.rb b/app/controllers/admins/shixuns_controller.rb index e2d2830ad..6593f27c2 100644 --- a/app/controllers/admins/shixuns_controller.rb +++ b/app/controllers/admins/shixuns_controller.rb @@ -8,6 +8,9 @@ class Admins::ShixunsController < Admins::BaseController @pending_shixuns = shixuns.where(status:1).size @processed_shixuns = shixuns.where(status:2).size @closed_shixuns = shixuns.where(status:3).size + @none_public_shixuns = shixuns.where(public:0).size + @pending_public_shixuns = shixuns.where(public:1).size + @processed_pubic_shixuns = shixuns.where(public:2).size @shixuns_type_check = MirrorRepository.pluck(:type_name,:id) @params_page = params[:page] || 1 @shixuns = paginate shixuns.preload(:user,:challenges) diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index c360972c3..52911e905 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -29,7 +29,7 @@ class CoursesController < ApplicationController :informs, :update_informs, :online_learning, :update_task_position, :tasks_list, :join_excellent_course, :export_couser_info, :export_member_act_score, :new_informs, :delete_informs, :change_member_role, :course_groups, :join_course_group, :statistics, - :work_score, :act_score] + :work_score, :act_score, :calculate_all_shixun_scores] before_action :user_course_identity, except: [:join_excellent_course, :index, :create, :new, :apply_to_join_course, :search_course_list, :get_historical_course_students, :mine, :search_slim, :board_list] before_action :teacher_allowed, only: [:update, :destroy, :settings, :search_teacher_candidate, @@ -48,7 +48,7 @@ class CoursesController < ApplicationController before_action :validate_page_size, only: :mine before_action :course_tasks, only: [:tasks_list, :update_task_position] before_action :validate_inform_params, only: [:update_informs, :new_informs] - before_action :course_member_allowed, only: [:statistics, :work_score, :act_score] + before_action :course_member_allowed, only: [:statistics, :work_score, :act_score, :calculate_all_shixun_scores] if RUBY_PLATFORM =~ /linux/ require 'simple_xlsx_reader' @@ -1334,6 +1334,16 @@ class CoursesController < ApplicationController end end + # 计算课堂所有已发布的实训作业成绩 + def calculate_all_shixun_scores + tip_exception(-1, "课堂已结束") if @course.is_end + shixun_homeworks = @course.homework_commons.homework_published.where(homework_type: 4) + shixun_homeworks.includes(:homework_challenge_settings, :published_settings, :homework_commons_shixun).each do |homework| + homework.update_homework_work_score + end + normal_status(0, "更新成功") + end + def search_slim courses = current_user.manage_courses.not_deleted.processing diff --git a/app/controllers/hacks_controller.rb b/app/controllers/hacks_controller.rb index 657ad0f2a..cab952a04 100644 --- a/app/controllers/hacks_controller.rb +++ b/app/controllers/hacks_controller.rb @@ -1,8 +1,8 @@ class HacksController < ApplicationController before_action :require_login, except: [:index] - before_action :find_hack, only: [:edit, :update, :publish, :start, :update_set, :delete_set, :destroy] + before_action :find_hack, only: [:edit, :update, :publish, :start, :update_set, :delete_set, :destroy, :cancel_publish] before_action :require_teacher_identity, only: [:create] - before_action :require_auth_identity, only: [:update, :edit, :publish, :update_set, :delete_set, :destroy] + before_action :require_auth_identity, only: [:update, :edit, :publish, :update_set, :delete_set, :destroy, :cancel_publish] # 开启编程,如果第一次开启,创建一条记录,如果已经开启过的话,直接返回标识即可 @@ -99,6 +99,12 @@ class HacksController < ApplicationController render_ok end + # 取消发布 + def cancel_publish + @hack.update_attribute(:status, 0) + render_ok + end + # 发布列表 def unpulished_list limit = params[:limit] || 16 diff --git a/app/controllers/myshixuns_controller.rb b/app/controllers/myshixuns_controller.rb index c9b027a1b..987f4873a 100644 --- a/app/controllers/myshixuns_controller.rb +++ b/app/controllers/myshixuns_controller.rb @@ -1,410 +1,411 @@ -class MyshixunsController < ApplicationController - before_action :require_login, :check_auth, :except => [:training_task_status, :code_runinng_message] - before_action :find_myshixun, :except => [:training_task_status, :code_runinng_message] - before_action :find_repo_name, :except => [:training_task_status, :code_runinng_message] - skip_before_action :verify_authenticity_token, :only => [:html_content] - - ## TPI关卡列表 - def challenges - # @challenges = Challenge.where(shixun_id: params[:shixun_id]) - @shixun = @myshixun.shixun - @games = @myshixun.games.includes(:challenge).reorder("challenges.position") - @identity = current_user.game_identity(@games.first) - end - - - # For Admin - # 强制重置实训 - # 前段需要按照操作过程提示 - def reset_my_game - unless (current_user.admin? || current_user.id == @myshixun.user_id) - tip_exception("403", "") - end - begin - ActiveRecord::Base.transaction do - begin - @shixun = Shixun.select(:id, :identifier, :challenges_count).find(@myshixun.shixun_id) - @myshixun.destroy! - StudentWork.where(:myshixun_id => @myshixun.id).update_all(myshixun_id: 0, work_status: 0, work_score: nil, - final_score: nil, efficiency: 0, eff_score: 0, calculation_time: nil, cost_time: 0, compelete_status: 0) - rescue Exception => e - logger.error("######reset_my_game_failed:#{e.message}") - raise("ActiveRecord::RecordInvalid") - end - end - # 删除版本库 - GitService.delete_repository(repo_path: @repo_path) unless @shixun.is_choice_type? - rescue Exception => e - if e.message != "ActiveRecord::RecordInvalid" - logger.error("######delete_repository_error-:#{e.message}") - end - raise "delete_repository_error:#{e.message}" - end - end - - # 代码运行中的信息接口 - # 这个方法是中间层主动调用的,点击评测后,中间层会发送参数过来,告诉目前Pod的启动情况,一次评测会调用两次请求 - def code_runinng_message - begin - jsonTestDetails = JSON.parse(params[:jsonTestDetails]) - game_id = jsonTestDetails['buildID'] - message = jsonTestDetails['textMsg'] - if game_id.present? && message.present? - game = Game.find game_id - msg = game.run_code_message - # 只有评测中的game才会创建和更新代码评测中的信息 - if game.status == 1 || game.status == 2 - if msg.blank? - RunCodeMessage.create!(:game_id => game_id, :status => 1, :message => message) - else - msg.update_attributes(:status => (msg.status + 1), :message => message) - end - end - render :json => {:data => "success"} - end - rescue Exception => e - render :json => {:data => "failed, exception_message: #{e}"} - end - end - - # 中间层评测接口 - # taskId 即返回的game id - # 返回结果:params [:stauts] 0 表示成功,其它则失败 - # msg 错误信息 - # output 为测试用户编译输出结果 - # myshixun:status 1为完成实训 - # @jenkins: caseId对应test_set的position,passed: 1表示成功,0表示失败 - # resubmit 1:表示已通关后重新评测;0:表示非重新评测 - # retry_status 0:初始值;1:重新评测失败;2:重新评测成功 - # tpiRepoPath 中间层图片的workspace路径 - # params[:jsonTestDetails] = '{"buildID":"19284","compileSuccess":"1", - # "msg":[{"caseId":"1","expectedOutput":"MSAyIDMNCg","input":"MiAzIDE","output":"MSAyIDMNCg","passed":"1"}, - # {"caseId":"2","expectedOutput":"LTMgMSA2DQo","input":"LTMgNiAx","output":"LTMgMSA2DQo","passed":"1"}, - # {"caseId":"3","expectedOutput":"LTcgLTUgLTMNCg","input":"LTcgLTMgLTU","output":"LTcgLTUgLTMNCg","passed":"1"}], - # "outPut":"Y29tcGlsZSBzdWNjZXNzZnVsbHk","resubmit":"","status":"0"}' - # params[:timeCost] = '{"evaluateEnd":"2017-11-24 11:04:37","pull":"0.086", - # "createPod":"1.610","evaluateAllTime":2820,"evaluateStart":"2017-11-24 11:04:35","execute":"0.294"}' - # params[:pics] = "a.png,b.png,c.png" - def training_task_status - - ActiveRecord::Base.transaction do - begin - t1 = Time.now - uid_logger_dubug("@@@222222#{params[:jsonTestDetails]}") - jsonTestDetails = JSON.parse(params[:jsonTestDetails]) - timeCost = JSON.parse(params[:timeCost]) - brige_end_time = Time.parse(timeCost['evaluateEnd']) if timeCost['evaluateEnd'].present? - return_back_time = format("%.3f", ( t1.to_f - brige_end_time.to_f)).to_f - status = jsonTestDetails['status'] - game_id = jsonTestDetails['buildID'] - sec_key = jsonTestDetails['sec_key'] - - uid_logger_dubug("training_task_status start-#{game_id}-1#{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") - resubmit = jsonTestDetails['resubmit'] - outPut = tran_base64_decode64(jsonTestDetails['outPut']) - - jenkins_testsets = jsonTestDetails['msg'] - compile_success = jsonTestDetails['compileSuccess'] - # message = Base64.decode64(params[:msg]) unless params[:msg].blank? - - game = Game.find(game_id) - myshixun = game.myshixun - challenge = game.challenge - # test_sets = challenge.test_sets - if challenge.picture_path.present? - #pics = params[:files] - pics = params[:tpiRepoPath] - game.update_column(:picture_path, pics) - end - max_query_index = game.outputs ? (game.outputs.first.try(:query_index).to_i + 1) : 1 - test_set_score = 0 - unless jenkins_testsets.blank? - jenkins_testsets.each_with_index do |j_test_set, i| - actual_output = tran_base64_decode64(j_test_set['output']) - #ts_time += j_test_set['testSetTime'].to_i - - # is_public = test_sets.where(:position => j_test_set['caseId']).first.try(:is_public) - ts_time = format("%.2f", j_test_set['testSetTime'].to_f/1000000000).to_f if j_test_set['testSetTime'] - ts_mem = format("%.2f", j_test_set['testSetMem'].to_f/1024/1024).to_f if j_test_set['testSetMem'] - - Output.create!(:code => status, :game_id => game_id, :out_put => outPut, :test_set_position => j_test_set['caseId'], - :actual_output => actual_output, :result => j_test_set['passed'].to_i, :query_index => max_query_index, - :compile_success => compile_success.to_i, :sec_key => sec_key, :ts_time => ts_time, :ts_mem => ts_mem) - # 如果设置了按测试集给分,则需要统计测试集的分值 - if challenge.test_set_score && j_test_set['passed'].to_i == 1 - test_set_score += challenge.test_sets.where(:position => j_test_set['caseId']).pluck(:score).first - end - end - end - record = EvaluateRecord.where(:identifier => sec_key).first - answer_deduction_percentage = (100 - game.answer_deduction) / 100.to_f # 查看答案后剩余分数的百分比. - # answer_deduction是查看答案的扣分比例 - # status:0表示评测成功 - if status == "0" - if resubmit.present? - game.update_attributes!(:retry_status => 2, :resubmit_identifier => resubmit) - challenge.path.split(";").each do |path| - game_passed_code(path.try(:strip), myshixun, game_id) - end - else - game.update_attributes!(:status => 2, - :end_time => Time.now, - :accuracy => format("%.4f", 1.0 / game.query_index)) - myshixun.update_attributes!(:status => 1) if game.had_done == 1 - challenge.path.split(";").each do |path| - game_passed_code(path.try(:strip), myshixun, game_id) - end - # 如果是已经发布的实训,则需要给出相应的奖励 - if challenge.shixun.try(:status) > 1 - score = (challenge.score * answer_deduction_percentage).to_i - if score > 0 - reward_attrs = { container_id: game.id, container_type: 'Game', score: score } - RewardGradeService.call(game.user, reward_attrs) - RewardExperienceService.call(game.user, reward_attrs) - end - # 需要扣除查看答案的分数 - game.update_attributes!(:final_score => score) - end - - # 更新实训关联的作品分数 TODO: 更新作品分数 - # HomeworksService.new.update_myshixun_work_score myshixun - end - # 如果过关了,下一关的状态是3(为开启),则需要把状态改成1(已开启) - # next_game = game.next_game - next_game = game.next_game(myshixun.shixun_id, game.myshixun_id, challenge.position) - next_game.update_column(:status, 0) if next_game.present? && next_game.status == 3 - # status == "-1" 表示返回结果错误 - else - if resubmit.present? - game.update_attributes!(:retry_status => 1, :resubmit_identifier => resubmit) - else - # 评测没通关则,测试集对的个数给分,并且还要扣除用户是否查看答案的值 - test_set_percentage = test_set_score / 100.to_f # 测试集得分比 - score = (challenge.score * test_set_percentage * answer_deduction_percentage).to_i - # 如果分数比上次多,则更新成绩 - game_update = - if game.final_score < score - {final_score: score, status: 0} - else - {status: 0} - end - game.update_attributes!(game_update) - end - end - test_cases_time = format("%.3f", (Time.now.to_f - t1.to_f)).to_f - if record.present? - consume_time = format("%.3f", (Time.now - record.created_at)).to_f - - record.update_attributes!(:consume_time => consume_time, :git_pull => timeCost['pull'] , :create_pod => timeCost['createPod'], - :pod_execute => timeCost['execute'], :test_cases => test_cases_time, - :brige => timeCost['evaluateAllTime'], :return_back => return_back_time) - end - sucess_status - # rescue Exception => e - # tip_exception(e.message) - # uid_logger_error("training_task_status error: #{e}") - # raise ActiveRecord::Rollback - end - end - end - - # 连接webssh - def open_webssh - username = edu_setting('webssh_username') - password = edu_setting('webssh_password') - old_time = Time.now.to_i - begin - shixun_tomcat = edu_setting('tomcat_webssh') - uri = "#{shixun_tomcat}/bridge/webssh/getConnectInfo" - # 由于中间层采用混合云的方式,因为local参数表示在有文件生成的实训是在本地生成,还是在其他云端生成评测文件 - params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh), local: @myshixun.shixun.show_type != -1, - containers:(Base64.urlsafe_encode64(shixun_container_limit @myshixun.shixun))} - res = uri_post uri, params - if res && res['code'].to_i != 0 - tip_exception("实训云平台繁忙(繁忙等级:92)") - end - render :json => {:host => res['address'], - :port => res['port'], - :ws_url => res['ws_address'], - :username => username, - :password => password, - :game_id => @myshixun.id, - :webssh_url => "#{shixun_tomcat}/bridge"} - rescue Exception => e - logger.error(e) - render :json => {:error => e.try(:message)} - ensure - use_time = Time.now.to_i - old_time - logger.info "open_webssh tpiID #{@myshixun.id} use time #{use_time}" - end - end - - include GitCommon - - # -----Repository - # TODO: 之类需要一个resubmit参数,但是是关于games. - def update_file - begin - @hide_code = Shixun.where(id: @myshixun.shixun_id).pluck(:hide_code).first - tip_exception("技术平台为空!") if @myshixun.mirror_name.blank? - path = params[:path].strip unless params[:path].blank? - game_id = params[:game_id] - game = Game.find(game_id) - @content_modified = 0 - - # params[:evaluate] 实训评测时更新必须给的参数,需要依据该参数做性能统计,其它类型的更新可以跳过 - # 自动保存的时候evaluate为0;点评测的时候为1 - if params[:evaluate] == 1 - exec_time = game.challenge.try(:exec_time) - @sec_key = generate_identifier(EvaluateRecord, 12) - record = EvaluateRecord.create!(:user_id => current_user.id, :shixun_id => @myshixun.shixun_id, :game_id => game_id, - :identifier => @sec_key, :exec_time => exec_time) - uid_logger_dubug("-- game build: file update #{@sec_key}, record id is #{record.id}, time is **** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") - end - # 隐藏代码文件 和 VNC的都不需要走版本库 - unless @hide_code || (@myshixun.shixun&.vnc_evaluate && params[:evaluate].present?) - # 远程版本库文件内容 - last_content = GitService.file_content(repo_path: @repo_path, path: path)["content"] - - content = - if python_file?(path) - params[:content].gsub(/\t/, ' ').gsub(/ /, ' ') - else - params[:content] - end - uid_logger_dubug("###11222333####{content}") - uid_logger_dubug("###222333####{last_content}") - - if content != last_content - @content_modified = 1 - - author_name = current_user.real_name - author_email = current_user.git_mail - message = params[:evaluate] == 0 ? "System automatically submitted" : "User submitted" - uid_logger_dubug("112233#{author_name}") - uid_logger_dubug("112233#{author_email}") - @content = GitService.update_file(repo_path: @repo_path, - file_path: path, - message: message, - content: content, - author_name: author_name, - author_email: author_email) - end - end - - if game.status == 2 - @resubmit = Time.now.to_i - end - - # 评测时间记录 - if record.present? - consume_time = format("%.3f", (Time.now.to_f - record.created_at.to_f)).to_f - record.update_attributes!(:file_update => consume_time) - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("文件内容更新异常,请稍后重试") - end - end - - # 渲染实训代码 - # educodercss: 字符串以 ‘,’分隔,存储的是版本库css的路径 - # educoderscript: 字符串以 ‘,’分隔,存储的是版本库js的路径 - # contents: html实训的整体内容 - def html_content - @contents = params[:contents] || "" - edu_css = params[:educodercss] - edu_js = params[:educoderscript] - if @contents.present? - @contents = @contents.gsub("w3equalsign", "=").gsub("w3scrw3ipttag", "script").gsub("edulink", "link").html_safe - end - # css - if edu_css.present? - css_path = edu_css.split(",") - css_path.each do |path| - file_content = git_fle_content(@repo_path, path)["content"] - file_content = tran_base64_decode64(file_content) unless file_content.blank? - @contents = @contents.sub(/EDUCODERCSS/, "") - end - end - # js - if edu_js.present? - js_path = edu_js.split(",") - js_path.each do |path| - file_content = git_fle_content(@repo_path, path)["content"] - file_content = tran_base64_decode64(file_content) unless file_content.blank? - @contents = @contents.sub(/EDUCODERJS/, "") - end - end - respond_to do |format| - format.json - format.html{render :layout => false} - end - end - - # 最新可以用的并发测试接口 - def sigle_mul_test - codes = %W(1 2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z) - begin - identifiers = Myshixun.where(:shixun_id => params[:shixun_id].split(",")).pluck(:identifier) - ide = identifiers[rand(identifiers.length)] - myshixun = Myshixun.where(:identifier => ide).first - - game = myshixun.games.last - logger.warn("###2mul test game_build start ") - identifier = game.try(:identifier) - if game.status == 2 - code = codes.sample(8).join - resubmit = "#{code}_#{myshixun.id}" - end - logger.warn("###3mul test game_build start ...") - EvaluateRecord.create!(:user_id => myshixun.user_id, :shixun_id => myshixun.shixun.id, :game_id => game.id) - redirect_to "/api/games/#{identifier}/game_build?resubmit=#{resubmit}&content_modified=0&first=1" - rescue Exception => e - logger.error("mul test failed ===> #{e.message}") - end - end - - def sync_code - shixun_tomcat = edu_setting('cloud_bridge') - begin - git_myshixun_url = repo_ip_url @myshixun.repo_path - git_shixun_url = repo_ip_url @myshixun.shixun.try(:repo_path) - git_myshixun_url = Base64.urlsafe_encode64(git_myshixun_url) - git_shixun_url = Base64.urlsafe_encode64(git_shixun_url) - # todo: identifier 是以前的密码,用来验证的,新版如果不需要,和中间层协调更改. - params = {tpiID: "#{@myshixun.try(:id)}", tpiGitURL: "#{git_myshixun_url}", tpmGitURL: "#{git_shixun_url}", - identifier: "xinhu1ji2qu3"} - uri = "#{shixun_tomcat}/bridge/game/resetTpmRepository" - res = uri_post uri, params - if (res && res['code'] != 0) - tip_exception("实训云平台繁忙(繁忙等级:95)") - end - shixun_new_commit = GitService.commits(repo_path: @myshixun.shixun.repo_path).first["id"] - @myshixun.update_attributes!(commit_id: shixun_new_commit, reset_time: @myshixun.shixun.try(:reset_time)) - # 更新完成后,弹框则隐藏不再提示 - @myshixun.update_column(:system_tip, false) - render_ok - rescue Exception => e - tip_exception("立即更新代码失败!#{e.message}") - end - end - - - # -----End - - private - def find_myshixun - @myshixun = Myshixun.find_by!(identifier: params[:identifier]) - end - - def find_repo_name - @repo_path = @myshixun.try(:repo_path) - @path = params[:path] - end - - def python_file?(path) - false if path.blank? - path.to_s.split(".").last.downcase == "py" - end -end +class MyshixunsController < ApplicationController + before_action :require_login, :check_auth, :except => [:training_task_status, :code_runinng_message] + before_action :find_myshixun, :except => [:training_task_status, :code_runinng_message] + before_action :find_repo_name, :except => [:training_task_status, :code_runinng_message] + skip_before_action :verify_authenticity_token, :only => [:html_content] + + ## TPI关卡列表 + def challenges + # @challenges = Challenge.where(shixun_id: params[:shixun_id]) + @shixun = @myshixun.shixun + @games = @myshixun.games.includes(:challenge).reorder("challenges.position") + @identity = current_user.game_identity(@games.first) + end + + + # For Admin + # 强制重置实训 + # 前段需要按照操作过程提示 + def reset_my_game + unless (current_user.admin? || current_user.id == @myshixun.user_id) + tip_exception("403", "") + end + begin + ActiveRecord::Base.transaction do + begin + @shixun = Shixun.select(:id, :identifier, :challenges_count).find(@myshixun.shixun_id) + @myshixun.destroy! + StudentWork.where(:myshixun_id => @myshixun.id).update_all(myshixun_id: 0, work_status: 0, work_score: nil, + final_score: nil, efficiency: 0, eff_score: 0, calculation_time: nil, cost_time: 0, compelete_status: 0) + rescue Exception => e + logger.error("######reset_my_game_failed:#{e.message}") + raise("ActiveRecord::RecordInvalid") + end + end + # 删除版本库 + GitService.delete_repository(repo_path: @repo_path) unless @shixun.is_choice_type? + rescue Exception => e + if e.message != "ActiveRecord::RecordInvalid" + logger.error("######delete_repository_error-:#{e.message}") + end + raise "delete_repository_error:#{e.message}" + end + end + + # 代码运行中的信息接口 + # 这个方法是中间层主动调用的,点击评测后,中间层会发送参数过来,告诉目前Pod的启动情况,一次评测会调用两次请求 + def code_runinng_message + begin + jsonTestDetails = JSON.parse(params[:jsonTestDetails]) + game_id = jsonTestDetails['buildID'] + message = jsonTestDetails['textMsg'] + if game_id.present? && message.present? + game = Game.find game_id + msg = game.run_code_message + # 只有评测中的game才会创建和更新代码评测中的信息 + if game.status == 1 || game.status == 2 + if msg.blank? + RunCodeMessage.create!(:game_id => game_id, :status => 1, :message => message) + else + msg.update_attributes(:status => (msg.status + 1), :message => message) + end + end + render :json => {:data => "success"} + end + rescue Exception => e + render :json => {:data => "failed, exception_message: #{e}"} + end + end + + # 中间层评测接口 + # taskId 即返回的game id + # 返回结果:params [:stauts] 0 表示成功,其它则失败 + # msg 错误信息 + # output 为测试用户编译输出结果 + # myshixun:status 1为完成实训 + # @jenkins: caseId对应test_set的position,passed: 1表示成功,0表示失败 + # resubmit 1:表示已通关后重新评测;0:表示非重新评测 + # retry_status 0:初始值;1:重新评测失败;2:重新评测成功 + # tpiRepoPath 中间层图片的workspace路径 + # params[:jsonTestDetails] = '{"buildID":"19284","compileSuccess":"1", + # "msg":[{"caseId":"1","expectedOutput":"MSAyIDMNCg","input":"MiAzIDE","output":"MSAyIDMNCg","passed":"1"}, + # {"caseId":"2","expectedOutput":"LTMgMSA2DQo","input":"LTMgNiAx","output":"LTMgMSA2DQo","passed":"1"}, + # {"caseId":"3","expectedOutput":"LTcgLTUgLTMNCg","input":"LTcgLTMgLTU","output":"LTcgLTUgLTMNCg","passed":"1"}], + # "outPut":"Y29tcGlsZSBzdWNjZXNzZnVsbHk","resubmit":"","status":"0"}' + # params[:timeCost] = '{"evaluateEnd":"2017-11-24 11:04:37","pull":"0.086", + # "createPod":"1.610","evaluateAllTime":2820,"evaluateStart":"2017-11-24 11:04:35","execute":"0.294"}' + # params[:pics] = "a.png,b.png,c.png" + def training_task_status + + ActiveRecord::Base.transaction do + begin + t1 = Time.now + uid_logger_dubug("@@@222222#{params[:jsonTestDetails]}") + jsonTestDetails = JSON.parse(params[:jsonTestDetails]) + timeCost = JSON.parse(params[:timeCost]) + brige_end_time = Time.parse(timeCost['evaluateEnd']) if timeCost['evaluateEnd'].present? + return_back_time = format("%.3f", ( t1.to_f - brige_end_time.to_f)).to_f + status = jsonTestDetails['status'] + game_id = jsonTestDetails['buildID'] + sec_key = jsonTestDetails['sec_key'] + + uid_logger_dubug("training_task_status start-#{game_id}-1#{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") + resubmit = jsonTestDetails['resubmit'] + outPut = tran_base64_decode64(jsonTestDetails['outPut']) + + jenkins_testsets = jsonTestDetails['msg'] + compile_success = jsonTestDetails['compileSuccess'] + # message = Base64.decode64(params[:msg]) unless params[:msg].blank? + + game = Game.find(game_id) + myshixun = game.myshixun + challenge = game.challenge + # test_sets = challenge.test_sets + if challenge.picture_path.present? + #pics = params[:files] + pics = params[:tpiRepoPath] + game.update_column(:picture_path, pics) + end + max_query_index = game.outputs ? (game.outputs.first.try(:query_index).to_i + 1) : 1 + test_set_score = 0 + unless jenkins_testsets.blank? + jenkins_testsets.each_with_index do |j_test_set, i| + actual_output = tran_base64_decode64(j_test_set['output']) + #ts_time += j_test_set['testSetTime'].to_i + + # is_public = test_sets.where(:position => j_test_set['caseId']).first.try(:is_public) + ts_time = format("%.2f", j_test_set['testSetTime'].to_f/1000000000).to_f if j_test_set['testSetTime'] + ts_mem = format("%.2f", j_test_set['testSetMem'].to_f/1024/1024).to_f if j_test_set['testSetMem'] + + Output.create!(:code => status, :game_id => game_id, :out_put => outPut, :test_set_position => j_test_set['caseId'], + :actual_output => actual_output, :result => j_test_set['passed'].to_i, :query_index => max_query_index, + :compile_success => compile_success.to_i, :sec_key => sec_key, :ts_time => ts_time, :ts_mem => ts_mem) + # 如果设置了按测试集给分,则需要统计测试集的分值 + if challenge.test_set_score && j_test_set['passed'].to_i == 1 + test_set_score += challenge.test_sets.where(:position => j_test_set['caseId']).pluck(:score).first + end + end + end + record = EvaluateRecord.where(:identifier => sec_key).first + answer_deduction_percentage = (100 - game.answer_deduction) / 100.to_f # 查看答案后剩余分数的百分比. + # answer_deduction是查看答案的扣分比例 + # status:0表示评测成功 + if status == "0" + if resubmit.present? + game.update_attributes!(:retry_status => 2, :resubmit_identifier => resubmit) + challenge.path.split(";").each do |path| + game_passed_code(path.try(:strip), myshixun, game_id) + end + else + game.update_attributes!(:status => 2, + :end_time => Time.now, + :accuracy => format("%.4f", 1.0 / game.query_index)) + myshixun.update_attributes!(:status => 1) if game.had_done == 1 + challenge.path.split(";").each do |path| + game_passed_code(path.try(:strip), myshixun, game_id) + end + # 如果是已经发布的实训,则需要给出相应的奖励 + if challenge.shixun.try(:status) > 1 + score = (challenge.score * answer_deduction_percentage).to_i + if score > 0 + reward_attrs = { container_id: game.id, container_type: 'Game', score: score } + RewardGradeService.call(game.user, reward_attrs) + RewardExperienceService.call(game.user, reward_attrs) + end + # 需要扣除查看答案的分数 + game.update_attributes!(:final_score => score) + end + + # 更新实训关联的作品分数 TODO: 更新作品分数 + # HomeworksService.new.update_myshixun_work_score myshixun + end + # 如果过关了,下一关的状态是3(为开启),则需要把状态改成1(已开启) + # next_game = game.next_game + next_game = game.next_game(myshixun.shixun_id, game.myshixun_id, challenge.position) + next_game.update_column(:status, 0) if next_game.present? && next_game.status == 3 + # status == "-1" 表示返回结果错误 + else + if resubmit.present? + game.update_attributes!(:retry_status => 1, :resubmit_identifier => resubmit) + else + # 评测没通关则,测试集对的个数给分,并且还要扣除用户是否查看答案的值 + test_set_percentage = test_set_score / 100.to_f # 测试集得分比 + score = (challenge.score * test_set_percentage * answer_deduction_percentage).to_i + # 如果分数比上次多,则更新成绩 + game_update = + if game.final_score < score + {final_score: score, status: 0} + else + {status: 0} + end + game.update_attributes!(game_update) + end + end + test_cases_time = format("%.3f", (Time.now.to_f - t1.to_f)).to_f + if record.present? + consume_time = format("%.3f", (Time.now - record.created_at)).to_f + + record.update_attributes!(:consume_time => consume_time, :git_pull => timeCost['pull'] , :create_pod => timeCost['createPod'], + :pod_execute => timeCost['execute'], :test_cases => test_cases_time, + :brige => timeCost['evaluateAllTime'], :return_back => return_back_time) + end + sucess_status + # rescue Exception => e + # tip_exception(e.message) + # uid_logger_error("training_task_status error: #{e}") + # raise ActiveRecord::Rollback + end + end + end + + # 连接webssh + def open_webssh + username = edu_setting('webssh_username') + password = edu_setting('webssh_password') + old_time = Time.now.to_i + begin + shixun_tomcat = edu_setting('tomcat_webssh') + uri = "#{shixun_tomcat}/bridge/webssh/getConnectInfo" + # 由于中间层采用混合云的方式,因为local参数表示在有文件生成的实训是在本地生成,还是在其他云端生成评测文件 + local = @myshixun.shixun.challenges.where.not(show_type: -1).count == 0 + params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh), local: local, + containers:(Base64.urlsafe_encode64(shixun_container_limit @myshixun.shixun))} + res = uri_post uri, params + if res && res['code'].to_i != 0 + tip_exception("实训云平台繁忙(繁忙等级:92)") + end + render :json => {:host => res['address'], + :port => res['port'], + :ws_url => res['ws_address'], + :username => username, + :password => password, + :game_id => @myshixun.id, + :webssh_url => "#{shixun_tomcat}/bridge"} + rescue Exception => e + logger.error(e) + render :json => {:error => e.try(:message)} + ensure + use_time = Time.now.to_i - old_time + logger.info "open_webssh tpiID #{@myshixun.id} use time #{use_time}" + end + end + + include GitCommon + + # -----Repository + # TODO: 之类需要一个resubmit参数,但是是关于games. + def update_file + begin + @hide_code = Shixun.where(id: @myshixun.shixun_id).pluck(:hide_code).first + tip_exception("技术平台为空!") if @myshixun.mirror_name.blank? + path = params[:path].strip unless params[:path].blank? + game_id = params[:game_id] + game = Game.find(game_id) + @content_modified = 0 + + # params[:evaluate] 实训评测时更新必须给的参数,需要依据该参数做性能统计,其它类型的更新可以跳过 + # 自动保存的时候evaluate为0;点评测的时候为1 + if params[:evaluate] == 1 + exec_time = game.challenge.try(:exec_time) + @sec_key = generate_identifier(EvaluateRecord, 12) + record = EvaluateRecord.create!(:user_id => current_user.id, :shixun_id => @myshixun.shixun_id, :game_id => game_id, + :identifier => @sec_key, :exec_time => exec_time) + uid_logger_dubug("-- game build: file update #{@sec_key}, record id is #{record.id}, time is **** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") + end + # 隐藏代码文件 和 VNC的都不需要走版本库 + unless @hide_code || (@myshixun.shixun&.vnc_evaluate && params[:evaluate].present?) + # 远程版本库文件内容 + last_content = GitService.file_content(repo_path: @repo_path, path: path)["content"] + + content = + if python_file?(path) + params[:content].gsub(/\t/, ' ').gsub(/ /, ' ') + else + params[:content] + end + uid_logger_dubug("###11222333####{content}") + uid_logger_dubug("###222333####{last_content}") + + if content != last_content + @content_modified = 1 + + author_name = current_user.real_name + author_email = current_user.git_mail + message = params[:evaluate] == 0 ? "System automatically submitted" : "User submitted" + uid_logger_dubug("112233#{author_name}") + uid_logger_dubug("112233#{author_email}") + @content = GitService.update_file(repo_path: @repo_path, + file_path: path, + message: message, + content: content, + author_name: author_name, + author_email: author_email) + end + end + + if game.status == 2 + @resubmit = Time.now.to_i + end + + # 评测时间记录 + if record.present? + consume_time = format("%.3f", (Time.now.to_f - record.created_at.to_f)).to_f + record.update_attributes!(:file_update => consume_time) + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception("文件内容更新异常,请稍后重试") + end + end + + # 渲染实训代码 + # educodercss: 字符串以 ‘,’分隔,存储的是版本库css的路径 + # educoderscript: 字符串以 ‘,’分隔,存储的是版本库js的路径 + # contents: html实训的整体内容 + def html_content + @contents = params[:contents] || "" + edu_css = params[:educodercss] + edu_js = params[:educoderscript] + if @contents.present? + @contents = @contents.gsub("w3equalsign", "=").gsub("w3scrw3ipttag", "script").gsub("edulink", "link").html_safe + end + # css + if edu_css.present? + css_path = edu_css.split(",") + css_path.each do |path| + file_content = git_fle_content(@repo_path, path)["content"] + file_content = tran_base64_decode64(file_content) unless file_content.blank? + @contents = @contents.sub(/EDUCODERCSS/, "") + end + end + # js + if edu_js.present? + js_path = edu_js.split(",") + js_path.each do |path| + file_content = git_fle_content(@repo_path, path)["content"] + file_content = tran_base64_decode64(file_content) unless file_content.blank? + @contents = @contents.sub(/EDUCODERJS/, "") + end + end + respond_to do |format| + format.json + format.html{render :layout => false} + end + end + + # 最新可以用的并发测试接口 + def sigle_mul_test + codes = %W(1 2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z) + begin + identifiers = Myshixun.where(:shixun_id => params[:shixun_id].split(",")).pluck(:identifier) + ide = identifiers[rand(identifiers.length)] + myshixun = Myshixun.where(:identifier => ide).first + + game = myshixun.games.last + logger.warn("###2mul test game_build start ") + identifier = game.try(:identifier) + if game.status == 2 + code = codes.sample(8).join + resubmit = "#{code}_#{myshixun.id}" + end + logger.warn("###3mul test game_build start ...") + EvaluateRecord.create!(:user_id => myshixun.user_id, :shixun_id => myshixun.shixun.id, :game_id => game.id) + redirect_to "/api/games/#{identifier}/game_build?resubmit=#{resubmit}&content_modified=0&first=1" + rescue Exception => e + logger.error("mul test failed ===> #{e.message}") + end + end + + def sync_code + shixun_tomcat = edu_setting('cloud_bridge') + begin + git_myshixun_url = repo_ip_url @myshixun.repo_path + git_shixun_url = repo_ip_url @myshixun.shixun.try(:repo_path) + git_myshixun_url = Base64.urlsafe_encode64(git_myshixun_url) + git_shixun_url = Base64.urlsafe_encode64(git_shixun_url) + # todo: identifier 是以前的密码,用来验证的,新版如果不需要,和中间层协调更改. + params = {tpiID: "#{@myshixun.try(:id)}", tpiGitURL: "#{git_myshixun_url}", tpmGitURL: "#{git_shixun_url}", + identifier: "xinhu1ji2qu3"} + uri = "#{shixun_tomcat}/bridge/game/resetTpmRepository" + res = uri_post uri, params + if (res && res['code'] != 0) + tip_exception("实训云平台繁忙(繁忙等级:95)") + end + shixun_new_commit = GitService.commits(repo_path: @myshixun.shixun.repo_path).first["id"] + @myshixun.update_attributes!(commit_id: shixun_new_commit, reset_time: @myshixun.shixun.try(:reset_time)) + # 更新完成后,弹框则隐藏不再提示 + @myshixun.update_column(:system_tip, false) + render_ok + rescue Exception => e + tip_exception("立即更新代码失败!#{e.message}") + end + end + + + # -----End + + private + def find_myshixun + @myshixun = Myshixun.find_by!(identifier: params[:identifier]) + end + + def find_repo_name + @repo_path = @myshixun.try(:repo_path) + @path = params[:path] + end + + def python_file?(path) + false if path.blank? + path.to_s.split(".").last.downcase == "py" + end +end diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index ca2dfa86b..9733bbd9f 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -20,14 +20,14 @@ class ShixunsController < ApplicationController before_action :allowed, only: [:update, :close, :update_propaedeutics, :settings, :publish, :shixun_members_added, :change_manager, :collaborators_delete, - :cancel_publish, :add_collaborators, :add_file] + :cancel_apply_public, :cancel_publish, :add_collaborators, :add_file] before_action :portion_allowed, only: [:copy] before_action :special_allowed, only: [:send_to_course, :search_user_courses] ## 获取课程列表 def index - @shixuns = current_laboratory.shixuns.unhidden + @shixuns = current_laboratory.shixuns.unhidden.publiced ## 方向 if params[:tag_level].present? && params[:tag_id].present? @@ -365,12 +365,7 @@ class ShixunsController < ApplicationController end def create - begin - @shixun = CreateShixunService.call(current_user, shixun_params, params) - rescue => e - logger_error("shixun_create_error: #{e.message}") - tip_exception("创建实训失败!") - end + @shixun = CreateShixunService.call(current_user, shixun_params, params) end # 保存jupyter到版本库 @@ -730,37 +725,41 @@ class ShixunsController < ApplicationController @status = 0 @position = [] begin - if @shixun.challenges.count == 0 - @status = 4 - else - @shixun.challenges.each do |challenge| - if challenge.challenge_tags.count == 0 - @status = 3 - @position << challenge.position + unless @shixun.is_jupyter? + if @shixun.challenges.count == 0 + @status = 4 + else + @shixun.challenges.each do |challenge| + if challenge.challenge_tags.count == 0 + @status = 3 + @position << challenge.position + end end - end - unfinish_challenge = @shixun.challenges.where(:st => 0, :path => nil) - if unfinish_challenge.count > 0 && !@shixun.is_choice_type? - @status = 2 - @pos = [] - unfinish_challenge.each do |challenge| - @pos << challenge.position + unfinish_challenge = @shixun.challenges.where(:st => 0, :path => nil) + if unfinish_challenge.count > 0 && !@shixun.is_choice_type? + @status = 2 + @pos = [] + unfinish_challenge.each do |challenge| + @pos << challenge.position + end end end end if @status == 0 - @shixun.update_attributes!(:status => 1) - apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first - if apply && apply.status == 0 - @status = 0 - else - ApplyAction.create(:container_type => "ApplyShixun", :container_id => @shixun.id, :user_id => current_user.id, :status => 0) - #begin - # status = Trustie::Sms.send(mobile: '18711011226', send_type:'publish_shixun' , name: '管理员') - #rescue => e - # Rails.logger.error "发送验证码出错: #{e}" - #end - @status = 1 + ActiveRecord::Base.transaction do + @shixun.update_attributes!(:status => 2) + apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first + if apply && apply.status == 0 + @status = 0 + else + ApplyAction.create(:container_type => "ApplyShixun", :container_id => @shixun.id, :user_id => current_user.id, :status => 0) + #begin + # status = Trustie::Sms.send(mobile: '18711011226', send_type:'publish_shixun' , name: '管理员') + #rescue => e + # Rails.logger.error "发送验证码出错: #{e}" + #end + @status = 1 + end end end rescue Exception => e @@ -905,14 +904,24 @@ class ShixunsController < ApplicationController :disposition => 'attachment' #inline can open in browser end + # 撤销申请公开 + def cancel_apply_public + tip_exception("实训已经公开,无法撤销") if @shixun.public == 2 + ActiveRecord::Base.transaction do + apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first + if apply && apply.status == 0 + apply.update_attributes!(status: 3) + apply.tidings&.destroy_all + end + @shixun.update_column(:public, 0) + end + normal_status(0, "成功撤销申请") + end + # 撤销发布 def cancel_publish - tip_exception("实训已经发布,无法撤销") if @shixun.status == 2 - apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first - if apply && apply.status == 0 - apply.update_attribute(:status, 3) - apply.tidings.destroy_all - end + tip_exception("请先撤销申请公开,再撤销发布") if @shixun.public == 1 + tip_exception("实训已经公开,无法撤销") if @shixun.public == 2 @shixun.update_column(:status, 0) end diff --git a/app/helpers/shixuns_helper.rb b/app/helpers/shixuns_helper.rb index b41750bed..655a7ed04 100644 --- a/app/helpers/shixuns_helper.rb +++ b/app/helpers/shixuns_helper.rb @@ -27,6 +27,17 @@ module ShixunsHelper end end + def shixun_public_status shixun + case shixun.try(:public) + when 0,nil + "未公开" + when 1 + "待审核" + when 2 + "已公开" + end + end + # 已完成实训所获得的经验值 def myshixun_exp myshixun score = 0 diff --git a/app/models/game.rb b/app/models/game.rb index d82392a59..ca7339352 100644 --- a/app/models/game.rb +++ b/app/models/game.rb @@ -119,6 +119,12 @@ class Game < ApplicationRecord # self.outputs.pluck(:query_index).first #end + # 是否查看了答案(通关的是否在通关前看的答案) + def view_answer + answer_exists = Grade.exists?("container_type = 'Answer' and container_id = #{id} and created_at < '#{end_time}'") + answer_open != 0 ? (status == 2 ? answer_exists : true) : false + end + # 用户关卡得分 def get_user_final_score diff --git a/app/models/myshixun.rb b/app/models/myshixun.rb index 7dccea3d2..a1732ecc3 100644 --- a/app/models/myshixun.rb +++ b/app/models/myshixun.rb @@ -88,9 +88,10 @@ class Myshixun < ApplicationRecord self.games.select{|game| game.status == 2}.size end - # 查看答案的关卡数 + # 查看答案的关卡数,只统计通关前看的关卡 def view_answer_count - self.games.select{|game| game.status == 2 && game.answer_open != 0}.size + answer_ids = user.grades.joins("join games on grades.container_id = games.id").where("container_type = 'Answer' and games.status=2 and games.end_time > grades.created_at").pluck(:container_id) + self.games.select{|game| game.status == 2 && game.answer_open != 0 && answer_ids.include?(game.id)}.size end # 通关时间 diff --git a/app/models/shixun.rb b/app/models/shixun.rb index 770dd81f7..2034c5ea0 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -3,6 +3,7 @@ class Shixun < ApplicationRecord attr_accessor :page_no #管理员页面 实训配置更新状态时,需要接受page_no参数 # status: 0:编辑 1:申请发布 2:正式发布 3:关闭 -1:软删除 + # public: 0:未公开 1:申请公开 2:公开 # hide_code: 隐藏代码窗口 # code_hidden: 隐藏代码目录 # task_pass: 跳关 @@ -79,6 +80,7 @@ class Shixun < ApplicationRecord scope :published_closed, lambda{ where(status: [2, 3]) } scope :none_closed, lambda{ where(status: [0, 1, 2]) } scope :unhidden, lambda{ where(hidden: 0, status: 2) } + scope :publiced, lambda{ where(public: 2) } scope :field_for_recommend, lambda{ select([:id, :name, :identifier, :myshixuns_count]) } scope :find_by_ids,lambda{|k| where(id:k)} diff --git a/app/models/shixun_info.rb b/app/models/shixun_info.rb index e16f16537..321b4c44a 100644 --- a/app/models/shixun_info.rb +++ b/app/models/shixun_info.rb @@ -1,8 +1,6 @@ class ShixunInfo < ApplicationRecord belongs_to :shixun validates_uniqueness_of :shixun_id - validates_presence_of :shixun_id, :description - after_commit :create_diff_record private diff --git a/app/queries/admins/shixun_query.rb b/app/queries/admins/shixun_query.rb index 0d726f267..0f8523599 100644 --- a/app/queries/admins/shixun_query.rb +++ b/app/queries/admins/shixun_query.rb @@ -21,7 +21,17 @@ class Admins::ShixunQuery < ApplicationQuery [0,1,2,3] end + public = + case params[:public] + when "editing" then [0] + when "pending" then [1] + when "processed" then [2] + else + [0,1,2] + end + all_shixuns = all_shixuns.where(status: status) if status.present? + all_shixuns = all_shixuns.where(public: public) if public.present? if params[:tag].present? all_shixuns = all_shixuns.joins(:mirror_repositories).where("mirror_repositories.id = ?",params[:tag].to_i) diff --git a/app/services/admins/shixun_auths/agree_apply_service.rb b/app/services/admins/shixun_auths/agree_apply_service.rb index 4734e03bb..b8875cf09 100644 --- a/app/services/admins/shixun_auths/agree_apply_service.rb +++ b/app/services/admins/shixun_auths/agree_apply_service.rb @@ -10,7 +10,7 @@ class Admins::ShixunAuths::AgreeApplyService < ApplicationService def call ActiveRecord::Base.transaction do apply.update!(status: 1, dealer_id: user.id) - shixun.update!(status: 2, publish_time: Time.now) + shixun.update!(public: 2, publish_time: Time.now) # 奖励金币、经验 reward_grade_and_experience! diff --git a/app/services/admins/shixun_auths/refuse_apply_service.rb b/app/services/admins/shixun_auths/refuse_apply_service.rb index 49416a2b0..76d420e53 100644 --- a/app/services/admins/shixun_auths/refuse_apply_service.rb +++ b/app/services/admins/shixun_auths/refuse_apply_service.rb @@ -10,7 +10,7 @@ class Admins::ShixunAuths::RefuseApplyService < ApplicationService def call ActiveRecord::Base.transaction do - shixun.update!(status: 0) + shixun.update!(public: 0) apply.update!(status: 2, reason: reason, dealer_id: user.id) deal_tiding! diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 5eb11f398..a45875e07 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -30,7 +30,6 @@ class SearchService < ApplicationService model_options = { includes: modal_name.searchable_includes } - model_options.deep_merge!(where: { status: 2 }) if modal_name == Shixun model_options.deep_merge!(extra_options) model_options.deep_merge!(default_options) @@ -40,7 +39,7 @@ class SearchService < ApplicationService def extra_options case params[:type].to_s.strip when 'shixun' then - { where: { id: Laboratory.current.shixuns.pluck(:id) } } + { where: { id: Laboratory.current.shixuns.where(public: 2, status: 2, fork_from: nil).or(Laboratory.current.shixuns.where(status: 2, id: User.current.shixuns)).pluck(:id) } } when 'subject' then { where: { id: Laboratory.current.subjects.pluck(:id) } } when 'course' then diff --git a/app/services/shixun_search_service.rb b/app/services/shixun_search_service.rb index 580208dfe..649de87bf 100644 --- a/app/services/shixun_search_service.rb +++ b/app/services/shixun_search_service.rb @@ -25,7 +25,7 @@ class ShixunSearchService < ApplicationService else none_shixun_ids = ShixunSchool.where("school_id != #{User.current.school_id}").pluck(:shixun_id) - @shixuns = @shixuns.where.not(id: none_shixun_ids).where(hidden: 0) + @shixuns = @shixuns.where.not(id: none_shixun_ids).where(hidden: 0, status: 2, public: 2).or(@shixuns.where(id: current_user.shixuns)) end end diff --git a/app/services/shixuns/create_shixun_service.rb b/app/services/shixuns/create_shixun_service.rb index aa9968f5b..2a350fd5d 100644 --- a/app/services/shixuns/create_shixun_service.rb +++ b/app/services/shixuns/create_shixun_service.rb @@ -14,34 +14,39 @@ class CreateShixunService < ApplicationService shixun.user_id = user.id main_mirror = MirrorRepository.find params[:main_type] sub_mirrors = MirrorRepository.where(id: params[:sub_type]) - ActiveRecord::Base.transaction do - shixun.save! - # 获取脚本内容 - shixun_script = get_shixun_script(shixun, main_mirror, sub_mirrors) - # 创建额外信息 - ShixunInfo.create!(shixun_id: shixun.id, evaluate_script: shixun_script, description: params[:description]) - # 创建合作者 - shixun.shixun_members.create!(user_id: user.id, role: 1) - # 创建镜像 - ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => main_mirror.id) - # 创建主服务配置 - ShixunServiceConfig.create!(:shixun_id => shixun.id, :mirror_repository_id => main_mirror.id) - # 创建子镜像相关数据(实训镜像关联表,子镜像服务配置) - sub_mirrors.each do |sub| - ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id) - # 实训子镜像服务配置 - name = sub.name #查看镜像是否有名称,如果没有名称就不用服务配置 - ShixunServiceConfig.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id) if name.present? - end - # 创建版本库 - repo_path = repo_namespace(user.login, shixun.identifier) - GitService.add_repository(repo_path: repo_path) - shixun.update_column(:repo_name, repo_path.split(".")[0]) - # 如果是云上实验室,创建相关记录 - if !Laboratory.current.main_site? - Laboratory.current.laboratory_shixuns.create!(shixun: shixun, ownership: true) + begin + ActiveRecord::Base.transaction do + shixun.save! + # 获取脚本内容 + shixun_script = get_shixun_script(shixun, main_mirror, sub_mirrors) + # 创建额外信息 + ShixunInfo.create!(shixun_id: shixun.id, evaluate_script: shixun_script, description: params[:description]) + # 创建合作者 + shixun.shixun_members.create!(user_id: user.id, role: 1) + # 创建镜像 + ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => main_mirror.id) + # 创建主服务配置 + ShixunServiceConfig.create!(:shixun_id => shixun.id, :mirror_repository_id => main_mirror.id) + # 创建子镜像相关数据(实训镜像关联表,子镜像服务配置) + sub_mirrors.each do |sub| + ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id) + # 实训子镜像服务配置 + name = sub.name #查看镜像是否有名称,如果没有名称就不用服务配置 + ShixunServiceConfig.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id) if name.present? + end + # 创建版本库 + repo_path = repo_namespace(user.login, shixun.identifier) + GitService.add_repository(repo_path: repo_path) + shixun.update_column(:repo_name, repo_path.split(".")[0]) + # 如果是云上实验室,创建相关记录 + if !Laboratory.current.main_site? + Laboratory.current.laboratory_shixuns.create!(shixun: shixun, ownership: true) + end + return shixun end - return shixun + rescue => e + Rails.logger.error("shixun_create_error: #{e.message}") + raise("创建实训失败!") end end diff --git a/app/views/admins/shixuns/index.html.erb b/app/views/admins/shixuns/index.html.erb index d9f8086d8..d04257927 100644 --- a/app/views/admins/shixuns/index.html.erb +++ b/app/views/admins/shixuns/index.html.erb @@ -4,25 +4,31 @@
<%= form_tag(admins_shixuns_path, method: :get, class: 'form-inline search-form',id:"shixuns-search-form",remote:true) do %> -
+
<% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["待审核(#{@pending_shixuns})", 'pending'], ["已发布(#{@processed_shixuns})", 'processed'],["已关闭(#{@closed_shixuns})",'closed']] %> <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
+
+ + <% public_options = [['全部', ''], ["未公开(#{@none_public_shixuns})", "editing"], ["待审核(#{@pending_public_shixuns})", 'pending'], ["已公开(#{@processed_pubic_shixuns})", 'processed']] %> + <%= select_tag(:public, options_for_select(public_options), class: 'form-control') %> +
+
<%= select_tag(:tag, options_for_select(@shixuns_type_check.unshift(["",nil])), class: 'form-control',id:"tag-choosed") %>
-
+
<% auto_trial_options = [['创建者姓名', 0], ['实训名称', 1], ['学校名称', 2]] %> <%= select_tag(:search_type, options_for_select(auto_trial_options), class: 'form-control') %>
- <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '输入关键字搜索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3','data-disable-with': '搜索中...') %> - <%= link_to "清除",admins_shixuns_path,class: "btn btn-default",id:"shixuns-clear-search",'data-disable-with': '清除中...' %> + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2', placeholder: '输入关键字搜索') %> + <%= submit_tag('搜索', class: 'btn btn-primary','data-disable-with': '搜索中...') %> + <%= link_to "清除", admins_shixuns_path,class: "btn btn-default",id:"shixuns-clear-search",'data-disable-with': '清除中...' %> <% end %> 导出
diff --git a/app/views/admins/shixuns/shared/_list.html.erb b/app/views/admins/shixuns/shared/_list.html.erb index 7503d8fd2..9ee44ece3 100644 --- a/app/views/admins/shixuns/shared/_list.html.erb +++ b/app/views/admins/shixuns/shared/_list.html.erb @@ -2,14 +2,15 @@ 序号 ID - 实训名称 + 实训名称 技术平台 Fork源 实践 选择 状态 + 公开 创建者 - <%= sort_tag('创建于', name: 'created_at', path: admins_shixuns_path) %> + <%= sort_tag('创建于', name: 'created_at', path: admins_shixuns_path) %> 单测 操作 @@ -33,6 +34,7 @@ <%= shixun.challenges.where(:st => 0).size %> <%= shixun.challenges.where(:st => 1).size %> <%= shixun_authentication_status shixun %> + <%= shixun_public_status shixun %> <%= link_to shixun.user.try(:real_name),"/users/#{shixun.user.try(:login)}",target:'_blank' %> <%= format_time shixun.created_at %> diff --git a/app/views/hack_user_lastest_codes/show.json.jbuilder b/app/views/hack_user_lastest_codes/show.json.jbuilder index 2d7ffd2bf..cfdc87d25 100644 --- a/app/views/hack_user_lastest_codes/show.json.jbuilder +++ b/app/views/hack_user_lastest_codes/show.json.jbuilder @@ -1,5 +1,5 @@ json.hack do - json.(@hack, :name, :difficult, :time_limit, :description, :score, :identifier) + json.(@hack, :name, :difficult, :time_limit, :description, :score, :identifier, :status) json.language @hack.language json.username @hack.user.real_name json.code @my_hack.code diff --git a/app/views/hacks/index.json.jbuilder b/app/views/hacks/index.json.jbuilder index c86884a41..2b4a8b8c7 100644 --- a/app/views/hacks/index.json.jbuilder +++ b/app/views/hacks/index.json.jbuilder @@ -8,6 +8,6 @@ end json.hacks_count @hacks_count json.hacks_list do json.array! @hacks do |hack| - json.(hack,:identifier, :name , :hack_user_lastest_codes_count, :difficult, :passed_rate, :category) + json.(hack,:identifier, :name , :hack_user_lastest_codes_count, :difficult, :passed_rate, :category, :open_or_not, :status) end end \ No newline at end of file diff --git a/app/views/shixuns/_top.json.jbuilder b/app/views/shixuns/_top.json.jbuilder index 358aae7f9..8cd78dd74 100644 --- a/app/views/shixuns/_top.json.jbuilder +++ b/app/views/shixuns/_top.json.jbuilder @@ -17,3 +17,5 @@ json.score_info shixun.shixun_preference_info # todo: 这块可以改成只 json.is_jupyter shixun.is_jupyter # 用于是否显示导航栏中的'背景知识' json.propaedeutics shixun.propaedeutics.present? + +json.public shixun.public diff --git a/app/views/student_works/shixun_work_report.json.jbuilder b/app/views/student_works/shixun_work_report.json.jbuilder index 162e2ab1c..068151856 100644 --- a/app/views/student_works/shixun_work_report.json.jbuilder +++ b/app/views/student_works/shixun_work_report.json.jbuilder @@ -42,7 +42,7 @@ if @shixun json.challenge_comment challenge_comment&.comment json.challenge_comment_hidden @user_course_identity < Course::STUDENT ? challenge_comment&.hidden_comment : nil json.comment_id challenge_comment&.id - json.view_answer game ? game.answer_open != 0 : 0 + json.view_answer game ? game.view_answer : false end end diff --git a/config/routes.rb b/config/routes.rb index ea942c5da..4203df43a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -55,6 +55,7 @@ Rails.application.routes.draw do end member do post :publish + post :cancel_publish get :start post :update_set delete :delete_set @@ -273,6 +274,7 @@ Rails.application.routes.draw do post :send_to_course delete :collaborators_delete get :cancel_publish + get :cancel_apply_public get :publish get :shixun_exec post :review_shixun @@ -440,6 +442,7 @@ Rails.application.routes.draw do get 'statistics' post :inform_up post :inform_down + get :calculate_all_shixun_scores end collection do diff --git a/db/migrate/20191212025227_add_public_status_to_shixun.rb b/db/migrate/20191212025227_add_public_status_to_shixun.rb new file mode 100644 index 000000000..d1d817fb8 --- /dev/null +++ b/db/migrate/20191212025227_add_public_status_to_shixun.rb @@ -0,0 +1,5 @@ +class AddPublicStatusToShixun < ActiveRecord::Migration[5.2] + def change + add_column :shixuns, :public, :integer, default: 0 + end +end diff --git a/db/migrate/20191212034354_migrate_shixun_status.rb b/db/migrate/20191212034354_migrate_shixun_status.rb new file mode 100644 index 000000000..bb977f173 --- /dev/null +++ b/db/migrate/20191212034354_migrate_shixun_status.rb @@ -0,0 +1,9 @@ +class MigrateShixunStatus < ActiveRecord::Migration[5.2] + def change + # 平台上所有已发布且未隐藏的实训都设为公开 + Shixun.unhidden.update_all(public: 2) + + # 所有已申请发布的实训状态都改为已发布,申请发布改为申请公开 + Shixun.where(status: 1, id: ApplyAction.where(container_type: 'ApplyShixun', status: 0).pluck(:container_id)).update_all(status: 2, public: 1) + end +end diff --git a/public/react/public/css/iconfont.css b/public/react/public/css/iconfont.css index 29e19aee4..f9c2e1e68 100644 --- a/public/react/public/css/iconfont.css +++ b/public/react/public/css/iconfont.css @@ -1,10 +1,10 @@ @font-face {font-family: "iconfont"; - src: url('iconfont.eot?t=1572859243353'); /* IE9 */ - src: url('iconfont.eot?t=1572859243353#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), - url('iconfont.woff?t=1572859243353') format('woff'), - url('iconfont.ttf?t=1572859243353') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ - url('iconfont.svg?t=1572859243353#iconfont') format('svg'); /* iOS 4.1- */ + src: url('iconfont.eot?t=1576206033975'); /* IE9 */ + src: url('iconfont.eot?t=1576206033975#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), + url('iconfont.woff?t=1576206033975') format('woff'), + url('iconfont.ttf?t=1576206033975') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ + url('iconfont.svg?t=1576206033975#iconfont') format('svg'); /* iOS 4.1- */ } .iconfont { @@ -55,6 +55,10 @@ content: "\e6bc"; } +.icon-jinzhi:before { + content: "\e6d4"; +} + .icon-vs:before { content: "\e682"; } @@ -115,6 +119,10 @@ content: "\e609"; } +.icon-liulan:before { + content: "\e6c7"; +} + .icon-luyou:before { content: "\e677"; } @@ -295,6 +303,10 @@ content: "\e694"; } +.icon-bokeyuan:before { + content: "\e6c6"; +} + .icon-base:before { content: "\e683"; } @@ -799,6 +811,10 @@ content: "\e68c"; } +.icon-pinglun:before { + content: "\e6c8"; +} + .icon-gongcheng:before { content: "\e60f"; } @@ -811,6 +827,10 @@ content: "\e604"; } +.icon-shangjiantou-tianchong:before { + content: "\e733"; +} + .icon-zhuye:before { content: "\e6d3"; } @@ -839,6 +859,10 @@ content: "\e6a1"; } +.icon-shenglvehao:before { + content: "\e708"; +} + .icon-paixu1:before { content: "\e6aa"; } @@ -923,3 +947,43 @@ content: "\e6c4"; } +.icon-bangdingshoujihao:before { + content: "\e6ca"; +} + +.icon-biaoqian1:before { + content: "\e6ce"; +} + +.icon-jilu:before { + content: "\e6cf"; +} + +.icon-shu:before { + content: "\e6d0"; +} + +.icon-tuijian:before { + content: "\e6d1"; +} + +.icon-chuangjianzhe:before { + content: "\e6d2"; +} + +.icon-wancheng1:before { + content: "\e6cb"; +} + +.icon-qiyezhanghao:before { + content: "\e6cc"; +} + +.icon-gerenzhanghao:before { + content: "\e6cd"; +} + +.icon-jiazaishibai1:before { + content: "\e6d6"; +} + diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index bb6e28b90..7a6f0fc04 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -109,15 +109,15 @@ export function initAxiosInterceptors(props) { } // // console.log(config); - if (config.method === "post") { - if (requestMap[config.url] === true) { // 避免重复的请求 导致页面f5刷新 也会被阻止 显示这个方法会影响到定制信息 - // console.log(config); - // console.log(JSON.parse(config)); - // console.log(config.url); - // console.log("被阻止了是重复请求================================="); - return false; - } - } + // if (config.method === "post") { + // if (requestMap[config.url] === true) { // 避免重复的请求 导致页面f5刷新 也会被阻止 显示这个方法会影响到定制信息 + // // console.log(config); + // // console.log(JSON.parse(config)); + // // console.log(config.url); + // // console.log("被阻止了是重复请求================================="); + // return false; + // } + // } // 非file_update请求 if (config.url.indexOf('update_file') === -1) { requestMap[config.url] = true; diff --git a/public/react/src/modules/courses/coursesPublic/NewShixunModel.js b/public/react/src/modules/courses/coursesPublic/NewShixunModel.js index 3b3cc2b37..9670e5e0b 100644 --- a/public/react/src/modules/courses/coursesPublic/NewShixunModel.js +++ b/public/react/src/modules/courses/coursesPublic/NewShixunModel.js @@ -19,7 +19,8 @@ class NewShixunModel extends Component{ order:'desc', diff:0, limit:15, - sort:"myshixuns_count" + sort:"myshixuns_count", + belongtoindex:0, } } componentDidMount() { @@ -161,7 +162,17 @@ class NewShixunModel extends Component{ }) let{status,order,diff,limit,sort}=this.state; if(this.props.type==='shixuns'){ - this.getdatalist(1,value,status,undefined,order,diff,limit) + this.getdatalist(1,value,status,undefined,order,diff,limit); + if(value==="all"){ + this.setState({ + belongtoindex:0 + }) + }else{ + this.setState({ + belongtoindex:1 + }) + } + }else{ this.getdatalist(1,value,undefined,undefined,order,undefined,limit,undefined,sort) } @@ -322,6 +333,7 @@ class NewShixunModel extends Component{ this.getdatalist(page,type,status,keyword,order,diff,limit) } + updatepathlist=(sorts,orders)=>{ let{page,type,keyword,order,diff,limit,status,sort}=this.state; let seartorders; @@ -352,7 +364,7 @@ class NewShixunModel extends Component{ } render() { - let {diff,Grouplist,status,shixun_list,shixuns_count,page,type,order,sort}=this.state; + let {diff,Grouplist,status,shixun_list,shixuns_count,page,type,order,sort,belongtoindex}=this.state; // let {visible,patheditarry}=this.props; // console.log(Grouplist) // console.log(allGrouplist) @@ -446,7 +458,7 @@ class NewShixunModel extends Component{
-
+
@@ -472,7 +484,36 @@ class NewShixunModel extends Component{ onSearch={ (value)=>this.setdatafuns(value)} />
-
+ + + + + + + {this.props.type==='shixuns'? +
+

筛选:

+

this.belongto("all")}>全部实训

+

this.belongto("mine")}>普通实训

+
:"" + } + {/*{this.props.type==='shixuns'? */} + {/* */} + {/* {diff===0?"难度":diff===1?"初级":diff===2?"中级":diff===3?"高级":diff===4?"顶级":""}*/} + {/* */} + {/*:""}*/} + {this.props.type==='shixuns'? +
+

难度:

+

this.DropdownClick(0)}>全部

+

this.DropdownClick(1)}>初级

+

this.DropdownClick(2)}>中级

+

this.DropdownClick(3)}>高级

+

this.DropdownClick(4)}>顶级

+
:"" + } + +
@@ -509,17 +550,18 @@ class NewShixunModel extends Component{ :"":""} - {this.props.type==='shixuns'? - - {diff===0?"难度":diff===1?"初级":diff===2?"中级":diff===3?"高级":diff===4?"顶级":""} - - :""} +
-
- {/*this.props.hideNewShixunModelType()}>返回*/} - this.belongto("mine")}>我的{this.props.type==='shixuns'?'实训':"课程"} - this.belongto("all")}>全部{this.props.type==='shixuns'?'实训':"课程"} +
+ + {this.props.type==='shixuns'?"": + this.belongto("mine")}>我的课程 + } + + {this.props.type==='shixuns'?"": + this.belongto("all")}>全部课程 + }
diff --git a/public/react/src/modules/courses/coursesPublic/Newshixunmodel.css b/public/react/src/modules/courses/coursesPublic/Newshixunmodel.css index 782979de0..b69c41e25 100644 --- a/public/react/src/modules/courses/coursesPublic/Newshixunmodel.css +++ b/public/react/src/modules/courses/coursesPublic/Newshixunmodel.css @@ -407,3 +407,110 @@ align-items: center; justify-content: center; } + + +/* 中间居中 */ +.intermediatecenter{ + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} +/* 简单居中 */ +.intermediatecenterysls{ + display: flex; + align-items: center; +} +.spacearound{ + display: flex; + justify-content: space-around; + +} +.spacebetween{ + display: flex; + justify-content: space-between; +} +/* 头顶部居中 */ +.topcenter{ + display: -webkit-flex; + flex-direction: column; + align-items: center; + +} + + +/* x轴正方向排序 */ +/* 一 二 三 四 五 六 七 八 */ +.sortinxdirection{ + display: flex; + flex-direction:row; +} +/* x轴反方向排序 */ +/* 八 七 六 五 四 三 二 一 */ +.xaxisreverseorder{ + display: flex; + flex-direction:row-reverse; +} +/* 垂直布局 正方向*/ +/* 一 + 二 + 三 + 四 + 五 + 六 + 七 + 八 */ +.verticallayout{ + display: flex; + flex-direction:column; +} +/* 垂直布局 反方向*/ +.reversedirection{ + display: flex; + flex-direction:column-reverse; +} + +.nandu{ + width: 42px; + height: 19px; + font-size: 14px; + color: #000000; + line-height: 19px; + margin-left: 6px; +} + +.clickbuts{ + text-align: center; + width: 60px; + height: 32px; + background: #4CACFF; + border-radius: 16px; + line-height: 30px; + color: #FFFFFF; + cursor:pointer; +} +.clickbutst{ + height:19px; + font-size:14px; + color:#505050; + line-height:19px; + cursor:pointer; +} + +.clickbutstwo{ + text-align: center; + width: 85px; + height: 32px; + background: #4CACFF; + border-radius: 16px; + line-height: 30px; + color: #FFFFFF; + cursor:pointer; +} +.clickbutstwos{ + height:19px; + font-size:14px; + color:#505050; + line-height:19px; + cursor:pointer; +} diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js index 745a249b0..a5d4d7011 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js @@ -483,8 +483,8 @@ class GraduationTasksnew extends Component { + 上传附件 + (单个文件150M以内) diff --git a/public/react/src/modules/modals/Bottomsubmit.js b/public/react/src/modules/modals/Bottomsubmit.js index b128b2afe..7287f0858 100644 --- a/public/react/src/modules/modals/Bottomsubmit.js +++ b/public/react/src/modules/modals/Bottomsubmit.js @@ -1,15 +1,16 @@ import React, {Component} from 'react'; +import { + Button, +} from 'antd'; class Bottomsubmit extends Component { constructor(props) { super(props) - this.state = { - - } + this.state = {} } - cannelfun=()=>{ + cannelfun = () => { // window.location.href= this.props.history.replace(this.props.url); } @@ -30,8 +31,11 @@ class Bottomsubmit extends Component {
- - + +
@@ -41,7 +45,6 @@ class Bottomsubmit extends Component { } - export default Bottomsubmit; diff --git a/public/react/src/modules/tpm/TPMBanner.js b/public/react/src/modules/tpm/TPMBanner.js index 7befed4c4..af14b25ab 100644 --- a/public/react/src/modules/tpm/TPMBanner.js +++ b/public/react/src/modules/tpm/TPMBanner.js @@ -311,6 +311,7 @@ class TPMBanner extends Component { console.log(error) }); } + cancel_publish = () => { this.setState({ Modalstype: true, @@ -971,7 +972,7 @@ class TPMBanner extends Component { - {shixunsDetails.shixun_status === 1 && this.props.identity < 5 ? + {shixunsDetails.shixun_status === 2 && shixunsDetails.public===0 && this.props.identity < 5 ? 撤销发布 : "" } diff --git a/public/react/src/modules/tpm/TPMDataset.js b/public/react/src/modules/tpm/TPMDataset.js index b7f168e0a..918868392 100644 --- a/public/react/src/modules/tpm/TPMDataset.js +++ b/public/react/src/modules/tpm/TPMDataset.js @@ -7,7 +7,7 @@ import TPMRightSection from './component/TPMRightSection'; import TPMNav from './component/TPMNav'; import axios from 'axios'; import './tpmmodel/tpmmodel.css' -import {getUploadActionUrl} from 'educoder'; +import {getUploadActionUrl,appendFileSizeToUploadFileAll} from 'educoder'; import moment from 'moment'; const confirm = Modal.confirm; @@ -20,8 +20,8 @@ class TPMDataset extends Component { columns: [ { title: '文件', - dataIndex: 'number', - key: 'number', + dataIndex: 'title', + key: 'title', align: 'left', className: " font-14 wenjiantit", width: '220px', @@ -33,8 +33,8 @@ class TPMDataset extends Component { }, { title: '最后修改时间', - dataIndex: 'number', - key: 'number', + dataIndex: 'timedata', + key: 'timedata', align: 'center', className: "edu-txt-center font-14 zuihoushijian", width: '150px', @@ -46,8 +46,8 @@ class TPMDataset extends Component { }, { title: '最后修改人', - dataIndex: 'number', - key: 'number', + dataIndex: 'author', + key: 'author', align: 'center', className: "edu-txt-center font-14 ", render: (text, record) => ( @@ -58,8 +58,8 @@ class TPMDataset extends Component { }, { title: '文件大小', - dataIndex: 'number', - key: 'number', + dataIndex: 'filesize', + key: 'filesize', align: 'center', className: "edu-txt-center font-14 ", render: (text, record) => ( @@ -260,38 +260,26 @@ class TPMDataset extends Component { if (index % 2 === 1) className = 'dark-row'; return className; } - - // 附件相关 START handleChange = (info) => { - if(info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') { - let {fileList} = this.state; - - if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') { - console.log("handleChange1fileLists"); - // if(fileList.length===0){ - let fileLists = info.fileList; - // console.log(fileLists); - this.setState({ - // fileList:appendFileSizeToUploadFileAll(fileList), - fileList: fileLists, - deleteisnot: false - }); - } + if(info.file.status == "done" || info.file.status == "uploading" || info.file.status === 'removed'){ + let fileList = info.fileList; + + // for(var list of fileList ){ + // console.log(list) + // } + this.setState({ + fileList: appendFileSizeToUploadFileAll(fileList), + }); if(info.file.status === 'done'){ //done 成功就会调用这个方法 this.getdatas(); // this.props.showNotification(`上传文件成功`); - }else if(info.file.status === 'removed'){ - // this.props.showNotification(`上传文件失败`); - - }else if(info.file.status === 'uploading'){ - // this.props.showNotification(`正在上传文件中`); - } } } + onAttachmentRemove = (file) => { // debugger if(!file.percent || file.percent == 100){ @@ -403,47 +391,27 @@ class TPMDataset extends Component { width: 600, fileList, data:{ - attachtype: 2, + attachtype: 2, container_id:this.props.match.params.shixunId, container_type: "Shixun", - }, + }, multiple: true, // https://github.com/ant-design/ant-design/issues/15505 // showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。 // showUploadList: false, - action: `${getUploadActionUrl()}`, + action: `${getUploadActionUrl()}`, onChange: this.handleChange, onRemove: this.onAttachmentRemove, - beforeUpload: (file, fileList) => { - - if (this.state.fileList.length >= 1) { - return false - } - // console.log('beforeUpload', file.name); - const isLt150M = file.size / 1024 / 1024 < 50; + beforeUpload: (file) => { + console.log('beforeUpload', file.name); + const isLt150M = file.size / 1024 / 1024 < 150; if (!isLt150M) { - // this.props.showNotification(`文件大小必须小于50MB`); - notification.open( - { - message: '提示', - description: - '文件大小必须小于50MB', - } - ) - } - if(this.state.file !== undefined){ - console.log("763") - this.setState({ - file:file - }) - }else { - this.setState({ - file:file - }) + this.props.showNotification('文件大小必须小于150MB!'); } return isLt150M; }, - } + }; + return (
@@ -460,13 +428,10 @@ class TPMDataset extends Component {
- { - data_sets_count>0? +
全选
- :"" - }
-

+

上传文件

{ diff --git a/public/react/src/modules/tpm/TPMsettings/Configuration.js b/public/react/src/modules/tpm/TPMsettings/Configuration.js index c7156abe8..803a6bf89 100644 --- a/public/react/src/modules/tpm/TPMsettings/Configuration.js +++ b/public/react/src/modules/tpm/TPMsettings/Configuration.js @@ -11,8 +11,6 @@ import { Button, } from 'antd'; -// import "antd/dist/antd.css"; - import locale from 'antd/lib/date-picker/locale/zh_CN'; import moment from 'moment'; @@ -21,8 +19,8 @@ import axios from 'axios'; import './css/TPMsettings.css'; -import {getImageUrl, toPath, getUrl, appendFileSizeToUploadFileAll, getUploadActionUrl} from 'educoder'; import {handleDateStrings} from "./oldTPMsettings"; + import Bottomsubmit from "../../modals/Bottomsubmit"; const $ = window.$; @@ -34,7 +32,6 @@ let currentValue; const Option = Select.Option; const RadioGroup = Radio.Group; -const confirm = Modal.confirm; function range(start, end) { const result = []; @@ -61,24 +58,25 @@ export default class Shixuninformation extends Component { constructor(props) { super(props) this.state = { - can_copy:false, - use_scope:0, - opening_time:null, - opentime:false, - oldscope_partment:[], - scope_partment:[] + can_copy: false, + use_scope: 0, + opening_time: null, + opentime: false, + oldscope_partment: [], + scope_partment: [], + loading: false } } componentDidMount() { - if (this.props.data) { + if (this.props.data&&this.props.data.shixun) { this.setState({ - can_copy: this.props.data && this.props.data.shixun.can_copy === undefined ? false :this.props.data.shixun.can_copy, - use_scope:this.props.data && this.props.data.shixun.use_scope, - opening_time: this.props.data && this.props.data.shixun.opening_time, - opentime:!this.props.data && this.props.data.shixun.opening_time?false:true, - oldscope_partment:this.props.data&&this.props.data.shixun.scope_partment, + can_copy:this.props.data.shixun && this.props.data.shixun.can_copy === undefined ? false : this.props.data.shixun&&this.props.data.shixun.can_copy, + use_scope: this.props.data.shixun && this.props.data.shixun.use_scope, + opening_time: this.props.data.shixun && this.props.data.shixun.opening_time, + opentime: !this.props.data.shixun && this.props.data.shixun.opening_time ? false : true, + oldscope_partment:this.props.data.shixun && this.props.data.shixun.scope_partment, }) } @@ -102,11 +100,11 @@ export default class Shixuninformation extends Component { if (this.props.data) { this.setState({ - can_copy: this.props.data && this.props.data.shixun.can_copy === undefined ? false :this.props.data.shixun.can_copy, - use_scope:this.props.data && this.props.data.shixun.use_scope, - opening_time: this.props.data && this.props.data.shixun.opening_time, - opentime:!this.props.data && this.props.data.shixun.opening_time?false:true, - oldscope_partment:this.props.data&&this.props.data.shixun.scope_partment, + can_copy: this.props.data.shixun && this.props.data.shixun.can_copy === undefined ? false : this.props.data.shixun&&this.props.data.shixun.can_copy, + use_scope: this.props.data.shixun&& this.props.data.shixun.use_scope, + opening_time: this.props.data.shixun && this.props.data.shixun.opening_time, + opentime: !this.props.data.shixun && this.props.data.shixun.opening_time ? false : true, + oldscope_partment: this.props.data.shixun && this.props.data.shixun.scope_partment, }) } @@ -115,75 +113,85 @@ export default class Shixuninformation extends Component { onChangeTimePicker = (value, dateString) => { this.setState({ - opening_time: dateString === "" ? "" :handleDateStrings(dateString) + opening_time: dateString === "" ? "" : handleDateStrings(dateString) }) } onSubmits = () => { - let {can_copy,use_scope,scope_partment,opening_time }=this.state; + this.setState({ + loading: true + }) + let {can_copy, use_scope, scope_partment, opening_time} = this.state; let id = this.props.match.params.shixunId; - let url=`/shixuns/${id}/update_permission_setting.json`; + let url = `/shixuns/${id}/update_permission_setting.json`; axios.post(url, { - scope_partment:scope_partment, - shixun:{ - can_copy: can_copy, - use_scope:use_scope, - opening_time:opening_time + scope_partment: scope_partment, + shixun: { + can_copy: can_copy, + use_scope: use_scope, + opening_time: opening_time + } } - } ).then((response) => { - if(response.data.status===-1){ + if (response.data.status === -1) { - }else{ - this.props.getdatas() - this.props.showNotification("保存成功") + } else { + this.props.getdatas("3") + this.props.showNotification("权限配置保存成功!") + this.setState({ + loading: false + }) } }).catch((error) => { - console.log(error) + this.setState({ + loading: false + }) }) + } - CheckboxonChange=(e)=>{ - this.setState({ - can_copy:e.target.checked - }) - } - SelectOpenpublic=(e)=>{ + CheckboxonChange = (e) => { + this.setState({ + can_copy: e.target.checked + }) + } + + SelectOpenpublic = (e) => { this.setState({ use_scope: e.target.value }); } shixunScopeInput = (e) => { - let {scope_partment,oldscope_partment} = this.state; + let {scope_partment, oldscope_partment} = this.state; let datalist = scope_partment; - if (datalist===undefined) { - datalist=[] + if (datalist === undefined) { + datalist = [] } datalist.push(e) - let scopetype=false; + let scopetype = false; - scope_partment.map((item,key)=>{ - if(item===e){ - scopetype=true + scope_partment.map((item, key) => { + if (item === e) { + scopetype = true } }) - oldscope_partment.map((item,key)=>{ - if(item===e){ - scopetype=true + oldscope_partment.map((item, key) => { + if (item === e) { + scopetype = true } }) - if(scopetype===false){ + if (scopetype === false) { this.setState({ scope_partment: datalist }); - }else{ + } else { this.props.showNotification("请勿指定相同的单位") } @@ -221,11 +229,12 @@ export default class Shixuninformation extends Component { }); } - setopentime=(e)=>{ + setopentime = (e) => { this.setState({ - opentime:e.target.checked + opentime: e.target.checked }) } + render() { let options; @@ -241,7 +250,7 @@ export default class Shixuninformation extends Component { return (
-
+
复制: @@ -253,9 +262,10 @@ export default class Shixuninformation extends Component {
- {this.props.data && this.props.data.shixun.use_scope === 0 &&this.props.data && this.props.data.shixun.status === 2?"":
- 公开程度: - + {this.props.data.shixun && this.props.data.shixun.use_scope === 0 && this.props.data.shixun && this.props.data.shixun.status === 2 ? "" : +
+ 公开程度: + 对所有单位公开 (实训发布后,所有用户可见) @@ -264,7 +274,7 @@ export default class Shixuninformation extends Component {
+ style={{display: this.state.use_scope === 0 ? 'none' : 'block'}}>
@@ -292,12 +302,12 @@ export default class Shixuninformation extends Component {
{ - this.state.oldscope_partment.map((item,key)=>{ + this.state.oldscope_partment.map((item, key) => { return (
  • - +
  • ) }) @@ -307,9 +317,9 @@ export default class Shixuninformation extends Component { return (
  • - this.deleteScopeInput(key)}> + this.deleteScopeInput(key)}>
  • @@ -331,31 +341,32 @@ export default class Shixuninformation extends Component { -
    } +
    }
    开启时间: - +
    - {this.state.opentime===false?"":
    - -
    } + {this.state.opentime === false ? "" :
    + +
    }
    @@ -365,7 +376,7 @@ export default class Shixuninformation extends Component {
    {this.props.identity < 5 ? : ""} + onSubmits={this.onSubmits} loadings={this.state.loading} bottomvalue={ this.props.shixunsDetails&&this.props.shixunsDetails.is_jupyter === true?"确 定":"下一步"} /> : ""}
    ); } diff --git a/public/react/src/modules/tpm/TPMsettings/LearningSettings.js b/public/react/src/modules/tpm/TPMsettings/LearningSettings.js index d8caa83ee..a548f9c71 100644 --- a/public/react/src/modules/tpm/TPMsettings/LearningSettings.js +++ b/public/react/src/modules/tpm/TPMsettings/LearningSettings.js @@ -1,29 +1,14 @@ import React, {Component} from 'react'; import { - Input, - Select, Radio, Checkbox, - Popconfirm, - message, - Modal, - Icon, - DatePicker, - Breadcrumb, - Upload, - Button, - notification, - Tooltip, - Tabs } from 'antd'; import axios from 'axios'; import './css/TPMsettings.css'; -import {getImageUrl, toPath, getUrl, appendFileSizeToUploadFileAll, getUploadActionUrl} from 'educoder'; - import Bottomsubmit from "../../modals/Bottomsubmit"; const RadioGroup = Radio.Group; @@ -32,144 +17,317 @@ const RadioGroup = Radio.Group; export default class Shixuninformation extends Component { constructor(props) { super(props) - this.state = {} + this.state = { + vnc: false, + hide_code: false, + is_secret_repository: false, + code_hidden: false, + forbid_copy: false, + test_set_permission: true, + task_pass: true, + websshshow: false, + multi_webssh: false, + opensshRadio: null, + loading: false + } } componentDidMount() { - if (this.props.data) { + if (this.props.data&&this.props.data.shixun) { this.setState({ vnc: this.props.data && this.props.data.shixun.vnc, - use_scope: this.props.data && this.props.data.shixun.use_scope, - opening_time: this.props.data && this.props.data.shixun.opening_time, - opentime: !this.props.data && this.props.data.shixun.opening_time ? false : true, - oldscope_partment: this.props.data && this.props.data.shixun.scope_partment, + code_hidden: this.props.data && this.props.data.shixun.code_hidden, + forbid_copy: this.props.data && this.props.data.shixun.forbid_copy, + hide_code: this.props.data && this.props.data.shixun.hide_code, + task_pass: this.props.data && this.props.data.shixun.task_pass, + test_set_permission: this.props.data && this.props.data.shixun.test_set_permission, + is_secret_repository: this.props.data && this.props.data.shixun.is_secret_repository, + websshshow: this.props.data && this.props.data.shixun.webssh === 0 ? false : true, + multi_webssh: this.props.data && this.props.data.shixun.multi_webssh, + opensshRadio: this.props.data && this.props.data.shixun.webssh === 0 ? null : this.props.data && this.props.data.shixun.webssh, }) + // if(this.props.data && this.props.data.shixun.status===0){ + // this.setState({ + // task_pass:true + // }) + // } + + } + + } + + componentDidUpdate(prevProps, prevState) { + if (prevProps.data != this.props.data) { + if (this.props.data) { + + this.setState({ + vnc: this.props.data && this.props.data.shixun.vnc, + code_hidden: this.props.data && this.props.data.shixun.code_hidden, + forbid_copy: this.props.data && this.props.data.shixun.forbid_copy, + hide_code: this.props.data && this.props.data.shixun.hide_code, + task_pass: this.props.data && this.props.data.shixun.task_pass, + test_set_permission: this.props.data && this.props.data.shixun.test_set_permission, + is_secret_repository: this.props.data && this.props.data.shixun.is_secret_repository, + websshshow: this.props.data && this.props.data.shixun.webssh === 0 ? false : true, + multi_webssh: this.props.data && this.props.data.shixun.multi_webssh, + opensshRadio: this.props.data && this.props.data.shixun.webssh === 0 ? null : this.props.data && this.props.data.shixun.webssh, + }) + + // if(this.props.data && this.props.data.shixun.status===0){ + // this.setState({ + // task_pass:true + // }) + // } + + } } - let departmentsUrl = `/shixuns/departments.json`; - axios.get(departmentsUrl).then((response) => { - if (response.status === 200) { - if (response.data.message === undefined) { - this.setState({ - departmentslist: response.data.shools_name - }); - } + } + + + onSubmits = () => { + this.setState({ + loading: true + }) + let id = this.props.match.params.shixunId; + let url = `/shixuns/${id}/update_permission_setting.json`; + axios.post(url, + { + shixun: { + code_hidden: this.state.code_hidden, + forbid_copy: this.state.forbid_copy, + hide_code: this.state.hide_code, + multi_webssh: this.state.multi_webssh, + task_pass: this.state.task_pass, + test_set_permission: this.state.test_set_permission, + vnc: this.state.vnc, + webssh: this.state.websshshow === false ? 0 : this.state.opensshRadio, + }, + is_secret_repository: this.state.is_secret_repository + } + ).then((response) => { + if (response.data.status === -1) { + + } else { + this.props.getdatas() + this.props.showNotification("学习页面设置保存成功!") + this.setState({ + loading: false + }) } }).catch((error) => { - console.log(error) - }); + this.setState({ + loading: false + }) + }) + } + + Checkvnc = () => { + console.log(this.state.vnc) + if (this.state.vnc === false) { + this.setState({ + hide_code: false, + is_secret_repository: false, + code_hidden: false, + forbid_copy: false, + multi_webssh: false, + websshshow: false, + }) + } + this.setState({ + vnc: !this.state.vnc + }) + } + + Checkhide_code = () => { + if (this.state.hide_code === false) { + this.setState({ + is_secret_repository: false + }) + } + this.setState({ + hide_code: !this.state.hide_code + }) + } + + Checkis_secret_repository = () => { + this.setState({ + is_secret_repository: !this.state.is_secret_repository + }) + } + + Checkcode_hidden = () => { + this.setState({ + code_hidden: !this.state.code_hidden + }) + } + + Checkforbid_copy = () => { + this.setState({ + forbid_copy: !this.state.forbid_copy + }) } + Checktask_pass = () => { + this.setState({ + task_pass: !this.state.task_pass + }) + } + + Checktest_set_permission = () => { + this.setState({ + test_set_permission: !this.state.test_set_permission + }) + } + + Checkwebsshshow = () => { + if (this.state.websshshow === false) { + this.setState({ + vnc: false, + opensshRadio: 1 + }) + } else { + this.setState({ + multi_webssh: false, + opensshRadio: null + }) + } + this.setState({ + websshshow: !this.state.websshshow + }) + + } + + Checkmulti_webssh = () => { + this.setState({ + multi_webssh: !this.state.multi_webssh + }) + } + + opensshRadio = (e) => { + if (e.target.value === 1) { + this.setState({ + multi_webssh: false + }) + } else { + this.setState({ + multi_webssh: true + }) + } + this.setState({ + opensshRadio: e.target.value + }); + } render() { console.log(this.props) return (
    -
    +
    -
    + {this.state.websshshow === true ? "" :
    开启图形化界面: + checked={this.state.vnc} + onChange={this.Checkvnc}> -
    +
    } -
    + {this.state.vnc === true ? "" :
    命令行: + checked={this.state.websshshow} + onChange={this.Checkwebsshshow}> -
    +
    } -
    + {this.state.vnc === true ? "" : this.state.websshshow === true ?
    - - 命令行练习窗口 + 命令行练习窗口 (选中则给学员提供用于练习操作的命令行,命令行的操作不会对学生的实验环境造成影响) - 命令行评测窗口 命令行评测窗口 (选中则给学员提供用于评测操作的命令行,命令行的操作可以对学生的实验环境产生影响) - + {this.state.opensshRadio === 2 ?
    + checked={this.state.multi_webssh} + onChange={this.Checkmulti_webssh}>
    -
    -
    + : ""} +
    : ""} -
    + {this.state.vnc === true ? "" :
    隐藏代码窗口: + checked={this.state.hide_code} + onChange={this.Checkhide_code}> -
    +
    } -
    + {this.state.vnc === true || this.state.hide_code === true ? "" :
    公开版本库: + checked={this.state.is_secret_repository} + onChange={this.Checkis_secret_repository}> -
    +
    } -
    - 隐藏代码目录: + {this.state.vnc === true ? "" :
    + 隐藏代码目录: + checked={this.state.code_hidden} + onChange={this.Checkcode_hidden}> -
    +
    } -
    - 禁用复制粘贴: + {this.state.vnc === true ? "" :
    + 禁用复制粘贴: + checked={this.state.forbid_copy} + onChange={this.Checkforbid_copy}> -
    +
    }
    - 跳关: + 跳关: + checked={this.state.task_pass} + onChange={this.Checktask_pass}>
    - 测试集解锁: + 测试集解锁: + checked={this.state.test_set_permission} + onChange={this.Checktest_set_permission}>
    @@ -179,7 +337,7 @@ export default class Shixuninformation extends Component { {this.props.identity < 5 ? : ""} + onSubmits={this.onSubmits} loadings={this.state.loading}/> : ""}
    ); } diff --git a/public/react/src/modules/tpm/TPMsettings/Shixuninformation.js b/public/react/src/modules/tpm/TPMsettings/Shixuninformation.js index 61f8c6bd8..ca12058ba 100644 --- a/public/react/src/modules/tpm/TPMsettings/Shixuninformation.js +++ b/public/react/src/modules/tpm/TPMsettings/Shixuninformation.js @@ -44,7 +44,8 @@ class Shixuninformation extends Component { Executiveordervalue: "", Compilecommandvalue: "", shixun_service_configs: undefined, - fileList:[] + fileList:[], + loading:false, } } @@ -54,33 +55,37 @@ class Shixuninformation extends Component { componentDidUpdate(prevProps, prevState) { if (prevProps.data != this.props.data) { - if (this.props.data) { + if (this.props.data&&this.props.data.shixun) { this.setState({ - shixunName: this.props.data.shixun.name, - trainee: this.props.data.shixun.trainee, - choice_main_type: this.props.data.shixun.choice_main_type, - choice_small_type: this.props.data.shixun.choice_small_type, - choice_standard_scripts: this.props.data.shixun.choice_standard_scripts, - shixunmemoMDvalue: this.props.data.shixun.evaluate_script, - simichecked: this.props.data.shixun.is_secret_repository, - shixun_service_configs: this.props.data.shixun.shixun_service_configs, - standard_scripts:this.props.data.shixun.standard_scripts, - shixun_service_configlist:this.props.data.shixun.shixun_service_configs, + shixunName: this.props.data.shixun&&this.props.data.shixun.name, + trainee:this.props.data.shixun&&this.props.data.shixun.trainee, + choice_main_type: this.props.data.shixun&&this.props.data.shixun.choice_main_type, + choice_small_type: this.props.data.shixun&&this.props.data.shixun.choice_small_type, + choice_standard_scripts:this.props.data.shixun&&this.props.data.shixun.choice_standard_scripts, + shixunmemoMDvalue: this.props.data.shixun&&this.props.data.shixun.evaluate_script, + simichecked: this.props.data.shixun&&this.props.data.shixun.is_secret_repository, + shixun_service_configs: this.props.data.shixun&&this.props.data.shixun.shixun_service_configs, + standard_scripts:this.props.data.shixun&&this.props.data.shixun.standard_scripts, + shixun_service_configlist:this.props.data.shixun&&this.props.data.shixun.shixun_service_configs, }) - if(this.props.data.shixun.choice_standard_scripts===null){ + if(this.props.data.shixun&&this.props.data.shixun.choice_standard_scripts===null){ this.setState({ - choice_standard_scripts:{id: this.props.data.shixun.standard_scripts[0].id, value: ""}, - choice_standard_scriptssum:this.props.data.shixun.standard_scripts[0].id + choice_standard_scripts:{id: this.props.data.shixun&&this.props.data.shixun.standard_scripts[0].id, value: ""}, + choice_standard_scriptssum:this.props.data.shixun&&this.props.data.shixun.standard_scripts[0].id }) this.props.form.setFieldsValue({ - selectscripts:this.props.data.shixun.standard_scripts[0].id + selectscripts:this.props.data.shixun&&this.props.data.shixun.standard_scripts[0].id + }) + this.get_mirror_script(this.props.data.shixun&&this.props.data.shixun.standard_scripts[0].id) + }else{ + this.props.form.setFieldsValue({ + selectscripts:this.props.data.shixun&&this.props.data.shixun.choice_standard_scripts }) - this.get_mirror_script(this.props.data.shixun.standard_scripts[0].id) } let newlist = "" - this.props.data.shixun.choice_small_type.map((item, key) => { + this.props.data.shixun&&this.props.data.shixun.choice_small_type.map((item, key) => { this.props.data.shixun.small_type.map((i,k)=>{ if (item===i.id) { newlist = newlist + `${i.description}` @@ -91,8 +96,8 @@ class Shixuninformation extends Component { subvalues: newlist }) - this.props.data.shixun.main_type.map((item,key)=>{ - if(item.id===this.props.data.shixun.choice_main_type){ + this.props.data.shixun&&this.props.data.shixun.main_type.map((item,key)=>{ + if(item.id===this.props.data.shixun&&this.props.data.shixun.choice_main_type){ this.setState({ mainvalues:item.description, }) @@ -100,12 +105,12 @@ class Shixuninformation extends Component { }) this.props.form.setFieldsValue({ - name: this.props.data.shixun.name, - trainee: this.props.data.shixun.trainee, - selectleft: this.props.data.shixun.choice_main_type, - selectright:this.props.data.shixun.choice_small_type, + name:this.props.data.shixun&&this.props.data.shixun.name, + trainee: this.props.data.shixun&&this.props.data.shixun.trainee, + selectleft: this.props.data.shixun&&this.props.data.shixun.choice_main_type, + selectright:this.props.data.shixun&&this.props.data.shixun.choice_small_type, }) - this.contentMdRef.current.setValue(this.props.data.shixun.description); + this.contentMdRef.current.setValue(this.props.data.shixun&&this.props.data.shixun.description); } } } @@ -641,6 +646,9 @@ class Shixuninformation extends Component { } onSubmits=()=>{ + this.setState({ + loading:true + }) const mdContnet = this.contentMdRef.current.getValue().trim(); let{choice_standard_scriptssum,choice_standard_scripts}=this.state; this.props.form.validateFieldsAndScroll((err, values) => { @@ -673,18 +681,29 @@ class Shixuninformation extends Component { axios.put(url, data).then((result) => { if (result) { if (result.data) { - this.props.getdatas() + this.props.getdatas("2") if(result.data.shixun_identifier){ - this.props.showNotification("基本信息更新成功") - + this.props.showNotification("基本信息更新成功!") + this.setState({ + loading:false + }) } } } }).catch((error) => { - // ////console.log(error) + this.setState({ + loading:false + }) }); + }else{ + this.setState({ + loading:false + }) } }); + this.setState({ + loading: false + }) } Selectthestudent = (value) => { @@ -822,7 +841,7 @@ class Shixuninformation extends Component { > { - this.props.data === undefined ? "" : this.props.data.shixun.main_type.map((item, key) => { + this.props.data === undefined ? "" : this.props.data.shixun&&this.props.data.shixun.main_type.map((item, key) => { return (