Merge branch 'dev_aliyun' into dev_tj

merge aliyun
chromesetting
tangjiang 5 years ago
commit 55c38b0744

@ -61,7 +61,10 @@ class HackUserLastestCodesController < ApplicationController
# 提交记录
def submit_records
@records = @my_hack.hack_user_codes.created_order
records = @my_hack.hack_user_codes
@records_count = records.count
@records = paginate records.created_order
end

@ -100,6 +100,7 @@ class HacksController < ApplicationController
@hack.update_attribute(:status, 1)
base_attrs = {
trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id,
parent_container_type: "HackPublish"
}
@hack.tidings.create!(base_attrs)
render_ok
@ -109,7 +110,8 @@ class HacksController < ApplicationController
def cancel_publish
@hack.update_attribute(:status, 0)
base_attrs = {
trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id
trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id,
parent_container_type: "HackUnPublish"
}
@hack.tidings.create!(base_attrs)
render_ok
@ -129,8 +131,19 @@ class HacksController < ApplicationController
def new;end
def destroy
@hack.destroy
render_ok
begin
base_attrs = {
user_id: @hack.user_id, viewed: 0, tiding_type: 'System', trigger_user_id: current_user.id,
parent_container_type: "HackDelete", extra: "#{@hack.name}"
}
@hack.tidings.create!(base_attrs)
@hack.destroy
render_ok
rescue => e
logger.error("####hack_delete_error: #{e.message}")
render_error("删除失败")
end
end
private

@ -80,4 +80,17 @@ class JupytersController < ApplicationController
render json: {status: 0}
end
def timeinfo_with_tpm
shixun = Shixun.find_by(identifier: params[:identifier])
info = jupyter_timeinfo_tpm(shixun)
render json: {status: 0}.merge(info)
end
def timeinfo_with_tpi
myshixun = Myshixun.find_by(identifier: params[:identifier])
info = jupyter_timeinfo_tpi(shixun)
render json: {status: 0}.merge(info)
end
end

@ -376,7 +376,7 @@ class MyshixunsController < ApplicationController
# todo: identifier 是以前的密码,用来验证的,新版如果不需要,和中间层协调更改.
params = {tpiID: "#{@myshixun.try(:id)}", tpiGitURL: "#{git_myshixun_url}", tpmGitURL: "#{git_shixun_url}",
identifier: "xinhu1ji2qu3"}
uri = "#{shixun_tomcat}/bridge/game/resetTpmRepository"
uri = "#{shixun_tomcat}/bridge/game/resetJupyterTpm"
res = uri_post uri, params
if (res && res['code'] != 0)
tip_exception("实训云平台繁忙繁忙等级95")

@ -216,7 +216,7 @@ class ShixunsController < ApplicationController
ShixunInfo.create!(shixun_id: @new_shixun.id,
description: @shixun.description,
evaluate_script: @shixun.evaluate_script,
shixun_reason: params[:reason].to_s.strip)
fork_reason: params[:reason].to_s.strip)
end
# 同步私密版本库
@ -266,8 +266,20 @@ class ShixunsController < ApplicationController
# 如果是jupyter先创建一个目录,为了挂载(因为后续数据集开启Pod后环境在没销毁前你上传数据集是挂载不上目录的因此要先创建目录方便中间层挂载)
if @new_shixun.is_jupyter?
folder = EduSetting.get('shixun_folder')
raise "存储目录未定义" unless folder.present?
path = "#{folder}/#{@new_shixun.identifier}"
FileUtils.mkdir_p(path, :mode => 0777) unless File.directory?(path)
# 复制数据集
save_path = File.join(folder, @shixun.identifier)
@shixun.data_sets.each do |set|
new_date_set = Attachment.new
new_date_set.attributes = set.attributes.dup.except("id", "container_id", "disk_directory")
new_date_set.container_id = @new_shixun.id
new_date_set.disk_directory = @new_shixun.identifier
new_date_set.save!
FileUtils.cp("#{save_path}/#{set.relative_path_filename}", path)
end
end
# 同步复制关卡
if @shixun.challenges.present?
@ -351,7 +363,7 @@ class ShixunsController < ApplicationController
page = params[:page] || 1
limit = params[:limit] || 10
@member_count = @shixun.shixun_members.count
@members = @shixun.shixun_members.includes(:user).page(page).per(limit)
@members = @shixun.shixun_members.order("role = 1 desc, created_at asc").includes(:user).page(page).per(limit)
end
def fork_list

@ -220,11 +220,13 @@ module TidingDecorator
when 'Journal' then
message = parent_container&.notes.present? ? '' + message_content_helper(parent_container.notes) : ''
I18n.t(locale_format(parent_container_type)) % message
when 'Hack' then
I18n.t(locale_format(parent_container_type)) % parent_container.name
end
end
def discuss_content
I18n.t(locale_format(container.parent_id.present?)) % message_content_helper(container.content)
I18n.t(locale_format(container_type, container.parent_id.present?)) % message_content_helper(container.content)
end
def grade_content
@ -250,6 +252,9 @@ module TidingDecorator
when 'shixunPublish' then
name = Shixun.find_by(id: parent_container_id)&.name || '---'
I18n.t(locale_format(parent_container_type)) % [name, container.score]
when 'Hack' then
name = Hack.find_by(id: container_id)&.name || '---'
I18n.t(locale_format(parent_container_type)) % [name, container.score]
else
I18n.t(locale_format(parent_container_type)) % container.score
end
@ -405,4 +410,8 @@ module TidingDecorator
def subject_start_course_content
I18n.t(locale_format) % belong_container&.name
end
def hack_content
I18n.t(locale_format(parent_container_type)) % (container&.name || extra)
end
end

@ -59,7 +59,7 @@ class Discuss < ApplicationRecord
elsif dis_type == 'Hack'
user_id = has_parent? ? parent.user_id : Hack.find(dis_id).user_id
parent_container_type = 'Hack'
challenge_id = nil
challenge_id = dis_id
end
base_attrs = {
trigger_user_id: user_id, parent_container_id: challenge_id, parent_container_type: parent_container_type,

@ -14,7 +14,7 @@ class Hack < ApplicationRecord
# 点赞
has_many :praise_treads, as: :praise_tread_object, dependent: :destroy
# 消息
has_many :tidings, as: :container, dependent: :destroy
has_many :tidings, as: :container
belongs_to :user
@ -23,8 +23,6 @@ class Hack < ApplicationRecord
scope :opening, -> {where(open_or_not: 1)}
scope :mine, -> (author_id){ where(user_id: author_id) }
after_destroy :send_delete_tiding
def language
if hack_codes.count == 1
hack_codes.first.language
@ -53,12 +51,4 @@ class Hack < ApplicationRecord
user_id == user.id || user.admin_or_business?
end
private
def send_delete_tiding
base_attrs = {
user_id: user_id, viewed: 0, tiding_type: 'Delete', trigger_user_id: current_user.id, content: "你删除了题目:#{name}"
}
tidings.create!(base_attrs)
end
end

@ -1,6 +1,7 @@
class ShixunInfo < ApplicationRecord
belongs_to :shixun
validates_uniqueness_of :shixun_id
validates_length_of :fork_reason, maximum: 60
after_commit :create_diff_record
private

@ -213,4 +213,27 @@ module JupyterService
_jupyter_active(tpiID)
end
def _jupyter_timeinfo(tpiID)
shixun_tomcat = edu_setting('cloud_bridge')
uri = "#{shixun_tomcat}/bridge/jupyter/getTimeInfo"
params = {:tpiID => tpiID}
res = uri_post uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级130")
end
res['data']
end
# 获取时间参数
def jupyter_timeinfo_tpm(shixun)
tpiID = "tpm#{shixun.id}"
_jupyter_timeinfo(tpiID)
end
# 获取时间参数
def jupyter_timeinfo_tpi(myshixun)
tpiID = myshixun.id
_jupyter_timeinfo(tpiID)
end
end

@ -79,7 +79,7 @@ class Subjects::CopySubjectService < ApplicationService
copy_shixun_service_configs_data!(shixun, to_shixun)
copy_challenges_data!(shixun, to_shixun)
copy_shixun_members_data!(to_shixun)
copy_jupyter_data_sets(shixun, to_shixun) if shixun.is_jupyter?
# 云上实验室
if laboratory
laboratory.laboratory_shixuns.create(shixun: to_shixun)
@ -87,6 +87,25 @@ class Subjects::CopySubjectService < ApplicationService
to_shixun
end
# 复制jupyter的数据集
def copy_jupyter_data_sets(shixun, to_shixun)
return unless shixun.is_jupyter?
folder = EduSetting.get('shixun_folder')
raise "存储目录未定义" unless folder.present?
path = "#{folder}/#{to_shixun.identifier}"
FileUtils.mkdir_p(path, :mode => 0777) unless File.directory?(path)
# 复制数据集
save_path = File.join(folder, shixun.identifier)
shixun.data_sets.each do |set|
new_date_set = Attachment.new
new_date_set.attributes = set.attributes.dup.except("id", "container_id", "disk_directory")
new_date_set.container_id = to_shixun.id
new_date_set.disk_directory = to_shixun.identifier
new_date_set.save!
FileUtils.cp("#{save_path}/#{set.relative_path_filename}", path)
end
end
# 创建实训长字段内容
def copy_shixun_info_data!(shixun, to_shixun)
to_shixun_info = ShixunInfo.new

@ -12,4 +12,5 @@ if discuss.parent_id
else
json.praise_count discuss.praises_count
json.user_praise discuss.praise_treads.select{|pt| pt.user_id == current_user.id}.length > 0
json.can_delete discuss.can_deleted?(current_user) && child.count == 0
end

@ -1,6 +1,6 @@
json.disscuss_count @discusses_count
json.comments @discusses do |discuss|
json.partial! 'comments/discuss', locals: { discuss: discuss}
json.partial! 'comments/discuss', locals: { discuss: discuss, child: discuss.child_discuss(current_user)}
json.children discuss.child_discuss(current_user) do |c_d|
json.partial! 'comments/discuss', locals: { discuss: c_d }
end

@ -1,5 +1,5 @@
json.status 0
json.message "评测成"
json.message "评测成"
json.data do
json.(@result, :id, :status, :error_line, :error_msg,
:input, :output, :execute_time, :execute_memory)

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

@ -10,4 +10,5 @@ json.data_sets do
json.file_path "#{@absolute_folder}/#{set.relative_path_filename}".gsub("/#{@shixun.identifier}", "")
end
end
json.data_sets_count @data_count
json.data_sets_count @data_count
json.folder_name @absolute_folder

@ -93,6 +93,7 @@
Challenge:
"1_end": "赞了你发布的实训任务:%s第%s关"
"2_end": "踩了你发布的实训任务:%s第%s关"
Hack_end: "赞了你发布的题目:%s"
Memo:
true_end: "赞了你的评论:%s"
false_end: "赞了发布的帖子:%s"
@ -107,8 +108,16 @@
Issue_end: "赞了你发布的项目Issue%s"
Journal_end: "赞了你的回复%s"
Discuss:
true_end: "评论了你的回复:%s"
false_end: "评论了你发布的实训:%s"
Shixun:
true_end: "评论了你的回复:%s"
false_end: "评论了你发布的实训:%s"
Hack:
true_end: "评论了你的回复:%s"
false_end: "评论了你发布的题目:%s"
Hack:
HackPublish_end: "你发布了题目:%s"
HackUnPublish_end: "你撤销发布了题目:%s"
HackDelete_end: "你删除了题目:%s"
Grade:
Avatar_end: "首次上传头像获得金币奖励:%s金币"
Phone_end: "首次绑定手机号码获得金币奖励:%s金币"
@ -118,6 +127,7 @@
Answer:
true_end: "查看实训%s第%s关的参考答案消耗金币%s金币"
false_end: "查看实训的参考答案消耗金币:%s金币"
Hack_end: "完成题目解答:%s获得金币奖励%s金币"
Game_end: "通过实训%s的第%s关获得金币奖励%s金币"
Memo_end: "发布的评论或者帖子获得平台奖励:%s金币"
Discusses_end: "发布的评论获得金币奖励:%s金币"

@ -35,6 +35,8 @@ Rails.application.routes.draw do
get :reset_with_tpm
get :active_with_tpm
get :active_with_tpi
get :timeinfo_with_tpm
get :timeinfo_with_tpi
post :import_with_tpm
end

@ -0,0 +1,5 @@
class ModifyOpenOrNotForHacks < ActiveRecord::Migration[5.2]
def change
change_column :hacks, :open_or_not, :boolean, :default => false
end
end

@ -30,7 +30,7 @@ const env = getClientEnvironment(publicUrl);
module.exports = {
// You may want 'eval' instead if you prefer to see the compiled output in DevTools.
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
// devtool: "cheap-module-eval-source-map",
devtool: "cheap-module-eval-source-map",
// 开启调试
//devtool: "source-map", // 开启调试
// These are the "entry points" to our application.

@ -1883,9 +1883,8 @@ a:hover.task_icons_close{background: url(../images/popup/sy_icons_close.png) -40
.newupload_nav li:last-child{ border-right: none;}
.newupload_nav li a{font-size:12px; color:#444;}
.newupload_nav_hover{ background: #3498db; }
.newupload_nav_nomal { }
.newupload_nav_hover a{color: #fff !important; }
.markdown-body { text-align: justify;word-break: break-all;}
.bor-reds{
border:1px solid #FF0000!important;
border-radius: 4px;
@ -1894,6 +1893,7 @@ a:hover.task_icons_close{background: url(../images/popup/sy_icons_close.png) -40
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
}
@charset "UTF-8";
/*!

@ -2934,7 +2934,7 @@ a.singlepublishtwo{
padding: 40px !important;
}
.editormd-html-preview{
width: 94% !important;
width: 100% !important;
color: #323232 !important;
}
#homework_editorMd_description hr{
@ -3478,3 +3478,9 @@ a.singlepublishtwo{
/*width: auto !important;*/
/*max-width: 600px !important;*/
/*}*/
.markdown-body {
text-align: justify;
word-break: break-all;
}

@ -25,23 +25,22 @@ class NewShixunModel extends Component{
}
componentDidMount() {
let{page,type,keyword,order,diff,limit,status,sort}=this.state;
let newsort=sort
if(this.props&&this.props.user.course_name===undefined){
newsort="created_at";
}else{
newsort="publish_time";
}
if(this.props.type==='shixuns'){
this.getdatalist(page,type,status,keyword,order,diff,limit,undefined,newsort);
this.getdatalist(page,type,status,keyword,order,diff,limit,undefined,sort);
}else{
this.getdatalist(page,type,undefined,keyword,order,undefined,limit,undefined,sort);
}
}
getdatalist=(page,type,newstatus,keyword,order,diff,limit,pagetype,sort)=>{
getdatalist=(page,type,newstatus,keyword,order,diff,limit,pagetype,sorts)=>{
let newsort=sorts;
if(this.props.type==="shixuns"&&type==="mine"){
if(this.props&&this.props.user.course_name===undefined){
newsort="created_at";
}else{
newsort="publish_time";
}
}
this.setState({
isspinning:true
})
@ -53,14 +52,14 @@ class NewShixunModel extends Component{
url="/subject_lists.json";
}
axios.get(url,{params:{
page,
type,
status,
keyword,
order,
diff,
limit,
sort
page:page,
type:type,
status:status,
keyword:keyword,
order:order,
diff:diff,
limit:limit,
sort:newsort
}}).then((response) => {
if(response.data){
if(pagetype===undefined){

@ -1,5 +1,5 @@
.editormd-html-preview, .editormd-preview-container {
width: 95% !important;
width: 100% !important;
}
.Finish_button{
height: 30px;

@ -1667,7 +1667,7 @@ class Listofworksstudentone extends Component {
],
yslpros: false,
datajs: [],
homework_status: [],
homework_status: undefined,
}
}
@ -3597,7 +3597,14 @@ class Listofworksstudentone extends Component {
starttimesend={this.state.starttimesend}
typs={this.state.typs}
/> : ""}
{
{homework_status===undefined?
<div className={"educontent "}>
<div className="edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center" style={{ width:"100%",height:"200px" }}>
<Spin style={{ width:"100%","line-height":"200px" }}></Spin>
</div>
</div>
</div>:
homework_status && homework_status.length === 0 ?
<div className="edu-back-white">
<NoneData></NoneData>
@ -3609,11 +3616,7 @@ class Listofworksstudentone extends Component {
</div>
:
<div className={"educontent "}>
<div className="edu-back-white">
<style>
{`
.startbox{

@ -502,6 +502,7 @@ class DetailCardsEditAndAdd extends Component{
<a className={ "paragraph_name paragraph_nameid"}
href={/shixuns/+item.shixun_identifier}
target="_blank"
>
<span className="subject_stage_shixun_index">

@ -504,6 +504,7 @@ class DetailCardsEditAndEdit extends Component{
<a className={ "paragraph_name paragraph_nameid"}
href={/shixuns/+item.shixun_identifier}
target="_blank"
>
<span className="subject_stage_shixun_index">

@ -555,6 +555,9 @@ class PathDetailIndex extends Component{
.pathDetailIndex .markdown-body > p {
line-height: 28px;
}
// #shixuns_propaedeutics{
// width: 100% !important;
// }
`
}
</style>

@ -59,7 +59,8 @@ class TPMBanner extends Component {
openknow:false,
openshowpublictype:false,
Radiovalue:1,
TextAreaintshow:false
TextAreaintshow:false,
}
}
@ -112,6 +113,15 @@ class TPMBanner extends Component {
componentDidUpdate(prevProps, prevState) {
if (prevProps != this.props) {
if(prevProps.user != this.props.user){
if(this.props.user&&this.props.user.admin===true||this.props.user&&this.props.user.business===true){
this.setState({
TextArea:"云上实验室使用"
})
}
}
let shixunopenprocess=window.localStorage.shixunopenprocess;
let openopenpublictype=window.localStorage.openopenpublictype;
if(this.props.status===0&&this.props.openknows===false){
@ -173,8 +183,12 @@ class TPMBanner extends Component {
})
}
if (this.props.user && this.props.user.admin === true || this.props.user && this.props.user.business === true) {
this.setState({
TextArea: "云上实验室使用"
})
}
}
/*
* Fork
* */
@ -736,6 +750,11 @@ class TPMBanner extends Component {
this.setState({
Radiovalue:e.target.value
})
if(e.target.value!=4){
this.setState({
TextAreaintshow:false
})
}
}
render() {
@ -827,7 +846,7 @@ class TPMBanner extends Component {
};
//
// console.log(this.props.shixunsDetails&&this.props.shixunsDetails.is_jupyter)
// console.log(this.props)
// console.log(this.state)
return (
@ -838,7 +857,7 @@ class TPMBanner extends Component {
`
.shixunDetail_top{
height: 180px !important;
padding-top:35px !important;
padding-top:50px !important;
}
.ant-popover{
z-index:1000 !important;
@ -881,9 +900,9 @@ class TPMBanner extends Component {
}
</p>
<div className="clearfix mt30">
<div className="clearfix mt10">
<ul className="fl color-grey-c pathInfo">
<ul className="fl color-grey-c pathInfo mt20">
{shixunsDetails&&shixunsDetails.stu_num===0?"":<li>
<span>学习人数</span>
<span className="mt3">{shixunsDetails.stu_num}</span>
@ -954,7 +973,7 @@ class TPMBanner extends Component {
</div>
</div>
}>
<div className="pr fl" id="commentsStar">
<div className="pr fl mt15" id="commentsStar">
<div className={"color-grey-c ml15"} style={{color: "#fff", textAlign: "center"}}>学员评分</div>
<div className="rateYo">
<MyRate allowHalf defaultValue={star_info[0]} disabled/>
@ -1288,7 +1307,7 @@ class TPMBanner extends Component {
}
</style>:""
}
<Modal
{Forkvisible===true?<Modal
keyboard={false}
title="Fork原因"
visible={Forkvisible}
@ -1318,7 +1337,12 @@ class TPMBanner extends Component {
其它原因
</Radio>
{this.state.Radiovalue === 4 ?
<TextArea className={this.state.TextAreaintshow===true?"bor-red mt10":"mt10"} rows={4} style={{ width: '85%', marginLeft: '30px' }} onInput={this.changeTextArea}/>: null}
<TextArea className={this.state.TextAreaintshow===true?"bor-red mt10":"mt10"}
placeholder="请填写fork原因60字以内"
value={this.state.TextArea}
rows={4} style={{ width: '85%', marginLeft: '30px' }} onInput={this.changeTextArea}
maxlength={60}
/>: null}
{this.state.TextAreaintshow===true?<div className={"color-red ml30"}>不能为空</div>:""}
</Radio.Group>
</div>
@ -1330,7 +1354,7 @@ class TPMBanner extends Component {
}
</Modal>
</Modal>:""}
<Modal
keyboard={false}

@ -423,22 +423,24 @@ class TPMIndex extends Component {
{ this.state.is_jupyter===false? <Menu.Item key="8" className={"competitionmr50"}>
<span className={"tpmbannernavstyler"}>排行榜</span>
</Menu.Item>:""}
{this.state.identity >4||this.state.identity===undefined ? "":
<Menu.Item key="9" className={"competitionmr50"}>
<Popover
<span>
<Popover
content={
<pre className={"bannerpd201"}>
<div>更多设置在这里点击配置看一看~</div>
<div className={"wechatcenter mt15"}><Button type="primary" onClick={this.openknow} >我知道了</Button></div>
</pre>
<div>更多设置在这里点击配置看一看~</div>
<div className={"wechatcenter mt15"}><Button type="primary" onClick={this.openknow} >我知道了</Button></div>
</pre>
}
trigger="click"
placement="top"
visible={this.state.openknows}
>
</Popover>
</span>
{this.state.identity >4||this.state.identity===undefined ? "":
<Menu.Item key="9" className={"competitionmr50"}>
<span className={"tpmbannernavstyler"}>配置</span>
</Popover>
</Menu.Item>
}

@ -35,14 +35,14 @@ if (!window['indexHOCLoaded']) {
// $('head').append($('<link rel="stylesheet" type="text/css" />')
// .attr('href', `${_url_origin}/stylesheets/educoder/antd.min.css?1525440977`));
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?6`));
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?8`));
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?6`));
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?8`));
// index.html有加载
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?6`));
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?8`));
// $('head').append($('<link rel="stylesheet" type="text/css" />')

@ -65,7 +65,8 @@ export default class Shixuninformation extends Component {
oldscope_partment: [],
scope_partment: [],
loading: false,
opening_timetype:false
opening_timetype:false,
use_scope_type:false
}
}
@ -80,6 +81,7 @@ export default class Shixuninformation extends Component {
timetype=true;
}
this.setState({
use_scope_type:this.props&&this.props.status>1&&this.state.use_scope===0&&this.props&&this.props.identity>2||this.props&&this.props.public===2&&this.state.use_scope===0&&this.props&&this.props.identity>2?true:false,
can_copy: this.props.data && this.props.data.shixun.can_copy === undefined ? false : this.props.data && 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,
@ -115,6 +117,7 @@ export default class Shixuninformation extends Component {
timetype=true;
}
this.setState({
use_scope_type:this.props&&this.props.status>1&&this.state.use_scope===0&&this.props&&this.props.identity>2||this.props&&this.props.public===2&&this.state.use_scope===0&&this.props&&this.props.identity>2?true:false,
can_copy: this.props.data && this.props.data.shixun.can_copy === undefined ? false : this.props.data && 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,
@ -194,7 +197,7 @@ export default class Shixuninformation extends Component {
SelectOpenpublic = (e) => {
this.setState({
use_scope: e.target.value
use_scope: e.target.value,
});
}
@ -295,6 +298,8 @@ export default class Shixuninformation extends Component {
const dateFormat = 'YYYY-MM-DD HH:mm';
// console.log()
console.log(this.props&&this.props.identity<8)
return (
<div>
<div className="educontent mb200 edu-back-white padding10-20 pdb30 mb50">
@ -308,8 +313,8 @@ export default class Shixuninformation extends Component {
</span>
</div>}
<div className="edu-back-white mb10 ml30 mt20">
<div>
<div className="edu-back-white mb10 ml30 mt20">
{this.props&&this.props.status>1&&this.state.use_scope===0&&this.props&&this.props.identity>2&&this.state.use_scope_type===true||this.props&&this.props.public===2&&this.state.use_scope===0&&this.props&&this.props.identity>2&&this.state.use_scope_type===true?"":<div>
<span className="color-grey-6 mt5 fl font-16" style={{minWidth: '45px'}}>公开程度:</span>
<span className="fl mt8 ml20">
<RadioGroup onChange={this.SelectOpenpublic} value={this.state.use_scope}>
@ -387,7 +392,7 @@ export default class Shixuninformation extends Component {
</span>
</div>
</div>}
<div className="clearfix mt20">
<span className="color-grey-6 mt5 fl font-16" style={{minWidth: '45px'}}>开启时间:</span>

@ -953,10 +953,10 @@ class Shixuninformation extends Component {
<div>
{this.state.mainvalues === undefined && this.state.subvalues === undefined || this.state.mainvalues === "" && this.state.subvalues === "" ? "" :
<div className={"font-12"} style={{'max-width': '600px'}}>
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : `已安装软件:` + this.state.mainvalues}`}
{`${this.state.subvalues === undefined || this.state.subvalues === "" ? "" : this.state.mainvalues === undefined || this.state.mainvalues === "" ? `已安装软件:` + this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : `说明:添加了` + this.state.mainvalues}${this.state.subvalues === undefined || this.state.subvalues === "" ? "" :
this.state.mainvalues === undefined || this.state.mainvalues === "" ? `说明:添加了` + this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : this.state.mainvalues}`}
{`${this.state.subvalues === undefined || this.state.subvalues === "" ? "" : this.state.mainvalues === undefined || this.state.mainvalues === "" ? this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : this.state.mainvalues}${this.state.subvalues === undefined || this.state.subvalues === "" ? "" :
this.state.mainvalues === undefined || this.state.mainvalues === "" ? this.state.subvalues : this.state.subvalues}`}
</div>}
</div>
</span>
@ -1185,7 +1185,11 @@ class Shixuninformation extends Component {
closable={false}
footer={null}
>
<div className="task-popup-content"><p className="task-popup-text-center font-16">评测脚本生成成功</p></div>
<div className="task-popup-content">
{/*<p className="task-popup-text-center font-16">已根据您的选择,生成新的评测脚本!</p>*/}
{/*<p className="task-popup-text-center font-16 mt10">您之前使用的脚本已复制到剪贴板可通过Ctrl+C贴贴</p>*/}
<p className="task-popup-text-center font-16">评测脚本生成成功</p>
</div>
<div className="task-popup-sure clearfix">
<a className="task-btn task-btn-orange" onClick={() => this.hidestandard_scriptsModal()}>确定</a>
</div>

@ -82,18 +82,18 @@ class TPMRightSection extends Component {
<div className="flex1">
<div className="creatorname sortinxdirection space-between">
<div className={"creatornamelist"}>
<div className={"creatornamelist color-grey-3"}>
{TPMRightSectionData === undefined ? "" : TPMRightSectionData.creator === undefined ? "" : TPMRightSectionData.creator.name}
</div>
<div className={"creatornamelist width80center"}>
{TPMRightSectionData.user_shixuns_count}
<span className={"color888hezuo"}>共发布实训</span> <span className={"color-grey-3"}>{TPMRightSectionData.user_shixuns_count}</span> <span className={"color888hezuo"}></span>
</div>
</div>
<div className="clearfix">
<span className={"fr color888hezuo"}>发布实训项目</span>
{/*<span className="ml20">粉丝 <span id="user_h_fan_count">{TPMRightSectionData.fans_count}</span></span>*/}
{/* <a href="/watchers/unwatch?className=fr+user_watch_btn+edu-default-btn+edu-focus-btn&amp;object_id=3039&amp;object_type=user&amp;shixun_id=61&amp;target_id=3039" className="fr edu-default-btn user_watch_btn edu-focus-btn" data-method="post" data-remote="true" id="cancel_watch" rel="nofollow">取消关注</a> */}
</div>
{/*<div className="clearfix">*/}
{/* <span className={"fr color888hezuo"}>发布实训项目</span>*/}
{/* /!*<span className="ml20">粉丝 <span id="user_h_fan_count">{TPMRightSectionData.fans_count}</span></span>*!/*/}
{/* /!* <a href="/watchers/unwatch?className=fr+user_watch_btn+edu-default-btn+edu-focus-btn&amp;object_id=3039&amp;object_type=user&amp;shixun_id=61&amp;target_id=3039" className="fr edu-default-btn user_watch_btn edu-focus-btn" data-method="post" data-remote="true" id="cancel_watch" rel="nofollow">取消关注</a> *!/*/}
{/*</div>*/}
</div>
</div>

@ -98,14 +98,15 @@
}
.creatornamelist {
-o-text-overflow: ellipsis;
cursor: default;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
width: 139px;
}
.width80center {
width: 80px;
font-size:12px;
text-align: center;
}

@ -19,13 +19,18 @@ import actions from '../../../redux/actions';
import RightPane from './rightPane';
import MyIcon from "../../../common/components/MyIcon";
function clearSlct() {
if("getSelection" in window){
window.getSelection().removeAllRanges();
}else{
document.selection.empty();
};
}
function jsCopy(s) {
var copyEle = document.getElementById(s);
const range = document.createRange(); // 创造range
window.getSelection().removeAllRanges(); //清除页面中已有的selection
range.selectNode(copyEle); // 选中需要复制的节点
window.getSelection().addRange(range); // 执行选中元素
const copyStatus = document.execCommand("Copy"); // 执行copy操作
clearSlct();
const copyEle = document.getElementById(s);
copyEle.select();
const copyStatus=document.execCommand("Copy");
// 对成功与否定进行提示
copyStatuss(copyStatus)
}
@ -66,7 +71,8 @@ function JupyterTPI (props) {
jupytertime,
active_with_tpi,
spinning,
updataspinning
updataspinning,
jupyter_folder_name
} = props;
const emptyCtx = (
@ -146,12 +152,12 @@ function JupyterTPI (props) {
title: '更新通知',
content: (<div className="update_notice">
{stopposttpip(1)}
<p className="update_txt">关卡任务的代码文件有更新啦</p>
<p className="update_txt">更新操作将保留已完成的评测记录和成绩</p>
<p className="update_txt">还未完成评测的任务代码请自行保存</p>
<p className="update_txt">该实训已更新更新后您编写的实训代码将会丢失</p>
<p className="update_txt">如有需要请先导出代码再进行更新</p>
{/*<p className="update_txt">还未完成评测的任务代码,请自行保存</p>*/}
</div>),
okText: '确定',
cancelText: '取消',
okText: '立即更新',
cancelText: '稍后再说',
onOk () {
syncJupyterCode(myshixun_identifier, '同步成功');
},onCancel() {
@ -274,8 +280,8 @@ function JupyterTPI (props) {
mouseLeaveDelay={0.3}
>
<div className="sortinxdirection">
<Icon type="file-text" className="jupyter_icon fl lineheighttaj" />
<a className="jupyter_name ml10 maxnamewidth150 lineheighttaj colorlineheighttaj" title={item.title}>{item.title}</a>
<Icon type="file-text" className="jupyter_icon fl lineheighttaj filestyles" />
<a className="jupyter_name ml10 maxnamewidth181 lineheighttaj colorlineheighttaj" title={item.title}>{item.title}</a>
<a className={"fr color-blue lineheighttaj"}
onClick={() => {
jsCopy("file_path"+i)
@ -382,11 +388,22 @@ function JupyterTPI (props) {
>
{/*<p className={"RightPaneDrawertop"}></p>*/}
<div className="jupyter_data_sets_area newjupyter_data_sets_area">
<h2 className="jupyter_h2_title">
<h2 className="jupyter_h2_title bortop17212F">
{/*<MyIcon type="iconwenti" className="jupyter_data_icon"/>*/}
<i className={"iconfont icon-base"}></i>
{/* <span className="iconfont icon-java jupyter_data_icon"></span>数据集 */}
</h2>
<h2 className="borbottom17212F jupyterfilepaths">
<span className={"ml50"}>文件路径</span>
<div className="sortinxdirection">
<a className="jupyter_name ml50 maxnamewidth200 lineheighttaj colorlineheighttaj">{jupyter_folder_name}</a>
<a className={"fr color-blue lineheighttaj font-14"}
onClick={() => {
jsCopy("jupyter_folder_name")
}}>复制地址</a>
</div>
<input id="jupyter_folder_name" className={"file_path_input"} value={jupyter_folder_name}/>
</h2>
{ renderCtx }
<div className='jupyter_pagination'>
{total<20?"":<Pagination
@ -413,6 +430,7 @@ const mapStateToProps = (state) => {
jupyter_data_set,
jupyter_tpi_url_state,
jupyter_data_set_count,
jupyter_folder_name,
jupyter_pagination,
jupyter_identifier
} = state.jupyterReducer;
@ -425,6 +443,7 @@ const mapStateToProps = (state) => {
jupyter_tpi_url_state,
total: jupyter_data_set_count,
pagination: jupyter_pagination,
jupyter_folder_name:jupyter_folder_name,
jupyter_identifier,
drawervisible,
jupytertime,

@ -23,7 +23,11 @@
cursor: row-resize;
width: 100%;
}
.filestyles{
color: #28b887 !important;
font-size: 25px !important;
margin-left:20px;
}
.Resizer.horizontal:hover {
border-top: 5px solid rgba(0, 0, 0, 0.5);
border-bottom: 5px solid rgba(0, 0, 0, 0.5);
@ -138,9 +142,9 @@
height:49px;
line-height: 49px;
background: #070F1A !important;
border-bottom: 1px solid #17212F !important;
//border-bottom: 1px solid #17212F !important;
color:#FFFFFF !important;
border-top: 1px solid #17212F !important;
//border-top: 1px solid #17212F !important;
}
.iconfont{
color:#28b887!important;
@ -193,4 +197,38 @@ line-height: 50px !important;
.jupyter_data_list{
padding-left: 20px;
}
.bortop17212F{
border-top: 1px solid #17212F !important;
}
.borbottom17212F{
border-bottom: 1px solid #17212F !important;
}
.jupyterfilepaths{
color: #888 !important;
font-size: 16px !important;
padding-left: 20px;
background: #070F1A !important;
}
.maxnamewidth200{
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
width: 200px;
}
.maxnamewidth181{
max-width:181px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
width: 181px;
}

@ -620,10 +620,10 @@ class Newshixuns extends Component {
<div>
{this.state.mainvalues === undefined && this.state.subvalues === undefined || this.state.mainvalues === "" && this.state.subvalues === "" ? "" :
<div className={"font-12"} style={{'max-width': '600px'}}>
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : `已安装软件:` + this.state.mainvalues}`}
{`${this.state.subvalues === undefined || this.state.subvalues === "" ? "" : this.state.mainvalues === undefined || this.state.mainvalues === "" ? `已安装软件:` + this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : `说明:添加了` + this.state.mainvalues}${this.state.subvalues === undefined || this.state.subvalues === "" ? "" :
this.state.mainvalues === undefined || this.state.mainvalues === "" ? `说明:添加了` + this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : this.state.mainvalues}`}
{`${this.state.subvalues === undefined || this.state.subvalues === "" ? "" : this.state.mainvalues === undefined || this.state.mainvalues === "" ? this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : this.state.mainvalues}${this.state.subvalues === undefined || this.state.subvalues === "" ? "" :
this.state.mainvalues === undefined || this.state.mainvalues === "" ? this.state.subvalues : this.state.subvalues}`}
</div>}
</div>

@ -1,14 +1,13 @@
import React, { Component } from 'react';
import { Link } from "react-router-dom";
import { markdownToHTML, configShareForCustom,getImageUrl,getUploadActionUrlthree,appendFileSizeToUploadFileAll} from 'educoder'
import { Divider, Tooltip,Upload,Spin} from 'antd';
import { Divider, Tooltip,Upload,Modal,Spin} from 'antd';
import LoadingSpin from '../../../../common/LoadingSpin';
import 'antd/lib/pagination/style/index.css';
import '../shixunchildCss/Challenges.css';
import axios from 'axios';
const $ = window.$;
class Challengesjupyter extends Component {
constructor(props) {
super(props)
@ -316,6 +315,50 @@ class Challengesjupyter extends Component {
}
}
handleClickResetTpisync_code=(id)=>{
this.setState({
jupyter_url : null,
booljupyterurls:false,
})
const url = `/jupyters/reset_with_tpm.json`;
axios.get(url,{params:{
identifier:id
}}).then((response) => {
if(response.data.status===0){
setTimeout(()=>{
this.setState({
jupyter_url :response.data.url,
booljupyterurls:true,
})
},1000);
this.props.showNotification('重置实训成功!');
}
});
}
// 重置实训
handleClickResetTpi = () => {
let id=this.props.match.params.shixunId;
let that=this;
Modal.confirm({
title: '重置实训',
content: (
<p style={{ lineHeight: '24px' }}>
你在本文件中修改的内容将丢失,<br />
是否确定重新加载初始代码
</p>
),
okText: '确定',
cancelText: '取消',
onOk () {
that.handleClickResetTpisync_code(id)
},
onCancel() {
},
})
}
render() {
let{ChallengesDataList,booljupyterurls,enlarge,fileList}=this.state;
let id = this.props.match.params.shixunId;
@ -514,11 +557,12 @@ class Challengesjupyter extends Component {
}
</style>
<Upload {...uploadProps}>
<div className="challenbaocun" type="upload">
<p
className="challenbaocuntest" type="upload" >导入</p>
</div>
<div className="challenbaocun" type="upload">
<p className="challenbaocuntest" type="upload" >导入</p>
</div>
</Upload>
{/*<button type="button" className="ant-btn deletebuttom chongzhistyles" onClick={this.handleClickResetTpi}><span>重置实训</span></button>*/}
</div>
</div>

@ -122,7 +122,7 @@
}
.fabushixunwidth{
color: #000000;
font-size: 16px;
font-size: 12px;
}
.fabushixunwidthcolor{
color: #4CACFF;
@ -143,11 +143,11 @@
height:34px;
line-height: 34px;
}
.hezuozhe630{
width: 630px;
.hezuozhe655{
width: 655px;
}
.hezuozhe634{
width: 634px;
.hezuozhe655{
width: 655px;
}
.color333hezuo{
color:#333333;
@ -193,4 +193,8 @@
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
}
.centertop20{
text-align: center;
padding-top: 20%;
}

@ -118,6 +118,7 @@ class Collaborators extends Component {
if (type === "cooperation") {
this.setState({
Collaboratorsvisibleadmin: true,
Collaboratorsvisible: false,
});
} else if ("admin") {
let id = this.props.match.params.shixunId;
@ -132,6 +133,7 @@ class Collaborators extends Component {
} else {
this.setState({
Collaboratorsvisible: true,
Collaboratorsvisibleadmin: false,
Collaboratorslist: response.data
})
}
@ -517,17 +519,16 @@ class Collaborators extends Component {
closable={false}
footer={null}
>
<div className="mb15 font-14 edu-txt-center color-orange-tip">
选择的成员将会成为新的管理员<br/> 您将不再拥有管理员的权限但您仍是合作团队的一员
</div>
<div className="clearfix mb15 edu-bg-light-blue edu-max-h200">
<ul className="">
<li className="clearfix">
<li className={Collaboratorslist&&Collaboratorslist.length===0?"centertop20 clearfix":"clearfix"}>
{Collaboratorslist&&Collaboratorslist.length===0?<span>
请先将新的管理员通过 <a className={"color-blue"} onClick={() => this.showCollaboratorsvisible("cooperation")}>"添加合作者"</a>
</span>:""}
<RadioGroup onChange={this.onChange} value={this.state.value}>
{
Collaboratorslist.length === 0 ? "" : Collaboratorslist.map((item, key) => {
return (
@ -536,7 +537,6 @@ class Collaborators extends Component {
)
})
}
</RadioGroup>
</li>
</ul>
@ -642,7 +642,7 @@ class Collaborators extends Component {
<style>
{
`
.collaborators-item-middles{width: 100% !important; margin-left: 20px;}
.collaborators-item-middles{width: 100% !important;}
.ysltithead{
padding-bottom: 20px;
}
@ -665,7 +665,7 @@ class Collaborators extends Component {
<div className="fl collaborators-item-middles">
<p className="mb10 sortinxdirection space-between hezuozhe634">
<p className="mb10 sortinxdirection space-between hezuozhe655">
<a href={item.user.user_url} target="_blank" className="yslusername">{item.user.name}</a>
{item.user.shixun_manager === true ? "" : <span>
<i className={this.state.hovertype===true&&key===this.state.hoverkey?"fontnewreds iconfont icon-shanchu_Hover":"fontneweees iconfont icon-shanchu_moren"}
@ -681,10 +681,10 @@ class Collaborators extends Component {
</p>
<p className="color-grey-B2 font-12 mb10 sortinxdirection mt14">
<p className="hezuozhe630 sortinxdirection space-between">
<p className="hezuozhe655 sortinxdirection space-between">
{/*<p className={item.user.identity===null||item.user.identity===undefined||item.user.identity===""?" font-16 ":"mr20 font-16 w70"}>{item.user.identity}</p>*/}
<p
className={item.user.school_name === null || item.user.school_name === "" ? "" : " font-16 color888hezuo maxfont450"}>{item.user.school_name}</p>
className={item.user.school_name === null || item.user.school_name === "" ? "" : " font-12 color888hezuo maxfont450"}>{item.user.school_name}</p>
<p className="fabushixunwidth color888hezuo">发布实训项目&nbsp;&nbsp;<span
className="ml2">{item.user.user_shixuns_count}</span></p>
</p>

@ -129,7 +129,7 @@ class Ranking_list extends Component {
{/*<li className="fl with13 edu-txt-center color-grey-74">*/}
{/*/!*{item.accuracy} %准确率*!/*/}
{/*</li>*/}
<li className="fl with25 edu-txt-center">{this.formatSeconds(item.use_time)}</li>
<li className="fl with25 edu-txt-center">{item.use_time===null?"":this.formatSeconds(item.use_time)}</li>
<li className="fl with14 edu-txt-center color-yellow">+{item.gold}金币 </li>
</div>
)

@ -1,5 +1,5 @@
.editormd-html-preview, .editormd-preview-container {
width: 95% !important;
width: 100% !important;
}
.Finish_button{
height: 30px;
@ -217,3 +217,21 @@
.jupyterswidth{
width: 1140px;
}
.chongzhistyles{
color: #fff;
width: 85px !important;
height: 32px !important;
margin-right: 20px;
}
.chongzhistyles:hover, .chongzhistyles:focus{
color: #fff !important;
background-color: #29BD8B !important;
border-color: transparent;
}
.chongzhistyles:active, .chongzhistyles:active{
color: #fff !important;
background-color: #29BD8B !important;
border-color: transparent ;
}

@ -155,7 +155,7 @@ class ShixunCard extends Component {
<p className="font-14 color-white">非试用内容需要授权</p>
</div>
<a href={"/shixuns/"+item.identifier+"/challenges"} className="square-img">
<a href={"/shixuns/"+item.identifier+"/challenges"} className="square-img" target="_blank">
{/*<img src={getImageUrl("images/"+item.pic+"?1540534846")}/>*/}
<img src={setImagesUrl(`${item.pic}`)}/>
</a>
@ -163,7 +163,7 @@ class ShixunCard extends Component {
<div className="square-main">
<p className="task-hide">
<a href={"/shixuns/"+item.identifier+"/challenges"} className="justify color-grey-name" title={item.name}>
<a href={"/shixuns/"+item.identifier+"/challenges"} className="justify color-grey-name" title={item.name} target="_blank">
{item.name}
</a>
</p>

@ -52,12 +52,13 @@ export const getJupyterTpiDataSet = (identifier, params) => {
fetchJupyterTpiDataSet(identifier, params).then(res => {
if (res.data.status === 401) return; // 用户未登录
if (res.status === 200) {
const {data_sets, data_sets_count} = res.data;
const {data_sets, data_sets_count,folder_name} = res.data;
dispatch({
type: types.GET_JUPYTER_DATA_SETS,
payload: {
data_sets,
data_sets_count
data_sets_count,
folder_name,
}
});
}

@ -25,11 +25,12 @@ const initState = {
const JupyterReducer = (state = initState, action) => {
switch (action.type) {
case types.GET_JUPYTER_DATA_SETS:
const { data_sets, data_sets_count } = action.payload;
const { data_sets, data_sets_count,folder_name} = action.payload;
return {
...state,
jupyter_data_set: data_sets,
jupyter_data_set_count: data_sets_count
jupyter_data_set_count: data_sets_count,
jupyter_folder_name:folder_name,
}
case types.GET_JUPYTER_TPI_URL:
const {url, status, port} = action.payload;

@ -2939,7 +2939,7 @@ a.singlepublishtwo{
padding: 40px !important;
}
.editormd-html-preview{
width: 94% !important;
width:100% !important;
color: #323232 !important;
}
#homework_editorMd_description hr{
@ -3798,4 +3798,9 @@ a.singlepublishtwo{
.ant-drawer{
z-index: 10000 !important;
}
.markdown-body {
text-align: justify;
word-break: break-all;
}

@ -821,3 +821,7 @@ html>body #ajax-indicator { position: fixed; }
.footer_con-p{
color: #898989 !important;
}
.markdown-body {
text-align: justify;
word-break: break-all;
}
Loading…
Cancel
Save