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

chromesetting
daiao 5 years ago
commit d34a9f3c28

@ -103,3 +103,6 @@ gem 'diffy'
# oauth2 # oauth2
gem 'omniauth', '~> 1.9.0' gem 'omniauth', '~> 1.9.0'
gem 'omniauth-oauth2', '~> 1.6.0' gem 'omniauth-oauth2', '~> 1.6.0'
# global var
gem 'request_store'

@ -303,7 +303,7 @@ class ApplicationController < ActionController::Base
current_domain_session = session[:"#{default_yun_session}"] current_domain_session = session[:"#{default_yun_session}"]
if current_domain_session if current_domain_session
# existing session # existing session
(User.active.find(current_domain_session) rescue nil) User.current = (User.active.find(current_domain_session) rescue nil)
elsif autologin_user = try_to_autologin elsif autologin_user = try_to_autologin
autologin_user autologin_user
elsif params[:format] == 'atom' && params[:key] && request.get? && accept_rss_auth? elsif params[:format] == 'atom' && params[:key] && request.get? && accept_rss_auth?

@ -30,5 +30,17 @@ class JupytersController < ApplicationController
render json: {status: 0, url: url, port: port} render json: {status: 0, url: url, port: port}
end end
def reset_with_tpi
myshixun = Myshixun.find_by(identifier: params[:identifier])
info = jupyter_tpi_reset(myshixun)
render json: {status: 0, url: info[:url], port: info[:port]}
end
def reset_with_tpm
shixun = Shixun.find_by(identifier: params[:identifier])
info = jupyter_tpm_reset(shixun)
render json: {status: 0, url: info[:url], port: info[:port]}
end
end end

@ -18,7 +18,7 @@ class ShixunsController < ApplicationController
before_action :find_repo_name, only: [:repository, :commits, :file_content, :update_file, :shixun_exec, :copy, before_action :find_repo_name, only: [:repository, :commits, :file_content, :update_file, :shixun_exec, :copy,
:add_file, :jupyter_exec] :add_file, :jupyter_exec]
before_action :allowed, only: [:update, :close, :update_propaedeutics, :settings, :publish, before_action :allowed, only: [:update, :close, :update_propaedeutics, :settings, :publish, :apply_public,
:shixun_members_added, :change_manager, :collaborators_delete, :shixun_members_added, :change_manager, :collaborators_delete,
:cancel_apply_public, :cancel_publish, :add_collaborators, :add_file] :cancel_apply_public, :cancel_publish, :add_collaborators, :add_file]
before_action :portion_allowed, only: [:copy] before_action :portion_allowed, only: [:copy]
@ -800,25 +800,25 @@ class ShixunsController < ApplicationController
end end
end end
if @status == 0 if @status == 0
ActiveRecord::Base.transaction do
@shixun.update_attributes!(:status => 2) @shixun.update_attributes!(:status => 2)
end
rescue Exception => e
logger.error("pushlish game #{e}")
end
end
def apply_public
tip_exception(-1, "请先发布实训再申请公开") if @shixun.status != 2
ActiveRecord::Base.transaction do
@shixun.update_attributes!(public: 1)
apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first
if apply && apply.status == 0 if apply && apply.status == 0
@status = 0 @status = 0
else else
ApplyAction.create(:container_type => "ApplyShixun", :container_id => @shixun.id, :user_id => current_user.id, :status => 0) 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
end end
rescue Exception => e normal_status(0, "申请成功")
logger.error("pushlish game #{e}")
end
end end
# 设置私密版本库的在tpm中的目录 # 设置私密版本库的在tpm中的目录

@ -38,12 +38,20 @@ class Laboratory < ApplicationRecord
find_by_identifier(subdomain) find_by_identifier(subdomain)
end end
def self.current=(laboratory) # def self.current=(laboratory)
Thread.current[:current_laboratory] = laboratory # Thread.current[:current_laboratory] = laboratory
# end
#
# def self.current
# Thread.current[:current_laboratory] ||= Laboratory.find(1)
# end
def self.current=(user)
RequestStore.store[:current_laboratory] = user
end end
def self.current def self.current
Thread.current[:current_laboratory] ||= Laboratory.find(1) RequestStore.store[:current_laboratory] ||= User.anonymous
end end
def shixuns def shixuns

@ -540,12 +540,20 @@ class User < ApplicationRecord
mail.present? mail.present?
end end
# def self.current=(user)
# Thread.current[:current_user] = user
# end
#
# def self.current
# Thread.current[:current_user] ||= User.anonymous
# end
def self.current=(user) def self.current=(user)
Thread.current[:current_user] = user RequestStore.store[:current_user] = user
end end
def self.current def self.current
Thread.current[:current_user] ||= User.anonymous RequestStore.store[:current_user] ||= User.anonymous
end end
def self.anonymous def self.anonymous

@ -7,7 +7,7 @@ module JupyterService
shixun_tomcat = edu_setting('cloud_bridge') shixun_tomcat = edu_setting('cloud_bridge')
uri = "#{shixun_tomcat}/bridge/jupyter/get" uri = "#{shixun_tomcat}/bridge/jupyter/get"
tpiID = "tpm#{shixun.id}" tpiID = "tpm#{shixun.id}"
params = {tpiID: tpiID, :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(shixun))}"} params = {tpiID: tpiID, identifier: shixun.identifier, :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(shixun))}"}
logger.info "test_juypter: uri->#{uri}, params->#{params}" logger.info "test_juypter: uri->#{uri}, params->#{params}"
res = uri_post uri, params res = uri_post uri, params
@ -45,7 +45,7 @@ module JupyterService
uri = "#{shixun_tomcat}/bridge/jupyter/get" uri = "#{shixun_tomcat}/bridge/jupyter/get"
tpiID = myshixun.id tpiID = myshixun.id
params = {tpiID: tpiID, :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(shixun))}"} params = {tpiID: tpiID, identifier: shixun.identifier, :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(shixun))}"}
res = uri_post uri, params res = uri_post uri, params
logger.info "test_juypter: #{res}" logger.info "test_juypter: #{res}"
@ -130,4 +130,59 @@ module JupyterService
end end
##重置jupyter环境
def jupyter_tpi_reset(myshixun)
jupyter_delete_tpi(myshixun)
url = jupyter_url_with_game(myshixun)
port = jupyter_port_with_game(myshixun)
{url: url, port: port}
end
## 重置tpm环境
def jupyter_tpm_reset(shixun)
jupyter_delete_tpm(shixun)
url = jupyter_url_with_shixun(shixun)
port = jupyter_port_with_shixun(shixun)
{url: url, port: port}
end
# 删除pod
def jupyter_delete_tpi(myshixun)
myshixun_id = myshixun.id
digest = myshixun.identifier + edu_setting('bridge_secret_key')
digest_key = Digest::SHA1.hexdigest("#{digest}")
begin
shixun_tomcat = edu_setting('cloud_bridge')
uri = "#{shixun_tomcat}/bridge/jupyter/delete"
Rails.logger.info("#{current_user} => cloese_jupyter digest is #{digest}")
params = {:tpiID => myshixun_id, :digestKey => digest_key, :identifier => myshixun.identifier}
res = uri_post uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级110")
end
end
end
def jupyter_delete_tpm(shixun)
tpiID = "tpm#{shixun.id}"
digest = shixun.identifier + edu_setting('bridge_secret_key')
digest_key = Digest::SHA1.hexdigest("#{digest}")
begin
shixun_tomcat = edu_setting('cloud_bridge')
uri = "#{shixun_tomcat}/bridge/jupyter/delete"
Rails.logger.info("#{current_user} => cloese_jupyter digest is #{digest}")
params = {:tpiID => tpiID, :digestKey => digest_key, :identifier => shixun.identifier}
res = uri_post uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级110")
end
end
end
end end

@ -25,7 +25,7 @@ class ShixunSearchService < ApplicationService
else else
none_shixun_ids = ShixunSchool.where("school_id != #{User.current.school_id}").pluck(:shixun_id) 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, status: 2, public: 2).or(@shixuns.where(id: current_user.shixuns)) @shixuns = @shixuns.where.not(id: none_shixun_ids).where(hidden: 0, status: 2, public: 2).or(@shixuns.where(id: User.current.shixuns))
end end
end end

@ -31,6 +31,8 @@ Rails.application.routes.draw do
get :save_with_tpm get :save_with_tpm
get :get_info_with_tpi get :get_info_with_tpi
get :get_info_with_tpm get :get_info_with_tpm
get :reset_with_tpi
get :reset_with_tpm
end end
end end
@ -276,6 +278,7 @@ Rails.application.routes.draw do
get :cancel_publish get :cancel_publish
get :cancel_apply_public get :cancel_apply_public
get :publish get :publish
get :apply_public
get :shixun_exec get :shixun_exec
post :review_shixun post :review_shixun
get :review_newest_record get :review_newest_record

@ -326,8 +326,8 @@ module.exports = {
comments: false comments: false
}, },
compress: { compress: {
drop_debugger: true, drop_debugger: false,
drop_console: true drop_console: false
} }
} }
}), }),

File diff suppressed because one or more lines are too long

@ -109,15 +109,15 @@ export function initAxiosInterceptors(props) {
} }
// //
// console.log(config); // console.log(config);
if (config.method === "post") { // if (config.method === "post") {
if (requestMap[config.url] === true) { // 避免重复的请求 导致页面f5刷新 也会被阻止 显示这个方法会影响到定制信息 // if (requestMap[config.url] === true) { // 避免重复的请求 导致页面f5刷新 也会被阻止 显示这个方法会影响到定制信息
// console.log(config); // // console.log(config);
// console.log(JSON.parse(config)); // // console.log(JSON.parse(config));
// console.log(config.url); // // console.log(config.url);
// console.log("被阻止了是重复请求================================="); // // console.log("被阻止了是重复请求=================================");
return false; // return false;
} // }
} // }
// 非file_update请求 // 非file_update请求
if (config.url.indexOf('update_file') === -1) { if (config.url.indexOf('update_file') === -1) {
requestMap[config.url] = true; requestMap[config.url] = true;

@ -205,15 +205,16 @@ class CommonWorkItem extends Component{
{item.uncommit_count===undefined?"":<span className="mr20 fl">{item.uncommit_count} 未交</span>} {item.uncommit_count===undefined?"":<span className="mr20 fl">{item.uncommit_count} 未交</span>}
{ {
item.status_time!="" && item.status_time!="" &&
<Tooltip placement="bottom" title={ item.status.indexOf('提交中') != -1 ? '提交剩余时间' :
item.status.indexOf('补交中') != -1 ? '补交剩余时间' :
item.status.indexOf('申诉中') != -1 ? '申诉剩余时间' :
item.status.indexOf('匿评中') != -1 ? '匿评剩余时间' :
item.status.indexOf('匿评申诉中') != -1 ? '匿评申诉剩余时间' : ''}>
<span className="mr20 fl">{item.status_time}</span> <span className="mr20 fl">{item.status_time}</span>
</Tooltip>
}
}
{/*<Tooltip placement="bottom" title={ item.status.indexOf('提交中') != -1 ? '提交剩余时间' :*/}
{/* item.status.indexOf('补交中') != -1 ? '补交剩余时间' :*/}
{/* item.status.indexOf('申诉中') != -1 ? '申诉剩余时间' :*/}
{/* item.status.indexOf('匿评中') != -1 ? '匿评剩余时间' :*/}
{/* item.status.indexOf('匿评申诉中') != -1 ? '匿评申诉剩余时间' : ''}>*/}
{/*</Tooltip>*/}
{isAdmin && <div className="fr"> {isAdmin && <div className="fr">
<WordsBtn style="blue" className="fl font-16 ml28" onClick={ () => { this.props.toEditPage(this.props.match.params, item.homework_id) }}>编辑</WordsBtn> <WordsBtn style="blue" className="fl font-16 ml28" onClick={ () => { this.props.toEditPage(this.props.match.params, item.homework_id) }}>编辑</WordsBtn>
<WordsBtn style="blue" className="fl font-16 ml28" onClick={ () => { this.props.toWorkSettingPage(this.props.match.params, item.homework_id) }}>设置</WordsBtn> <WordsBtn style="blue" className="fl font-16 ml28" onClick={ () => { this.props.toWorkSettingPage(this.props.match.params, item.homework_id) }}>设置</WordsBtn>

@ -494,7 +494,7 @@ class NewShixunModel extends Component{
<div className="clearfix sortinxdirection mt30 intermediatecenterysls"> <div className="clearfix sortinxdirection mt30 intermediatecenterysls">
<p className="nandu">筛选</p> <p className="nandu">筛选</p>
<p className={belongtoindex===0?"clickbutstwo ml13":"clickbutstwos ml13"} onClick={()=>this.belongto("all")}>全部实训</p> <p className={belongtoindex===0?"clickbutstwo ml13":"clickbutstwos ml13"} onClick={()=>this.belongto("all")}>全部实训</p>
<p className={belongtoindex===1?"clickbutstwo ml20":"clickbutstwos ml20"} onClick={()=>this.belongto("mine")}>普通实训</p> <p className={belongtoindex===1?"clickbutstwo ml20":"clickbutstwos ml20"} onClick={()=>this.belongto("mine")}>我的实训</p>
</div>:"" </div>:""
} }
{/*{this.props.type==='shixuns'? <Dropdown overlay={menus}>*/} {/*{this.props.type==='shixuns'? <Dropdown overlay={menus}>*/}

@ -366,10 +366,10 @@ class ShixunWorkReport extends Component {
<p className=" fl color-black mt25 summaryname">{data&&data.shixun_name}</p> <p className=" fl color-black mt25 summaryname">{data&&data.shixun_name}</p>
{/*{this.props.isAdmin()?<a className=" fr font-14 ml30 mt10 mr20 color-grey-9 ">导出实训报告数据</a>:""}*/} {/*{this.props.isAdmin()?<a className=" fr font-14 ml30 mt10 mr20 color-grey-9 ">导出实训报告数据</a>:""}*/}
<a onClick={this.goback} className="color-grey-6 fr font-14 ml20 mt15">返回</a> <a onClick={this.goback} className="color-grey-6 fr font-14 ml20 mt15">返回</a>
{this.props.isAdmin() ? <a <a
className=" color-blue font-14 fr ml20 mt15" className=" color-blue font-14 fr ml20 mt15"
onClick={()=>this.confirmysl(`/student_works/${homeworkid}/export_shixun_work_report.pdf`)} onClick={()=>this.confirmysl(`/student_works/${homeworkid}/export_shixun_work_report.pdf`)}
> <Spin size="small" spinning={this.state.isspinning}>导出实训报告数据</Spin></a> : ""} > <Spin size="small" spinning={this.state.isspinning}>导出实训报告数据</Spin></a>
{/*{this.props.isAdmin() ?work_comment_hidden===true? "":<a*/} {/*{this.props.isAdmin() ?work_comment_hidden===true? "":<a*/}
{/*className=" color-blue font-14 fr ml20 mt15"*/} {/*className=" color-blue font-14 fr ml20 mt15"*/}
{/*onClick={()=>this.showAppraiseModal(1)}*/} {/*onClick={()=>this.showAppraiseModal(1)}*/}

@ -393,21 +393,13 @@ class ShixunhomeWorkItem extends Component{
{ {
discussMessage.time_status===1? discussMessage.time_status===1?
<Tooltip title={"提交剩余时间"} placement="bottom">
<span className="mr15 color-grey9">{discussMessage.status_time}</span> <span className="mr15 color-grey9">{discussMessage.status_time}</span>
</Tooltip>
:discussMessage.time_status===2? :discussMessage.time_status===2?
<Tooltip title={"补交剩余时间"} placement="bottom">
<span className="mr15 color-grey9">{discussMessage.status_time}</span> <span className="mr15 color-grey9">{discussMessage.status_time}</span>
</Tooltip>
:discussMessage.time_status===3? :discussMessage.time_status===3?
<Tooltip title={"匿评剩余时间"} placement="bottom">
<span className="mr15 color-grey9">{discussMessage.status_time}</span> <span className="mr15 color-grey9">{discussMessage.status_time}</span>
</Tooltip>
:discussMessage.time_status===4? :discussMessage.time_status===4?
<Tooltip title={"申诉剩余时间"} placement="bottom">
<span className="mr15 color-grey9">{discussMessage.status_time}</span> <span className="mr15 color-grey9">{discussMessage.status_time}</span>
</Tooltip>
: :
<span className="mr15 color-grey9">{discussMessage.status_time}</span> <span className="mr15 color-grey9">{discussMessage.status_time}</span>
} }

@ -14,7 +14,7 @@ function UserInfo (props) {
const {image_url, name} = props.userInfo; const {image_url, name} = props.userInfo;
return ( return (
<div className={'avator_nicker'}> <div className={'avator_nicker'}>
<img alt="用户头像" className={'student_img'} src={getImageUrl(`images/${image_url}` || 'images/educoder/headNavLogo.png?1526520218')} /> <img style={{ display: image_url ? 'inline-block' : 'none'}} alt="用户头像" className={'student_img'} src={getImageUrl(`images/${image_url}` || 'images/educoder/headNavLogo.png?1526520218')} />
<span className={'student_nicker'}> <span className={'student_nicker'}>
{name || ''} {name || ''}
</span> </span>

@ -28,6 +28,9 @@ render() {
` `
body{ body{
overflow: hidden !important; overflow: hidden !important;
}
.ant-modal-body {
padding: 20px 40px;
} }
` `
} }

@ -1,14 +1,10 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import {Redirect} from 'react-router';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
import PropTypes from 'prop-types';
import {Rating, Progress} from "@icedesign/base"; import {Rating, Progress} from "@icedesign/base";
import {Modal, Input, Radio, Pagination, message, Spin, Icon, Tooltip, Rate} from 'antd'; import {Modal, Input, Radio, Pagination, message, Spin, Icon, Tooltip, Button,Popover} from 'antd';
import AccountProfile from "../user/AccountProfile"; import AccountProfile from "../user/AccountProfile";
@ -57,6 +53,8 @@ class TPMBanner extends Component {
isSpin: false, isSpin: false,
Senttothevcaluetype: false, Senttothevcaluetype: false,
jupyterbool: false, jupyterbool: false,
openknow:false,
openshowpublictype:false
} }
} }
@ -99,7 +97,54 @@ class TPMBanner extends Component {
} }
} }
openknow=()=>{
let storage=window.localStorage;
this.setState({
openknow:false
})
storage.setItem("shixunopenprocess",true);
}
openshowpublic=()=>{
let storage=window.localStorage;
this.setState({
openshowpublictype:false
})
storage.setItem("openopenpublictype",true);
}
componentDidUpdate(prevProps, prevState) {
if (prevProps != this.props) {
let shixunopenprocess=window.localStorage.shixunopenprocess;
let openopenpublictype=window.localStorage.openopenpublictype;
if(this.props.shixunsDetails.shixun_status === 0 && this.props.identity < 5){
if(shixunopenprocess===undefined||shixunopenprocess===false){
this.setState({
openknow:true
})
}else{
this.setState({
openknow:false
})
}
}
if(this.props.shixunsDetails.shixun_status === 2 && this.props.shixunsDetails.public===0 && this.props.identity < 5){
if(openopenpublictype===undefined||openopenpublictype===false){
this.setState({
openshowpublictype:true
})
}else{
this.setState({
openshowpublictype:false
})
}
}
}
}
componentDidMount() { componentDidMount() {
let thiisie = this.IEVersion(); let thiisie = this.IEVersion();
if (thiisie != -1) { if (thiisie != -1) {
this.setState({ this.setState({
@ -298,7 +343,10 @@ class TPMBanner extends Component {
ModalCancel = () => { ModalCancel = () => {
this.setState({ this.setState({
Modalstype: false Modalstype: false,
Modalstopval: "",
modalsMidval:undefined,
ModalsBottomval:"",
}) })
} }
ModalSave = () => { ModalSave = () => {
@ -311,16 +359,53 @@ class TPMBanner extends Component {
console.log(error) console.log(error)
}); });
} }
cancel_publish = () => { cancel_publish = () => {
this.setState({ this.setState({
Modalstype: true, Modalstype: true,
Modalstopval: "是否确认撤销发布?", Modalstopval: "是否确认撤销发布?",
modalsMidval:"撤销发布后,学员将无法进行练习,若您新增关",
ModalsBottomval:"卡,学员需要重新体验课程",
ModalCancel: this.ModalCancel, ModalCancel: this.ModalCancel,
ModalSave: this.ModalSave, ModalSave: this.ModalSave,
}) })
} }
openpublic=()=>{
let id = this.props.match.params.shixunId;
let url = `/shixuns/${id}/apply_public.json`;
axios.get(url).then((response) => {
if(response.data.status===0){
window.location.reload()
}
}).catch((error) => {
console.log(error)
});
}
ModalhidenpublicSave=()=>{
let id = this.props.match.params.shixunId;
let url = `/shixuns/${id}/cancel_apply_public.json`;
axios.get(url).then((response) => {
if(response.data.status===0){
window.location.reload()
}
}).catch((error) => {
console.log(error)
});
}
hidenpublic=()=>{
this.setState({
Modalstype: true,
Modalstopval: "是否确认撤销公开?",
modalsMidval:" ",
ModalsBottomval:" ",
ModalCancel: this.ModalCancel,
ModalSave: this.ModalhidenpublicSave,
})
}
/* /*
* 申请发布按钮 * 申请发布按钮
* */ * */
@ -334,12 +419,17 @@ class TPMBanner extends Component {
} else { } else {
evaluation_set_position = response.data.evaluation_set_position evaluation_set_position = response.data.evaluation_set_position
} }
if(response.data.status===0){
window.location.reload()
}else{
this.setState({ this.setState({
Issuevisible: true, Issuevisible: true,
tag_position: response.data.tag_position, tag_position: response.data.tag_position,
evaluation_set_position: evaluation_set_position, evaluation_set_position: evaluation_set_position,
publishboxstatus: response.data.status, publishboxstatus: response.data.status,
}) })
}
}).catch((error) => { }).catch((error) => {
console.log(error) console.log(error)
}); });
@ -448,7 +538,7 @@ class TPMBanner extends Component {
}) })
// this.shixunexec(response.data.message+".json") // this.shixunexec(response.data.message+".json")
} else if (response.data.status === -1) { } else if (response.data.status === -1) {
console.log(response)
} else if (response.data.status === -3) { } else if (response.data.status === -3) {
this.setState({ this.setState({
shixunsmessage: response.data.message, shixunsmessage: response.data.message,
@ -520,7 +610,7 @@ class TPMBanner extends Component {
}) })
// this.shixunexec(response.data.message+".json") // this.shixunexec(response.data.message+".json")
} else if (response.data.status === -1) { } else if (response.data.status === -1) {
console.log(response)
} else if (response.data.status === -3) { } else if (response.data.status === -3) {
this.setState({ this.setState({
shixunsmessage: response.data.message, shixunsmessage: response.data.message,
@ -699,6 +789,7 @@ class TPMBanner extends Component {
modalCancel={this.state.ModalCancel} modalCancel={this.state.ModalCancel}
modalSave={this.state.ModalSave} modalSave={this.state.ModalSave}
modalsBottomval={this.state.ModalsBottomval} modalsBottomval={this.state.ModalsBottomval}
modalsMidval={this.state.modalsMidval}
loadtype={this.state.Loadtype} loadtype={this.state.Loadtype}
/> : ""} /> : ""}
@ -907,8 +998,21 @@ class TPMBanner extends Component {
{/*}*/} {/*}*/}
{shixunsDetails.shixun_status === 0 && this.props.identity < 5 ? {shixunsDetails.shixun_status === 0 && this.props.identity < 5 ?
<Popover
content={
<pre className={"bannerpd201"}>
<div>您编辑完成后可以马上使用到自</div>
<div className={"wechatcenter mt10"}>己的课堂和实训课程哦</div>
<div className={"wechatcenter mt15"}><Button type="primary" onClick={this.openknow} >我知道了</Button></div>
</pre>
}
trigger="click"
placement="bottom"
visible={this.state.openknow}
>
<a onClick={this.applyrelease} className="fr user_default_btn user_blue_btn mr20 font-18 height39" <a onClick={this.applyrelease} className="fr user_default_btn user_blue_btn mr20 font-18 height39"
id="challenge_begin">申请发布</a> : "" id="challenge_begin">发布</a>
</Popover>: ""
} }
<Modal <Modal
@ -971,7 +1075,32 @@ class TPMBanner extends Component {
</Modal> </Modal>
{shixunsDetails.shixun_status === 1 && this.props.identity < 5 ? {shixunsDetails.shixun_status === 2 && shixunsDetails.public===0 && this.props.identity < 5 ?
<Popover
content={
<pre className={"bannerpd201"}>
<div>申请公开成功后您的实训将会展示实训列表</div>
<div className={"wechatcenter mt10"}>平台审核通过您将获得<span className={"FF6802"}> 1000 </span></div>
<div className={"wechatcenter mt15"}><Button type="primary" onClick={this.openshowpublic} >我知道了</Button></div>
</pre>
}
trigger="click"
placement="bottom"
visible={this.state.openshowpublictype}
>
<Button type="primary" ghost id="challenge_begin" onClick={this.openpublic} className="fr user_default_btn user_blue_btn mr20 font-18 height39">
申请公开
</Button>
</Popover>: ""
}
{shixunsDetails.shixun_status === 2 && shixunsDetails.public===1 && this.props.identity < 5 ?
<Button type="primary" ghost id="challenge_begin" onClick={this.hidenpublic} className="fr user_default_btn user_blue_btn mr20 font-18 height39">
撤销公开
</Button>: ""
}
{shixunsDetails.shixun_status === 2 && shixunsDetails.public===0 && this.props.identity < 5 ?
<a onClick={this.cancel_publish} className="fr user_default_btn user_blue_btn mr20 font-18 height39" <a onClick={this.cancel_publish} className="fr user_default_btn user_blue_btn mr20 font-18 height39"
id="challenge_begin">撤销发布</a> : "" id="challenge_begin">撤销发布</a> : ""
} }

@ -7,7 +7,7 @@ import TPMRightSection from './component/TPMRightSection';
import TPMNav from './component/TPMNav'; import TPMNav from './component/TPMNav';
import axios from 'axios'; import axios from 'axios';
import './tpmmodel/tpmmodel.css' import './tpmmodel/tpmmodel.css'
import {getUploadActionUrl} from 'educoder'; import {getUploadActionUrl,appendFileSizeToUploadFileAll} from 'educoder';
import moment from 'moment'; import moment from 'moment';
const confirm = Modal.confirm; const confirm = Modal.confirm;
@ -75,6 +75,7 @@ class TPMDataset extends Component {
mylistansum:30, mylistansum:30,
collaboratorList:[], collaboratorList:[],
fileList:[], fileList:[],
fileListimgs:[],
file:null, file:null,
datalist:[], datalist:[],
data_sets_count:0, data_sets_count:0,
@ -225,6 +226,31 @@ class TPMDataset extends Component {
} }
getdatasthree = (page,limit) => {
let id=this.props.match.params.shixunId;
let collaborators=`/shixuns/${id}/jupyter_data_sets.json`;
axios.get(collaborators,{params:{
page:page,
limit:limit,
}}).then((response)=> {
if(response.status===200){
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
}
}
}).catch((error)=>{
});
}
paginationonChanges = (pageNumber) => { paginationonChanges = (pageNumber) => {
// //console.log('Page: '); // //console.log('Page: ');
this.setState({ this.setState({
@ -260,40 +286,39 @@ class TPMDataset extends Component {
if (index % 2 === 1) className = 'dark-row'; if (index % 2 === 1) className = 'dark-row';
return className; return className;
} }
// 附件相关 START
handleChange = (info) => { handleChange = (info) => {
console.log("handleChange"); if(info.file.status == "done" || info.file.status == "uploading" || info.file.status === 'removed'){
console.log(info); let fileList = info.fileList;
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({ this.setState({
// fileList:appendFileSizeToUploadFileAll(fileList), fileList: appendFileSizeToUploadFileAll(fileList),
fileList: fileLists,
deleteisnot: false
}); });
}
if(info.file.status === 'done'){ if(info.file.status === 'done'){
console.log("handleChange");
console.log(info);
//done 成功就会调用这个方法 //done 成功就会调用这个方法
this.getdatas(); this.getdatas();
// this.props.showNotification(`上传文件成功`); try {
// let datas=this.state.fileListimgs;
}else if(info.file.status === 'removed'){ // for(var i=0;i<info.fileList.length;i++){
// this.props.showNotification(`上传文件失败`); // datas.push(info.fileList[i].originFileObj);
// }
// this.setState({
// fileListimgs:datas,
// })
// console.log("datasdatasdatasdatasdatas");
// console.log(datas);
}catch (e) {
}else if(info.file.status === 'uploading'){ }
// this.props.showNotification(`正在上传文件中`); // this.props.showNotification(`上传文件成功`);
} }
} }
} }
onAttachmentRemove = (file) => { onAttachmentRemove = (file) => {
// debugger // debugger
if(!file.percent || file.percent == 100){ if(!file.percent || file.percent == 100){
@ -414,42 +439,19 @@ class TPMDataset extends Component {
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。 // showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false, // showUploadList: false,
action: `${getUploadActionUrl()}`, action: `${getUploadActionUrl()}`,
showUploadList:false,
onChange: this.handleChange, onChange: this.handleChange,
onRemove: this.onAttachmentRemove, onRemove: this.onAttachmentRemove,
beforeUpload: (file, fileList) => { beforeUpload: (file) => {
console.log("beforeUpload"); //上传前的操作
console.log(this.state.fileList); console.log('beforeUpload', file.name);
console.log(this.state.fileList.length); const isLt150M = file.size / 1024 / 1024 < 150;
if (this.state.fileList.length >= 1) {
return false
}
// console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 50;
if (!isLt150M) { if (!isLt150M) {
// this.props.showNotification(`文件大小必须小于50MB`); this.props.showNotification('文件大小必须小于150MB!');
notification.open(
{
message: '提示',
description:
'文件大小必须小于50MB',
}
)
}
if(this.state.file !== undefined){
console.log("763")
this.setState({
file:file
})
}else {
this.setState({
file:file
})
} }
return isLt150M; return isLt150M;
}, },
} };
return ( return (
<React.Fragment> <React.Fragment>
<div className="tpmComment educontent clearfix mt30 mb80"> <div className="tpmComment educontent clearfix mt30 mb80">
@ -481,7 +483,7 @@ class TPMDataset extends Component {
` `
} }
</style> </style>
<div className="deletebuttom intermediatecenter "> <Upload {...uploadProps}><p className="deletebuttomtest"> <div className="deletebuttom intermediatecenter "> <Upload {...uploadProps}><p className="deletebuttomtest" type="upload">
上传文件</p> </Upload></div> 上传文件</p> </Upload></div>
{ {

@ -69,16 +69,16 @@ export default class Shixuninformation extends Component {
} }
componentDidMount() { componentDidMount() {
if (this.props.data) {
if (this.props.data.shixun) { if (this.props.data.shixun) {
this.setState({ this.setState({
can_copy:this.props.data.shixun && this.props.data.shixun.can_copy === undefined ? false : this.props.data.shixun&&this.props.data.shixun.can_copy, 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.shixun && this.props.data.shixun.use_scope, use_scope: this.props.data && this.props.data.shixun.use_scope,
opening_time: this.props.data.shixun && this.props.data.shixun.opening_time, opening_time: this.props.data && this.props.data.shixun.opening_time,
opentime: !this.props.data.shixun && this.props.data.shixun.opening_time ? false : true, opentime: !this.props.data && this.props.data.shixun.opening_time ? false : true,
oldscope_partment:this.props.data.shixun && this.props.data.shixun.scope_partment, oldscope_partment: this.props.data && this.props.data.shixun.scope_partment,
}) })
}
} }
let departmentsUrl = `/shixuns/departments.json`; let departmentsUrl = `/shixuns/departments.json`;
axios.get(departmentsUrl).then((response) => { axios.get(departmentsUrl).then((response) => {
@ -98,15 +98,15 @@ export default class Shixuninformation extends Component {
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
if (prevProps.data != this.props.data) { if (prevProps.data != this.props.data) {
if (this.props.data) { if (this.props.data) {
if (this.props.data.shixun) {
this.setState({ this.setState({
can_copy: this.props.data.shixun && this.props.data.shixun.can_copy === undefined ? false : this.props.data.shixun&&this.props.data.shixun.can_copy, 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.shixun&& this.props.data.shixun.use_scope, use_scope: this.props.data && this.props.data.shixun.use_scope,
opening_time: this.props.data.shixun && this.props.data.shixun.opening_time, opening_time: this.props.data && this.props.data.shixun.opening_time,
opentime: !this.props.data.shixun && this.props.data.shixun.opening_time ? false : true, opentime: !this.props.data && this.props.data.shixun.opening_time ? false : true,
oldscope_partment: this.props.data.shixun && this.props.data.shixun.scope_partment, oldscope_partment: this.props.data && this.props.data.shixun.scope_partment,
}) })
}
} }
} }
} }
@ -262,7 +262,7 @@ export default class Shixuninformation extends Component {
</div> </div>
<div className="edu-back-white mb10 ml30 mt20"> <div className="edu-back-white mb10 ml30 mt20">
{this.props.data.shixun && this.props.data.shixun.use_scope === 0 && this.props.data.shixun && this.props.data.shixun.status === 2 ? "" : {this.props.data && this.props.data.shixun.use_scope === 0 && this.props.data && this.props.data.shixun.status === 2 ? "" :
<div> <div>
<span className="color-grey-6 mt5 fl font-16" style={{minWidth: '45px'}}>公开程度:</span> <span className="color-grey-6 mt5 fl font-16" style={{minWidth: '45px'}}>公开程度:</span>
<span className="fl mt8 ml20"> <span className="fl mt8 ml20">

@ -34,8 +34,8 @@ export default class Shixuninformation extends Component {
componentDidMount() { componentDidMount() {
if (this.props.data ) {
if (this.props.data.shixun) { if (this.props.data.shixun) {
this.setState({ this.setState({
vnc: this.props.data && this.props.data.shixun.vnc, vnc: this.props.data && this.props.data.shixun.vnc,
code_hidden: this.props.data && this.props.data.shixun.code_hidden, code_hidden: this.props.data && this.props.data.shixun.code_hidden,
@ -56,13 +56,14 @@ export default class Shixuninformation extends Component {
// } // }
} }
}
} }
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
if (prevProps.data != this.props.data) { if (prevProps.data != this.props.data) {
if (this.props.data) { if (this.props.data) {
if (this.props.data.shixun) {
this.setState({ this.setState({
vnc: this.props.data && this.props.data.shixun.vnc, vnc: this.props.data && this.props.data.shixun.vnc,
code_hidden: this.props.data && this.props.data.shixun.code_hidden, code_hidden: this.props.data && this.props.data.shixun.code_hidden,
@ -85,6 +86,7 @@ export default class Shixuninformation extends Component {
} }
} }
} }
}
onSubmits = () => { onSubmits = () => {
@ -222,7 +224,7 @@ export default class Shixuninformation extends Component {
} }
render() { render() {
console.log(this.props) // console.log(this.props)
return ( return (
<div> <div>
<div className="educontent mb200 edu-back-white padding10-20 pdb30 mb50"> <div className="educontent mb200 edu-back-white padding10-20 pdb30 mb50">

@ -55,38 +55,40 @@ class Shixuninformation extends Component {
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
if (prevProps.data != this.props.data) { if (prevProps.data != this.props.data) {
if (this.props.data ) { if (this.props.data ) {
if (this.props.data.shixun){
this.setState({ this.setState({
shixunName: this.props.data.shixun&&this.props.data.shixun.name, shixunName: this.props.data && this.props.data.shixun.name,
trainee:this.props.data.shixun&&this.props.data.shixun.trainee, trainee: this.props.data && this.props.data.shixun.trainee,
choice_main_type: this.props.data.shixun&&this.props.data.shixun.choice_main_type, choice_main_type: this.props.data && this.props.data.shixun.choice_main_type,
choice_small_type: this.props.data.shixun&&this.props.data.shixun.choice_small_type, choice_small_type: this.props.data && this.props.data.shixun.choice_small_type,
choice_standard_scripts:this.props.data.shixun&&this.props.data.shixun.choice_standard_scripts, choice_standard_scripts: this.props.data && this.props.data.shixun.choice_standard_scripts,
shixunmemoMDvalue: this.props.data.shixun&&this.props.data.shixun.evaluate_script, shixunmemoMDvalue: this.props.data && this.props.data.shixun.evaluate_script,
simichecked: this.props.data.shixun&&this.props.data.shixun.is_secret_repository, simichecked: this.props.data && this.props.data.shixun.is_secret_repository,
shixun_service_configs: this.props.data.shixun&&this.props.data.shixun.shixun_service_configs, shixun_service_configs: this.props.data && this.props.data.shixun.shixun_service_configs,
standard_scripts:this.props.data.shixun&&this.props.data.shixun.standard_scripts, standard_scripts: this.props.data && this.props.data.shixun.standard_scripts,
shixun_service_configlist:this.props.data.shixun&&this.props.data.shixun.shixun_service_configs, shixun_service_configlist: this.props.data && this.props.data.shixun.shixun_service_configs,
}) })
if(this.props.data.shixun&&this.props.data.shixun.choice_standard_scripts===null){ if (this.props.data && this.props.data.shixun.choice_standard_scripts === null) {
this.setState({ this.setState({
choice_standard_scripts:{id: this.props.data.shixun&&this.props.data.shixun.standard_scripts[0].id, value: ""}, choice_standard_scripts: {id: this.props.data && this.props.data.shixun.standard_scripts[0].id, value: ""},
choice_standard_scriptssum:this.props.data.shixun&&this.props.data.shixun.standard_scripts[0].id choice_standard_scriptssum: this.props.data && this.props.data.shixun.standard_scripts[0].id
}) })
this.props.form.setFieldsValue({ this.props.form.setFieldsValue({
selectscripts:this.props.data.shixun&&this.props.data.shixun.standard_scripts[0].id selectscripts: this.props.data && this.props.data.shixun.standard_scripts[0].id
}) })
this.get_mirror_script(this.props.data.shixun&&this.props.data.shixun.standard_scripts[0].id) this.get_mirror_script(this.props.data && this.props.data.shixun.standard_scripts[0].id)
} else { } else {
this.props.form.setFieldsValue({ this.props.form.setFieldsValue({
selectscripts:this.props.data.shixun&&this.props.data.shixun.choice_standard_scripts selectscripts: this.props.data && this.props.data.shixun.choice_standard_scripts
}) })
} }
let newlist = "" let newlist = ""
this.props.data.shixun&&this.props.data.shixun.choice_small_type.map((item, key) => { this.props.data && this.props.data.shixun.choice_small_type.map((item, key) => {
this.props.data.shixun.small_type.map((i,k)=>{ this.props.data && this.props.data.shixun.small_type.map((i, k) => {
if (item === i.id) { if (item === i.id) {
newlist = newlist + `${i.description}` newlist = newlist + `${i.description}`
} }
@ -96,8 +98,8 @@ class Shixuninformation extends Component {
subvalues: newlist subvalues: newlist
}) })
this.props.data.shixun&&this.props.data.shixun.main_type.map((item,key)=>{ this.props.data && this.props.data.shixun.main_type.map((item, key) => {
if(item.id===this.props.data.shixun&&this.props.data.shixun.choice_main_type){ if (item.id === this.props.data && this.props.data.shixun.choice_main_type) {
this.setState({ this.setState({
mainvalues: item.description, mainvalues: item.description,
}) })
@ -105,12 +107,13 @@ class Shixuninformation extends Component {
}) })
this.props.form.setFieldsValue({ this.props.form.setFieldsValue({
name:this.props.data.shixun&&this.props.data.shixun.name, name: this.props.data && this.props.data.shixun.name,
trainee: this.props.data.shixun&&this.props.data.shixun.trainee, trainee: this.props.data && this.props.data.shixun.trainee,
selectleft: this.props.data.shixun&&this.props.data.shixun.choice_main_type, selectleft: this.props.data && this.props.data.shixun.choice_main_type,
selectright:this.props.data.shixun&&this.props.data.shixun.choice_small_type, selectright: this.props.data && this.props.data.shixun.choice_small_type,
}) })
this.contentMdRef.current.setValue(this.props.data.shixun&&this.props.data.shixun.description); this.contentMdRef.current.setValue(this.props.data && this.props.data.shixun.description);
}
} }
} }
} }
@ -713,7 +716,7 @@ class Shixuninformation extends Component {
} }
render() { render() {
let operateauthority = this.props.identity === 1 ? true : this.props.identity < 5 && this.props.data.shixun.status == 0 ? true : false;
// console.log(operateauthority) // console.log(operateauthority)
const {getFieldDecorator} = this.props.form; const {getFieldDecorator} = this.props.form;
const { fileList, choice_standard_scripts, postapplyvisible, shixunmemoMDvalue} = this.state; const { fileList, choice_standard_scripts, postapplyvisible, shixunmemoMDvalue} = this.state;
@ -754,7 +757,7 @@ class Shixuninformation extends Component {
return isLt150M; return isLt150M;
}, },
} }
let operateauthority = this.props.identity === 1 ? true : this.props.identity < 5 && this.props.data&&this.props.data.shixun.status == 0 ? true : false;
return ( return (
<div> <div>
<div className="educontent mb50 edu-back-white padding10-20"> <div className="educontent mb50 edu-back-white padding10-20">
@ -841,7 +844,9 @@ class Shixuninformation extends Component {
> >
{ {
this.props.data === undefined ? "" : this.props.data.shixun&&this.props.data.shixun.main_type.map((item, key) => { this.props.data === undefined ? "" : this.props.shixunsDetails&&this.props.shixunsDetails.is_jupyter === true?this.props.data.shixun&&this.props.data.shixun.main_type.map((item, key) => {
let itemtype=item.type_name.toLowerCase().indexOf('jupyter'.toLowerCase())
if(itemtype>-1) {
return ( return (
<Option value={item.id} key={key} name={item.description}> <Option value={item.id} key={key} name={item.description}>
<Tooltip placement="right" title={item.description === "" ? "无描述" : item.description}> <Tooltip placement="right" title={item.description === "" ? "无描述" : item.description}>
@ -849,7 +854,23 @@ class Shixuninformation extends Component {
</Tooltip> </Tooltip>
</Option> </Option>
) )
}) }
}):""
}
{
this.props.data === undefined ? "" : this.props.shixunsDetails&&this.props.shixunsDetails.is_jupyter === false?this.props.data.shixun&&this.props.data.shixun.main_type.map((item, key) => {
let itemtype=item.type_name.toLowerCase().indexOf('jupyter'.toLowerCase())
if(itemtype===-1) {
return (
<Option value={item.id} key={key} name={item.description}>
<Tooltip placement="right" title={item.description === "" ? "无描述" : item.description}>
{item.type_name}
</Tooltip>
</Option>
)
}
}):""
} }
</Select> </Select>

@ -6,6 +6,8 @@ import {
Modal Modal
} from 'antd'; } from 'antd';
import './css/TPMsettings.css';
import TopShixuninformation from './Shixuninformation'; import TopShixuninformation from './Shixuninformation';
import Configuration from './Configuration'; import Configuration from './Configuration';
@ -14,8 +16,6 @@ import LearningSettings from './LearningSettings';
import axios from 'axios'; import axios from 'axios';
import './css/TPMsettings.css';
const {TabPane} = Tabs; const {TabPane} = Tabs;
// 处理整点 半点 // 处理整点 半点
@ -41,17 +41,17 @@ export default class TPMsettings extends Component {
axios.get(Url).then((response) => { axios.get(Url).then((response) => {
// alert(response.data.shixun.choice_standard_scripts) // alert(response.data.shixun.choice_standard_scripts)
if (response.status === 200) { if (response.status === 200) {
if(response.data){
this.setState({ if (response.data.shixun&&response.data.shixun.scope_partment.length > 0) {
data: response.data
})
if (response.data.shixun.scope_partment.length > 0) {
this.setState({ this.setState({
scopetype: true scopetype: true
}) })
} }
}
this.setState({
data: response.data
})
} }
}); });
@ -96,7 +96,8 @@ export default class TPMsettings extends Component {
operateshixunstype: false, operateshixunstype: false,
}); });
window.location.href = "/shixuns"; // window.location.href = "/shixuns";
this.props.history.replace( "/shixuns/");
} }
}).catch((error) => { }).catch((error) => {
console.log(error) console.log(error)
@ -113,7 +114,8 @@ export default class TPMsettings extends Component {
operateshixunstype: false, operateshixunstype: false,
}); });
window.location.href = "/shixuns/" + id + "/challenges"; // window.location.href = "/shixuns/" + id + "/challenges";
this.props.history.replace( "/shixuns/" + id + "/challenges");
} }
}).catch((error) => { }).catch((error) => {
console.log(error) console.log(error)
@ -128,7 +130,7 @@ export default class TPMsettings extends Component {
render() { render() {
let showtabs = this.props.shixunsDetails === undefined ? "" : this.props.shixunsDetails.is_jupyter === true ? "" : "学习页面设置" let showtabs = this.props.shixunsDetails === undefined ? "" : this.props.shixunsDetails&&this.props.shixunsDetails.is_jupyter === true ? "" : "学习页面设置"
// let a="isvnc"; // let a="isvnc";
// let b="isVNC"; // let b="isVNC";
@ -197,7 +199,7 @@ export default class TPMsettings extends Component {
getdatas={(key) => this.getdatas(key)} getdatas={(key) => this.getdatas(key)}
/> />
</TabPane> </TabPane>
{this.props.shixunsDetails === undefined ? "" : this.props.shixunsDetails.is_jupyter === false ? {this.props.shixunsDetails === undefined ? "" : this.props.shixunsDetails&&this.props.shixunsDetails.is_jupyter === false ?
<TabPane tab={showtabs} key="3"> <TabPane tab={showtabs} key="3">
<LearningSettings <LearningSettings
{...this.state} {...this.state}

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2019-12-11 08:35:23 * @Date: 2019-12-11 08:35:23
* @LastEditors: tangjiang * @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 20:19:48 * @LastEditTime: 2019-12-13 15:25:50
*/ */
import './index.scss'; import './index.scss';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
@ -26,16 +26,20 @@ function JupyterTPI (props) {
}, },
url, url,
loading, // 保存按钮状态 loading, // 保存按钮状态
total,
pagination,
dataSets, // 数据集 dataSets, // 数据集
jupyter_info, jupyter_info,
getJupyterInfo, getJupyterInfo,
syncJupyterCode, syncJupyterCode,
jupyter_tpi_url_state, jupyter_tpi_url_state,
// getJupyterTpiDataSet, getJupyterTpiDataSet,
getJupyterTpiUrl, getJupyterTpiUrl,
saveJupyterTpi, saveJupyterTpi,
changeLoadingState, changeLoadingState,
changeGetJupyterUrlState changeGetJupyterUrlState,
jupyter_identifier,
changeCurrentPage
} = props; } = props;
const {identifier} = params; const {identifier} = params;
@ -107,6 +111,7 @@ function JupyterTPI (props) {
const handleClickQuitTpi = () => { const handleClickQuitTpi = () => {
// console.log(jupyterInfo); // console.log(jupyterInfo);
const { identifier } = jupyterInfo; const { identifier } = jupyterInfo;
if (!identifier) return;
props.history.push(`/shixuns/${identifier}/challenges`); props.history.push(`/shixuns/${identifier}/challenges`);
} }
@ -125,6 +130,14 @@ function JupyterTPI (props) {
saveJupyterTpi(); saveJupyterTpi();
} }
// 分页信息改变时
const handlePageChange = (current) => {
// 改变当前页
changeCurrentPage(current);
// 分页查找数据
getJupyterTpiDataSet(jupyter_identifier);
}
return ( return (
<div className="jupyter_area"> <div className="jupyter_area">
<div className="jupyter_header"> <div className="jupyter_header">
@ -152,7 +165,12 @@ function JupyterTPI (props) {
<div className="jupyter_ctx"> <div className="jupyter_ctx">
<SplitPane split="vertical" minSize={350} maxSize={-350} defaultSize="30%"> <SplitPane split="vertical" minSize={350} maxSize={-350} defaultSize="30%">
<div className={'split-pane-left'}> <div className={'split-pane-left'}>
<LeftPane dataSets={dataSets} /> <LeftPane
dataSets={dataSets}
total={total}
pagination={pagination}
onPageChange={handlePageChange}
/>
</div> </div>
<SplitPane split="vertical" defaultSize="100%" allowResize={false}> <SplitPane split="vertical" defaultSize="100%" allowResize={false}>
<RightPane <RightPane
@ -176,7 +194,10 @@ const mapStateToProps = (state) => {
jupyter_info, jupyter_info,
jupyter_tpi_url, jupyter_tpi_url,
jupyter_data_set, jupyter_data_set,
jupyter_tpi_url_state jupyter_tpi_url_state,
jupyter_data_set_count,
jupyter_pagination,
jupyter_identifier
} = state.jupyterReducer; } = state.jupyterReducer;
const { loading } = state.commonReducer; const { loading } = state.commonReducer;
return { return {
@ -184,7 +205,10 @@ const mapStateToProps = (state) => {
jupyter_info, jupyter_info,
url: jupyter_tpi_url, url: jupyter_tpi_url,
dataSets: jupyter_data_set, dataSets: jupyter_data_set,
jupyter_tpi_url_state jupyter_tpi_url_state,
total: jupyter_data_set_count,
pagination: jupyter_pagination,
jupyter_identifier
}; };
} }
@ -193,10 +217,11 @@ const mapDispatchToProps = (dispatch) => ({
getJupyterInfo: (identifier) => dispatch(actions.getJupyterInfo(identifier)), getJupyterInfo: (identifier) => dispatch(actions.getJupyterInfo(identifier)),
// 重置代码 // 重置代码
syncJupyterCode: (identifier, msg) => dispatch(actions.syncJupyterCode(identifier, msg)), syncJupyterCode: (identifier, msg) => dispatch(actions.syncJupyterCode(identifier, msg)),
// getJupyterTpiDataSet: (identifier) => dispatch(actions.getJupyterTpiDataSet(identifier)), getJupyterTpiDataSet: (identifier, current) => dispatch(actions.getJupyterTpiDataSet(identifier, current)),
getJupyterTpiUrl: (identifier) => dispatch(actions.getJupyterTpiUrl(identifier)), getJupyterTpiUrl: (identifier) => dispatch(actions.getJupyterTpiUrl(identifier)),
saveJupyterTpi: () => dispatch(actions.saveJupyterTpi()), saveJupyterTpi: () => dispatch(actions.saveJupyterTpi()),
changeLoadingState: (flag) => dispatch(actions.changeLoadingState(flag)) changeLoadingState: (flag) => dispatch(actions.changeLoadingState(flag)),
changeCurrentPage: (current) => dispatch(actions.changeCurrentPage(current))
}); });
export default connect( export default connect(

@ -78,9 +78,13 @@
right: 10px; right: 10px;
top: 14px; top: 14px;
.btn_common{
color: #888;
}
.btn_common:hover{ .btn_common:hover{
// background-color: #29BD8B; // background-color: #29BD8B;
color: #29BD8B; // color: #29BD8B;
color: #1890ff;
} }
} }
} }

@ -4,17 +4,22 @@
* @Github: * @Github:
* @Date: 2019-12-12 10:34:03 * @Date: 2019-12-12 10:34:03
* @LastEditors: tangjiang * @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 20:18:46 * @LastEditTime: 2019-12-13 15:31:35
*/ */
import './index.scss'; import './index.scss';
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import {Icon, Empty} from 'antd'; import {Icon, Empty, Pagination, Tooltip } from 'antd';
import MyIcon from '../../../../common/components/MyIcon'; import MyIcon from '../../../../common/components/MyIcon';
function LeftPane (props) { function LeftPane (props) {
// 获取数据集 // 获取数据集
const { dataSets = [] } = props; const {
dataSets = [],
total,
pagination,
onPageChange
} = props;
const emptyCtx = ( const emptyCtx = (
<div className="jupyter_empty"> <div className="jupyter_empty">
@ -31,8 +36,10 @@ function LeftPane (props) {
const oList = dataSets.map((item, i) => { const oList = dataSets.map((item, i) => {
return ( return (
<li className="jupyter_item" key={`key_${i}`}> <li className="jupyter_item" key={`key_${i}`}>
<Tooltip placement="right" title={'文字提示信息'}>
<Icon type="file-text" className="jupyter_icon"/> <Icon type="file-text" className="jupyter_icon"/>
<span className="jupyter_name">{item.title}</span> <span className="jupyter_name">{item.title}</span>
</Tooltip>
</li> </li>
); );
}); });
@ -46,37 +53,30 @@ function LeftPane (props) {
setRenderCtx(oUl); setRenderCtx(oUl);
} }
}, [props]); }, [props]);
// 渲染数据集
// const renderList = () => {
// // 空数据
// if (dataSets.length === 0) {
// return <div className="jupyter_empty">
// <Empty />
// </div>
// } else {
// // 渲染列表
// const oList = dataSets.map((item, i) => {
// return (
// <li className="jupyter_item" key={`key_${i}`}>
// <Icon type="file-text" className="jupyter_icon"/>
// <span className="jupyter_name">{item.title}</span>
// </li>
// );
// });
// return (
// <ul className="jupyter_data_list">
// { oList }
// </ul>
// );
// }
// }
// 分页处理
const handleChangePage = (page) => {
// console.log(page, pageSize);
// setCurrent(page);
onPageChange && onPageChange(page);
}
return ( return (
<div className="jupyter_data_sets_area"> <div className="jupyter_data_sets_area">
<h2 className="jupyter_h2_title"> <h2 className="jupyter_h2_title">
<MyIcon type="iconwenti" className="jupyter_data_icon"/> 数据集 <MyIcon type="iconwenti" className="jupyter_data_icon"/> 数据集
{/* <span className="iconfont icon-java jupyter_data_icon"></span>数据集 */}
</h2> </h2>
{ renderCtx } { renderCtx }
<div className='jupyter_pagination'>
<Pagination
simple
current={pagination.page}
pageSize={pagination.limit}
total={total}
onChange={handleChangePage}
/>
</div>
</div> </div>
) )
} }

@ -1,22 +1,30 @@
.jupyter_data_sets_area{ .jupyter_data_sets_area{
height: 100%; height: 100%;
background: #fff;
.jupyter_h2_title{ .jupyter_h2_title{
height: 50px; height: 44px;
line-height: 50px; line-height: 44px;
background-color: #EEEEEE; // background-color: #EEEEEE;
background: #fff;
padding: 0 30px; padding: 0 30px;
font-size: 16px;
// box-size: border-box;
box-sizing: border-box;
border-bottom: 1px solid rgba(238,238,238,1);
.jupyter_data_icon{ .jupyter_data_icon{
color: #7286ff; // color: #7286ff;
color: #1890ff;
font-size: 24px; font-size: 24px;
position: relative; position: relative;
top: 2px; top: 2px;
transform: scale(1.5); transform: scale(1.5);
margin-right: 5px;
} }
} }
.jupyter_data_list, .jupyter_data_list,
.jupyter_empty{ .jupyter_empty{
height: calc(100vh - 110px); height: calc(100vh - 160px);
overflow-y: auto; overflow-y: auto;
} }
@ -52,4 +60,13 @@
justify-content: center; justify-content: center;
width: 100%; width: 100%;
} }
.jupyter_pagination{
display: flex;
justify-content: center;
align-items: center;
height: 56px;
box-sizing: border-box;
border-top: 1px solid rgba(238,238,238,1);
}
} }

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2019-12-12 15:04:20 * @Date: 2019-12-12 15:04:20
* @LastEditors: tangjiang * @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 17:41:41 * @LastEditTime: 2019-12-13 11:25:22
*/ */
import './index.scss'; import './index.scss';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
@ -32,8 +32,9 @@ function RightPane (props) {
const loadError = ( const loadError = (
<div className="jupyter_load_url_error"> <div className="jupyter_load_url_error">
<span className="iconfont icon-jiazaishibai1 icon-error"></span>
<p className="jupyter_error_txt"> <p className="jupyter_error_txt">
加载实训出错是否 实训加载失败
<span <span
className="jupyter_reload" className="jupyter_reload"
onClick={handleClickReload} onClick={handleClickReload}

@ -28,17 +28,29 @@
} }
.jupyter_load_url_error{ .jupyter_load_url_error{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
// &::before{ // &::before{
// background-color: rgba(0,0,0,.2); // background-color: rgba(0,0,0,.2);
// } // }
.jupyter_error_txt{ .jupyter_error_txt{
position: relative; position: relative;
z-index: 1; z-index: 1;
font-size: 12px;
.jupyter_reload{ .jupyter_reload{
cursor: pointer; cursor: pointer;
color: #1890ff; color: #1890ff;
} }
} }
.icon-error{
position: relative;
color: #DCE0E6;
transform: scale(5);
top: -35px;
}
} }
.jupyter_result{ .jupyter_result{

@ -32,6 +32,7 @@ class Newshixuns extends Component {
run_method: undefined, run_method: undefined,
postapplyvisible: undefined, postapplyvisible: undefined,
fileList: [], fileList: [],
Radiovalue:"1"
} }
} }
@ -85,6 +86,9 @@ class Newshixuns extends Component {
this.setState({ this.setState({
Radiovalue: e.target.value, Radiovalue: e.target.value,
}); });
this.props.form.setFieldsValue({
is_jupyter: e.target.value,
});
}; };
handleSubmit = (e) => { handleSubmit = (e) => {
@ -535,7 +539,9 @@ class Newshixuns extends Component {
defaultOpen={false} defaultOpen={false}
> >
{ {
newshixunlist === undefined ? "" : newshixunlist.main_type.map((item, key) => { newshixunlist === undefined ? "" : this.state.Radiovalue==="2"?newshixunlist.main_type.map((item, key) => {
let itemtype=item.type_name.toLowerCase().indexOf('jupyter'.toLowerCase())
if(itemtype>-1){
return ( return (
<Option value={item.id} key={key} name={item.description}> <Option value={item.id} key={key} name={item.description}>
<Tooltip placement="right" <Tooltip placement="right"
@ -544,7 +550,25 @@ class Newshixuns extends Component {
</Tooltip> </Tooltip>
</Option> </Option>
) )
}) }
}):""
}
{
newshixunlist === undefined ? "" : this.state.Radiovalue==="1"?newshixunlist.main_type.map((item, key) => {
let itemtype=item.type_name.toLowerCase().indexOf('jupyter'.toLowerCase())
if(itemtype===-1){
return (
<Option value={item.id} key={key} name={item.description}>
<Tooltip placement="right"
title={item.description === "" ? "无描述" : item.description}>
{item.type_name}
</Tooltip>
</Option>
)
}
}):""
} }
</Select> </Select>

@ -212,9 +212,9 @@ class Challengesjupyter extends Component {
booljupyterurls===true? booljupyterurls===true?
( (
this.state.jupyter_url === null? this.state.jupyter_url === null?
<div className="mt50"> <div className="mt50 intermediatecenter juplbool">
<span className="icon iconfontysl icon-jiazaishibai1"></span>
<p className="intermediatecenter sortinxdirection"><p className="colorbluetest">加载实训出错是否</p><p className="colorbluetwo" onClick={()=>this.updatamakedowns()}></p></p> <p className="intermediatecenter sortinxdirection mt5 juplboolp"><p className="colorbluetest">加载实训出错是否</p><p className="colorbluetwo" onClick={()=>this.updatamakedowns()}></p></p>
</div> </div>
@ -244,6 +244,8 @@ class Challengesjupyter extends Component {
display: flex; display: flex;
flex-direction:row-reverse; flex-direction:row-reverse;
} }
;
}
` `
} }
</style> </style>
@ -256,7 +258,7 @@ class Challengesjupyter extends Component {
<div className="sortinxdirection mt60"> <div className="sortinxdirection mt60">
<div className="renwuxiangssi sortinxdirection"> <div className="renwuxiangssi sortinxdirection">
<div><p className="renwuxiangqdiv">任务详情</p></div> <div><p className="renwuxiangqdiv">任务详情</p></div>
<div><p className="renwuxiangqdivtest ml24">请将实训题目写在下方</p></div> <div><p className="renwuxiangqdivtest ml1 shixunbingbaocun">请将实训题目写在下方并保存</p></div>
</div> </div>
<div className="renwuxiangssit xaxisreverseorder"> <div className="renwuxiangssit xaxisreverseorder">
<div className="challenbaocun" onClick={() => this.modifyjupyter(this.state)}><p <div className="challenbaocun" onClick={() => this.modifyjupyter(this.state)}><p

@ -69,9 +69,37 @@
color: #1E8FFD; color: #1E8FFD;
font-size: 12px; font-size: 12px;
cursor:pointer; cursor:pointer;
margin-right: 18px;
} }
.colorbluetest{ .colorbluetest{
color: #06101A; color: #06101A;
font-size: 12px; font-size: 12px;
cursor:default cursor:default
} }
.shixunbingbaocun{
font-size:14px;
color:#888888;
}
.intermediatecenter{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.iconfontysl{
vertical-align:middle;
font-family:"iconfont" !important;
font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
font-size: 100px;
color: #F5F5F5;
}
.juplbool{
position: relative;
}
.juplboolp{
position: absolute;
bottom: 21px;
}

@ -112,3 +112,11 @@ a:active{text-decoration:none;}
.width360{ .width360{
width:360px; width:360px;
} }
.bannerpd201{
padding: 20px 20px 10px 20px;
}
.FF6802{
color:#FF6802;
}

@ -57,6 +57,7 @@ const types = {
SAVE_JUPYTER_INFO: 'SAVE_JUPYTER_INFO', // 保存 jupyter 信息 SAVE_JUPYTER_INFO: 'SAVE_JUPYTER_INFO', // 保存 jupyter 信息
CHANGE_JUPYTER_URL_STATE: 'CHANGE_JUPYTER_URL_STATE', // 获取url返回的状态值 CHANGE_JUPYTER_URL_STATE: 'CHANGE_JUPYTER_URL_STATE', // 获取url返回的状态值
SAVE_JUPYTER_TPI: 'SAVE_JUPYTER_TPI', // 保存 jupyter tpi SAVE_JUPYTER_TPI: 'SAVE_JUPYTER_TPI', // 保存 jupyter tpi
CHANGE_JUPYTER_CURRENT_PAGE: 'CHANGE_JUPYTER_CURRENT_PAGE'
} }
export default types; export default types;

@ -68,7 +68,8 @@ import {
getJupyterInfo, getJupyterInfo,
syncJupyterCode, syncJupyterCode,
changeGetJupyterUrlState, changeGetJupyterUrlState,
saveJupyterTpi saveJupyterTpi,
changeCurrentPage
} from './jupyter'; } from './jupyter';
export default { export default {
@ -119,6 +120,7 @@ export default {
getJupyterInfo, getJupyterInfo,
syncJupyterCode, syncJupyterCode,
changeGetJupyterUrlState, changeGetJupyterUrlState,
saveJupyterTpi saveJupyterTpi,
changeCurrentPage
// isUpdateCodeCtx // isUpdateCodeCtx
} }

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2019-12-12 09:01:30 * @Date: 2019-12-12 09:01:30
* @LastEditors: tangjiang * @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 17:58:38 * @LastEditTime: 2019-12-13 15:27:13
*/ */
import types from "./actionTypes"; import types from "./actionTypes";
import { message } from 'antd'; import { message } from 'antd';
@ -18,20 +18,22 @@ import {
// 获取 jupyter 相关信息 // 获取 jupyter 相关信息
export const getJupyterInfo = (id) => { export const getJupyterInfo = (id) => {
return (dispatch) => { return (dispatch, getState) => {
const { jupyter_pagination } = getState().jupyterReducer;
console.log(jupyter_pagination);
fetchJupyterInfo(id).then(res => { fetchJupyterInfo(id).then(res => {
if (res.data.status === 401) return; if (res.data.status === 401) return;
if (res.status === 200) { if (res.status === 200) {
const { data } = res; const { data } = res;
console.log(data);
if (data.status === 0) { if (data.status === 0) {
dispatch({ dispatch({
type: types.SAVE_JUPYTER_INFO, type: types.SAVE_JUPYTER_INFO,
payload: data payload: data
}); });
const { identifier, myshixun_identifier } = data; const { identifier, myshixun_identifier } = data;
dispatch(saveJupyterIdentifier(identifier));
// 调用获取数据集接口 // 调用获取数据集接口
dispatch(getJupyterTpiDataSet(identifier)); dispatch(getJupyterTpiDataSet(identifier, jupyter_pagination));
// 调用获取url接口 // 调用获取url接口
dispatch(getJupyterTpiUrl({identifier: myshixun_identifier})); dispatch(getJupyterTpiUrl({identifier: myshixun_identifier}));
} }
@ -40,16 +42,21 @@ export const getJupyterInfo = (id) => {
} }
} }
// 获取 jupyter tpi 数据集 // 获取 jupyter tpi 数据集
export const getJupyterTpiDataSet = (identifier) => { export const getJupyterTpiDataSet = (identifier, params) => {
return (dispatch) => { return (dispatch, getState) => {
fetchJupyterTpiDataSet(identifier).then(res => { if (!params) {
params = getState().jupyterReducer.jupyter_pagination;
}
fetchJupyterTpiDataSet(identifier, params).then(res => {
if (res.data.status === 401) return; // 用户未登录 if (res.data.status === 401) return; // 用户未登录
console.log('数据集:', res);
if (res.status === 200) { if (res.status === 200) {
const {data_sets} = res.data; const {data_sets, data_sets_count} = res.data;
dispatch({ dispatch({
type: types.GET_JUPYTER_DATA_SETS, type: types.GET_JUPYTER_DATA_SETS,
payload: data_sets payload: {
data_sets,
data_sets_count
}
}); });
} }
}); });
@ -59,7 +66,6 @@ export const getJupyterTpiDataSet = (identifier) => {
export const getJupyterTpiUrl = (obj) => { export const getJupyterTpiUrl = (obj) => {
return (dispatch, getState) => { return (dispatch, getState) => {
const {jupyter_info} = getState().jupyterReducer; const {jupyter_info} = getState().jupyterReducer;
console.log(obj.identifier, jupyter_info.myshixun_identifier);
if (!obj.identifier && !jupyter_info.myshixun_identifier) return; if (!obj.identifier && !jupyter_info.myshixun_identifier) return;
const id = obj.identifier || jupyter_info.myshixun_identifier; const id = obj.identifier || jupyter_info.myshixun_identifier;
fetchJupyterTpiUrl({identifier: id}).then(res => { fetchJupyterTpiUrl({identifier: id}).then(res => {
@ -137,3 +143,10 @@ export const saveJupyterTpi = () => {
}); });
} }
} }
// 改变当前页数
export const changeCurrentPage = (current) => {
return {
type: types.CHANGE_JUPYTER_CURRENT_PAGE,
payload: current
}
}

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2019-12-12 09:01:39 * @Date: 2019-12-12 09:01:39
* @LastEditors: tangjiang * @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 17:23:54 * @LastEditTime: 2019-12-13 15:28:45
*/ */
import types from "../actions/actionTypes"; import types from "../actions/actionTypes";
@ -14,15 +14,22 @@ const initState = {
jupyter_data_set: [], jupyter_data_set: [],
jupyter_identifier: '', jupyter_identifier: '',
jupyter_tpi_url_state: -1, // 获取 url 状态值: 0 成功, 其它 失败 jupyter_tpi_url_state: -1, // 获取 url 状态值: 0 成功, 其它 失败
jupyter_tpi_code: '' // 端口号 jupyter_tpi_code: '', // 端口号
jupyter_data_set_count: 1, // 数据集总数
jupyter_pagination: {
page: 1,
limit: 20 // 默认加载20条
}
}; };
const JupyterReducer = (state = initState, action) => { const JupyterReducer = (state = initState, action) => {
switch (action.type) { switch (action.type) {
case types.GET_JUPYTER_DATA_SETS: case types.GET_JUPYTER_DATA_SETS:
const { data_sets, data_sets_count } = action.payload;
return { return {
...state, ...state,
jupyter_data_set: action.payload jupyter_data_set: data_sets,
jupyter_data_set_count: data_sets_count
} }
case types.GET_JUPYTER_TPI_URL: case types.GET_JUPYTER_TPI_URL:
const {url, status, port} = action.payload; const {url, status, port} = action.payload;
@ -33,6 +40,7 @@ const JupyterReducer = (state = initState, action) => {
jupyter_tpi_code: port jupyter_tpi_code: port
} }
case types.SAVE_JUPYTER_IDENTIFIER: case types.SAVE_JUPYTER_IDENTIFIER:
console.log('保存的jupyter_identifier', action.payload);
return { return {
...state, ...state,
jupyter_identifier: action.payload jupyter_identifier: action.payload
@ -47,6 +55,11 @@ const JupyterReducer = (state = initState, action) => {
...state, ...state,
jupyter_tpi_url_state: action.payload jupyter_tpi_url_state: action.payload
} }
case types.CHANGE_JUPYTER_CURRENT_PAGE:
return {
...state,
jupyter_pagination: Object.assign({}, state.jupyter_pagination, { page: action.payload })
}
default: default:
return { return {
...state ...state

@ -4,7 +4,7 @@
* @Github: * @Github:
* @Date: 2019-12-12 09:07:07 * @Date: 2019-12-12 09:07:07
* @LastEditors: tangjiang * @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 17:46:17 * @LastEditTime: 2019-12-13 14:30:51
*/ */
import axios from 'axios'; import axios from 'axios';
@ -14,9 +14,9 @@ export async function fetchJupyterInfo (identifier) {
return axios.get(url); return axios.get(url);
} }
// 获取数据集 // 获取数据集
export async function fetchJupyterTpiDataSet (identifier) { export async function fetchJupyterTpiDataSet (identifier, params) {
const url = `/shixuns/${identifier}/jupyter_data_sets.json`; const url = `/shixuns/${identifier}/jupyter_data_sets.json`;
return axios.get(url); return axios.get(url, { params });
} }
// 获取 tpi url // 获取 tpi url
export async function fetchJupyterTpiUrl (params) { export async function fetchJupyterTpiUrl (params) {

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save