Merge branch 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

dev_hjm
caishi 6 years ago
commit 4bfb9bd9b6

@ -494,17 +494,10 @@ class GamesController < ApplicationController
path = path.try(:strip) path = path.try(:strip)
uid_logger("--rep_content: path is #{path}") uid_logger("--rep_content: path is #{path}")
begin begin
if @myshixun.repo_name.nil? @content = git_fle_content(@myshixun.repo_path, path) || ""
g = Gitlab.client
repo_name = g.project(@myshixun.gpid).path_with_namespace
@myshixun.update_column(:repo_name, repo_name)
@content = git_fle_content("#{repo_name}.git", path) || ""
else
@content = git_fle_content(@myshixun.repo_path, path) || ""
end
rescue Exception => e rescue Exception => e
# 思路: 异常首先应该考虑去恢复 # 思路: 异常首先应该考虑去恢复
# retry为1表示已经轮训完成后还没有解决问题这个时候需要检测异常
if params[:retry].to_i == 1 if params[:retry].to_i == 1
begin begin
# 如果模板没有问题,则通过中间层检测实训仓库是否异常 # 如果模板没有问题,则通过中间层检测实训仓库是否异常
@ -542,7 +535,7 @@ class GamesController < ApplicationController
end end
end end
end end
# 有异常,版本库获取不到代码,前端轮训30S后调用retry == 1 # 有异常,版本库获取不到代码,前端轮训15S后调用retry == 1
tip_exception(0, e.message) tip_exception(0, e.message)
end end
end end

@ -514,6 +514,103 @@ class ShixunsController < ApplicationController
# 以前在开启挑战的时候检测实训是否更新更新则重置觉得应该放在TPI更好 # 以前在开启挑战的时候检测实训是否更新更新则重置觉得应该放在TPI更好
# 中间需要一个过渡动画 # 中间需要一个过渡动画
# TODO: 第一次开启实训都会去判断是否是纯选择题类型,感觉做成在创建关卡的时候就判断该实训是否是纯选择题更加合适 # TODO: 第一次开启实训都会去判断是否是纯选择题类型,感觉做成在创建关卡的时候就判断该实训是否是纯选择题更加合适
def shixun_exec
if is_shixun_opening?
tip_show_exception(-3, "#{@shixun.opening_time.strftime('%Y-%m-%d %H:%M:%S')}")
end
current_myshixun = @shixun.current_myshixun(current_user.id)
min_challenges = @shixun.challenges.pluck(:id , :st)
Rails.logger.info("11111111112#{current_myshixun.try(:id)}")
Rails.logger.info("111111111102#{params[:reset] != 1}")
# 因为读写分离有延迟所以如果是重置来的请求可以先跳过重置过来的params[:reset]为1
if current_myshixun && params[:reset] != "1"
games = current_myshixun.games
# 如果TPM和TPI的管卡数不相等或者关卡顺序错了说明实训被极大的改动需要重置,实训发布前打过的实训都需要重置
if is_shixun_reset?(games, min_challenges, current_myshixun)
# 这里页面弹框要收到 当前用户myshixun的identifier.
tip_show_exception("/myshixuns/#{current_myshixun.try(:identifier)}/reset_my_game")
end
# 如果存在实训,则直接进入实训
# 如果实训允许跳关传参params[:challenge_id]跳入具体的关卡
@current_task =
if params[:challenge_id]
game = games.where(challenge_id: params[:challenge_id]).take
if @shixun.task_pass || game.status != 3
game
else
current_myshixun.current_task(games)
end
else
current_myshixun.current_task(games)
end
else
# 如果未创建关卡一定不能开启实训否则TPI没法找到当前的关卡
if @shixun.challenges_count == 0
tip_exception("开启实战前请先创建实训关卡")
end
# 判断实训是否全为选择题
is_choice_type = (min_challenges.size == min_challenges.select{|challenge| challenge.last == 1}.count)
if !is_choice_type
commit = GitService.commits(repo_path: @repo_path).try(:first)
uid_logger("First comit########{commit}")
tip_exception("开启实战前请先在版本库中提交代码") if commit.blank?
commit_id = commit["id"]
end
ActiveRecord::Base.transaction do
begin
cloud_bridge = edu_setting('cloud_bridge')
myshixun_identifier = generate_identifier Myshixun, 10
myshixun = @shixun.myshixuns.create!(user_id: current_user.id, identifier: myshixun_identifier,
modify_time: @shixun.modify_time, reset_time: @shixun.reset_time,
onclick_time: Time.now, commit_id: commit_id, repo_name: (is_choice_type ? "-1" : nil))
uid_logger("myshixun_id is #{myshixun.id}")
# 其它创建关卡等操作
challenges = @shixun.challenges
# 之所以增加user_id是为了方便统计查询性能
game_attrs = %i[challenge_id myshixun_id status user_id open_time identifier modify_time created_at updated_at]
Game.bulk_insert(*game_attrs) do |worker|
base_attr = { myshixun_id: myshixun.id, user_id: myshixun.user_id }
challenges.each_with_index do |challenge, index|
status = (index == 0 ? 0 : 3)
game_identifier = generate_identifier(Game, 12)
worker.add(base_attr.merge(challenge_id: challenge.id, status: status, open_time: Time.now,
identifier: game_identifier, modify_time: challenge.modify_time))
end
end
# 如果实训是纯选择题则不需要去fork仓库以及中间层的相关操作了
unless is_choice_type
# fork仓库
project_fork(myshixun, @repo_path, current_user.login)
rep_url = Base64.urlsafe_encode64(repo_ip_url @repo_path )
uid_logger("start openGameInstance")
uri = "#{cloud_bridge}/bridge/game/openGameInstance"
logger.info("end openGameInstance")
params = {tpiID: "#{myshixun.id}", tpmGitURL:rep_url, tpiRepoName: myshixun.repo_name.split("/").last}
uid_logger("openGameInstance params is #{params}")
interface_post uri, params, 83, "实训云平台繁忙繁忙等级83"
end
@current_task = myshixun.current_task(myshixun.games)
uid_logger("## shixun exec: myshixun id is #{myshixun.id}")
rescue Exception => e
uid_logger_error(e.message)
tip_exception("实训云平台繁忙繁忙等级81")
raise ActiveRecord::Rollback
end
end
end
end
# def shixun_exec # def shixun_exec
# if is_shixun_opening? # if is_shixun_opening?
# tip_show_exception(-3, "#{@shixun.opening_time.strftime('%Y-%m-%d %H:%M:%S')}") # tip_show_exception(-3, "#{@shixun.opening_time.strftime('%Y-%m-%d %H:%M:%S')}")
@ -521,10 +618,6 @@ class ShixunsController < ApplicationController
# current_myshixun = @shixun.current_myshixun(current_user.id) # current_myshixun = @shixun.current_myshixun(current_user.id)
# #
# min_challenges = @shixun.challenges.pluck(:id , :st) # min_challenges = @shixun.challenges.pluck(:id , :st)
#
# Rails.logger.info("11111111112#{current_myshixun.try(:id)}")
# Rails.logger.info("111111111102#{params[:reset] != 1}")
#
# # 因为读写分离有延迟所以如果是重置来的请求可以先跳过重置过来的params[:reset]为1 # # 因为读写分离有延迟所以如果是重置来的请求可以先跳过重置过来的params[:reset]为1
# if current_myshixun && params[:reset] != "1" # if current_myshixun && params[:reset] != "1"
# games = current_myshixun.games # games = current_myshixun.games
@ -541,7 +634,6 @@ class ShixunsController < ApplicationController
# current_myshixun.update_column(:repo_name, repo_name) # current_myshixun.update_column(:repo_name, repo_name)
# end # end
# #
#
# # 如果存在实训,则直接进入实训 # # 如果存在实训,则直接进入实训
# # 如果实训允许跳关传参params[:challenge_id]跳入具体的关卡 # # 如果实训允许跳关传参params[:challenge_id]跳入具体的关卡
# @current_task = # @current_task =
@ -570,159 +662,59 @@ class ShixunsController < ApplicationController
# commit_id = commit["id"] # commit_id = commit["id"]
# end # end
# #
# ActiveRecord::Base.transaction do # begin
# begin # ActiveRecord::Base.transaction do
# cloud_bridge = edu_setting('cloud_bridge') # begin
# myshixun_identifier = generate_identifier Myshixun, 10 # myshixun_identifier = generate_identifier Myshixun, 10
# myshixun = @shixun.myshixuns.create!(user_id: current_user.id, identifier: myshixun_identifier, # myshixun_params = {user_id: current_user.id, identifier: myshixun_identifier,
# modify_time: @shixun.modify_time, reset_time: @shixun.reset_time, # modify_time: @shixun.modify_time, reset_time: @shixun.reset_time,
# onclick_time: Time.now, commit_id: commit_id) # onclick_time: Time.now, commit_id: commit_id}
# uid_logger("myshixun_id is #{myshixun.id}") # @myshixun = @shixun.myshixuns.create!(myshixun_params)
# # # 其它创建关卡等操作
# # challenges = @shixun.challenges
# # 其它创建关卡等操作 # # 之所以增加user_id是为了方便统计查询性能
# challenges = @shixun.challenges # game_attrs = %i[challenge_id myshixun_id status user_id open_time identifier modify_time created_at updated_at]
# # 之所以增加user_id是为了方便统计查询性能 # Game.bulk_insert(*game_attrs) do |worker|
# game_attrs = %i[challenge_id myshixun_id status user_id open_time identifier modify_time created_at updated_at] # base_attr = {myshixun_id: @myshixun.id, user_id: @myshixun.user_id}
# Game.bulk_insert(*game_attrs) do |worker| # challenges.each_with_index do |challenge, index|
# base_attr = { myshixun_id: myshixun.id, user_id: myshixun.user_id } # status = (index == 0 ? 0 : 3)
# challenges.each_with_index do |challenge, index| # game_identifier = generate_identifier(Game, 12)
# status = (index == 0 ? 0 : 3) # worker.add(base_attr.merge(challenge_id: challenge.id, status: status, open_time: Time.now,
# game_identifier = generate_identifier(Game, 12) # identifier: game_identifier, modify_time: challenge.modify_time))
# worker.add(base_attr.merge(challenge_id: challenge.id, status: status, open_time: Time.now, # end
# identifier: game_identifier, modify_time: challenge.modify_time))
# end # end
# @current_task = @myshixun.current_task(@myshixun.games)
# rescue Exception => e
# logger.error("------ActiveRecord::RecordInvalid: #{e.message}")
# raise("ActiveRecord::RecordInvalid")
# end # end
# # end
# # 如果实训是纯选择题则不需要去fork仓库以及中间层的相关操作了 # # 如果实训是纯选择题则不需要去fork仓库以及中间层的相关操作了
# ActiveRecord::Base.transaction do
# unless is_choice_type # unless is_choice_type
# # fork仓库 # # fork仓库
# project_fork(myshixun, @repo_path, current_user.login) # cloud_bridge = edu_setting('cloud_bridge')
# # project_fork(@myshixun, @repo_path, current_user.login)
# rep_url = Base64.urlsafe_encode64(repo_ip_url @repo_path ) # rep_url = Base64.urlsafe_encode64(repo_ip_url @repo_path)
# uid_logger("start openGameInstance") # uid_logger("start openGameInstance")
# uri = "#{cloud_bridge}/bridge/game/openGameInstance" # uri = "#{cloud_bridge}/bridge/game/openGameInstance"
# logger.info("end openGameInstance") # logger.info("end openGameInstance")
# params = {tpiID: "#{myshixun.id}", tpmGitURL:rep_url, tpiRepoName: myshixun.repo_name.split("/").last} # params = {tpiID: "#{@myshixun.id}", tpmGitURL: rep_url, tpiRepoName: @myshixun.repo_name.split("/").last}
# uid_logger("openGameInstance params is #{params}") # uid_logger("openGameInstance params is #{params}")
# interface_post uri, params, 83, "实训云平台繁忙繁忙等级83" # interface_post uri, params, 83, "实训云平台繁忙繁忙等级83"
# end # end
#
# @current_task = myshixun.current_task(myshixun.games)
# uid_logger("## shixun exec: myshixun id is #{myshixun.id}")
# rescue Exception => e
# uid_logger_error(e.message)
# tip_exception("实训云平台繁忙繁忙等级81")
# raise ActiveRecord::Rollback
# end # end
# rescue Exception => e
# logger.info("shixun_exec error: #{e.message}")
# if e.message != "ActiveRecord::RecordInvalid"
# logger.error("##########project_fork error #{e.message}")
# @myshixun.destroy!
# end
# raise "实训云平台繁忙繁忙等级81"
# end # end
# end # end
# end # end
def shixun_exec
if is_shixun_opening?
tip_show_exception(-3, "#{@shixun.opening_time.strftime('%Y-%m-%d %H:%M:%S')}")
end
current_myshixun = @shixun.current_myshixun(current_user.id)
min_challenges = @shixun.challenges.pluck(:id , :st)
# 因为读写分离有延迟所以如果是重置来的请求可以先跳过重置过来的params[:reset]为1
if current_myshixun && params[:reset] != "1"
games = current_myshixun.games
# 如果TPM和TPI的管卡数不相等或者关卡顺序错了说明实训被极大的改动需要重置,实训发布前打过的实训都需要重置
if is_shixun_reset?(games, min_challenges, current_myshixun)
# 这里页面弹框要收到 当前用户myshixun的identifier.
tip_show_exception("/myshixuns/#{current_myshixun.try(:identifier)}/reset_my_game")
end
if current_myshixun.repo_name.nil?
g = Gitlab.client
repo_name = g.project(current_myshixun.gpid).try(:path_with_namespace)
current_myshixun.update_column(:repo_name, repo_name)
end
# 如果存在实训,则直接进入实训
# 如果实训允许跳关传参params[:challenge_id]跳入具体的关卡
@current_task =
if params[:challenge_id]
game = games.where(challenge_id: params[:challenge_id]).take
if @shixun.task_pass || game.status != 3
game
else
current_myshixun.current_task(games)
end
else
current_myshixun.current_task(games)
end
else
# 如果未创建关卡一定不能开启实训否则TPI没法找到当前的关卡
if @shixun.challenges_count == 0
tip_exception("开启实战前请先创建实训关卡")
end
# 判断实训是否全为选择题
is_choice_type = (min_challenges.size == min_challenges.select{|challenge| challenge.last == 1}.count)
if !is_choice_type
commit = GitService.commits(repo_path: @repo_path).try(:first)
uid_logger("First comit########{commit}")
tip_exception("开启实战前请先在版本库中提交代码") if commit.blank?
commit_id = commit["id"]
end
begin
ActiveRecord::Base.transaction do
begin
myshixun_identifier = generate_identifier Myshixun, 10
myshixun_params = {user_id: current_user.id, identifier: myshixun_identifier,
modify_time: @shixun.modify_time, reset_time: @shixun.reset_time,
onclick_time: Time.now, commit_id: commit_id}
@myshixun = @shixun.myshixuns.create!(myshixun_params)
# 其它创建关卡等操作
challenges = @shixun.challenges
# 之所以增加user_id是为了方便统计查询性能
game_attrs = %i[challenge_id myshixun_id status user_id open_time identifier modify_time created_at updated_at]
Game.bulk_insert(*game_attrs) do |worker|
base_attr = {myshixun_id: @myshixun.id, user_id: @myshixun.user_id}
challenges.each_with_index do |challenge, index|
status = (index == 0 ? 0 : 3)
game_identifier = generate_identifier(Game, 12)
worker.add(base_attr.merge(challenge_id: challenge.id, status: status, open_time: Time.now,
identifier: game_identifier, modify_time: challenge.modify_time))
end
end
@current_task = @myshixun.current_task(@myshixun.games)
rescue Exception => e
logger.error("------ActiveRecord::RecordInvalid: #{e.message}")
raise("ActiveRecord::RecordInvalid")
end
end
# 如果实训是纯选择题则不需要去fork仓库以及中间层的相关操作了
ActiveRecord::Base.transaction do
unless is_choice_type
# fork仓库
cloud_bridge = edu_setting('cloud_bridge')
project_fork(@myshixun, @repo_path, current_user.login)
rep_url = Base64.urlsafe_encode64(repo_ip_url @repo_path)
uid_logger("start openGameInstance")
uri = "#{cloud_bridge}/bridge/game/openGameInstance"
logger.info("end openGameInstance")
params = {tpiID: "#{@myshixun.id}", tpmGitURL: rep_url, tpiRepoName: @myshixun.repo_name.split("/").last}
uid_logger("openGameInstance params is #{params}")
interface_post uri, params, 83, "实训云平台繁忙繁忙等级83"
end
end
rescue Exception => e
logger.info("shixun_exec error: #{e.message}")
if e.message != "ActiveRecord::RecordInvalid"
logger.error("##########project_fork error #{e.message}")
@myshixun.destroy!
end
raise "实训云平台繁忙繁忙等级81"
end
end
end
# gameID 及实训ID # gameID 及实训ID
# status: 0 , 1 申请过, 2实训关卡路径未填 3 实训标签未填, 4 实训未创建关卡 # status: 0 , 1 申请过, 2实训关卡路径未填 3 实训标签未填, 4 实训未创建关卡
def publish def publish

@ -7,4 +7,4 @@ json.pagination @total_count > 16 ? true : false
json.search_tags @search_tags json.search_tags @search_tags
json.shixuns do json.shixuns do
json.partial! 'shixun', locals: {shixuns: @shixuns} json.partial! 'shixun', locals: {shixuns: @shixuns}
end end

@ -1,43 +1,43 @@
class ModifyKeContentsForMarkdown < ActiveRecord::Migration[5.2] class ModifyKeContentsForMarkdown < ActiveRecord::Migration[5.2]
include ActionView::Helpers::SanitizeHelper include ActionView::Helpers::SanitizeHelper
def change def change
# def ke_transform_to_md content def ke_transform_to_md content
# return content if content.blank? return content if content.blank?
# s_contents = sanitize(content, tags: %w(img a span table td tr tbody pre), attributes: %w(src href target style)) s_contents = sanitize(content, tags: %w(img a span table td tr tbody pre), attributes: %w(src href target style))
# s_contents.gsub(/^(\n)/, "").gsub(/(\n)+/, "<br>").gsub(/$(\n)/, "") s_contents.gsub(">\n<", "><").gsub(/^\n/, "").gsub(" ", "").gsub(/(\n)+/, "<br />")
# .gsub(/(\n)+/, "<br>").gsub("\t", " ") .gsub("\t", "").gsub("\n", "").gsub(" ", "&nbsp;&nbsp;&nbsp;&nbsp;").gsub(/(<br\s?\/?>)+/, "<br />")
# end end
# #
# # 课程讨论区 # # 课程讨论区
# MessageDetail.find_each do |m| # MessageDetail.find_each do |m|
# content = ke_transform_to_md m.content # content = ke_transform_to_md m.content
# m.update_column(:content, content) # m.update_column(:content, content)
# end # end
#
# # 试卷的标题 #试卷的标题
# ExerciseQuestion.find_each do |eq| # ExerciseQuestion.find_each do |eq|
# question_title = ke_transform_to_md eq.question_title # question_title = ke_transform_to_md eq.question_title
# eq.update_column(:question_title, question_title) # eq.update_column(:question_title, question_title)
# end # end
#
# # 试卷的答案 # # 试卷的答案
# ExerciseStandardAnswer.find_each do |esa| # ExerciseStandardAnswer.find_each do |esa|
# answer_text = ke_transform_to_md esa.answer_text # answer_text = ke_transform_to_md esa.answer_text
# esa.update_column(:answer_text, answer_text) # esa.update_column(:answer_text, answer_text)
# end # end
# #
# # 试卷题库的问题标题 # 试卷题库的问题标题
# ExerciseBankQuestion.find_each do |ebq| ExerciseBankQuestion.find_each do |ebq|
# question_title = ke_transform_to_md ebq.question_title question_title = ke_transform_to_md ebq.question_title
# ebq.update_column(:question_title, question_title) ebq.update_column(:question_title, question_title)
# end end
# #
# # 试卷答案 # # 试卷答案
# ExerciseBankStandardAnswer.find_each do |ebsa| # ExerciseBankStandardAnswer.find_each do |ebsa|
# answer_text = ke_transform_to_md ebsa.answer_text # answer_text = ke_transform_to_md ebsa.answer_text
# ebsa.update_column(:answer_text, answer_text) # ebsa.update_column(:answer_text, answer_text)
# end # end
#
# # 问卷的标题 # # 问卷的标题
# PollQuestion.find_each do |pq| # PollQuestion.find_each do |pq|
# question_title = ke_transform_to_md pq.question_title # question_title = ke_transform_to_md pq.question_title

@ -1,63 +1,64 @@
class SecondMofidyKeContentsForMd < ActiveRecord::Migration[5.2] class SecondMofidyKeContentsForMd < ActiveRecord::Migration[5.2]
include ActionView::Helpers::SanitizeHelper include ActionView::Helpers::SanitizeHelper
def change def change
# def ke_transform_to_md content def ke_transform_to_md content
# return content if content.blank? return content if content.blank?
# s_contents = sanitize(content, tags: %w(img a span table td tr tbody pre), attributes: %w(src href target style)) s_contents = sanitize(content, tags: %w(img a span table td tr tbody pre), attributes: %w(src href target style))
# s_contents.gsub(/^(\n)/, "").gsub(/(\n)+/, "<br>").gsub(/$(\n)/, "") s_contents.gsub(">\n<", "><").gsub(/^\n/, "").gsub(" ", "&nbsp;").gsub(/(\n)+/, "<br />")
# .gsub(/(\n)+/, "<br>").gsub("\t", " ") .gsub("\t", "&nbsp;&nbsp;&nbsp;&nbsp;").gsub("\n", "").gsub(" ", "&nbsp;").gsub(/(<br\s?\/?>)+/, "<br />")
# end
# end
# # 作业
# HomeworkCommon.find_each do |hc| # 作业
# description = ke_transform_to_md hc.description HomeworkCommon.find_each do |hc|
# reference_answer = ke_transform_to_md hc.reference_answer description = ke_transform_to_md hc.description
# explanation = ke_transform_to_md hc.explanation reference_answer = ke_transform_to_md hc.reference_answer
# hc.update_attributes(description: description, reference_answer: reference_answer, explanation: explanation) explanation = ke_transform_to_md hc.explanation
# end hc.update_attributes(description: description, reference_answer: reference_answer, explanation: explanation)
# end
# # 作业题库
# HomeworkBank.find_each do |hb| # 作业题库
# description = ke_transform_to_md hb.description HomeworkBank.find_each do |hb|
# reference_answer = ke_transform_to_md hb.reference_answer description = ke_transform_to_md hb.description
# hb.update_attributes(description: description, reference_answer: reference_answer) reference_answer = ke_transform_to_md hb.reference_answer
# end hb.update_attributes(description: description, reference_answer: reference_answer)
# end
# # 毕业任务
# GraduationTask.find_each do |gt| # 毕业任务
# description = ke_transform_to_md gt.description GraduationTask.find_each do |gt|
# gt.update_column(:description, description) description = ke_transform_to_md gt.description
# end gt.update_column(:description, description)
# end
# # 毕设选题
# GraduationTopic.find_each do |gt| # 毕设选题
# description = ke_transform_to_md gt.description GraduationTopic.find_each do |gt|
# gt.update_column(:description, description) description = ke_transform_to_md gt.description
# end gt.update_column(:description, description)
# end
# # 毕设作品
# GraduationWork.find_each do |gw| # 毕设作品
# description = ke_transform_to_md gw.description GraduationWork.find_each do |gw|
# gw.update_column(:description, description) description = ke_transform_to_md gw.description
# end gw.update_column(:description, description)
# end
# # 毕设任务题库
# GtaskBank.find_each do |gb| # 毕设任务题库
# description = ke_transform_to_md gb.description GtaskBank.find_each do |gb|
# gb.update_column(:description, description) description = ke_transform_to_md gb.description
# end gb.update_column(:description, description)
# end
# # 毕设选题题库
# GtopicBank.find_each do |gb| # 毕设选题题库
# description = ke_transform_to_md gb.description GtopicBank.find_each do |gb|
# gb.update_column(:description, description) description = ke_transform_to_md gb.description
# end gb.update_column(:description, description)
# end
# # 交流问答
# Memo.find_each do |m| # 交流问答
# content = ke_transform_to_md m.content Memo.find_each do |m|
# m.update_column(:content, content) content = ke_transform_to_md m.content
# end m.update_column(:content, content)
end
end end
end end

@ -1,17 +1,17 @@
class ThirdModifyKeForStudentWork < ActiveRecord::Migration[5.2] class ThirdModifyKeForStudentWork < ActiveRecord::Migration[5.2]
include ActionView::Helpers::SanitizeHelper include ActionView::Helpers::SanitizeHelper
def change def change
# def ke_transform_to_md content def ke_transform_to_md content
# return content if content.blank? return content if content.blank?
# s_contents = sanitize(content, tags: %w(img a span table td tr tbody pre), attributes: %w(src href target style)) s_contents = sanitize(content, tags: %w(img a span table td tr tbody pre), attributes: %w(src href target style))
# s_contents.gsub(/^(\n)/, "").gsub(/(\n)+/, "<br>").gsub(/$(\n)/, "") s_contents.gsub(">\n<", "><").gsub(/^\n/, "").gsub(" ", "&nbsp;").gsub(/(\n)+/, "<br />")
# .gsub(/(\n)+/, "<br>").gsub("\t", " ") .gsub("\t", "&nbsp;&nbsp;&nbsp;&nbsp;").gsub("\n", "").gsub(" ", "&nbsp;").gsub(/(<br\s?\/?>)+/, "<br />")
# end end
#
# # 学生的作品 过滤掉一些描述的ke图片的作品 # 学生的作品 过滤掉一些描述的ke图片的作品
# StudentWork.where("description is not null and LENGTH(description) < 1000000").find_each do |sw| StudentWork.where("description is not null and LENGTH(description) < 1000000").find_each do |sw|
# description = ke_transform_to_md sw.description description = ke_transform_to_md sw.description
# sw.update_column(:description, description) sw.update_column(:description, description)
# end end
end end
end end

@ -19,7 +19,7 @@ namespace :myshixun do
challenges = shixun.challenges challenges = shixun.challenges
# 如果是选择题则把myshixuns表的repo_name改成-1 # 如果是选择题则把myshixuns表的repo_name改成-1
if challenges.select{|challenge| challenge.st.to_i == 1}.size == challenges.count if challenges.select{|challenge| challenge.st.to_i == 1}.size == challenges.count
puts myshixun.games.first.try(:identifier) myshixun.update_attributes(:repo_name => "-1")
end end
end end
end end

@ -17,6 +17,7 @@ function locationurl(list){
window.location.replace(list) window.location.replace(list)
} }
} }
let hashTimeout
// TODO 开发期多个身份切换 // TODO 开发期多个身份切换
let debugType ="" let debugType =""
@ -137,6 +138,18 @@ export function initAxiosInterceptors(props) {
} }
throw new axios.Cancel('Operation canceled by the user.'); throw new axios.Cancel('Operation canceled by the user.');
} else {
// hash跳转
var hash = window.location.hash;
if (hash) {
hashTimeout && window.clearTimeout(hashTimeout)
hashTimeout = setTimeout(() => {
var element = document.querySelector(hash);
if (element) {
element.scrollIntoView();
}
}, 400)
}
} }
// if(response.data.status === 401){ // if(response.data.status === 401){
// console.log("401401401") // console.log("401401401")

@ -189,7 +189,7 @@ class MemoDetail extends Component {
let filesize = item.filesize let filesize = item.filesize
attachments.push( attachments.push(
<div className="color-grey df" key={index}> <div className="color-grey df" key={index} style={{ lineHeight: '17px'}}>
<a className="color-grey "> <a className="color-grey ">
<i className="font-14 color-green iconfont icon-fujian mr8" aria-hidden="true"></i> <i className="font-14 color-green iconfont icon-fujian mr8" aria-hidden="true"></i>
</a> </a>

@ -116,7 +116,7 @@ class ShixunsHome extends Component {
} }
return ( return (
<div className="newMain clearfix backFAFAFA"> <div className="newMain clearfix backFAFAFA shixunsHome">
{this.state.updata===undefined?"":<UpgradeModals {this.state.updata===undefined?"":<UpgradeModals
{...this.state} {...this.state}
/>} />}
@ -128,6 +128,9 @@ class ShixunsHome extends Component {
<style> <style>
{ {
` `
.shixunsHome .educontent {
width: 1223px;
}
.banners{ .banners{
overflow: hidden; overflow: hidden;
} }

@ -372,7 +372,7 @@ class PathDetailIndex extends Component{
<span className="font-16">课程须知</span> <span className="font-16">课程须知</span>
{detailInfoList===undefined?"":detailInfoList.allow_statistics===true? {detailInfoList===undefined?"":detailInfoList.allow_statistics===true?
<Tooltip placement="bottom" title={"编辑"}> <Tooltip placement="bottom" title={"编辑"}>
<Link to={"/paths/"+this.props.match.params.pathId+"/edit"} className="fr mtf5"> <Link to={"/paths/"+this.props.match.params.pathId+"/edit#learning_notes"} className="fr mtf5">
<i className="iconfont icon-bianjidaibeijing font-20 color-green"></i> <i className="iconfont icon-bianjidaibeijing font-20 color-green"></i>
</Link> </Link>
</Tooltip> </Tooltip>

@ -213,13 +213,15 @@ class PathNew extends Component{
} }
render(){ render(){
let pathId = this.props.match.params.pathId;
let {pathName,description,point,flag_name}=this.state; let {pathName,description,point,flag_name}=this.state;
return( return(
<div className="newContainer"> <div className="newContainer">
<div className="newMain clearfix"> <div className="newMain clearfix">
<div className="educontent mt10 mb50"> <div className="educontent mt10 mb50">
<div className="mb10 edu-back-white"> <div className="mb10 edu-back-white">
<p className="padding20 bor-bottom-greyE font-18 color-grey-3">创建实践课程</p> <p className="padding20 bor-bottom-greyE font-18 color-grey-3">{pathId ? '编辑' : '创建'}实践课程</p>
<div className="padding30-20" id="part_Name"> <div className="padding30-20" id="part_Name">
<p className="color-grey-6 font-16 mb15">实践课程名称</p> <p className="color-grey-6 font-16 mb15">实践课程名称</p>
<div className="df"> <div className="df">
@ -251,7 +253,7 @@ class PathNew extends Component{
</div> </div>
<div className="mb10 edu-back-white padding30-20" id="part_point"> <div className="mb10 edu-back-white padding30-20" id="part_point">
<p className="color-grey-6 font-16 mb15">学习须知</p> <p className="color-grey-6 font-16 mb15" id="learning_notes">学习须知</p>
<div className="df"> <div className="df">
<span className="mr30 color-orange pt10">*</span> <span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20"> <div className="flex1 mr20">

@ -653,8 +653,8 @@ submittojoinclass=(value)=>{
{isRender===true?<LoginDialog {isRender===true?<LoginDialog
Modifyloginvalue={()=>this.Modifyloginvalue()} Modifyloginvalue={()=>this.Modifyloginvalue()}
{...this.state}
{...this.props} {...this.props}
{...this.state}
/>:""} />:""}
{AccountProfiletype===true?<AccountProfile {AccountProfiletype===true?<AccountProfile

@ -101,7 +101,7 @@ function md_elocalStorage(editor,mdu,id){
function create_editorMD(id, width, high, placeholder, imageUrl, callback, initValue, function create_editorMD(id, width, high, placeholder, imageUrl, callback, initValue,
onchange, watch, { noStorage, showNullButton }, that) { onchange, watch, { noStorage, showNullButton, emoji }, that) {
// 还是出现了setting只有一份被共用的问题 // 还是出现了setting只有一份被共用的问题
var editorName = window.editormd(id, { var editorName = window.editormd(id, {
@ -115,7 +115,7 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback, initV
syncScrolling: "single", syncScrolling: "single",
tex: true, tex: true,
tocm: true, tocm: true,
emoji: true, emoji: !!emoji ,
taskList: true, taskList: true,
codeFold: true, codeFold: true,
searchReplace: true, searchReplace: true,
@ -266,7 +266,8 @@ export default class TPMMDEditor extends Component {
window[__editorName.id+'_'] = __editorName; window[__editorName.id+'_'] = __editorName;
}, initValue, this.onEditorChange,this.props.watch, { }, initValue, this.onEditorChange,this.props.watch, {
noStorage: this.props.noStorage, noStorage: this.props.noStorage,
showNullButton: this.props.showNullButton showNullButton: this.props.showNullButton,
emoji: this.props.emoji
}, this); }, this);
} }

@ -194,7 +194,8 @@ export default class TPMquestion extends Component {
}) })
// this.contentMdRef.current.setValue(response.data.task_pass || '') // this.contentMdRef.current.setValue(response.data.task_pass || '')
if(response.data.chooses.length===0){ if(response.data.chooses.length===0){
this.questionadd() // 新建选择题时,没法切回 ‘本关任务’ tab
// this.questionadd()
} }
this.shixunsautoHeight() this.shixunsautoHeight()

Loading…
Cancel
Save