删除多余

dev_daiao
杨树明 5 years ago
parent 3abf3f7975
commit a4a1a75ecf

@ -1,83 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import Comments from '../comment/Comments'
import { commentHOC } from '../comment/CommentsHOC'
import { CircularProgress } from 'material-ui/Progress';
import './TPMShixunDiscuss.css'
import TPMRightSection from './component/TPMRightSection'
import TPMNav from './component/TPMNav'
class TPMShixunDiscuss extends Component {
constructor(props) {
super(props)
}
componentWillReceiveProps(newProps, newContext) {
if (newProps.shixun && newProps.shixun.id && (!this.props || !this.props.shixun || this.props.shixun.id != newProps.shixun.id) ) {
window.document.title = newProps.shixun.name
// this.props.fetchCommentIfNotFetched &&
// this.props.fetchCommentIfNotFetched();
}
}
componentDidMount() {
// TODO 加了HOC后 mount了两次
this.props.fetchCommentIfNotFetched &&
this.props.fetchCommentIfNotFetched();
}
//
onPaginationChange = (page) => {
window.$("html,body").animate({"scrollTop":160})
this.props.onPaginationChange(page)
}
render() {
const { loadingComments, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
aboutFocus, user, match
} = this.props;
let _user = user;
if (user) {
_user = Object.assign({}, user);
_user.user_url = `/users/${user.login}`
}
return (
<React.Fragment>
<div className="tpmComment educontent clearfix mt30 mb80">
<div className="with65 fl edu-back-white commentsDelegateParent" >
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.props}
></TPMNav>
{ loadingComments ?
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
<Comments
{...this.props}
user={_user}
onPaginationChange={this.onPaginationChange}
></Comments>
}
</div>
<div className="with35 fr pl20">
<TPMRightSection {...this.props}></TPMRightSection>
</div>
</div>
</React.Fragment>
);
}
}
export default commentHOC( TPMShixunDiscuss );

@ -1,260 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { List,Typography,Tag,Modal,Radio} from 'antd';
import TPMRightSection from './component/TPMRightSection';
import TPMNav from './component/TPMNav';
import axios from 'axios';
class Audit_situationComponent extends Component {
constructor(props) {
super(props)
this.state = {
datas:undefined,
value:undefined,
}
}
componentDidMount() {
this.getdatas()
}
getdatas=()=>{
let url=`/shixuns/${this.props.match.params.shixunId}/review_newest_record.json`;
axios.get(url).then((response) => {
if(response.data===undefined||JSON.stringify(response.data) == "{}"||response.data===null){
this.setState({
datas:[
{
name: '内容审核情况',
id:"Content",
},
{
name: '性能审核情况',
id:"Performance",
},
]
})
}else{
let newlist=[]
if(response.data.content_info!=undefined&&response.data.perference_info===undefined){
let arr=[
{
name: '内容审核情况',
id:"Content",
status:response.data.content_info.status,
username:response.data.content_info.username,
time:response.data.content_info.time,
},
{
name: '性能审核情况',
id:"Performance",
},
]
newlist=arr
}
if(response.data.content_info===undefined&&response.data.perference_info!=undefined){
let arr=[
{
name: '内容审核情况',
id:"Content",
},
{
name: '性能审核情况',
id:"Performance",
status:response.data.perference_info.status,
username:response.data.perference_info.username,
time:response.data.perference_info.time,
},
]
newlist=arr
}
if(response.data.content_info!=undefined&&response.data.perference_info!=undefined){
let arr=[
{
name: '内容审核情况',
id:"Content",
status:response.data.content_info.status,
username:response.data.content_info.username,
time:response.data.content_info.time,
},
{
name: '性能审核情况',
id:"Performance",
status:response.data.perference_info.status,
username:response.data.perference_info.username,
time:response.data.perference_info.time,
},
]
newlist=arr
}
this.setState({
datas:newlist
})
}
}).catch((error) => {
console.log(error)
});
}
showModal = (id,status) => {
debugger
this.setState({
visible: true,
editid:id,
value:status
});
};
handleOk=(id,editid)=>{
let url = `/shixuns/${this.props.match.params.shixunId}/review_shixun.json`;
axios.post(url, {
status: id===undefined?1:id,
review_type: editid,
}).then((response) => {
if(response.data.status===0){
this.props.showNotification(response.data.message);
this.setState({
visible: false,
});
this.getdatas()
}
}).catch((error) => {
console.log(error)
});
};
handleCancel = e => {
this.setState({
visible: false,
});
};
onChange = e => {
this.setState({
value: e.target.value,
});
};
render() {
const { tpmLoading, shixun, user, match } = this.props;
let {value,editid,datas}=this.state;
console.log(this.props)
return (
<React.Fragment>
{this.state.visible===true?<Modal
title="审核情况更改"
visible={this.state.visible}
keyboard={false}
closable={false}
footer={null}
destroyOnClose={true}
centered={true}
>
<div>
<style>
{
`
body{
width: 100% !important;
}
.ant-modal-body{
text-align: center;
}
`
}
</style>
<Radio.Group onChange={this.onChange} value={this.state.value===undefined?1:this.state.value}>
<Radio value={1}>已完成</Radio>
<Radio value={0}>未完成</Radio>
</Radio.Group>
<div className={"mt30"}>
<a className="pop_close task-btn mr20 margin-tp26" onClick={()=>this.handleCancel()}>取消</a>
<a className="task-btn task-btn-orange margin-tp26" onClick={()=>this.handleOk(value,editid)}>确定</a>
</div>
</div>
</Modal>:""}
<style>
{
`
.Itemtitle{
float: left;
padding-top: 2px;
margin-right: 10px;
}
`
}
</style>
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
<div className="tpmComment educontent clearfix mt30 mb80">
<div className="with65 fl edu-back-white commentsDelegateParent" >
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.props}
></TPMNav>
<div className="padding20 edu-back-white mt20" style={{minHeight: '640px'}}>
{this.props.identity >2||this.props.identity===undefined?"":<List
dataSource={datas}
bordered
renderItem={(item,key) => (
<List.Item
key={item.id}
actions={[
<a onClick={()=>this.showModal(item.id,item.status)} key={key}>
<i className="iconfont icon-bianjidaibeijing font-22 color-green"></i>
</a>,
]}
>
<List.Item.Meta
title={<div className={"font-16"}>
<div className={"Itemtitle"}>{item.name}</div>
{item.status===undefined?"":item.status===1?<Tag color="#FF6800">已完成</Tag>:<Tag color="#bcbcbc"></Tag>}
</div>}
description={
<div>
{item.time===undefined?"":<span>审核时间: {item.time}</span>}
{item.username===undefined?"":<span className={"ml30"}>审核人: {item.username}</span>}
</div>
}
/>
</List.Item>
)}
/>}
</div>
</div>
<div className="with35 fr pl20">
<TPMRightSection {...this.props}></TPMRightSection>
</div>
</div>
}
</React.Fragment>
);
}
}
export default Audit_situationComponent;

@ -1,67 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { Link } from 'react-router-dom';
import { getImageUrl, toPath } from 'educoder'
import PropTypes from 'prop-types';
class NewFooter extends Component {
constructor(props) {
super(props)
}
componentWillReceiveProps(newProps, newContext) {
}
render() {
return (
<div className="newFooter edu-txt-center ">
{/*newContainers*/}
<div className="inner-footer_con">
{this.props.user&&this.props.user.main_site===true?<div className="footercon">
{/* <div className="inline mt40 mb5">
<a href="/" className="fl" style={{height:'70px'}}>
<img alt="高校智能化教学与实训平台" src={getImageUrl(`images/educoder/headNavLogo.png?1526520218`)} width="70px">
</img>
</a>
<span className="fl color-grey-c cdefault font-28 ml22" style={{lineHeight:'74px'}}>EduCoder.net</span>
</div> */}
<ul className="clearfix inner-footernav">
<li><a href="/" className="fl" target="_blank">网站首页</a></li>
<li><Link to="/help/about_us" className="fl" target="_blank">关于我们</Link></li>
<li><Link to="/help/contact_us" className="fl" target="_blank">联系我们</Link></li>
<li><Link to="/help/cooperatives" className="fl" target="_blank">合作伙伴</Link></li>
<li><Link to="/help/agreement" className="fl" target="_blank">服务协议</Link></li>
<li><Link to="/help/help_center" className="fl" target="_blank">帮助中心</Link></li>
<li><Link to="/help/feedback" className="fl" target="_blank">意见反馈</Link></li>
</ul>
</div>:""}
<div>
{this.props.mygetHelmetapi === null ? "" :
this.props.mygetHelmetapi===undefined|| this.props.mygetHelmetapi.footer===null||this.props.mygetHelmetapi.footer===undefined?
<p className="footer_con-p inline lineh-30 font-14">
<span className="font-18 fl">©</span>&nbsp;2019&nbsp;EduCoder
<a style={{"color":"#888"}} target="_blank" href="http://beian.miit.gov.cn/" className="ml15 mr15">湘ICP备17009477号</a>
<a style={{"color":"#888"}} target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=43019002000962" className="mr15">
<img className="vertical4" src={require('./beian.png')}/>湘公网安备43019002000962号
</a>
<a href="https://team.trustie.net" style={{"color":"#888"}}
target="_blank">Trustie</a>&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;IntelliDE inside. <span
className="mr15">版权所有 湖南智擎科技有限公司</span>
</p>
:
<div dangerouslySetInnerHTML={{__html: this.props.mygetHelmetapi.footer}}></div>
}
</div>
<div className="cl"></div>
</div>
</div>
);
}
}
export default NewFooter;

File diff suppressed because it is too large Load Diff

@ -1,143 +0,0 @@
import React, { Component } from 'react';
import { getImageUrl} from 'educoder';
import './TPMIndex.css';
const $ = window.$;
$(window).resize(function(){
rightSlider();
});
$(window).scroll(function(){
if($(".gotop").length>0){
if($(document).scrollTop()>0){
$(".-task-sidebar .gotop").show();
$(".gotop").click(function(){
$("html,body").scrollTop(0);
});
}
if($(document).scrollTop()==0){
$(".-task-sidebar .gotop").hide();
}
}
});
function rightSlider(){
var poi=parseInt((parseInt($(window).width())- 1200 )/2)-81;
// console.log(parseInt($(window).width())+" "+poi);
if(poi>0){
$(".-task-sidebar").css("right",poi);
}else{
$(".-task-sidebar").css("right","0px");
}
$(".-task-sidebar").show();
}
function _initSider() {
var $descSide = $("<div class='-task-desc'></div>").appendTo("body");
$(".-task-sidebar>div").hover(function(){
//移入显示二维码
if($(this).hasClass("scan")){
$(".scan_ewm").show().css({right:"75px",opacity:0}).stop().animate({
right:"45px",opacity:1
})
return;
}
var $tool = $(this).attr("tooltips");
$descSide.html($tool+"<div><img src='/images/edu_user/jt.png'></div>");
$descSide.data('_dom', this)
$descSide.show().css({
left:$(this).offset().left - $descSide.width()-30,
opacity:0,
top:$(this).offset().top
}).stop().animate({
left:$(this).offset().left - $descSide.width()-5,
opacity:1
},400);
},function(){
if($(this).hasClass("scan")){
$(".scan_ewm").stop().animate({right:"75px",opacity:0},200).hide();
}
$descSide.stop().animate({
left:$(this).offset().left - $descSide.width()-30,
opacity:0
},200).hide();
});
rightSlider();
$(window).scroll(function() {
if ($descSide.height()) {
var hoverIcon = $descSide.data('_dom')
$descSide.css('top', $(hoverIcon).offset().top)
}
})
}
class SiderBar extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
_initSider();
}
render() {
// console.log(this.props)
return (
<div className="-task-sidebar" >
{this.props.mygetHelmetapi&&this.props.mygetHelmetapi.main_site===true?<div>
<div className="gotop" tooltips="返回顶部">
<a>
<i className="iconfont icon-shangjiantou color-white"></i>
</a>
</div>
<div className="feedback" tooltips="意见反馈">
<a target="_blank" className="color_white" href="/help?index=6">
<i className="iconfont icon-yijianfankui color-white font-22"></i>
</a>
</div>
<div className="scan pr">
<span className="inline"><i className="iconfont icon-erweima color-white font-22 fl"></i></span>
<p className="scan_ewm" style={{display: 'none', right:' 75px',opacity: '0'}}>
<p className="pr padding10">
<style>
{
`
.WeChatstyle{
margin-bottom: 0 !important;
}
`
}
</style>
<img src={getImageUrl("images/educoder/EWM.jpg")} width="158px" height="158px" />
<p className={"WeChatstyle"}>微信扫一扫</p>
<p className={"WeChatstyle"}>关注公众号</p>
<span className="trangle_right"></span>
</p>
</p>
</div>
<div className="consult" tooltips="在线咨询">
<a target="_blank" className="color_white" href="//shang.qq.com/wpa/qunwpa?idkey=2f2043d88c1bd61d182b98bf1e061c6185e23055bec832c07d8148fe11c5a6cd">
<i className="iconfont icon-qqzaixianzixun color-white font-22"></i>
</a>
</div>
</div>:""}
</div>
);
}
}
export default SiderBar;

File diff suppressed because it is too large Load Diff

@ -1,54 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import { CircularProgress } from 'material-ui/Progress';
import './TPMShixunDiscuss.css'
import Challenges from './shixunchild/Challenges/Challenges'
import TPMRightSection from './component/TPMRightSection'
import TPMNav from './component/TPMNav'
class TPMChallenge extends Component {
constructor(props) {
super(props)
}
render() {
const { loadingContent, shixun, user, match
} = this.props;
return (
<React.Fragment>
<div className="educontent clearfix mt30 mb80">
<div className="with65 fl edu-back-white" >
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.props}
></TPMNav>
<Challenges
{...this.props}
/>
</div>
<div className="with35 fr pl20">
<TPMRightSection
{...this.props}
/>
</div>
</div>
</React.Fragment>
);
}
}
export default TPMChallenge;

@ -1,34 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import TPMChallenge from './TPMChallenge';
class TPMChallengeContainer extends Component {
constructor(props) {
super(props)
this.state = {
tpmLoading: true,
creator: {
owner_id: '',
}
}
}
render() {
const { tpmLoading } = this.props;
const user = this.props.current_user;
return (
<React.Fragment>
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
<TPMChallenge
{...this.props}
>
</TPMChallenge>
}
</React.Fragment>
);
}
}
export default TPMChallengeContainer;

@ -1,53 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import { CircularProgress } from 'material-ui/Progress';
import './TPMShixunDiscuss.css'
import Collaborators from './shixunchild/Collaborators/Collaborators'
import TPMRightSection from './component/TPMRightSection'
import TPMNav from './component/TPMNav'
class TPMCollaborators extends Component {
constructor(props) {
super(props)
}
render() {
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
aboutFocus, user, match
} = this.props;
return (
<React.Fragment>
<div className="educontent clearfix mt30 mb80">
<div className="with65 fl edu-back-white" >
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.props}
></TPMNav>
<Collaborators
{...this.props}
/>
</div>
<div className="with35 fr pl20">
<TPMRightSection
{...this.props}
/>
</div>
</div>
</React.Fragment>
);
}
}
export default TPMCollaborators;

@ -1,47 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import TPMCollaborators from './TPMCollaborators'
import axios from 'axios';
class TPMChallengeContainer extends Component {
constructor(props) {
super(props)
this.state = {
}
}
componentWillReceiveProps(newProps, newContext) {
}
componentDidMount() {
// this.props.showShixun();
}
render() {
const { tpmLoading } = this.props;
const user = this.props.current_user;
return (
<React.Fragment>
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
<TPMCollaborators
{...this.props}
{...this.state}
user={user}
aboutFocus={this.props.aboutFocus}
>
</TPMCollaborators>
}
</React.Fragment>
);
}
}
export default TPMChallengeContainer;

@ -1,213 +0,0 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal,Pagination,Tooltip,Spin} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css";
import { Rating } from "@icedesign/base";
import axios from 'axios';
import {getImageUrl, toPath, getUrl} from 'educoder'
import './shixunCss/fork.css';
let origin = getUrl();
let path = getUrl("/editormd/lib/")
const $ = window.$;
let timeout;
let currentValue;
export default class TPMFork_listComponent extends Component {
constructor(props) {
super(props)
this.state = {
shixuns:undefined,
total_count:0,
shixunsID:undefined,
Forkvisible: true,
Forkcurrent: 1
}
}
componentDidMount() {
let id = this.props.match.params.shixunId;
let Url="/shixuns/"+id+"/fork_list.json";
axios.get(Url, {
params: {
page:1,
limit:8
}
}).then((response)=> {
this.setState({
shixunsID:id,
shixuns:response.data.shixuns,
total_count:response.data.total_count,
Forkvisible:false
})
}).catch((error)=>{
console.log(error)
});
}
TPMForkonChange=(pageNumber)=>{
let id = this.props.match.params.shixunId;
this.setState({
Forkvisible:true
})
let Url="/shixuns/"+id+"/fork_list.json";
axios.get(Url, {
params: {
page:pageNumber,
limit:8
}
}).then((response)=> {
this.setState({
shixunsID:id,
shixuns:response.data.shixuns,
total_count:response.data.total_count,
Forkvisible: false,
Forkcurrent: pageNumber
})
}).catch((error)=>{
console.log(error)
});
}
render() {
let {shixuns, total_count, shixunsID, Forkvisible, Forkcurrent} = this.state;
const MyRate = ({ defaultValue, ...rest }) => {
let myValue = defaultValue;
// console.log(myValue-Math.floor(myValue))
// if (myValue < Math.ceil(myValue)) {
// myValue = Math.floor(myValue) + 0.5;
// }
return <Rating {...rest} value={myValue} />;
};
return (
<React.Fragment>
<div className="educontent mb20">
<div className="edu-back-white padding20 clearfix mt30">
<span className="fl font-16">Fork实训列表</span>
<a href={"/shixuns/"+shixunsID+"/challenges"} className="font-16 color-grey-9 fr">返回</a>
</div>
<style>
{
`
.taglistleft{
position: absolute;
left: 10px;
bottom: 118px;
}
`
}
</style>
{/*<Loading visible={Forkvisible} shape="dot-circle" style={{width:'100%'}}color='#4AC7FF'>*/}
<Spin spinning={Forkvisible} size="large" style={{marginTop:'15%'}}>
<div className="mt30 square-list clearfix mh320">
{ shixuns===undefined?" ":shixuns.map((item,key)=>{
return(
<div className="square-Item" key={key} id={item.id}>
<div className="tag-green taglistleft">
<span className="tag-name"> {item.tag_name}</span>
{/*<img src={require(`./shixunCss/tag2.png`)}/>*/}
</div>
<div className={item.power === false ? "closeSquare" : "none"}>
<img src={getImageUrl("images/educoder/icon/lockclose.svg")}
className="mt80 mb25"/>
<p className="font-14 color-white">非试用内容需要授权</p>
</div>
<a href={"/shixuns/"+item.identifier+"/challenges"} className="square-img" target="_blank">
<img src={'/'+item.pic}/>
</a>
<div className="square-main">
<p className="task-hide">
<a href={"/shixuns/"+item.identifier+"/challenges"} target="_blank" className="justify color-grey-name">
{item.name}
</a>
</p>
<p className="clearfix mt8 ml-3">
<span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
<MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/>
</span>
<span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span>
</p>
<p className="clearfix mt8 font-12 color-grey-B4">
<Tooltip placement="bottom" title={"关卡"}>
<span className="mr10 fl squareIconSpan">
<i className="iconfont icon-shixunguanqia fl mr3"></i>{item.challenges_count}
</span>
</Tooltip>
{/*<Tooltip placement="bottom" title={"经验值"}>*/}
{/*<span className="mr10 fl squareIconSpan">*/}
{/*<i className="iconfont icon-jingyan fl mr3"></i>{item.exp}*/}
{/*</span>*/}
{/*</Tooltip>*/}
<Tooltip placement="bottom" title={"学习人数"}>
<span className="mr10 fl squareIconSpan" style={{display:item.stu_num===0?"none":'block'}}>
<i className="iconfont icon-chengyuan fl mr3"></i>{item.stu_num}
</span>
</Tooltip>
<span className="fr color-grey-B3 squareIconSpan">{item.level}</span>
</p>
</div>
</div>
)
})
}
</div>
{/*<div>{total_count}</div>*/}
<div className="educontent mb80 edu-txt-center mt10" style={{display: total_count > 8 ? "block" : "none"}}>
{/*<div className={total_count < 9 ? " ml32" : "ml105"}>*/}
<Pagination
showQuickJumper
defaultCurrent={1}
pageSize={8}
total={total_count}
current={Forkcurrent}
style={
{
display: total_count < 9 ? 'none' : 'block'
}
}
onChange={this.TPMForkonChange}/>
</div>
</Spin>
{/*</Loading>*/}
</div>
</React.Fragment>
)
}
}

@ -1,3 +0,0 @@
.ml105 {
margin-left: 15%;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

@ -1,50 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import TPMForklist from './TPMForklist'
import axios from 'axios';
class TPMRanking_listContainer extends Component {
constructor(props) {
super(props)
this.state = {
tpmLoading: true,
creator: {
owner_id: ''
}
}
}
componentWillReceiveProps(newProps, newContext) {
}
componentDidMount() {
this.props.showShixun();
}
render() {
const { tpmLoading } = this.props;
const user = this.props.current_user;
return (
<React.Fragment>
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
<TPMForklist
{...this.props}
{...this.state}
user={user}
aboutFocus={this.props.aboutFocus}
>
</TPMForklist>
}
</React.Fragment>
);
}
}
export default TPMRanking_listContainer;

@ -1,63 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import { CircularProgress } from 'material-ui/Progress';
import './TPMShixunDiscuss.css'
import Shixunfork_list from './shixunchild/Shixunfork_list'
import TPMRightSection from './component/TPMRightSection'
import TPMNav from './component/TPMNav'
class TPMForklist extends Component {
constructor(props) {
super(props)
}
componentWillReceiveProps(newProps, newContext) {
}
componentDidMount() {
}
render() {
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
aboutFocus, user, match
} = this.props;
return (
<React.Fragment>
<div className="tpmComment educontent clearfix mt30 mb80">
<div className="with65 fl edu-back-white commentsDelegateParent" >
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.props}
></TPMNav>
{ loadingContent ?
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
<Shixunfork_list/>
}
</div>
<div className="with35 fr pl20">
<TPMRightSection {...this.props}></TPMRightSection>
</div>
</div>
</React.Fragment>
);
}
}
export default TPMForklist;

@ -1,229 +0,0 @@
html{
height: 100%;
overflow: hidden;
}
body {
overflow: auto !important;
font-family: "Microsoft YaHei";
}
#root {
/* ie兼容性 */
position: relative;
min-height: 100%;
}
body>.-task-title {
opacity: 1 !important;
}
/*<2A><><EFBFBD><EFBFBD><EFBFBD>Ŵ󾵵<C5B4><F3BEB5B5><EFBFBD><EFBFBD><EFBFBD>·Ŵ󾵵<C5B4>λ<EFBFBD><CEBB>*/
#root .search-all {
width: 219px;
}
/*Header START*/
.newHeader .logoimg {
margin-top: 16px;
float: left;
width: 97px;
}
.head-right i {
font-size: 20px;
float: none !important;
}
.headIcon, #header_keyword_search {
padding-top: 13px !important;
}
.search-icon {
height: 30px !important;
}
.search-icon i {
font-size: 20px;
}
#header_keyword_search i {
color: #4cacff;
}
.ant-select-selection--multiple{
padding-bottom: 0px!important;
padding-top:3px;
}
/* 先注释掉下面2个样式这样写影响范围太广了并不是所有的select都需要40px高 */
/* .ant-select-selection--single{
height:40px!important;
}
.ant-select-selection__rendered{
line-height: 40px!important;
} */
.ant-select-selection--multiple .ant-select-selection__rendered>ul>li, .ant-select-selection--multiple>ul>li{
height: 25px!important;
line-height: 23px!important;
margin-bottom:3px;
margin-top:0px;
}
/*Main START*/
.newContainer{
background: #fafafa!important;
}
.ant-modal-title{
font-size: 16px;
font-weight: bold !important;
color: #333;
}
.ant-modal-title{
text-align: center;
}
/*.ant-modal{*/
/*top:10rem !important;*/
/*}*/
@-moz-document url-prefix() {
.ant-radio-inner {
width: 17px !important;
height: 17px !important;
}
}
/* IE只能用padding不能用上下居中 */
.shixunDetail_top{
display: block!important;
padding-top: 48px;
}
.totalScore{
display: block!important;
padding-top: 28px;
}
.head-nav ul#header-nav li{
/*font-weight: 600;*/
}
/*.newFooter{*/
/*position: fixed !important;*/
/*}*/
.edu-menu-panel .edu-menu-listnew:hover .careersiconfont{
color: #000 !important;
}
.newHeader {
background: #24292D !important;
height: 60px !important;
}
/*-------------------个人主页:右侧提示区域--------------------------*/
.-task-sidebar{position:fixed;width:40px;height:180px;right:0;bottom:30px;z-index: 10;}
.-task-sidebar>div{height: 40px;line-height: 40px;box-sizing: border-box;width:40px;background:#4CACFF;color:#fff;font-size:20px;text-align:center;margin-bottom:5px;border-radius: 4px;}
.-task-sidebar>div i{ color:#fff;}
.-task-sidebar>div i:hover{color: #fff!important;}
.gotop{background-color: rgba(208,207,207,0.5)!important;padding: 0px!important;}
.-task-desc{background:#494949;width:90px;line-height: 36px;text-align: center;
position: absolute;color: #fff;font-size: 13px;z-index: 999999;opacity: 0;}
.-task-desc div{position: absolute;top:10px;right: -7px;height: 13px;}
.-task-desc div img{float: left}
.-task-sidebar .scan_ewm{
position: absolute !important;
right: 45px !important;
bottom: 0px !important;
background-color: #494949 !important;
-webkit-box-sizing: border-box !important;
box-sizing: border-box !important;
font-size: 14px !important;
line-height: 16px !important;
display: none;
height: 213px !important;
}
.trangle_right{position: absolute;right: -5px;bottom: 15px;width: 0;height: 0px;border-top: 6px solid transparent;border-left: 5px solid #494949;border-bottom: 6px solid transparent}
.HeaderSearch{
margin-top: 18px;
margin-right: 20px;
}
.HeaderSearch .ant-input-search .ant-input{
/*height:30px;*/
background: #373e3f !important;
border: 1px solid #373e3f !important;
}
.ant-input-search .ant-input-affix-wrapper{
border:transparent;
}
.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled) {
/* 比较奇怪的需求先注释掉了如果需要启用麻烦增加class限制别影响别的地方的使用 */
/* border-color: transparent; */
}
.ant-input:focus {
/*border-color: transparent;*/
border-right-width: 1px !important;
outline: 0;
-webkit-box-shadow: 0 0 0 2px transparent;
box-shadow: 0 0 0 2px transparent;
border: 1px solid #d9d9d9;
}
.HeaderSearch .ant-input-search .ant-input::-webkit-input-placeholder{
color: #999;
font-size: 14px;
}
.HeaderSearch .ant-input-search .ant-input:-moz-placeholder {
color: #999;
font-size: 14px;
}
.HeaderSearch .ant-input-search .ant-input::-moz-placeholder{
color: #999;
font-size: 14px;
}
.HeaderSearch .ant-input-search .ant-input:-ms-input-placeholder{
color: #999;
font-size: 14px;
}
.HeaderSearch .ant-input-search .ant-input-suffix .anticon-search {
color: #999;
}
.HeaderSearch .ant-input-search .ant-input{
color: #fff;
}
.HeaderSearch .ant-input-search .ant-input-suffix{
background: transparent !important;
}
.roundedRectangles{
position: absolute;
top: 10px;
right: -22px;
}
.HeaderSearch{
width: 325px;
/*right: 20px;*/
}
.HeaderSearch .ant-input-search{
right: 20px;
}
.mainheighs{
height: 100%;
display: block;
}
.ml18a{
margin-left:18%;
}
.logoimg{
float: left;
min-width: 40px;
height:40px;
}
.headwith100b{
width: 100%;
}

@ -1,416 +0,0 @@
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import Loading from '../../Loading';
import Loadable from 'react-loadable';
import { TPMIndexHOC } from './TPMIndexHOC';
import { SnackbarHOC } from 'educoder';
import TPMBanner from './TPMBanner';
import axios from 'axios';
import TPMShixunDiscussContainer from './TPMShixunDiscussContainer';
import TPMRepositoryComponent from './TPMRepositoryComponent';
import TPMRepositoryCommits from './shixunchild/Repository/TPMRepositoryCommits';
import TPMsettings from './TPMsettings/TPMsettings';
import TPMChallengeComponent from './TPMChallengeContainer';
import TPMPropaedeuticsComponent from './TPMPropaedeuticsComponent';
import TPMRanking_listComponent from './TPMRanking_listContainer';
import TPMCollaboratorsComponent from './TPMCollaboratorsContainer';
import Audit_situationComponent from './Audit_situationComponent';
import '../page/tpiPage.css'
const $ = window.$
//任务
// const TPMChallengeComponent = Loadable({
// loader: () => import('./TPMChallengeContainer'),
// loading: Loading,
// })
//背景知识
// const TPMPropaedeuticsComponent = Loadable({
// loader: () => import('./TPMPropaedeuticsComponent'),
// loading: Loading,
// })
//版本库
// const TPMRepositoryComponent = Loadable({
// loader: () => import('./TPMRepositoryComponent'),
// loading: Loading,
// })
// const TPMRepositoryComponent = Loadable({
// loader: () => import('./TPMRepositoryComponent'),
// loading: Loading,
// })
//合作
// const TPMCollaboratorsComponent = Loadable({
// loader: () => import('./TPMCollaboratorsContainer'),
// loading: Loading,
// })
//评论
// const TPMShixunDiscussComponent = Loadable({
// loader: () => import('./TPMShixunDiscussContainer'),
// loading: Loading,
// })
//排行版
// const TPMRanking_listComponent = Loadable({
// loader: () => import('./TPMRanking_listContainer'),
// loading: Loading,
// })
// //编辑实训
// const TPMModifysettings = Loadable({
// loader: () =>import('./modules/tpm/TPMsettings/TPMsettings'),
// loading: Loading,
// })
//新建实训
const TPMchallengesnew = Loadable({
loader: () => import('./challengesnew/TPMchallengesnew'),
loading: Loading,
})
//新建tab2
const TPMevaluation = Loadable({
loader: () => import('./challengesnew/TPMevaluation'),
loading: Loading,
})
//新建tab3答案
// const TPManswer = Loadable({
// loader: () => import('./challengesnew/TPManswer'),
// loading: Loading,
// })
const TPManswer = Loadable({
loader: () => import('./challengesnew/TPManswer2'),
loading: Loading,
})
//选择题
const TPMquestion = Loadable({
loader: () => import('./challengesnew/TPMquestion'),
loading: Loading,
})
//fork列表
const TPMFork_listComponent = Loadable({
loader: () => import('./TPMFork/TPMForklist'),
loading: Loading,
})
//背景知识修改
const TPMUpdatepropaede = Loadable({
loader: () => import('./TPMUpdatepropaede/TPMUpdatepropaede'),
loading: Loading,
})
// 版本库添加文件
const AddFile = Loadable({
loader: () => import('./shixunchild/Repository/RepositoryAddFile'),
loading: Loading,
})
const interceptorUrlArray = ['repository.json', 'commits.json', 'propaedeutics.json'
, 'challenges.json', 'discusses.json', 'ranking_list.json', 'collaborators.json']
const cacheInterceptorUrlMap = {}
class TPMIndex extends Component {
constructor(props) {
super(props)
this.state = {
loadingContent: false,
power: false,
shixunsDetails: {},
shixunId: undefined,
star_info: [0, 0, 0, 0, 0, 0],
star_infos: [0, 0, 0, 0, 0, 0],
identity:undefined,
TPMRightSectionData:undefined,
PropaedeuticsList: undefined,
}
}
componentDidMount = () => {
let id = this.props.match.params.shixunId;
// let collaborators = `/shixuns/` + id + `/propaedeutics.json`;
//
// axios.get(collaborators).then((response) => {
// if (response.status === 200) {
// if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
//
// }else{
// this.setState({
// PropaedeuticsList: response.data,
// shixunId: id
// });
// }
//
// }
// }).catch((error) => {
// console.log(error)
// });
let Url = `/shixuns/` + id + `.json`;
axios.get(Url).then((response) => {
if (response.status === 200) {
document.title=response.data.name;
let newstar_info = [];
// let start1=
for (var i = 0; i < response.data.score_info.length; i++) {
if (i === 0) {
newstar_info.push(response.data.score_info[i])
} else {
newstar_info.push((response.data.score_info[i] / 100) * 5)
}
}
let newstar_infos = response.data.score_info;
this.setState({
shixunsDetails: response.data,
shixunId: id,
star_info: newstar_info,
star_infos: newstar_infos,
power: response.data.power,
identity: response.data.identity,
propaedeutics:response.data.propaedeutics,
status: response.data.shixun_status,
secret_repository: response.data.secret_repository,
});
}
}).catch((error) => {
this.setState({
shixunsDetails: undefined,
shixunId: undefined,
star_info: undefined,
star_infos: undefined,
power: undefined,
identity: undefined,
status: undefined,
propaedeutics:undefined
});
});
this.tpmContentRequestInterceptor = axios.interceptors.request.use((config) => {
let url = config.url;
// console.log('tpmContentRequestInterceptor:', url)
for ( let i = 0; i < interceptorUrlArray.length; i++ ) {
if (url.indexOf(interceptorUrlArray[i]) != -1) {
url = url.split('?')[0]
console.log('loadingContent, url:', url)
this.setState({ loadingContent: true })
cacheInterceptorUrlMap[url] = true
}
}
return config;
}, function (error) {
return Promise.reject(error);
});
// Add a response interceptor
this.tpmContentResponseInterceptor = axios.interceptors.response.use((response) => {
// console.log('loadingContent finished, url:', response.config.url)
// TODO 依赖了api这个前缀
let url = response.config.url.split('api')[1];
url = url.split('?')[0]
if (cacheInterceptorUrlMap[url]) {
this.setState({ loadingContent: false })
delete cacheInterceptorUrlMap[response.url]
}
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
//右侧数据
let shixunsDetailsURL=`/shixuns/`+id+`/show_right.json`;
axios.get(shixunsDetailsURL).then((response)=> {
this.setState({
TPMRightSectionData: response.data
});
})
}
componentWillUnmount = () => {
axios.interceptors.request.eject(this.tpmContentRequestInterceptor);
this.tpmContentRequestInterceptor = null;
axios.interceptors.request.eject(this.tpmContentResponseInterceptor);
this.tpmContentResponseInterceptor = null;
}
setLoadingContent = (isLoadingContent) => {
this.setState({ loadingContent: isLoadingContent })
}
// TpmTPMBannertype(type){
//
// }
render() {
let url = window.location.href;
let flag = url.indexOf("add_file")>-1;
return (
<div className="newMain clearfix">
{
!flag &&
<TPMBanner
{...this.props}
{...this.state}
></TPMBanner>
}
<Switch {...this.props}>
<Route path="/shixuns/:shixunId/repository/:repoId/commits" render={
(props) => (<TPMRepositoryCommits {...this.props} {...this.state} {...props}
/>)
}></Route>
<Route path="/shixuns/:shixunId/secret_repository/:repoId/commits" render={
(props) => (<TPMRepositoryCommits {...this.props} {...this.state} {...props} secret_repository_tab={true}
/>)
}></Route>
<Route exact path="/shixuns/:shixunId/challenges" render={
(props) => (<TPMChallengeComponent {...this.props} {...this.state} {...props}
/>)
}></Route>
<Route path="/shixuns/:shixunId/repository/add_file" render={
(props) => (<AddFile {...this.props} {...this.state} {...props}
/>)
}></Route>
<Route path="/shixuns/:shixunId/repository" render={
(props) => (<TPMRepositoryComponent {...this.props} {...this.state} {...props}
/>)
}></Route>
<Route path="/shixuns/:shixunId/secret_repository" render={
(props) => (<TPMRepositoryComponent {...this.props} {...this.state} {...props} secret_repository_tab={true}
/>)
}></Route>
{/* <Route exact path="/shixuns/:shixunId/propaedeutics" component={TPMPropaedeuticsComponent}></Route> */}
<Route exact path="/shixuns/:shixunId/propaedeutics" render={
(props) => (<TPMPropaedeuticsComponent {...this.props} {...this.state} {...props}
/>)
}></Route>
<Route exact path="/shixuns/:shixunId/collaborators" render={
(props) => (<TPMCollaboratorsComponent {...this.props} {...this.state} {...props}
/>)
}></Route>
{/* <Route exact path="/shixuns/:shixunId/repository/:shixunId/" component={TPMRepositoryComponent}></Route> */}
<Route path="/shixuns/:shixunId/shixun_discuss" render={
(props) => (<TPMShixunDiscussContainer {...this.props} {...this.state} {...props}
initForumState={(data)=>this.initForumState(data)}
setSearchValue={this.setSearchValue}
setHotLabelIndex={this.setHotLabelIndex}
/>)
}></Route>
<Route path="/shixuns/:shixunId/settings" render={
(props) => (<TPMsettings {...this.props} {...this.state} {...props} />)
}></Route>
<Route exact path="/shixuns/:shixunId/ranking_list" render={
(props) => (<TPMRanking_listComponent {...this.props} {...this.state} {...props}
/>)
}></Route>
<Route exact path="/shixuns/:shixunId/audit_situation" render={
(props) => (<Audit_situationComponent {...this.props} {...this.state} {...props}
/>)
}></Route>
<Route exact path="/shixuns/:shixunId/fork_list" render={
(props) => (<TPMFork_listComponent {...this.props} {...props}
/>)
}></Route>
<Route exact path="/shixuns/:shixunId/update_propaedeutics" render={
(props) => (<TPMUpdatepropaede {...this.props} {...props}
/>)
}></Route>
{/*评测设置*/}
<Route path="/shixuns/:shixunId/challenges/:checkpointId/tab=2" render={
(props) => (<TPMevaluation {...this.props} {...props} {...this.state}/>)
}></Route>
{/*参考答案*/}
<Route path="/shixuns/:shixunId/challenges/:checkpointId/tab=3" render={
(props) => (<TPManswer {...this.props} {...props} {...this.state}/>)
}></Route>
{/*新建关卡*/}
<Route path="/shixuns/:shixunId/challenges/new" render={
(props) => (<TPMchallengesnew {...this.props} {...props} {...this.state}/>)
}></Route>
{/*编辑关卡*/}
<Route path="/shixuns/:shixunId/challenges/:checkpointId/editcheckpoint" render={
(props) => (<TPMchallengesnew {...this.props} {...props} {...this.state} />)
}></Route>
{/*新建选择题*/}
<Route path="/shixuns/:shixunId/challenges/newquestion" render={
(props) => (<TPMquestion {...this.props} {...props} {...this.state} />)
}></Route>
{/*修改选择题*/}
<Route path="/shixuns/:shixunId/challenges/:checkpointId/editquestion/:choose_id" render={
(props) => (<TPMquestion {...this.props} {...props} {...this.state}/>)
}></Route>
{/*修改选择题*/}
<Route path="/shixuns/:shixunId/challenges/:checkpointId/editquestion" render={
(props) => (<TPMquestion {...this.props} {...props} {...this.state}/>)
}></Route>
<Route exact path="/shixuns/:shixunId" render={
(props) => (<TPMChallengeComponent {...this.props} {...this.state} {...props}
/>)
}></Route>
{/*<Route exact path="/shixuns/:shixunId" component={TPMChallengeComponent}></Route>*/}
</Switch>
</div>
);
}
}
export default SnackbarHOC() (TPMIndexHOC ( TPMIndex ));

@ -1,754 +0,0 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import NewHeader from './NewHeader'
import NewFooter from './NewFooter'
import SiderBar from './SiderBar'
import { getUrl, downloadFile } from 'educoder'
import axios from 'axios';
import { Spin } from 'antd';
import './TPMIndex.css';
import LoginDialog from '../login/LoginDialog';
import AccountProfile from '../user/AccountProfile';
import Trialapplication from "../login/Trialapplication";
// import "antd/dist/antd.css";
// import '../../css/educoder/edu-common.css'
// import '../../css/educoder/edu-all.css'
// import '../../css/educoder/edu-main.css'
const $ = window.$;
const versionNum = '0001';
// let _url_origin = getUrl()
let _url_origin='';
if(window.location.port === "3007"){
_url_origin="http://pre-newweb.educoder.net";
}
// let _url_origin=`https://www.educoder.net`;
if (!window['indexHOCLoaded']) {
window.indexHOCLoaded = true;
//解决首屏加载问题
// $('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?1`));
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?1`));
// index.html有加载
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?1`));
// $('head').append($('<link rel="stylesheet" type="text/css" />')
// .attr('href', `${_url_origin}/stylesheets/educoder/css_min_all.css?1525440977`));
// 加timeout 为了覆盖掉antd的样式
// setTimeout(() => {
// $('head').append( $('<link rel="stylesheet" type="text/css" />')
// .attr('href', `${_url_origin}/stylesheets/css/edu-common.css?1525440977`) );
// $('head').append( $('<link rel="stylesheet" type="text/css" />')
// .attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?1525440977`) );
// $('head').append( $('<link rel="stylesheet" type="text/css" />')
// .attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?1525440977`) );
// }, 1000);
$("script").append('<script></script>')
.attr('src', `${_url_origin}/javascripts/jquery-1.8.3-ui-1.9.2-ujs-2.0.3.js?_t=${versionNum}`);
}
// `${_url_origin}/javascripts/jquery-1.8.3-ui-1.9.2-ujs-2.0.3.js?_t=${versionNum}`
// TODO css加载完成后再打开页面行为和tpm其他页面一致
export function TPMIndexHOC(WrappedComponent) {
// 这里如果extends WrappedComponent 会出现 WrappedComponent mount twice的问题
return class II extends React.Component {
constructor(props) {
super(props)
window.$('#root').css('position', 'relative')
this.state = {
tpmLoading: true,
resLoading: true,
Headertop:undefined,
Footerdown:undefined,
coursedata: {},
isRender: false,
AccountProfiletype: false,
globalLoading: false,
dataquerys:{},
isloginCancel:undefined,
mygetHelmetapi: null,
}
}
// header里面需要有user
initCommonState(user) {
// 更新头像后,需要改变参数,不然会被图片缓存影响到 --> 后台已加 ?t=${new Date().getTime()
const newUser = Object.assign({}, {...user}, { image_url: `${user.image_url}`});
this.setState({
user: newUser,
current_user: newUser
})
}
showShixun = () => {
const { shixunId } = this.props.match.params
const url = `/api/v1/shixuns/${shixunId}/show_shixun`
this.setState({ tpmLoading: true })
axios.get(url,
{
withCredentials: true
}
).then((response) => {
if (response.data && response.data.shixun) {
this.initCommonState(response.data.current_user)
response.data.tpmLoading = false;
this.setState(response.data);
}
}).catch((error) => {
console.log(error)
})
}
aboutFocus = () => {
const { creator, watched } = this.state
/*http://localhost:3000/api/v1/users/155/watch?object_id=156&object_type=user*/
const focusUrl = `/api/v1/users/${creator.owner_id}/${watched ? 'unwatch' : 'watch'}?object_id=${creator.owner_id}&object_type=user`
axios.get(focusUrl,{
})
.then((response) => {
const status = response.data.status;
if(status == 1){
const new_author_info = Object.assign({}, creator)
this.setState({
watched: !watched
})
}
}).catch((error) => {
console.log(error)
})
}
keyupListener = (e) => {
if (e.key === "Escape") {
this.setState({ globalLoading: false })
}
}
componentWillUnmount() {
window.removeEventListener('keyup', this.keyupListener)
}
componentDidMount() {
// console.log("TPMIndexHOC========");
// console.log(this.props);
window.addEventListener('keyup', this.keyupListener)
if(this.props.match.path==="/"){
// document.title="创新源于实践";
}else if(this.props.match.path==="/403"){
document.title="你没有权限访问";
}else if(this.props.match.path==="/nopage"){
document.title="没有找到该页面";
}else if(this.props.match.path==="/shixuns"){
document.title="实训项目";
}else if(this.props.match.path==="/paths"){
document.title="实践课程";
}else if(this.props.match.path==="/courses"){
document.title="翻转课堂";
}
$.ajaxSetup({
cache: true
});
//帮助后台传参数
const query = this.props.location.search;
// const type = query.split('?chinaoocTimestamp=');
// console.log("Eduinforms12345");
// console.log(this.foo(query));
// console.log(JSON.stringify(this.foo(query)));
var dataqueryss={}
try {
var foqus=this.foo(query);
if(JSON.stringify(foqus) ==="{}"){
this.setState({
dataquerys:{},
});
}else{
this.setState({
dataquerys:foqus,
});
dataqueryss=foqus;
}
}catch (e) {
this.setState({
dataquerys:{},
})
}
this.fetchUsers(dataqueryss);
let url=`/users/get_navigation_info.json`;
axios.get(url, {
}).then((response) => {
// console.log("开始请求/get_navigation_info.json");
// console.log(response);
if(response!=undefined){
if(response.status===200){
this.setState({
Headertop:response.data.top,
Footerdown:response.data.down
})
}
}
});
///请求定制化的信息
this.getAppdata();
}
/**
课堂权限相关方法暂时写这里了 ----------------------------------------START
ADMIN = 0 # 超级管理员
CREATOR = 1 # 课程创建者
PROFESSOR = 2 # 课程老师
ASSISTANT_PROFESSOR = 3 # 课程助教
STUDENT = 4 # 学生
NORMAL = 5 # 普通用户
v2
# 课程权限判断
ADMIN = 0 # 超级管理员
BUSINESS = 1 # 运营人员
CREATOR = 2 # 课程创建者 课堂管理员
PROFESSOR = 3 # 课程老师
ASSISTANT_PROFESSOR = 4 # 课程助教
STUDENT = 5 # 学生
NORMAL = 6 # 普通用户
Anonymous = 7 # 普未登录
*/
//超管0
isSuperAdmin = () => {
// return false
return this.state.coursedata&&this.state.coursedata.course_identity === 0
}
isCourseAdmin = () => {
return this.state.coursedata&&this.state.coursedata.course_identity === 2
}
//超管、运维0-1
isClassManagement = () => {
return this.state.coursedata&&this.state.coursedata.course_identity < 2
}
//超管、运维、课堂管理0-2
isAdminOrCreator = () => {
return this.state.coursedata&&this.state.coursedata.course_identity < 3
}
//超管、运维、课堂管理、老师0-3
isAdminOrTeacher = () => {
return this.state.coursedata&&this.state.coursedata.course_identity < 4
}
// 超管、运维、课堂管理、老师、助教0-4
isAdmin = () => {
return this.state.coursedata&&this.state.coursedata.course_identity < 5
}
// 学生5
isStudent = () => {
return this.state.coursedata&&this.state.coursedata.course_identity === 5
}
// 超管、运维、课堂管理、老师、助教、学生0-5
isAdminOrStudent = () => {
return this.state.coursedata&&this.state.coursedata.course_identity <= 5
}
// 游客未登录/非课堂成员6>
isNotMember = () => {
return this.state.coursedata&&this.state.coursedata.course_identity >= 6
}
//课堂是否已结束
isCourseEnd = () => {
return this.state.current_user ? this.state.current_user.course_is_end : false
}
// setTrialapplication = ()=>{
// this.setState({
// isRenders:true
// })
//
// }
//获取数据为空的时候
gettablogourlnull = () => {
this.setState({
mygetHelmetapi: undefined
});
document.title = "EduCoder";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
};
//获取数据的时候
gettablogourldata = (response) => {
document.title = response.data.setting.name;
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = '/' + response.data.setting.tab_logo_url;
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
//获取当前定制信息
getAppdata = () => {
let url = "/setting.json";
axios.get(url).then((response) => {
// console.log("app.js开始请求/setting.json");
// console.log("获取当前定制信息");
if (response) {
if (response.data) {
this.setState({
mygetHelmetapi: response.data.setting
});
try {
if (response.data.setting.tab_logo_url) {
this.gettablogourldata(response);
} else {
this.gettablogourlnull();
}
} catch (e) {
this.gettablogourlnull();
}
} else {
this.gettablogourlnull();
}
} else {
this.gettablogourlnull();
}
}).catch((error) => {
this.gettablogourlnull();
});
};
/**
课堂权限相关方法暂时写这里了 ----------------------------------------END
*/
fetchUser = () => {
let url = `/users/get_user_info.json`
let courseId;
let query = this.props.location.pathname;
const type = query.split('/');
if (type[1] == 'courses' && type[2]) {
courseId = parseInt(type[2])
// url += `?course_id=${courseId}`
}
var datay={};
if(JSON.stringify(this.state.dataquerys) ==="{}"){
datay={
course_id:isNaN(courseId)?undefined:courseId,
school:1
}
}else{
datay={
course_id:isNaN(courseId)?undefined:courseId,
school:1,
chinaoocTimestamp:this.state.dataquerys.chinaoocTimestamp,
websiteName:this.state.dataquerys.websiteName,
chinaoocKey:this.state.dataquerys.chinaoocKey,
}
}
axios.get(url,{params:
datay
},
{
// withCredentials: true
}
).then((response) => {
/*
{
"username": "黄井泉",
"login": "Hjqreturn",
"user_id": 12,
"image_url": "avatar/User/12",
"admin": true,
"is_teacher": false,
"tidding_count": 0
}
*/
if(response=== undefined){
return
}
if (response.data) {
this.initCommonState(response.data)
this.setState({
tpmLoading: false,
coursedata: {
course_identity: response.data.course_identity >= 0 ? response.data.course_identity : undefined,
course_public: response.data.course_public,
name: response.data.course_name,
userid:response.data.user_id
},
})
}
}).catch((error) => {
console.log(error)
})
};
fetchUsers = (yslurlobject) => {
let url = `/users/get_user_info.json`
let courseId;
let query = this.props.location.pathname;
const type = query.split('/');
if (type[1] == 'courses' && type[2]) {
courseId = parseInt(type[2])
// url += `?course_id=${courseId}`
}
var datay={};
if(JSON.stringify(yslurlobject) ==="{}"){
datay={
course_id:isNaN(courseId)?undefined:courseId,
school:1
}
}else{
datay={
course_id:isNaN(courseId)?undefined:courseId,
school:1,
chinaoocTimestamp:yslurlobject.chinaoocTimestamp,
websiteName:yslurlobject.websiteName,
chinaoocKey:yslurlobject.chinaoocKey,
}
}
axios.get(url,{params:
datay
},
{
// withCredentials: true
}
).then((response) => {
/*
{
"username": "黄井泉",
"login": "Hjqreturn",
"user_id": 12,
"image_url": "avatar/User/12",
"admin": true,
"is_teacher": false,
"tidding_count": 0
}
*/
if(response=== undefined){
return
}
if (response.data) {
this.initCommonState(response.data)
this.setState({
tpmLoading: false,
coursedata: {
course_identity: response.data.course_identity >= 0 ? response.data.course_identity : undefined,
course_public: response.data.course_public,
name: response.data.course_name,
userid:response.data.user_id
},
})
}
}).catch((error) => {
console.log(error)
})
};
//截取url 数据的
foo=(url)=> {
var json = {};
var regExp = /[\?\&](\w+)(=?)(\w*)/g;
var arr;
do {
arr = regExp.exec(url);
// console.log(arr); // arr = [完整的字符串, key, 等号或'', value或'']
if (arr) {
var key = arr[1];
var value = arr[3];
// arr[2] === ''时, value = undefined
if (!arr[2])
value = undefined;
json[key] = value;
}
} while (arr);
return json;
};
hideLoginDialog = () => {
this.setState({
isRender: false,
isloginCancel:undefined
})
}
showLoginDialog = () => {
this.setState({
isRender: true,
isloginCancel:"iscancel"
})
}
//验证登录是否成功方法
checkIfLogin = () => {
return this.state.current_user && this.state.current_user.login != ''
}
hideAccountProfile = () => {
this.setState({
AccountProfiletype: false
})
}
showProfileCompleteDialog = () => {
this.dialogObj = {}
this.setState({
AccountProfiletype: true
})
}
//验证是否完善资料
checkIfProfileCompleted = () => {
return this.state.current_user && this.state.current_user.profile_completed
}
showProfessionalCertificationDialog = () => {
this.dialogObj = {
content: '您需要去完成您的职业认证,才能使用此功能',
okText: '立即完成',
okHref: '/account/certification'
}
this.setState({
AccountProfiletype: true,
})
}
checkIfProfessionalCertification = () => {
return this.state.current_user && this.state.current_user.professional_certification
}
ShowOnlinePdf = (url) => {
return axios({
method:'get',
url:url,
responseType: 'arraybuffer',
}).then((result)=>{
var binaryData = [];
binaryData.push(result.data);
this.url =window.URL.createObjectURL(new Blob(binaryData, {type:"application/pdf"}));
window.open(this.url);
})
}
DownloadFileA=(title,url)=>{
let link = document.createElement('a');
document.body.appendChild(link);
link.href =url;
link.download = title;
//兼容火狐浏览器
let evt = document.createEvent("MouseEvents");
evt.initEvent("click", false, false);
link.dispatchEvent(evt);
document.body.removeChild(link);
}
DownloadOpenPdf=(type,url)=>{
type===true?window.open(url):window.location.href=url;
}
slowDownload = (url, tip) => {
this._gLoadingTip = tip || '正在生成文件,请稍后...';
this.setState({ globalLoading: true })
const fileUrl = url;
downloadFile({
url: fileUrl,
successCallback: (url) => {
this.setState({ globalLoading: false })
console.log('successCallback')
},
failCallback: (responseHtml, url) => {
this.setState({ globalLoading: false })
console.log('failCallback')
}
})
}
yslslowCheckresults =(tip) =>{
this._gLoadingTip = tip || '成绩计算中,请稍候...';
this.setState({ globalLoading: true })
}
yslslowCheckresultsNo =() =>{
this.setState({ globalLoading: false })
}
showGlobalLoading = (tip) => {
this._gLoadingTip = tip || '加载中,请稍后...';
this.setState({ globalLoading: true })
}
hideGlobalLoading = () => {
this.setState({ globalLoading: false })
}
MdifHasAnchorJustScorll=()=>{
//mdhash滚动
let anchor = decodeURI(this.props.location.hash).replace('#', '');
// 对应id的话, 滚动到相应位置
if (!!anchor) {
let anchorElement = document.getElementsByName(anchor);
if (anchorElement) {
if (anchorElement.length>0){
anchorElement[anchorElement.length-1].scrollIntoView();
}
}
}
}
render() {
let{Headertop,Footerdown, isRender, AccountProfiletype,mygetHelmetapi}=this.state;
const common = {
isSuperAdmin:this.isSuperAdmin,
isAdminOrCreator:this.isAdminOrCreator,
isClassManagement:this.isClassManagement,
isCourseAdmin:this.isCourseAdmin,
isAdmin: this.isAdmin,
isAdminOrTeacher: this.isAdminOrTeacher,
isStudent: this.isStudent,
isAdminOrStudent: this.isAdminOrStudent,
isNotMember: this.isNotMember,
isCourseEnd: this.isCourseEnd,
isUserid:this.state.coursedata&&this.state.coursedata.userid,
fetchUser: this.fetchUser,
showLoginDialog: this.showLoginDialog,
checkIfLogin: this.checkIfLogin,
showProfileCompleteDialog: this.showProfileCompleteDialog,
checkIfProfileCompleted: this.checkIfProfileCompleted,
checkIfProfessionalCertification: this.checkIfProfessionalCertification,
showProfessionalCertificationDialog: this.showProfessionalCertificationDialog,
ShowOnlinePdf:(url)=>this.ShowOnlinePdf(url),
DownloadFileA:(title,url)=>this.DownloadFileA(title,url),
DownloadOpenPdf:(type,url)=>this.DownloadOpenPdf(type,url),
slowDownload: this.slowDownload,
showGlobalLoading: this.showGlobalLoading,
hideGlobalLoading: this.hideGlobalLoading,
yslslowCheckresults:this.yslslowCheckresults,
yslslowCheckresultsNo:this.yslslowCheckresultsNo,
MdifHasAnchorJustScorll:this.MdifHasAnchorJustScorll
};
// console.log("this.props.mygetHelmetapi");
// console.log(this.props.mygetHelmetapi);
return (
<div className="indexHOC">
{isRender===true ? <LoginDialog
Modifyloginvalue={()=>this.hideLoginDialog()}
{...this.props}
{...this.state}
/> : ""}
{/* AccountProfile 也用作职业认证 */}
{AccountProfiletype===true ? <AccountProfile
hideAccountProfile={()=>this.hideAccountProfile()}
{...this.props}
{...this.state}
{...this.dialogObj}
/>:""}
<SiderBar
{...this.props}
{...this.state}
Headertop={Headertop}/>
{/* 注释掉了1440 影响到了手机屏幕的展示 */}
<style>{
`
.newContainers{
min-width: 1200px;
max-width: unset;
height: 100%;
min-height: 100%;
overflow: hidden;
}
.newHeaders{
// position: fixed;
max-width: unset;
background: #24292D !important;
width: 100%;
height: 60px !important;
min-width: 1200px;
z-index: 1000;
-moz-box-shadow: 0px 0px 12px rgba(0,0,0,0.1);
box-shadow: 0px 0px 12px rgba(0,0,0,0.1);
}
.globalSpin {
max-height: 700px !important;
}
.indexHOC > .ant-spin-nested-loading {
background: #000;
height: 100%;
}
.indexHOC > .ant-spin-nested-loading > div > .ant-spin .ant-spin-dot {
top: 50% !important;
}
.globalSpin .ant-spin-text {
text-shadow: none !important;
color: #fff;
}
.globalSpin .ant-spin-dot-item {
background-color: #fff;
}
`
}</style>
<NewHeader {...this.state} {...this.props}></NewHeader>
<Spin spinning={this.state.globalLoading} delay={0} className="globalSpin"
size="large"
tip= {this._gLoadingTip || "加载中..."}
>
<div className="newContainer newContainers">
<WrappedComponent initCommonState={(user)=>this.initCommonState(user)}
{...this.props} {...this.state}
showShixun={this.showShixun} aboutFocus={this.aboutFocus}
{...common}
>
</WrappedComponent>
</div>
</Spin>
<NewFooter
{...this.state} {...this.props}
Footerdown={Footerdown}
/>
</div>
);
}
}
}

@ -1,74 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import { CircularProgress } from 'material-ui/Progress';
import './TPMShixunDiscuss.css'
import Propaedeutics from './shixunchild/Propaedeutics/Propaedeu_tics'
import TPMRightSection from './component/TPMRightSection'
import TPMNav from './component/TPMNav'
import axios from 'axios';
class TPMPropaedeutics extends Component {
constructor(props) {
super(props)
this.state = {
shixunId: undefined
}
}
componentWillReceiveProps(newProps, newContext) {
}
componentDidMount() {
}
render() {
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
aboutFocus, user, match
} = this.props;
// <Comments
// {...this.props}
// user={_user}
// onPaginationChange={this.onPaginationChange}
// ></Comments>
return (
<React.Fragment>
<div className="tpmComment educontent clearfix mt30 mb80">
<div className="with65 fl edu-back-white commentsDelegateParent" >
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.state}
{...this.props}
/>
<Propaedeutics
{...this.props}
{...this.state}
/>
</div>
<div className="with35 fr pl20">
<TPMRightSection {...this.props}></TPMRightSection>
</div>
</div>
</React.Fragment>
);
}
}
export default TPMPropaedeutics;

@ -1,39 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import TPMPropaedeutics from './TPMPropaedeutics'
import axios from 'axios';
class TPMPropaedeuticsComponent extends Component {
constructor(props) {
super(props)
this.state = {
// tpmLoading: true,
// creator: {
// owner_id: ''
// }
}
}
render() {
const { tpmLoading } = this.props;
return (
<React.Fragment>
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
<TPMPropaedeutics
{...this.props}
>
</TPMPropaedeutics>
}
</React.Fragment>
);
}
}
export default TPMPropaedeuticsComponent ;

@ -1,59 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import { CircularProgress } from 'material-ui/Progress';
import './TPMShixunDiscuss.css'
import Ranking_list from './shixunchild/Ranking_list/Ranking_list'
import TPMRightSection from './component/TPMRightSection'
import TPMNav from './component/TPMNav'
class TPMRanking_list extends Component {
constructor(props) {
super(props)
}
render() {
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
aboutFocus, user, match
} = this.props;
// <Comments
// {...this.props}
// user={_user}
// onPaginationChange={this.onPaginationChange}
// ></Comments>
return (
<React.Fragment>
<div className="tpmComment educontent clearfix mt30 mb80">
<div className="with65 fl edu-back-white commentsDelegateParent" >
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.props}
></TPMNav>
<Ranking_list
{...this.props}
/>
</div>
<div className="with35 fr pl20">
<TPMRightSection {...this.props}></TPMRightSection>
</div>
</div>
</React.Fragment>
);
}
}
export default TPMRanking_list;

@ -1,37 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import TPMRanking_list from './TPMRanking_list'
import axios from 'axios';
class TPMRanking_listContainer extends Component {
constructor(props) {
super(props)
this.state = {
}
}
render() {
const { tpmLoading } = this.props;
const user = this.props.current_user;
return (
<React.Fragment>
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
<TPMRanking_list
{...this.props}
{...this.state}
user={user}
aboutFocus={this.props.aboutFocus}
>
</TPMRanking_list>
}
</React.Fragment>
);
}
}
export default TPMRanking_listContainer;

@ -1,58 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import { CircularProgress } from 'material-ui/Progress';
import './TPMShixunDiscuss.css'
import Repository from './shixunchild/Repository/Repository'
import TPMRightSection from './component/TPMRightSection'
import TPMNav from './component/TPMNav'
// import RepositoryChooseModal from './component/modal/RepositoryChooseModal'
class TPMRepository extends Component {
constructor(props) {
super(props)
}
render() {
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
aboutFocus, user, match, isContentWidth100
} = this.props;
return (
<React.Fragment>
<div className="tpmComment educontent clearfix mt30 mb80">
{/* 可能会影响到其他页面的样式,需要测试、协商 */}
<div className={`${isContentWidth100 ? 'width100': 'with65'} fl edu-back-white`}
style={{background: 'transparent'}}>
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.props}
></TPMNav>
{/* <RepositoryChooseModal {...this.props}></RepositoryChooseModal> */}
{ loadingContent ?
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
<Repository
{...this.props}
/>
}
</div>
{ !isContentWidth100 && <div className="with35 fr pl20">
<TPMRightSection {...this.props}></TPMRightSection>
</div>}
</div>
</React.Fragment>
);
}
}
export default TPMRepository;

@ -1,229 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import TPMRepository from './TPMRepository'
import axios from 'axios';
import { trace_collapse, info } from 'educoder'
import RepositoryCodeEditor from './shixunchild/Repository/RepositoryCodeEditor'
class TPMRepositoryComponent extends Component {
constructor(props) {
super(props)
this.nameTypeMap = {}
let pathArray = []
var splitArray = window.location.pathname.split('shixun_show/');
if (splitArray[1]) {
pathArray = splitArray[1].split('/')
if (pathArray[pathArray.length - 1] == '') {
// 有可能是这么访问的: http://localhost:3007/shixuns/3ozvy5f8/repository/fsu7tkaw/master/shixun_show/src/
pathArray.length = pathArray.length - 1;
}
}
this.state = {
repositoryLoading: true,
pathArray: pathArray,
isContentWidth100: this._isFileInPathArray(pathArray)
}
}
componentDidUpdate(prevProps, prevState) {
if (this.props.secret_repository_tab != prevProps.secret_repository_tab) {
this.fetchRepo()
}
}
componentDidMount = () => {
this.fetchRepo()
}
setContentWidth100 = (flag) => {
const newFileContent = flag === false ? '' : this.state.fileContent
this.setState({
// isCodeFile
isContentWidth100: flag,
fileContent: newFileContent
})
}
saveCode = (content) => {
const path = this.state.pathArray.join('/')
let id = this.props.match.params.shixunId;
let url = `/shixuns/${id}/update_file.json`;
axios.post(url, {
path: path,
content
}).then((response) => {
if(response.status === 200){
this.setState({
fileContent: response.data.content,
repositoryLoading: false
});
}
trace_collapse('tpm save code res: ', response)
this.props.showSnackbar('文件保存成功')
}).catch((error)=>{
console.log(error)
});
}
fetchCode = (newPathArray) => {
const path = newPathArray.join('/')
// https://testeduplus2.educoder.net/shixuns/3ozvy5f8/file_content.json
this.setContentWidth100(true)
this.setState({ repositoryLoading: true, pathArray: newPathArray })
let id = this.props.match.params.shixunId;
let url = `/shixuns/${id}/file_content.json`;
axios.post(url, {
path: path,
secret_repository: this.props.secret_repository_tab
}).then((response) => {
trace_collapse('repository res: ', response)
if (response.data.status == -1) {
this.props.showSnackbar('无法找到对应的资源,请变更地址或联系管理员!')
return;
}
if(response.status === 200){
this.setState({
fileContent: response.data.content,
repositoryLoading: false
});
this.props.history
.replace(`${this.props.match.url}/master/shixun_show/${newPathArray.join('/')}`)
}
}).catch((error)=>{
this.props.showSnackbar('无法找到对应的资源,请变更地址或联系管理员!')
console.log(error)
});
}
_isFileName = (name) => {
return name.indexOf('.') !== -1
}
_isFileInPathArray = (array) => {
if (!array || array.length === 0) {
return false
}
return this.nameTypeMap[array[array.length - 1]] !== 'tree' && this._isFileName( array[array.length - 1] )
}
// listItem 如果是num则是通过面包屑点击过来的取pathArray的子集
fetchRepo = (listItem) => {
const { pathArray } = this.state;
let newPathArray = pathArray.slice(0)
if (listItem === 0 || listItem) {
this.setContentWidth100(false)
this.nameTypeMap[listItem.name] = listItem.type
if (typeof listItem == 'number') { // 参数是数字的话,做截取
// if (this._isFileName(newPathArray[listItem])) { // 面包屑中的文件不让点击了
// listItem--;
// }
newPathArray = newPathArray.slice(0, listItem)
} else if (listItem.type === 'tree') {
newPathArray.push(listItem.name)
} else if (listItem.type === 'blob') {
newPathArray.push(listItem.name)
this.setState({ pathArray: newPathArray })
this.fetchCode(newPathArray)
return;
}
}
// https://testeduplus2.educoder.net/shixuns/3ozvy5f8/repository.json
this.setState({ repositoryLoading: true, pathArray: newPathArray })
let urlNewPathArray = newPathArray;
let fileInPathArray = false;
if (newPathArray.length) {
fileInPathArray = this.nameTypeMap[newPathArray[newPathArray.length - 1]] ? this.nameTypeMap[newPathArray[newPathArray.length - 1]] !== 'tree'
: (listItem ? listItem.type !== 'tree' : this._isFileName( newPathArray[newPathArray.length - 1] ))
if ( fileInPathArray ) {
urlNewPathArray = newPathArray.slice(0, newPathArray.length - 1)
}
}
const path = urlNewPathArray.join('/')
let id = this.props.match.params.shixunId;
let url = `/shixuns/${id}/${this.props.secret_repository_tab ? 'secret_repository' : 'repository'}.json`;
// this.props.setLoadingContent(true)
axios.post(url, {
path: path ? path : ''
}).then((response) => {
// this.props.setLoadingContent(false)
const trees = response.data.trees
const treeIsFileMap = {}
if (!trees || !Array.isArray(trees)) {
// this.props.showSnackbar('无法找到对应的资源,请变更地址或联系管理员!')
// return;
} else {
trees.forEach(item => {
treeIsFileMap[item.name] = item.type == 'blob'
})
}
if(response.status === 200){
this.setState({
treeIsFileMap,
...response.data,
repositoryLoading: false
});
this.props.history
.replace(`${this.props.match.url}` +
(newPathArray.length ? `/master/shixun_show/${newPathArray.join('/')}` : ''))
}
// 初始化时repo接口完毕后需要看是否需要fetchCode
if (fileInPathArray) {
this.fetchCode(newPathArray)
}
// info(response)
trace_collapse('repository res: ', response)
}).catch((error)=>{
console.log(error)
});
}
render() {
const { isContentWidth100 } = this.state;
// 需要重构
return (
<React.Fragment>
{ !isContentWidth100 ? <TPMRepository
{...this.props}
{...this.state}
nameTypeMap={this.nameTypeMap}
fetchRepo={this.fetchRepo}
>
</TPMRepository>
:
<div className="tpmComment educontent clearfix mt30 mb80">
{/* 可能会影响到其他页面的样式,需要测试、协商 */}
<div className={`width100 fl edu-back-white`}
style={{background: 'transparent'}}>
<RepositoryCodeEditor
{...this.state}
{...this.props}
fetchRepo={this.fetchRepo}
saveCode={this.saveCode}
nameTypeMap={this.nameTypeMap}
></RepositoryCodeEditor>
</div>
</div>
}
</React.Fragment>
);
}
}
export default TPMRepositoryComponent ;

@ -1,47 +0,0 @@
.tpmComment .-fit {
position: inherit;
}
.tpmComment .rc-pagination {
margin-left: auto;
margin-right: auto;
margin-top: 12px;
margin-bottom: 20px;
}
.tpmComment .paginationSection {
background: #FAFAFA;
}
.tpmComment .comment_item_cont.df.clearfix:nth-last-child(1) {
border-bottom: none;
}
/*.tpmComment .fl.edu-back-white {*/
/*min-height: 600px;*/
/*}*/
.user_watch_btn {
cursor: pointer;
}
/*md编辑器*/
.tpmComment .commentItemMDEditor a.task-btn {
background: #4cacff!important;
margin-right: 16px;
margin-top: 16px;
}
/* md编辑器 resizeBar*/
.tpmComment .commentItemMDEditor .editor__resize {
transform: translateX(-176%)
}
#ratePanel > div > div > div.fr div.rateYo.fl.mt3 {
height: 20px;
line-height: 20px;
cursor: default;
width: 110px;
}
.tpmComment .icon-jiangli {
/* margin-top: 2px; */
}

@ -1,72 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import { CircularProgress } from 'material-ui/Progress';
import './TPMShixunDiscuss.css'
import ShixunDiscuss from './shixunchild/ShixunDiscuss/ShixunDiscuss'
import TPMRightSection from './component/TPMRightSection'
import TPMNav from './component/TPMNav'
import Comments from '../comment/Comments'
import { commentHOC } from '../comment/CommentsHOC'
class TPMShixunDiscuss extends Component {
constructor(props) {
super(props)
}
componentWillReceiveProps(newProps, newContext) {
}
componentDidMount() {
// TODO 加了HOC后 mount了两次
this.props.fetchCommentIfNotFetched &&
this.props.fetchCommentIfNotFetched();
}
render() {
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
aboutFocus, user, match
} = this.props;
return (
<React.Fragment>
<div className="tpmComment educontent clearfix mt30 mb80">
<div className="with65 fl edu-back-white commentsDelegateParent" >
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.props}
></TPMNav>
{ loadingContent ?
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
<Comments
{...this.props}
user={user}
showHiddenButton={true}
></Comments>
// onPaginationChange={this.onPaginationChange}
// <ShixunDiscuss
// {...this.props}
// />
}
</div>
<div className="with35 fr pl20">
<TPMRightSection {...this.props}></TPMRightSection>
</div>
</div>
</React.Fragment>
);
}
}
export default commentHOC ( TPMShixunDiscuss );

@ -1,45 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
import TPMShixunDiscuss from './TPMShixunDiscuss'
import axios from 'axios';
class TPMShixunDiscussContainer extends Component {
constructor(props) {
super(props)
this.state = {
}
}
componentWillReceiveProps(newProps, newContext) {
}
componentDidMount() {
}
render() {
const { tpmLoading } = this.props;
const user = this.props.current_user;
return (
<React.Fragment>
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
<TPMShixunDiscuss
{...this.props}
{...this.state}
user={user}
aboutFocus={this.props.aboutFocus}
>
</TPMShixunDiscuss>
}
</React.Fragment>
);
}
}
export default TPMShixunDiscussContainer;

@ -1,100 +0,0 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
import axios from 'axios';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import {getUrl} from 'educoder';
export default class TPMUpdatepropaede extends Component {
constructor(props) {
super(props)
this.neweditanswerRef=React.createRef();
this.state = {
shixunId:undefined,
}
}
componentDidMount() {
let id = this.props.match.params.shixunId;
let url="/shixuns/"+id+"/propaedeutics.json";
axios.get(url).then((response) => {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
this.setState({
shixunId:id,
})
if(response.data.content[0]!=null){
this.setState({
editanswersRefval:response.data.content,
})
this.neweditanswerRef.current.setValue(response.data.content)
}else{
this.setState({
editanswersRefval:"",
})
this.neweditanswerRef.current.setValue('')
}
}
}).catch((error) => {
console.log(error)
});
}
updatepropaedeuticsvalue=()=>{
let id = this.props.match.params.shixunId;
let url="/shixuns/"+id+"/update_propaedeutics.json";
const update_propaedeuticsvalue = this.neweditanswerRef.current.getValue().trim();
axios.post(url,{
content:update_propaedeuticsvalue
}
).then((response) => {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
this.props.showSnackbar(response.data.message);
}
}).catch((error) => {
console.log(error)
});
}
render() {
let {shixunId} = this.state;
return (
<React.Fragment>
<div className="educontent">
<div className="edu-back-white mt30">
<div className="font-16 pt30 pl20 pr20 pb40 bor-bottom-greyE clearfix">
<span className="fl">背景知识</span>
<a href={"/shixuns/"+shixunId+"/propaedeutics"}className="color-grey-9 fr">返回</a>
</div>
<div className="padding40-20">
<TPMMDEditor ref={this.neweditanswerRef} placeholder="请输入选择题的题干内容" mdID={'editquestioMDid'} refreshTimeout={1500}
needRecreate={true} watch={true} className="courseMessageMD" initValue={this.neweditanswerRefval}></TPMMDEditor>
</div>
</div>
<div className="clearfix mb30 mt30">
<a className="defalutSubmitbtn fl mr20"
onClick={this.updatepropaedeuticsvalue}>保存</a>
<a href={"/shixuns/"+shixunId+"/propaedeutics"} className="defalutCancelbtn fl"
>取消</a>
</div>
</div>
</React.Fragment>
)
}
}

File diff suppressed because it is too large Load Diff

@ -1,113 +0,0 @@
.radioStyle{
display: block;
height: 30px;
}
#settingsMarkdown{
background:transparent;
}
#challenge_begin{
height: 30px;
line-height: 30px;
}
#shixundescription .CodeMirror{
margin-top: 31px !important;
height: 364px !important;
}
#shixundescription .editormd-preview{
width:578px !important;
top: 40px !important;
height: 364px !important;
}
#shixunmemoMD .CodeMirror{
margin-top: 31px !important;
height: 578px !important;
}
#shixunmemoMD .editormd-preview{
width: 578px !important;
top: 40px !important;
height: 578px !important;
}
.radioStyle {
display: block;
height: 30px;
}
a.white-btn.use_scope-btn:hover {
color: #FFF !important;
}
.shixunScopeInput {
width: 218px;
height: 33px;
display: block;
margin-bottom: 15px;
}
.ant-modal-title {
text-align: center;
}
a.newuse_scope-btn:hover {
border: 1px solid #F06200;
color: #fff !important;
background: #FF7500;
}
a.newuse_scope-btn {
border: 1px solid #FF7500;
color: #FF7500 !important;
}
.tpmprompt {
padding-left: 20px;
margin-top: -4px;
}
.ml36{
margin-left: 26px;
}
#shixunmemoMD{
width:98% !important;
height: 620px !important;
}
#shixunmemoMDs{
width: 98% !important;
height: 420px !important;
}
#shixunmemoMDs .CodeMirror {
/* width: 548px !important; */
margin-top: 31px !important;
height: 402px !important;
}
.pdr20{
padding-right:20px;
}
.nonemodel{
width: 59%;
height: 468px;
/*background: rgba(0, 0, 0, 0.65);*/
background: #f5f5f5;
position: absolute;
z-index: 100;
opacity: 0.5;
left: 21.5%;
}
.shixunmemoMDdiv{
width: 99%;
height: 615px;
}
.shixunspanred{
margin-left: 142px;
margin-top: 5px;
margin-bottom: 5px;
}
.ml82{
margin-left:82px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

@ -1,355 +0,0 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css";
import { getImageUrl, toPath, getUrl } from 'educoder';
import '../../courses/css/Courses.css'
import axios from 'axios';
import './css/TPMchallengesnew.css';
require('codemirror/lib/codemirror.css');
let origin = getUrl();
let path = '/editormd/lib/'
path = getUrl("/editormd/lib/")
const $ = window.$;
let timeout;
let currentValue;
const Option = Select.Option;
const RadioGroup = Radio.Group;
// 保存数据
function md_add_data(k,mdu,d){
window.sessionStorage.setItem(k+mdu,d);
}
// 清空保存的数据
function md_clear_data(k,mdu,id){
window.sessionStorage.removeItem(k+mdu);
var id1 = "#e_tip_"+id;
var id2 = "#e_tips_"+id;
if(k == 'content'){
$(id2).html(" ");
}else{
$(id1).html(" ");
}
}
window.md_clear_data = md_clear_data
// editor 存在了jquery对象上应用不需要自己写md_rec_data方法了
function md_rec_data(k, mdu, id) {
if (window.sessionStorage.getItem(k + mdu) !== null) {
var editor = $("#e_tips_" + id).data('editor');
editor.setValue(window.sessionStorage.getItem(k + mdu));
// debugger;
// /shixuns/b5hjq9zm/challenges/3977/tab=3 setValue可能导致editor样式问题
md_clear_data(k, mdu, id);
}
}
window.md_rec_data = md_rec_data;
function md_elocalStorage(editor,mdu,id){
if (window.sessionStorage){
var oc = window.sessionStorage.getItem('content'+mdu);
if(oc !== null && oc != editor.getValue()){
console.log("#e_tips_"+id)
$("#e_tips_"+id).data('editor', editor);
var h = '您上次有已保存的数据,是否<a style="cursor: pointer;" class="link-color-blue" onclick="md_rec_data(\'content\',\''+ mdu + '\',\'' + id + '\')">恢复</a> ? / <a style="cursor: pointer;" class="link-color-blue" onclick="md_clear_data(\'content\',\''+ mdu + '\',\'' + id + '\')">不恢复</a>';
$("#e_tips_"+id).html(h);
}
setInterval(function() {
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
h = h < 10 ? '0' + h : h;
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
if(editor.getValue().trim() != ""){
md_add_data("content",mdu,editor.getValue());
var id1 = "#e_tip_"+id;
var id2 = "#e_tips_"+id;
var textStart = " 数据已于 "
var text = textStart + h + ':' + m + ':' + s +" 保存 ";
// 占位符
var oldHtml = $(id2).html();
if (oldHtml && oldHtml != ' ' && oldHtml.startsWith(textStart) == false) {
$(id2).html( oldHtml.split(' (')[0] + ` (${text})`);
} else {
$(id2).html(text);
}
// $(id2).html("");
}
},10000);
}else{
$("#e_tip_"+id).after('您的浏览器不支持localStorage.无法开启自动保存草稿服务,请升级浏览器!');
}
}
function create_editorMD(id, width, high, placeholder, imageUrl, callback, initValue,
onchange, watch, { noStorage, showNullButton, emoji }, that) {
// 还是出现了setting只有一份被共用的问题
var editorName = window.editormd(id, {
width: width,
height: high===undefined?400:high,
path: path, // "/editormd/lib/"
markdown : initValue,
dialogLockScreen: false,
watch:watch===undefined?true:watch,
syncScrolling: "single",
tex: true,
tocm: true,
emoji: !!emoji ,
taskList: true,
codeFold: true,
searchReplace: true,
htmlDecode: "style,script,iframe",
sequenceDiagram: true,
autoFocus: false,
// mine
toolbarIcons: function (mdEditor) {
let react_id = `react_${mdEditor.id}`;
const __that = window[react_id]
// Or return editormd.toolbarModes[name]; // full, simple, mini
// Using "||" set icons align right.
const icons = ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"];
// 试卷处用到的填空题新增按钮
if (__that.props.showNullButton) {
icons.push('nullBtton')
}
return icons
},
toolbarCustomIcons: {
testIcon: "<a type=\"inline\" class=\"latex\" ><div class='zbg'></div></a>",
testIcon1: "<a type=\"latex\" class=\"latex\" ><div class='zbg_latex'></div></a>",
nullBtton: "<a type=\"nullBtton\" class='pr' title='增加填空'><div class='border-left'><span></span></div><span class='fillTip'>点击插入填空项</span><i class=\"iconfont icon-edit font-16\"></i></a>",
},
//这个配置在simple.html中并没有但是为了能够提交表单使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中方便post提交表单。
saveHTMLToTextarea: true,
// 用于增加自定义工具栏的功能可以直接插入HTML标签不使用默认的元素创建图标
dialogMaskOpacity: 0.6,
placeholder: placeholder,
imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
imageUploadURL: imageUrl,//url
onchange: onchange,
onload: function() {
let _id = this.id // 如果要使用this这里不能使用箭头函数
let _editorName = this;
let react_id = `react_${_editorName.id}`;
const __that = window[react_id]
// this.previewing();
// let _id = id;
$("#" + _id + " [type=\"latex\"]").bind("click", function () {
_editorName.cm.replaceSelection("```latex");
_editorName.cm.replaceSelection("\n");
_editorName.cm.replaceSelection("\n");
_editorName.cm.replaceSelection("```");
var __Cursor = _editorName.cm.getDoc().getCursor();
_editorName.cm.setCursor(__Cursor.line - 1, 0);
});
$("#" + _id + " [type=\"inline\"]").bind("click", function () {
_editorName.cm.replaceSelection("`$$$$`");
var __Cursor = _editorName.cm.getDoc().getCursor();
_editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
_editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");
$("[type=\"latex\"]").attr("title", "多行公式");
if (__that.props.showNullButton) {
const NULL_CH = '▁'
// const NULL_CH = ''
// const NULL_CH = '🈳'
$("#" + _id + " [type=\"nullBtton\"]").bind("click", function () {
_editorName.cm.replaceSelection(NULL_CH);
// var __Cursor = _editorName.cm.getDoc().getCursor();
// _editorName.cm.setCursor(__Cursor.line - 1, 0);
});
}
if (noStorage == true) {
} else {
md_elocalStorage(_editorName, `MDEditor__${_id}`, _id);
}
callback && callback(_editorName)
}
});
return editorName;
}
export default class TPMMDEditor extends Component {
constructor(props) {
super(props)
this.state = {
initValue: ''
}
}
componentDidUpdate(prevProps, prevState) {
// 不能加,影响了试卷填空题
// if (this.props.initValue != prevProps.initValue) {
// this.answers_editormd.setValue(this.props.initValue)
// }
}
// react_mdEditor_
componentDidMount = () => {
const { mdID, initValue, placeholder, showNullButton} = this.props;
let _id = `mdEditor_${mdID}`
this.contentChanged = false;
const _placeholder = placeholder || "";
// amp;
// 编辑时要传memoId
const imageUrl = `/api/attachments.json`;
// 创建editorMd
let react_id = `react_${_id}`;
// 将实例存到了window
window[react_id] = this
const answers_editormd = create_editorMD(_id, '100%', this.props.height, _placeholder, imageUrl, (_editorName) => {
const __editorName = _editorName;
react_id = `react_${__editorName.id}`;
const that = window[react_id]
// 一个延迟的recreate或resize不加这段代码md初始化可能会出现样式问题
setTimeout(() => {
if (that.props.needRecreate == true) {
__editorName.recreate() // 注意 必须在setValue之前触发不然会清空
} else {
__editorName.resize()
}
console.log('timeout', __editorName.id)
__editorName.cm && __editorName.cm.refresh()
}, that.props.refreshTimeout || 500)
if (this.props.noSetValueOnInit) {
that.onEditorChange()
} else {
if (that.props.initValue != undefined && that.props.initValue != '') {
__editorName.setValue(that.props.initValue)
}
if (that.state.initValue) {
__editorName.setValue(that.state.initValue)
}
}
__editorName.cm.on("change", (_cm, changeObj) => {
that.contentChanged = true;
if (that.state.showError) {
that.setState({showError: false})
}
that.onEditorChange()
})
that.props.onCMBlur && __editorName.cm.on('blur', () => {
that.props.onCMBlur()
})
that.props.onCMBeforeChange && __editorName.cm.on('beforeChange', (cm,change) => {
that.props.onCMBeforeChange(cm,change)
})
that.answers_editormd = __editorName;
// 这里应该可以去掉了,方便调试加的
window[__editorName.id+'_'] = __editorName;
}, initValue, this.onEditorChange,this.props.watch, {
noStorage: this.props.noStorage,
showNullButton: this.props.showNullButton,
emoji: this.props.emoji
}, this);
}
// 用在form里时validate失败时出现一个红色边框
showError = () => {
this.setState({showError: true})
}
onEditorChange = () => {
if (!this.answers_editormd) return;
const val = this.answers_editormd.getValue();
//console.log('onEditorChange', this.props.id, val)
try {
this.props.onChange && this.props.onChange(val)
} catch(e) {
// http://localhost:3007/courses/1309/common_homeworks/6566/setting
// 从这个页面,跳转到编辑页面,再在编辑页面点击返回的时候,这里会报错
console.error('出错')
console.error(e)
}
}
resize = () => {
if (!this.answers_editormd) { // 还未初始化
return;
}
this.answers_editormd.resize()
this.answers_editormd.cm && this.answers_editormd.cm.refresh()
this.answers_editormd.cm.focus()
}
getValue = () => {
try {
return this.answers_editormd.getValue()
} catch (e) {
return ''
}
}
setValue = (val) => {
try {
this.answers_editormd.setValue(val)
} catch (e) {
// TODO 这里多实例的时候前一个实例的state会被后面这个覆盖 参考NewWork.js http://localhost:3007/courses/1309/homework/9300/edit/1
// 未初始化
this.setState({ initValue: val })
}
}
render() {
let {
showError
} = this.state;
let { mdID, className, noStorage, imageExpand } = this.props;
let _style = {}
if (showError) {
_style.border = '1px solid red'
}
return (
<React.Fragment>
<div className={`df ${className} ${imageExpand && 'editormd-image-click-expand' }`} >
{/* padding10-20 */}
<div className="edu-back-greyf5 radius4" id={`mdEditor_${mdID}`} style={{..._style}}>
<textarea style={{display: 'none'}} id={`mdEditors_${mdID}`} name="content"></textarea>
<div className="CodeMirror cm-s-defualt">
</div>
</div>
</div>
<div className={"fr rememberTip"}>
{noStorage == true ? ' ' : <p id={`e_tips_mdEditor_${mdID}`} className="edu-txt-right color-grey-cd font-12"> </p>}
{/* {noStorage == true ? ' ' : <p id={`e_tips_mdEditor_${mdID}`} className="edu-txt-right color-grey-cd font-12"> </p>} */}
</div>
</React.Fragment>
)
}
}

@ -1,366 +0,0 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css";
import { getImageUrl, toPath, getUrl } from 'educoder';
import axios from 'axios';
import './css/TPMchallengesnew.css';
let origin = getUrl();
let path = getUrl("/editormd/lib/")
const $ = window.$;
let timeout;
let currentValue;
const Option = Select.Option;
const RadioGroup = Radio.Group;
// 恢复数据
function md_rec_data(k,mdu,id, editor){
if(window.sessionStorage.getItem(k+mdu) !== null){
editor.setValue(window.sessionStorage.getItem(k+mdu));
md_clear_data(k,mdu,id);
}
}
// 保存数据
function md_add_data(k,mdu,d){
window.sessionStorage.setItem(k+mdu,d);
}
// 清空保存的数据
function md_clear_data(k,mdu,id){
window.sessionStorage.removeItem(k+mdu);
var id1 = "#e_tip_"+id;
var id2 = "#e_tips_"+id;
if(k == 'content'){
$(id2).html("");
}else{
$(id1).html("");
}
}
function md_elocalStorage(editor,mdu,id){
if (window.sessionStorage){
var oc = window.sessionStorage.getItem('content'+mdu);
if(oc !== null ){
console.log("#e_tips_"+id)
$("#e_tips_"+id).data('editor', editor);
var h = '您上次有已保存的数据,是否<a style="cursor: pointer;" class="link-color-blue" onclick="md_rec_data(\'content\',\''+ mdu + '\',\'' + id + '\')">恢复</a> ? / <a style="cursor: pointer;" class="link-color-blue" onclick="md_clear_data(\'content\',\''+ mdu + '\',\'' + id + '\')">不恢复</a>';
$("#e_tips_"+id).html(h);
}
setInterval(function() {
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
h = h < 10 ? '0' + h : h;
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
if(editor.getValue().trim() != ""){
md_add_data("content",mdu,editor.getValue());
var id1 = "#e_tip_"+id;
var id2 = "#e_tips_"+id;
$(id1).html(" 数据已于 " + h + ':' + m + ':' + s +" 保存 ");
$(id2).html("");
}
},10000);
}else{
$("#e_tip_"+id).after('您的浏览器不支持localStorage.无法开启自动保存草稿服务,请升级浏览器!');
}
}
function create_editorMD(id, width, high, placeholder, imageUrl, callback) {
var editorName = window.editormd(id, {
width: width,
height: high,
path: path, // "/editormd/lib/"
syncScrolling: "single",
tex: true,
tocm: true,
emoji: true,
taskList: true,
codeFold: true,
searchReplace: true,
htmlDecode: "style,script,iframe",
sequenceDiagram: true,
autoFocus: false,
toolbarIcons: function () {
// Or return editormd.toolbarModes[name]; // full, simple, mini
// Using "||" set icons align right.
return ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"]
},
toolbarCustomIcons: {
testIcon: "<a type=\"inline\" class=\"latex\" ><div class='zbg'></div></a>",
testIcon1: "<a type=\"latex\" class=\"latex\" ><div class='zbg_latex'></div></a>"
},
//这个配置在simple.html中并没有但是为了能够提交表单使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中方便post提交表单。
saveHTMLToTextarea: true,
// 用于增加自定义工具栏的功能可以直接插入HTML标签不使用默认的元素创建图标
dialogMaskOpacity: 0.6,
placeholder: placeholder,
imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
imageUploadURL: imageUrl,//url
onload: function () {
// this.previewing();
$("#" + id + " [type=\"latex\"]").bind("click", function () {
editorName.cm.replaceSelection("```latex");
editorName.cm.replaceSelection("\n");
editorName.cm.replaceSelection("\n");
editorName.cm.replaceSelection("```");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line - 1, 0);
});
$("#" + id + " [type=\"inline\"]").bind("click", function () {
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");
$("[type=\"latex\"]").attr("title", "多行公式");
md_elocalStorage(editorName, `answers__${id}`, "Memoanswers");
callback && callback()
}
});
return editorName;
}
export default class TPManswer extends Component {
constructor(props) {
super(props)
this.state = {
choice_url: undefined,
practice_url: undefined,
go_back_url: undefined,
value: 1,
answer:"",
id:undefined,
checkpointId:undefined,
power: false,
prev_challenge: undefined,
next_challenge: undefined,
}
}
answerMD(initValue, id) {
this.contentChanged = false;
const placeholder = "";
// amp;
// 编辑时要传memoId
const imageUrl = `/api/attachments.json`;
// 创建editorMd
const answers_editormd = create_editorMD(id, '100%', 400, placeholder, imageUrl, () => {
setTimeout(() => {
answers_editormd.resize()
answers_editormd.cm && answers_editormd.cm.refresh()
}, 500)
if (initValue != undefined) {
answers_editormd.setValue(initValue)
}
answers_editormd.cm.on("change", (_cm, changeObj) => {
console.log('....contentChanged')
this.contentChanged = true;
})
});
this.answers_editormd = answers_editormd;
window.answers_editormd = answers_editormd;
}
componentDidMount() {
let id = this.props.match.params.shixunId;
let checkpointId=this.props.match.params.checkpointId;
let newchoice_url= "/shixuns/"+id+"/challenges/newquestion";
let newpractice_url= "/shixuns/"+id+"/challenges/new";
let newgo_back_url="/shixuns/"+id+"/challenges";
this.setState({
shixunId:id,
checkpointId:checkpointId
})
let url = "/shixuns/" + id + "/challenges/" + checkpointId + "/edit.json?tab=2";
axios.get(url).then((response) => {
let newprev_challenge = response.data.prev_challenge;
let next_challenge = response.data.next_challenge;
if (newprev_challenge != undefined) {
if(newprev_challenge.st===0){
newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editcheckpoint";
}else{
newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editquestion";
}
}
if (next_challenge != undefined) {
if(next_challenge.st===0){
next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editcheckpoint";
}else{
next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editquestion";
}
}
this.setState({
answer:response.data.answer,
power: response.data.power,
choice_url: newchoice_url, // 导航中的新建选择题url
practice_url: newpractice_url, //string 导航中新建实践题url
go_back_url: newgo_back_url, //string 导航中的返回url
position: response.data.position, //int 关卡位置,导航栏中的第几关
prev_challenge: newprev_challenge,
next_challenge: next_challenge,
})
if(response.data.power===false){
this.props.showSnackbar("没有权限修改");
}
if(response.data.answer===undefined||response.data.answer===null){
this.answerMD("", "answerMD");
}else{
this.answerMD(response.data.answer, "answerMD");
}
}).catch((error) => {
console.log(error)
});
}
challenge_answer_submit=()=> {
let id = this.props.match.params.shixunId;
let{checkpointId}=this.state;
let url = "/shixuns/"+id+"/challenges/"+checkpointId+".json";
const answer_editormdvalue = this.answers_editormd.getValue();
axios.put(url,{
tab:2,
identifier:id,
id:checkpointId,
challenge:{
answer:answer_editormdvalue
}
}
).then((response) => {
this.props.showSnackbar(response.data.messages);
}).catch((error) => {
console.log(error)
});
}
render() {
let {
choice_url,
practice_url,
go_back_url,
position,
task_pass_default,
submit_url,
shixunId,
checkpointId,
power,
prev_challenge,
next_challenge,
} = this.state;
let tab1url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/editcheckpoint";
let tab2url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/tab=2";
let tab3url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/tab=3";
// console.log(this.props)
return (
<React.Fragment>
<div className="educontent mt30 mb30">
<div className="padding10-20 mb10 edu-back-white clearfix">
<span className="fl ring-blue mr10 mt7">
<img src={getImageUrl("images/educoder/icon/code.svg")} data-tip-down="实训任务" className="fl mt2 ml2"/>
</span>
<span className="font-16 task-hide fl TPMtaskName">{position}</span>
<Link to={go_back_url === undefined ? "" : go_back_url}
className="color-grey-6 fr font-15 mt3">返回</Link>
{prev_challenge === undefined ? "" :
<a href={prev_challenge} className="fr color-blue mr15 mt4">上一关</a>
}
{next_challenge === undefined ? "" :
<a href={next_challenge} className="fr color-blue mr15 mt4">下一关</a>
}
<Link to={practice_url === undefined ? "" : practice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.status===2||this.props.status===1?'none':'block'}}
data-tip-down="新增代码编辑类型的任务">+&nbsp;实践类型</Link>
<Link to={choice_url === undefined ? "" : choice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.status===2||this.props.status===1?'none':'block'}}
data-tip-down="新增选择题类型的任务">+&nbsp;选择题类型</Link>
</div>
<div className="challenge_nav clearfix edu-back-white">
<li>
<Link to={tab1url}>本关任务</Link>
</li>
<li >
<Link to={tab2url}>评测设置</Link>
</li>
<li className="active">
<Link to={tab3url}>参考答案</Link>
</li>
</div>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb30">参考答案</p>
<div className="df">
<div className="padding10-20 edu-back-greyf5 radius4" id="answerMD">
<textarea style={{display: 'none'}} id="evaluate_script_show" name="content"> </textarea>
<div className="CodeMirror cm-s-defualt">
</div>
</div>
</div>
<p id="e_tip_Memoanswers" className="edu-txt-right color-grey-cd font-12"></p>
<p id="e_tips_Memoanswers" className="edu-txt-right color-grey-cd font-12"></p>
</div>
</div>
<div className="clearfix mt20" style={{display:this.props.identity>4||this.props.identity===undefined||power===false?"none":"block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={this.challenge_answer_submit}>提交</a>
<a href={"/shixuns/" + shixunId + "/challenges"} className="defalutCancelbtn fl">取消</a>
</div>
</div>
</React.Fragment>
)
}
}

@ -1,368 +0,0 @@
import React, {Component} from 'react';
import {Input, InputNumber, Select, Radio, Checkbox, Popconfirm, message, Modal, Tooltip} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css";
import { getImageUrl, toPath, getUrl } from 'educoder';
import axios from 'axios';
import './css/TPMchallengesnew.css';
import TPMMDEditor from './TPMMDEditor';
let origin = getUrl();
let path = getUrl("/editormd/lib/")
const $ = window.$;
let timeout;
let currentValue;
const Option = Select.Option;
const RadioGroup = Radio.Group;
// const testAnswers = [{
// "id": 4337,
// "name": "解题思路1",
// "contents": "答案的解题思路1",
// "level": 1,
// "score": 25
// },
// {
// "id": 4338,
// "name": "解题思路2",
// "contents": "答案的解题思路2",
// "level": 2,
// "score": 25
// }]
export default class TPManswer extends Component {
constructor(props) {
super(props)
this.state = {
choice_url: undefined,
practice_url: undefined,
go_back_url: undefined,
value: 1,
answer:"",
id:undefined,
checkpointId:undefined,
power: false,
prev_challenge: undefined,
next_challenge: undefined,
answers: [] //testAnswers
}
}
componentDidMount() {
let id = this.props.match.params.shixunId;
let checkpointId=this.props.match.params.checkpointId;
let newchoice_url= "/shixuns/"+id+"/challenges/newquestion";
let newpractice_url= "/shixuns/"+id+"/challenges/new";
let newgo_back_url="/shixuns/"+id+"/challenges";
this.setState({
shixunId:id,
checkpointId:checkpointId
})
let url = "/shixuns/" + id + "/challenges/" + checkpointId + "/edit.json?tab=2";
axios.get(url).then((response) => {
let newprev_challenge = response.data.prev_challenge;
let next_challenge = response.data.next_challenge;
if (newprev_challenge != undefined) {
if(newprev_challenge.st===0){
newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editcheckpoint";
}else{
newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editquestion";
}
}
if (next_challenge != undefined) {
if(next_challenge.st===0){
next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editcheckpoint";
}else{
next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editquestion";
}
}
this.setState({
answer:response.data.answer,
power: response.data.power,
choice_url: newchoice_url, // 导航中的新建选择题url
practice_url: newpractice_url, //string 导航中新建实践题url
go_back_url: newgo_back_url, //string 导航中的返回url
position: response.data.position, //int 关卡位置,导航栏中的第几关
prev_challenge: newprev_challenge,
next_challenge: next_challenge,
})
if(response.data.power===false){
this.props.showSnackbar("没有权限修改");
}
// if(response.data.answer===undefined||response.data.answer===null){
// this.answerMD("", "answerMD");
// }else{
// this.answerMD(response.data.answer, "answerMD");
// }
}).catch((error) => {
console.log(error)
});
let urlAnswer = `/shixuns/${id}/challenges/${checkpointId}/answer.json`;
axios.get(urlAnswer).then((response) => {
if (response.data.status === 401) {
} else if (response.data) {
this.setState({ answers: response.data })
}
})
}
challenge_answer_submit=()=> {
// `levelSection${index}`
// this.refs.md0
const { answers } = this.state;
const answersParams = answers.slice(0)
console.log(answersParams)
let isValidate = true;
let totalScore = 0;
answersParams.forEach( (item, index) => {
if (!isValidate) {
return;
}
const sectionId = `#levelSection${index}`;
const mdContnet = this.refs[`md${index}`].getValue().trim();;
item.contents = mdContnet;
item.name = item.name.trim()
totalScore += item.score;
delete item.id;
if (!item.name) {
this.props.showSnackbar("请先填写参考答案名称");
isValidate = false;
} else if (!mdContnet) {
this.props.showSnackbar("请先填写参考答案内容");
isValidate = false;
}
if (!isValidate) {
$("html, body").animate({ scrollTop: $(`${sectionId}`).offset().top - 100})
}
})
if (!isValidate) {
return;
}
if (answersParams.length != 0 && totalScore != 100) {
this.props.showSnackbar("请先保证占比和为100%");
return;
}
let id = this.props.match.params.shixunId;
let {checkpointId} = this.state;
let url = `/shixuns/${id}/challenges/${checkpointId}/crud_answer.json`;
axios.post(url,{
challenge_answer: answersParams
}
).then((response) => {
if (response.data) {
if (response.data.message) {
this.props.showSnackbar(response.data.message);
}
if (response.data.status == 1) {
$("html").animate({ scrollTop: 0 })
}
}
}).catch((error) => {
console.log(error)
});
}
onNameChange = (e, index) => {
const newAnswer = Object.assign({}, this.state.answers[index])
newAnswer.name = e.target.value
const newAnswers = this.state.answers.slice(0)
newAnswers[index] = newAnswer
this.setState({ answers: newAnswers})
}
onScoreChange = (val, index) => {
const newAnswer = Object.assign({}, this.state.answers[index])
newAnswer.score = val
const newAnswers = this.state.answers.slice(0)
newAnswers[index] = newAnswer
this.setState({ answers: newAnswers})
}
answerOnChange = (val, index) => {
if (!this.state.answers[index]) {
// 1、2、3删除2会走到这里
return;
}
const newAnswer = Object.assign({}, this.state.answers[index])
newAnswer.contents = val
const newAnswers = this.state.answers.slice(0)
newAnswers[index] = newAnswer
this.setState({ answers: newAnswers})
}
addAnswer = () => {
const newAnswers = this.state.answers.slice(0)
newAnswers.push({
"name": `解题思路${newAnswers.length + 1}`,
"contents": "",
"score": 10
})
this.setState({ answers: newAnswers })
}
delanswers=(index)=>{
let {answers}=this.state;
let newanswers=answers;
newanswers.splice(index,1)
this.setState({
answers:newanswers
}, () => {
for(let i = index; i < newanswers.length; i ++) {
this.refs[`md${i}`].setValue(newanswers[i].contents)
}
})
}
render() {
let {
choice_url,
practice_url,
go_back_url,
position,
task_pass_default,
submit_url,
shixunId,
checkpointId,
power,
prev_challenge,
next_challenge,
answers,
} = this.state;
let tab1url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/editcheckpoint";
let tab2url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/tab=2";
let tab3url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/tab=3";
// console.log(this.props)
return (
<React.Fragment>
<div className="educontent mt30 mb30 tpmAnswer">
<div className="padding10-20 mb10 edu-back-white clearfix">
<span className="fl ring-blue mr10 mt7">
<img src={getImageUrl("images/educoder/icon/code.svg")} data-tip-down="实训任务" className="fl mt2 ml2"/>
</span>
<span className="font-16 task-hide fl TPMtaskName">{position}</span>
<Link to={go_back_url === undefined ? "" : go_back_url}
className="color-grey-6 fr font-15 mt3">返回</Link>
{prev_challenge === undefined ? "" :
<a href={prev_challenge} className="fr color-blue mr15 mt4">上一关</a>
}
{next_challenge === undefined ? "" :
<a href={next_challenge} className="fr color-blue mr15 mt4">下一关</a>
}
<Link to={practice_url === undefined ? "" : practice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.status===2||this.props.status===1?'none':'block'}}
data-tip-down="新增代码编辑类型的任务">+&nbsp;实践类型</Link>
<Link to={choice_url === undefined ? "" : choice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.status===2||this.props.status===1?'none':'block'}}
data-tip-down="新增选择题类型的任务">+&nbsp;选择题类型</Link>
</div>
<div className="challenge_nav clearfix edu-back-white">
<li>
<Link to={tab1url}>本关任务</Link>
</li>
<li >
<Link to={tab2url}>评测设置</Link>
</li>
<li className="active">
<Link to={tab3url}>参考答案</Link>
</li>
</div>
<div className="edu-back-white mb10 clearfix">
<div className="padding30-20">
<p className=" font-12" style={{ paddingBottom: '5px'
, color: '#666666'}}>
可以将参考答案分级设置让学员自行选择级别每级查看后按照比例扣分值学员已完成任务再查看则不影响原因已获得的成绩
</p>
<p className=" font-12 "
style={{ maxWidth: "782px"
, color: '#999999'}}>
示例级别1扣减分值占比25%级别2扣减分值占比35%级别3扣减分值占比40%则学员选择查看级别1的答案将被扣减25%的分值
选择查看级别2的答案将被扣减60%的分值选择查看级别3的答案将被扣减100%的分值
</p>
<style>{`
.tpmAnswer .ant-input { width: 230px }
.tpmAnswer .score.ant-input-number { width: 62px; }
.levelSection { margin-top: 16px }
`}</style>
{
answers.map((answer, index) => {
return <div className="levelSection" id={`levelSection${index}`} style={{ clear: 'both' }}>
<span className="mr4 color-orange pt10">*</span>
<p className="color-grey-6 font-16 mb30 mt10" style={{ display: "inline" }}>级别{index + 1}</p>
<Tooltip title="删除">
<a className="fr sample_icon_remove mr30 mt8" onClick={()=>this.delanswers(index)}>
<i className="fa fa-times-circle color-grey-c font-16 fl" ></i>
</a>
</Tooltip>
<div className=" color-grey-6 font-16" style={{ marginLeft: "9px", margin: '8px 9px'}}>
<div className=" ">
<span>名称</span>
<Input value={answer.name} onChange={(e) => this.onNameChange(e, index)}></Input>
<span style={{ marginLeft: "20px"}} >扣减分值占比</span>
<InputNumber className="score" step={1} min={1} max={100} defaultValue={answer.score}
onChange={(e) => this.onScoreChange(e, index)} ></InputNumber>%
</div>
<div className="mt10">
<span>参考答案</span>
<TPMMDEditor ref={`md${index}`} mdID={index} initValue={answer.contents}
onChange={(val) => this.answerOnChange(val, index)}></TPMMDEditor>
</div>
</div>
</div>
})
}
<div className="clearfix mt20" style={{display:this.props.identity>4||this.props.identity===undefined||power===false?"none":"block"}}>
<a href={"javascript:void(0)"} className="defalutCancelbtn fl" onClick={this.addAnswer}>新增</a>
</div>
</div>
</div>
<div className="clearfix mt20" style={{display:this.props.identity>4||this.props.identity===undefined||power===false?"none":"block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={this.challenge_answer_submit}>提交</a>
<a href={"/shixuns/" + shixunId + "/challenges"} className="defalutCancelbtn fl">取消</a>
</div>
</div>
</React.Fragment>
)
}
}

@ -1,615 +0,0 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css";
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import axios from 'axios';
import './css/TPMchallengesnew.css';
import { getImageUrl, toPath } from 'educoder';
import {getUrl} from 'educoder';
let origin = getUrl();
let path = getUrl("/editormd/lib/")
const $ = window.$;
let timeout;
let currentValue;
const Option = Select.Option;
const RadioGroup = Radio.Group;
export default class TPMchallengesnew extends Component {
constructor(props) {
super(props)
this.exercisememoMDRef=React.createRef();
this.state = {
choice_url: undefined,
practice_url: undefined,
go_back_url: undefined,
task_pass_default: undefined,
submit_url: undefined,
shixunCreatePracticeGroup: 1,
optionsums:[100,200],
activetype:0,
setopen: false,
shixunCreatePractice: undefined,
onshixunsmarkvalue: 100,
shixunsskillvalue: undefined,
shixunsskillvaluelist: [],
tab2url: "",
tab3url: "",
prev_challenge:undefined,
next_challenge:undefined,
power: false,
shixunCreatePracticetype: false,
shixunsskillvaluelisttype: false,
marktype:false,
editPracticesendtype:false,
CreatePracticesendtype:false,
exec_time:20,
shixunExec_timeType:false
}
}
componentDidMount() {
let id = this.props.match.params.shixunId;
let checkpointId=this.props.match.params.checkpointId;
let newchoice_url= "/shixuns/"+id+"/challenges/newquestion";
let newpractice_url= "/shixuns/"+id+"/challenges/new";
let newgo_back_url="/shixuns/"+id+"/challenges"
if(checkpointId===undefined){
//新建模式
let url = "/shixuns/" + id + "/challenges/new.json"
axios.get(url).then((response) => {
this.setState({
choice_url: newchoice_url,
practice_url: newpractice_url,
go_back_url: newgo_back_url,
position: response.data.position,
task_pass_default: response.data.task_pass_default,
submit_url: response.data.submit_url,
checkpointId:checkpointId,
exercisememoMDRefval:response.data.task_pass_default
})
this.exercisememoMDRef.current.setValue(response.data.task_pass_default||'')
}).catch((error) => {
console.log(error)
});
}else{
//编辑模式
let url="/shixuns/"+id+"/challenges/"+checkpointId+".json?tab=0";
axios.get(url).then((response) => {
let optionsum;
if(response.data.difficulty===1){
optionsum=[100,200];
}else if(response.data.difficulty===2){
optionsum=[300,400,500,600];
}else if(response.data.difficulty===3){
optionsum=[700,800,900,1000]
}
let newprev_challenge=response.data.prev_challenge;
let next_challenge=response.data.next_challenge;
if (newprev_challenge != undefined) {
if(newprev_challenge.st===0){
newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editcheckpoint";
}else{
newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editquestion";
}
}
if (next_challenge != undefined) {
if(next_challenge.st===0){
next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editcheckpoint";
}else{
next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editquestion";
}
}
this.setState({
power: response.data.power,
prev_challenge:newprev_challenge,
next_challenge:next_challenge,
choice_url: newchoice_url,
practice_url: newpractice_url,
go_back_url: newgo_back_url,
shixunCreatePractice:response.data.subject,
position:response.data.position,
shixunCreatePracticeGroup:response.data.difficulty,
optionsums:optionsum,
onshixunsmarkvalue:response.data.score,
shixunsskillvaluelist:response.data.tags,
checkpointId:checkpointId,
exec_time:response.data.exec_time,
tab2url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=2",
tab3url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=3",
exercisememoMDRefval:response.data.task_pass
})
if(response.data.power===false){
this.props.showSnackbar("你没有权限修改");
}
this.exercisememoMDRef.current.setValue(response.data.task_pass||'')
}).catch((error) => {
console.log(error)
});
}
}
onshixunCreatePracticeChange = (e) => {
let optionsum;
let onshixunsmark;
if(e.target.value===1){
optionsum=[100,200];
onshixunsmark=100;
}else if(e.target.value===2){
optionsum=[300,400,500,600];
onshixunsmark=300;
}else if(e.target.value===3){
optionsum=[700,800,900,1000]
onshixunsmark=700;
}
this.setState({
shixunCreatePracticeGroup: e.target.value,
optionsums:optionsum,
onshixunsmarkvalue:onshixunsmark
})
}
shixunCreatePractice = (e) => {
this.setState({
shixunCreatePractice: e.target.value
})
}
CreatePracticesend = () => {
this.setState({
CreatePracticesendtype:true
})
if(this.props.status===2){
this.props.showSnackbar("该实训已经发布不能新建")
this.setState({
CreatePracticesendtype:false
})
return
}
let {shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvaluelist,exec_time} = this.state;
if (shixunCreatePractice === undefined||shixunCreatePractice=="") {
this.setState({
shixunCreatePracticetype: true
})
this.props.showSnackbar("任务名称为空")
$('html').animate({
scrollTop: 10
}, 1000);
this.setState({
CreatePracticesendtype:false
})
return
}
if (shixunsskillvaluelist.length === 0) {
this.setState({
shixunsskillvaluelisttype: true,
CreatePracticesendtype:false
})
this.props.showSnackbar("技能标签为空")
return
}
if(exec_time===null||exec_time===undefined||exec_time===""){
this.setState({
shixunExec_timeType:false
})
return
}
const exercise_editormdvalue = this.exercisememoMDRef.current.getValue().trim();
let id = this.props.match.params.shixunId;
let url = "/shixuns/" + id + "/challenges.json";
axios.post(url, {
identifier:id,
subject: shixunCreatePractice,
task_pass: exercise_editormdvalue,
difficulty: shixunCreatePracticeGroup,
score: onshixunsmarkvalue,
challenge_tag: shixunsskillvaluelist,
st: 0,
exec_time:exec_time
}).then((response) => {
if (response.data.status === 1) {
// $("html").animate({ scrollTop: 0 })
window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/editcheckpoint`;
// this.setState({
// setopen: true,
// CreatePracticesendtype:false,
// tab2url: "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=2",
// tab3url: "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=3",
// })
}
// this.props.showSnackbar(response.data.messages);
}).catch((error) => {
console.log(error)
});
}
onshixunsmark = (value) => {
this.setState({
onshixunsmarkvalue: value
})
}
shixunsskill = (e) => {
this.setState({
shixunsskillvalue: e.target.value
})
}
clickshixunsskill = () => {
let {shixunsskillvalue, shixunsskillvaluelist} = this.state;
if (shixunsskillvalue === "") {
return
} else if (shixunsskillvalue === undefined) {
return
}
if(shixunsskillvalue == "" || shixunsskillvalue == undefined || shixunsskillvalue == null || (shixunsskillvalue.length>0 && shixunsskillvalue.trim().length == 0)){
message.error("输入为空,不能保存!");
return
}
let list = shixunsskillvaluelist;
list.push(shixunsskillvalue);
this.setState({
shixunsskillvaluelist: list,
shixunsskillvalue: ""
})
}
delshixunsskilllist = (key) => {
let {shixunsskillvaluelist} = this.state;
let newshixunsskillvaluelist = shixunsskillvaluelist;
newshixunsskillvaluelist.splice(key, 1);
this.setState({
shixunsskillvaluelist: newshixunsskillvaluelist
})
}
editPracticesend=()=>{
this.setState({
editPracticesendtype:true
})
let {shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvaluelist,checkpointId,exec_time} = this.state;
const exercise_editormdvalue = this.exercisememoMDRef.current.getValue().trim();
let id = this.props.match.params.shixunId;
let url = "/shixuns/"+id+"/challenges/"+checkpointId+".json";
if (shixunCreatePractice === undefined||shixunCreatePractice=="") {
// this.setState({
// shixunCreatePracticetype: true
// })
this.props.showSnackbar("任务名称为空")
$('html').animate({
scrollTop: 10
}, 1000);
this.setState({
editPracticesendtype:false
})
return
}
if (shixunsskillvaluelist.length === 0) {
// this.setState({
// shixunsskillvaluelisttype: true
// })
this.props.showSnackbar("技能标签为空")
this.setState({
editPracticesendtype:false
})
return
}
if(exec_time===null||exec_time===undefined||exec_time===""){
this.setState({
shixunExec_timeType:false
})
return
}
axios.put(url, {
tab:0,
identifier:id,
id:checkpointId,
challenge:{
subject: shixunCreatePractice,
task_pass: exercise_editormdvalue,
difficulty: shixunCreatePracticeGroup,
score: onshixunsmarkvalue,
exec_time:exec_time
},
challenge_tag:shixunsskillvaluelist
}).then((response) => {
this.props.showSnackbar(response.data.messages);
if (response.data.status === 1) {
this.setState({
setopen: true,
editPracticesendtype:false,
tab2url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=2",
tab3url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=3",
})
// window.location.href = "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=2"
}
}).catch((error) => {
console.log(error)
});
}
onshixunsmarks=()=> {
this.setState({
marktype:true
})
}
onshixunsmarkss=()=> {
this.setState({
marktype:false
})
}
setexec_time=(e)=>{
this.setState({
exec_time:e.target.value
})
}
render() {
let shixuntype = this.props.match.params.type;
let {marktype,
shixunCreatePracticetype, shixunsskillvaluelisttype,
choice_url, practice_url, go_back_url, position, task_pass_default, submit_url, setopen,checkpointId,prev_challenge,next_challenge,power,
shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvalue, shixunsskillvaluelist, tab2url, tab3url,optionsums,
CreatePracticesendtype,editPracticesendtype
} = this.state;
let options;
if(optionsums!=undefined){
options = optionsums.map((d, k) => {
return (
<Option key={d} id={k}>{d}</Option>
)
})
}
return (
<React.Fragment>
<div className="educontent mt30 mb30">
<div className="padding10-20 mb10 edu-back-white clearfix">
<span className="fl ring-blue mr10 mt7">
<img src={getImageUrl("images/educoder/icon/code.svg")} data-tip-down="实训任务" className="fl mt2 ml2"/>
</span>
<span className="font-16 task-hide fl TPMtaskName">{position}</span>
<Link to={go_back_url === undefined ? "" : go_back_url}
className="color-grey-6 fr font-15 mt3">返回</Link>
{ next_challenge===undefined?"":
<a href={next_challenge}className="fr color-blue mr15 mt4">下一关</a>
}
{ prev_challenge===undefined?"":
<a href={prev_challenge} className="fr color-blue mr15 mt4">上一关</a>
}
<a href={practice_url === undefined ? "" : practice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}}
data-tip-down="新增代码编辑类型的任务">+&nbsp;实践类型</a>
<a href={choice_url === undefined ? "" : choice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}}
data-tip-down="新增选择题类型的任务">+&nbsp;选择题类型</a>
</div>
<div className="challenge_nav clearfix edu-back-white">
<li className="active">
<a>本关任务</a>
</li>
<li className="">
{tab2url === "" ? <span>评测设置</span> : <Link to={tab2url}></Link>}
</li>
<li className="">
{tab3url === "" ? <span>参考答案</span> : <Link to={tab3url}></Link>}
</li>
</div>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb30">任务名称</p>
<div className="df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20">
<input type="text"
// className="input-100-45 greyInput"
className={shixunCreatePracticetype===true?"input-100-45 greyInpus wind100":"input-100-45 greyInput "}
maxLength="50"
name="challenge[subject]"
value={shixunCreatePractice}
onInput={this.shixunCreatePractice}
placeholder="请输入任务名称(此信息将提前展示给学员),例:计算学生的课程成绩绩点"/>
</div>
<div style={{width: '57px'}}>
<span
className={shixunCreatePracticetype === true ? "color-orange mt8 fl block" : "color-orange mt8 fl none"}
id="new_shixun_name"><i
className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">过关任务</p>
<TPMMDEditor ref={this.exercisememoMDRef} placeholder="请输入选择题的题干内容" mdID={'exercisememoMD'} refreshTimeout={1500}
watch={true} className="courseMessageMD" initValue={this.state.exercisememoMDRefval} height={700}></TPMMDEditor>
<p id="e_tip_Memochallengesnew" className="edu-txt-right color-grey-cd font-12"></p>
<p id="e_tips_Memochallengesnew" className="edu-txt-right color-grey-cd font-12"></p>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">难度系数</p>
<div className="clearfix mb40">
<RadioGroup value={shixunCreatePracticeGroup} className="fl mr40"
disabled={this.props.status===2?true:false}
onChange={this.props.status===2?"":this.onshixunCreatePracticeChange}>
<Radio value={1}>简单</Radio>
<Radio value={2}>中等</Radio>
<Radio value={3}>困难</Radio>
</RadioGroup>
</div>
<p className="color-grey-6 font-16 mb30">奖励经验值</p>
<div className="clearfix"
// onMouseLeave={this.props.status===2?"":this.onshixunsmarkss}
>
<span className="fl mr30 color-orange pt10">*</span>
<Select style={{width: 120}} className="winput-240-40 fl"
id="challenge_score"
onChange={this.props.status===2?"":this.onshixunsmark}
// onMouseEnter={this.props.status===2?"":this.onshixunsmarks}
disabled={this.props.status===2?true:false}
// open={marktype}
value={onshixunsmarkvalue}
getPopupContainer={triggerNode => triggerNode.parentNode}
>
{options}
</Select>
<p className="fl color-grey-9 font-12 ml20">
如果学员答题错误则不能得到相应的经验值<br/>
如果学员成功得到经验值那么将同时获得等值的金币奖励+10经验值+10金币
</p>
<span className="color-orange mt7 fl ml20 none" id="ex_value_notice"><i
className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">技能标签</p>
<div className="clearfix df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1">
<Input type="text"
className="winput-240-40 fl mr20 winput-240-40s"
id="input_task_tag"
placeholder="添加标签"
onInput={this.shixunsskill}
value={shixunsskillvalue}
onPressEnter={this.clickshixunsskill}
onBlur={this.clickshixunsskill}
/>
{/*<a className="white-btn orange-btn fl mt1 use_scope-btn ml20 mt5 mr20"*/}
{/*onClick={this.clickshixunsskill}>+ 添加</a>*/}
<div className="ml15 color-grey-9 mt5">学员答题正确将获得技能否则不能获得技能</div>
<div className="mt20 clearfix" id="task_tag_content">
{
shixunsskillvaluelist===undefined?"":shixunsskillvaluelist.length === 0 ? "" : shixunsskillvaluelist.map((itme, key) => {
return (
<li className="task_tag_span" key={key}><span>{itme}</span>
<a onClick={() => this.delshixunsskilllist(key)}>×</a>
</li>
)
})
}
</div>
</div>
<span
className={shixunsskillvaluelisttype === true ? "color-orange mt7 fl ml20 block" : " color-orange mt7 fl ml20 none"}
id="stage_name_notice">
<i className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">服务配置</p>
<div className="clearfix mb5">
<span className="color-orange pt10 fl">*</span>
<label className="panel-form-label fl">评测时限(S)</label>
<div className="pr fl with80 status_con">
<input value={this.state.exec_time} className="panel-box-sizing task-form-100 task-height-40" placeholder="请输入类别名称" onInput={this.setexec_time}/>
</div>
<span
className={this.state.shixunExec_timeType === true ? "color-orange mt8 fl block ml20" : "color-orange mt8 fl none"}
id="new_shixun_name"><i className="fa fa-exclamation-circle mr3"></i></span>
<div className="cl"></div>
</div>
</div>
<div className="clearfix mt30"
style={{display:this.props.identity>4||this.props.identity===undefined?"none":'block'}}
>
{checkpointId===undefined?<a className="defalutSubmitbtn fl mr20" onClick={CreatePracticesendtype===true?"":this.CreatePracticesend}>提交</a>:
<a className="defalutSubmitbtn fl mr20" onClick={editPracticesendtype===true?"":this.editPracticesend}>提交</a>}
<a href={go_back_url === undefined ? "" : go_back_url} className="defalutCancelbtn fl">取消</a>
</div>
</div>
</React.Fragment>
)
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,229 +0,0 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal,Tooltip} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
import axios from 'axios';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
const Option = Select.Option;
const RadioGroup = Radio.Group;
export default class TpmQuestionEdit extends Component {
constructor(props) {
super(props)
this.state = {
}
}
componentDidMount() {
}
delecbtns=()=>{
let url=`/shixuns/${this.props.match.params.shixunId}/challenges/${this.props.match.params.checkpointId}/destroy_challenge_choose.json`;
axios.delete((url), { data: {
choose_id:this.props.match.params.choose_id
}})
.then((result)=>{
if(result.data.status===1){
window.location.href=`/shixuns/${this.props.match.params.shixunId}/challenges/${this.props.match.params.checkpointId}/editquestion`;
}
})
}
render() {
return (
<div>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb30">题干</p>
<div className="df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20">
<TPMMDEditor ref={this.props.neweditanswerRef} placeholder="请输入选择题的题干内容" mdID={'editquestioMDid'} refreshTimeout={1500}
needRecreate={true} watch={true} className="courseMessageMD" initValue={this.props.neweditanswerRefval}></TPMMDEditor>
</div>
<div style={{width: '57px'}} style={{display:this.props.newquestioMDvaluetype===true?"block":"none"}}>
<span className="color-orange mt8 fl" id="choose_name"
style={{display: 'inline'}}><i className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<p id="e_tip_neweditanswerQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
<p id="e_tips_neweditanswerQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
<div id="shixun_form" className="mt10">
{
this.props.questionlists===undefined||this.props.questionlists.length===0?"":this.props.questionlists.map((item,key)=>{
return(
<li className="clearfix pr mb20 df questionli" key={key}>
<label className="fl"><span
className={item.type===true?"option-item fr mr10 color-grey select-choice check-option-bg":"option-item fr mr10 color-grey select-choice"}
onClick={()=>this.props.selquestionlists(key)}
name="option_span"
data-tip-down="点击设置答案"
>{item.str}</span></label>
<textarea className="input-flex-40 fl candiate_answer"
name="question[cnt][]"
placeholder="请输入选项内容"
value={item.val}
autoHeight="true"
id={"question"+key}
onInput={(e)=>this.props.onInputoquestionption(e,key)}
style={{resize: 'none', height: '62px'}}></textarea>
<a className="position-delete option_icon_remove" onClick={()=>this.props.delquestionlists(key)}>
<i className="fa fa-times-circle color-grey-c font-16 fl"></i>
</a>
</li>
)
})
}
<p className="clearfix ml40">
<a onClick={()=>this.props.addquestionlists()}
className="fl edu-default-btn edu-greyline-btn mb20 option_icon_add">新增选项</a>
<span className="color-orange mt8 fr mr20" style={{display:this.props.newcnttype===true?"block":"none"}}id="chooce_error">
<i className="fa fa-exclamation-circle mr3"></i>
{this.props.newcnttypesum===0?"请选择答案":"选项内容不能为空"}
</span>
</p>
<li className="clearfix color-grey-9 ">
<label className="fl ml40">温馨提示点击选项标题可以直接设置答案选择多个答案即为多选题</label>
<label className="fr mr20">标准答案
<span d="current-option" className="color-orange">{this.props.questionlistss===undefined?"请点击正确选项":this.props.questionlistss.length===0? <span>{this.props.standard_answer}</span>:this.props.questionlistss.map((item,key)=>{
return(
<span key={key}>{item}</span>
)
})}</span>
</label>
</li>
</div>
</div>
</div>
<div className={"edu-back-white mb10 clearfix"}>
<div className={"padding40-20"}>
<p className="color-grey-6 font-16 mb30">参考答案</p>
<div className={"df mr20"}>
<div className={"flex1 mr20"}>
<TPMMDEditor ref={this.props.editanswersRef} placeholder="请输入各个选项的具体解析或其他相关信息" mdID={'editanswersRefConts'} refreshTimeout={1500}
watch={true} className="courseMessageMD" initValue={this.props.editanswersRefval}></TPMMDEditor>
</div>
<div className={"choose_names"} style={{display:this.props.newquestioMDvaluetypes===true?"block":"none"}}>
<span className="color-orange mt8 fl" id="choose_name"
style={{display: 'inline'}}><i className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<p id="e_tip_editanswersQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
<p id="e_tips_editanswersQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">难度系数</p>
<div className="clearfix mb40">
<RadioGroup value={this.props.answeshixunsGroup} className="fl mr40"
disabled={this.props.status===2?true:false}
onChange={this.props.status===2?"":(e)=>this.props.onshixunGroupanswe(e)}>
<Radio value={1}>简单</Radio>
<Radio value={2}>中等</Radio>
<Radio value={3}>困难</Radio>
</RadioGroup>
</div>
<p className="color-grey-6 font-16 mb30">奖励经验值</p>
<div className="clearfix"
// onMouseLeave={this.onshixunsmarkss}
id="challenge_score"
>
<span className="fl mr30 color-orange pt10">*</span>
<Select style={{width: 120}} className="winput-240-40 fl"
disabled={this.props.status===2?true:false}
onChange={this.props.status===2?"":(e)=>this.props.onshixunsansweSelect(e)}
// onMouseEnter={this.onshixunsmarks}
value={this.props.answeonshixunsmark}
// open={marktype}
>
{this.props.options}
</Select>
<p className="fl color-grey-9 font-12 ml20">
如果学员答题错误则不能得到相应的经验值<br/>
如果学员成功得到经验值那么将同时获得等值的金币奖励+10经验值+10金币
</p>
<span className="color-orange mt7 fl ml20 none" id="ex_value_notice"><i
className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">技能标签</p>
<div className="clearfix df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1">
<Input type="text"
className="winput-240-40 fl mr20"
id="input_task_tag"
placeholder="添加标签"
onInput={(e)=>this.props.shixunssanswerkill(e)}
value={this.props.shixunssanswerkillvalue}
onPressEnter={(e)=>this.props.clickshixunsanswerskill(e)}
onBlur={(e)=>this.props.clickshixunsanswerskill(e)}
/>
{/*<a className="white-btn orange-btn fl mt1 use_scope-btn ml20 mt5 mr20"*/}
{/*onClick={this.clickshixunsanswerskill}>+ 添加</a>*/}
<div className="ml15 color-grey-9 mt5">学员答题正确将获得技能否则不能获得技能
<span className=" color-orange ml20" style={{display:this.props.challenge_tagtype===true?"inline-block":"none"}} id="stage_name_notice">
<i className="fa fa-exclamation-circle mr3"></i>
</span>
</div>
<div className="mt20 clearfix" id="task_tag_content">
{
this.props.shixunsskillanswerlist.length === 0 ? "" : this.props.shixunsskillanswerlist.map((itme, key) => {
return (
<li className="task_tag_span" key={key}><span>{itme}</span>
<a onClick={() =>this.props.delshixunssnswerllist(key)}>×</a>
</li>
)
})
}
</div>
</div>
</div>
</div>
<div className="clearfix mt30" style={{display:this.props.identity>4||this.props.identity===undefined||this.props.power===false?"none":"block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={()=>this.props.answer_subit()}>提交</a>
<a href={this.props.go_back_url}
className="defalutCancelbtn fl">取消</a>
<a onClick={()=>this.delecbtns()}
className="delectshixuncdbtn fr">删除</a>
</div>
</div>
)
}
}

@ -1,84 +0,0 @@
import React, {Component} from 'react';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
export default class TpmQuestionMain extends Component {
constructor(props) {
super(props)
this.state = {
}
}
componentDidMount() {
}
render() {
return (
<div>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb30">任务名称</p>
<div className="df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20">
<input type="text"
className={this.props.questionInputvaluetype === true ? "input-100-45 greyInpus wind100" : "input-100-45 greyInput "}
maxLength="50"
name="challenge[subject]"
value={this.props.questionsInputvalue}
placeholder="请输入任务名称(此信息将提前展示给学员),例:计算学生的课程成绩绩点"
onInput={this.props.questionInputvalue}
/>
</div>
<div style={{width: '57px'}}>
<span
className={this.props.questionInputvaluetype === true ? "color-orange mt8 fl" : "color-orange mt8 fl none"}
id="new_shixun_name"><i className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">过关任务</p>
<div className="df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20">
<TPMMDEditor ref={this.props.contentMdRef} placeholder="请输入选择题的过关任务内容" mdID={'courseContentMD'} refreshTimeout={1500}
watch={true} className="courseMessageMD" initValue={this.props.contentMdRefval} height={700}></TPMMDEditor>
</div>
<div>
<span
className={this.props.questionInputvaluetypes === true ? "color-orange mt8 fl" : "color-orange mt8 fl none"}
id="new_shixun_pass"><i
className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<p id="e_tip_questioMDQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
<p id="e_tips_questioMDQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
</div>
<div className="clearfix mt30"
style={{display: this.props.identity > 4 || this.props.identity === undefined || this.props.power === false ? "none" : "block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={this.props.sumittype === true ? "" : this.props.clickquestionsumit}>提交</a>
<a href={this.props.go_back_url}
className="defalutCancelbtn fl">取消</a>
</div>
</div>
)
}
}

@ -1,219 +0,0 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal,Tooltip} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
const Option = Select.Option;
const RadioGroup = Radio.Group;
export default class TpmQuestionNew extends Component {
constructor(props) {
super(props)
this.state = {
}
}
componentDidMount() {
}
render() {
// console.log( this.props.questionlists)
return (
<div>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb30">题干</p>
<div className="df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20">
<TPMMDEditor ref={this.props.newquestioMDMdRef} placeholder="请输入选择题的题干内容" mdID={'newquestioMDid'} refreshTimeout={1500}
needRecreate={true} watch={true} className="courseMessageMD" initValue={this.props.contentMdRefval}></TPMMDEditor>
</div>
<div style={{width: '57px'}} style={{display:this.props.newquestioMDvaluetype===true?"block":"none"}}>
<span className="color-orange mt8 fl" id="choose_name"
style={{display: 'inline'}}><i className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<p id="e_tip_newquestioMDsQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
<p id="e_tips_newquestioMDsQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
<div id="shixun_form" className="mt10">
{
this.props.questionlists===undefined||this.props.questionlists.length===0?"":this.props.questionlists.map((item,key)=>{
return(
<li className="clearfix pr mb20 df questionli" key={key}>
<label className="fl"><span
className={item.type===true?"option-item fr mr10 color-grey select-choice check-option-bg":"option-item fr mr10 color-grey select-choice"}
onClick={()=>this.props.selquestionlists(key)}
name="option_span"
data-tip-down="点击设置答案"
>{item.str}</span></label>
<textarea className="input-flex-40 fl candiate_answer"
name="question[cnt][]"
placeholder="请输入选项内容"
value={item.val}
autoHeight="true"
id={"question"+key}
onInput={(e)=>this.props.onInputoquestionption(e,key)}
style={{resize: 'none', height: '62px'}}></textarea>
<a className="position-delete option_icon_remove" onClick={()=>this.props.delquestionlists(key)}>
<Tooltip placement="bottom" title={"删除"}>
<i className="fa fa-times-circle color-grey-c font-16 fl"></i>
</Tooltip>
</a>
</li>
)
})
}
<p className="clearfix ml40">
<a onClick={()=>this.props.addquestionlists()}
className="fl edu-default-btn edu-greyline-btn mb20 option_icon_add">新增选项</a>
<span className="color-orange mt8 fr mr20" style={{display:this.props.newcnttype===true?"block":"none"}}id="chooce_error">
<i className="fa fa-exclamation-circle mr3"></i>
{this.props.newcnttypesum===0?"请选择答案":"选项内容不能为空"}
</span>
</p>
<li className="clearfix color-grey-9 ">
<label className="fl ml40">温馨提示点击选项标题可以直接设置答案选择多个答案即为多选题</label>
<label className="fr mr20">标准答案
<span id="current-option" className="color-orange">{this.props.questionlistss===undefined?"请点击正确选项":this.props.questionlistss.length===0? <span>{this.props.standard_answer}</span>:this.props.questionlistss.map((item,key)=>{
return(
<span key={key}>{item}</span>
)
})}</span>
</label>
</li>
</div>
</div>
</div>
<div className={"edu-back-white mb10 clearfix"}>
<div className={"padding40-20"}>
<p className="color-grey-6 font-16 mb30">参考答案</p>
<div className={"df"}>
<div className={"flex1 mr20"}>
<TPMMDEditor ref={this.props.newquestioMDMdCont} placeholder="请输入各个选项的具体解析或其他相关信息" mdID={'newquestioMDMdConts'} refreshTimeout={1500}
needRecreate={true} watch={true} className="courseMessageMD" initValue={this.props.newquestioMDMdContval}></TPMMDEditor>
</div>
<div className={"choose_names"} style={{display:this.props.newquestioMDvaluetypes===true?"block":"none"}}>
<span className="color-orange mt8 fl" id="choose_name" style={{display: 'inline'}}><i className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<p id="e_tip_challenge_choose_answerQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
<p id="e_tips_challenge_choose_answerQuestion" className="edu-txt-right color-grey-cd font-12 pdr20"></p>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">难度系数</p>
<div className="clearfix mb40">
<RadioGroup value={this.props.answeshixunsGroup} className="fl mr40"
onChange={(e)=>this.props.onshixunGroupanswe(e)}
>
<Radio value={1}>简单</Radio>
<Radio value={2}>中等</Radio>
<Radio value={3}>困难</Radio>
</RadioGroup>
</div>
<p className="color-grey-6 font-16 mb30">奖励经验值</p>
<div className="clearfix"
// onMouseLeave={this.onshixunsmarkss}
>
<span className="fl mr30 color-orange pt10">*</span>
<Select style={{width: 120}} className="winput-240-40 fl"
id="challenge_score"
onChange={(e)=>this.props.onshixunsansweSelect(e)}
// onMouseEnter={this.onshixunsmarks}
// open={marktype}
value={this.props.answeonshixunsmark}
>
{this.props.options}
</Select>
<p className="fl color-grey-9 font-12 ml20">
如果学员答题错误则不能得到相应的经验值<br/>
如果学员成功得到经验值那么将同时获得等值的金币奖励+10经验值+10金币
</p>
<span className="color-orange mt7 fl ml20 none" id="ex_value_notice"><i
className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">技能标签</p>
<div className="clearfix df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1">
<Input type="text"
className="winput-240-40 fl mr20"
id="input_task_tag"
placeholder="添加标签"
onInput={(e)=>this.props.shixunssanswerkill(e)}
value={this.props.shixunssanswerkillvalue}
onPressEnter={(e)=>this.props.clickshixunsanswerskill(e)}
onBlur={(e)=>this.props.clickshixunsanswerskill(e)}
/>
{/*<a className="white-btn orange-btn fl mt1 use_scope-btn ml20 mt5 mr20"*/}
{/*onClick={this.clickshixunsanswerskill}>+ 添加</a>*/}
<div className="ml15 color-grey-9 mt5">学员答题正确将获得技能否则不能获得技能
<span className=" color-orange ml20" style={{display:this.props.challenge_tagtype===true?"inline-block":"none"}} id="stage_name_notice">
<i className="fa fa-exclamation-circle mr3"></i>
</span>
</div>
<div className="mt20 clearfix" id="task_tag_content">
{
this.props.shixunsskillanswerlist.length === 0 ? "" : this.props.shixunsskillanswerlist.map((itme, key) => {
return (
<li className="task_tag_span" key={key}><span>{itme}</span>
<a onClick={()=>this.props.delshixunssnswerllist(key)}>×</a>
</li>
)
})
}
</div>
</div>
</div>
</div>
<div className="clearfix mt30" style={{display:this.props.identity>4||this.props.identity===undefined||this.props.power===false?"none":"block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={this.props.answer_subit}>提交</a>
<a href={this.props.go_back_url}
className="defalutCancelbtn fl">取消</a>
</div>
</div>
)
}
}

@ -1,269 +0,0 @@
.CodeMirror-scroll {
overflow: auto !important;
margin-bottom: -30px;
margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none;
position: relative;
}
a.white-btn.orange-btn:hover {
border: 1px solid #F06200;
color: #FFF !important;
}
.flex1 a.white-btn.orange-btn:hover {
border: 1px solid #F06200;
color: #FFF !important;
}
/*.challenge_nav li a{*/
/*color:#000 !important;*/
/*}*/
.questionli{
width: 95%;
margin-left: 37px;
}
#directory_file{
height:200px;
overflow-y:auto;
background:#f5f5f5;
padding:10px;
}
.directory_filepath{
width:120px;
text-align:left;
}
a{
text-decoration: none;
color: #05101a;
}
.repository_url_tippostion{
position: absolute;
left: 22%;
width: 500px;
top: 100%;
}
.top-black-trangleft {
display: block;
border-width: 8px;
position: absolute;
top: -16px;
/* right: 4px; */
border-style: dashed solid dashed dashed;
border-color: transparent transparent rgba(5,16,26,0.6) transparent;
font-size: 0;
line-height: 0;
}
#exercisememoMD .CodeMirror {
margin-top: 31px !important;
height: 370px !important;
/*width: 579px !important;*/
}
#exercisememoMD .editormd-preview {
top: 40px !important;
height: 370px !important;
width: 578px !important;
}
#exercisememoMD{
/*height: 700px !important;*/
}
#questioMD{
/*width: 95% !important;*/
height: 417px !important;
margin-left: 0% !important;
}
#questioMD .CodeMirror {
/*width: 550.5px !important;*/
margin-top: 31px !important;
height: 374px !important;
}
#questioMD .editormd-preview {
top: 40px !important;
height: 375px !important;
width: 550px !important;
}
#newquestioMD .CodeMirror {
/*width: 549px !important;*/
margin-top: 31px !important;
height: 364px !important;
}
#newquestioMD .editormd-preview {
top: 40px !important;
height: 364px !important;
width: 578px !important;
}
#challenge_choose_answer .CodeMirror {
margin-top: 31px !important;
height: 364px !important;
/*width: 578px !important;*/
}
#challenge_choose_answer .editormd-preview {
top: 40px !important;
height: 364px !important;
width: 578px !important;
}
#neweditanswer .CodeMirror {
margin-top: 31px !important;
height: 364px !important;
/*width: 549.5px !important;*/
}
#neweditanswer .editormd-preview {
top: 40px !important;
height: 364px !important;
width: 551px !important;
}
#repository_url_tip {
top: 30px !important;
left: 249px !important;
width: 292px !important;
}
#editanswers .CodeMirror{
/*width: 548px !important;*/
height: 358px !important;
margin-top: 30px !important;
}
#editanswers .editormd-preview{
width: 578px !important;
height: 358px !important;
}
#newquestioMDs .CodeMirror{
/*width: 510px !important;*/
height: 358px !important;
margin-top: 30px !important;
}
#newquestioMDs .editormd-preview{
width: 578px !important;
height: 358px !important;
}
.choose_names{
width: 80px;
margin-left: 20px;
}
#answerMD .CodeMirror{
/*width: 569px !important;*/
height: 600px !important;
margin-top: 30px !important;
}
#answerMD .editormd-preview{
width: 578px !important;
height: 600px !important;
}
#answerMD {
height: 600px !important;
}
.textareavalue{
width: 100%;
padding: 5px;
box-sizing: border-box;
}
.greyInput{
width: 107%;
}
.greyInpus{
width: 100%;
}
.pdr20{
padding-right:20px;
}
.winput-240-40s {
background-color: #F5F5F5;
}
.winput-240-40s:focus{
background-color: #fff;
}
.input-100-45{
background-color: #F5F5F5;
}
.input-100-45:focus{
background-color: #fff;
}
.wind100{
width:100% !important;
}
.color-bule-tip {
color: #5485f7 !important;
}
.martopf4{
margin-top:-4px;
}
.headdfgf{
display: block;
width: 100px;
height: 30px;
line-height: 30px;
float: left;
}
.color979797{
color: #979797 !important;
}
.border-left{
width: 0;
height: 0;
border-bottom: 6px solid transparent;
border-right: 6px solid #cccbcb;
border-top: 6px solid transparent;
position: absolute;
left: 30px;
top: 12px;
}
.border-left span{
display: block;
width: 0;
height: 0;
border-bottom: 6px solid transparent;
border-right: 6px solid #fff;
border-top: 6px solid transparent;
position: absolute;
left: 1px;
top: -6px;
z-index: 10;
}
.fillTip{
position: absolute;
left: 36px;
top: 2px;
width: 125px;
font-size: 12px;
display: block;
padding: 5px;
border: 1px solid #eaeaea;
border-radius: 5px;
box-sizing: border-box;
height: 32px;
line-height: 20px;
font-family: "微软雅黑","宋体";
}

@ -1,122 +0,0 @@
import React, {Component} from 'react';
import {getUrl} from 'educoder';
let path = getUrl("/editormd/lib/");
const $ = window.$;
function create_editorMD(id, width, high, placeholder, imageUrl, callback) {
var editorName = window.editormd(id, {
width: width,
height: high,
path: path, // "/editormd/lib/"
syncScrolling: "single",
tex: true,
tocm: true,
emoji: true,
taskList: true,
codeFold: true,
searchReplace: true,
htmlDecode: "style,script,iframe",
sequenceDiagram: true,
autoFocus: false,
toolbarIcons: function () {
// Or return editormd.toolbarModes[name]; // full, simple, mini
// Using "||" set icons align right.
return ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"]
},
toolbarCustomIcons: {
testIcon: "<a type=\"inline\" class=\"latex\" ><div class='zbg'></div></a>",
testIcon1: "<a type=\"latex\" class=\"latex\" ><div class='zbg_latex'></div></a>"
},
//这个配置在simple.html中并没有但是为了能够提交表单使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中方便post提交表单。
saveHTMLToTextarea: true,
// 用于增加自定义工具栏的功能可以直接插入HTML标签不使用默认的元素创建图标
dialogMaskOpacity: 0.6,
placeholder: placeholder,
imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
imageUploadURL: imageUrl,//url
onload: function () {
// this.previewing();
$("#" + id + " [type=\"latex\"]").bind("click", function () {
editorName.cm.replaceSelection("```latex");
editorName.cm.replaceSelection("\n");
editorName.cm.replaceSelection("\n");
editorName.cm.replaceSelection("```");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line - 1, 0);
});
$("#" + id + " [type=\"inline\"]").bind("click", function () {
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");
$("[type=\"latex\"]").attr("title", "多行公式");
window.md_elocalStorage(editorName, `MemoQuestion_${id}`, `${id}Question`);
callback && callback()
}
});
return editorName;
}
export default class TPMeditorMD extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
}
questioMD=(initValue, id)=> {
this.contentChanged = false;
const placeholder = "";
// amp;
// 编辑时要传memoId
// const imageUrl = `/upload_with_markdown?container_id=&container_type=Memo`;
const imageUrl = `/api/attachments.json`;
// 创建editorMd
let questio_editormd = create_editorMD(id, '100%', 400, placeholder, imageUrl, () => {
setTimeout(() => {
questio_editormd.resize()
questio_editormd.cm && questio_editormd.cm.refresh()
}, 500)
if (initValue != undefined) {
questio_editormd.setValue(initValue)
}
questio_editormd.cm.on("change", (_cm, changeObj) => {
console.log('....contentChanged')
this.contentChanged = true;
})
});
this.questio_editormd = questio_editormd;
window.questio_editormd = questio_editormd;
}
componentWillReceiveProps(newProps) {
this.questioMD(newProps.value,newProps.id)
}
render() {
return (
<div className="padding10-20 edu-back-greyf5 radius4" id="questioMD">
<textarea style={{display: 'none'}} id="questioadd" name="content"> </textarea>
<div className="CodeMirror cm-s-defualt">
</div>
</div>
)
}
}

@ -1,57 +0,0 @@
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
class TPMNav extends Component {
render() {
const { user, match, shixun, secret_repository } = this.props;
let isAdminOrCreator = false;
if (user) {
isAdminOrCreator = user.admin || user.manager
}
const shixunId = match.params.shixunId;
// const challengesPath = `/shixuns/${shixunId}/challenges`;
// console.log(this.props.propaedeutics)
const challengesPath = `/shixuns/${shixunId}/challenges`;
// console.log(match.path)
return (
<div className="bor-bottom-greyE clearfix pl20 pr20 pt40 pb20 edu-back-white challengeNav">
<Link
to={challengesPath}
className={match.path === "/shixuns/:shixunId"|| match.path ==="/shixuns/:shixunId/challenges"? " active fl mr40": 'fl mr40'}>任务</Link>
{
this.props.propaedeutics===undefined?"":this.props.propaedeutics===false?"":<Link to={`/shixuns/${shixunId}/propaedeutics`}
className={`${match.url.indexOf('propaedeutics') != -1 ? 'active' : ''} fl mr40 `}
id={"knowledge"}
>背景知识</Link>
}
{ this.props.identity >4||this.props.identity===undefined ?"":<Link to={`/shixuns/${shixunId}/repository`}
className={`${match.url.indexOf('/repository') != -1 ? 'active' : ''} fl mr40`}>版本库</Link>}
{this.props.identity >4||this.props.identity===undefined ?"": secret_repository && <Link to={`/shixuns/${shixunId}/secret_repository`}
className={`${match.url.indexOf('secret_repository') != -1 ? 'active' : ''} fl mr40`}>私密版本库</Link>}
<Link to={`/shixuns/${shixunId}/collaborators`}
className={`${match.url.indexOf('collaborators') != -1 ? 'active' : ''} fl mr40`}>合作者</Link>
<Link to={`/shixuns/${shixunId}/shixun_discuss`}
className={`${match.url.indexOf('shixun_discuss') != -1 ? 'active' : ''} fl mr40`}>评论</Link>
<Link to={`/shixuns/${shixunId}/ranking_list`}
className={`${match.url.indexOf('ranking_list') != -1 ? 'active' : ''} fl mr40`}>排行榜</Link>
{this.props.identity >2||this.props.identity===undefined?"":<Link to={`/shixuns/${shixunId}/audit_situation`}
className={`${match.url.indexOf('audit_situation') != -1 ? 'active' : ''} fl`}>审核情况</Link>}
<a
href={`/shixuns/${shixunId}/settings`} className="edu-default-btn edu-blueline-btn ml20 fr"
style={{display: this.props.identity >4||this.props.identity===undefined ? "none" : 'block'}}
>配置</a>
</div>
);
}
}
export default TPMNav;

@ -1,205 +0,0 @@
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import axios from 'axios';
import { getImageUrl,} from "educoder";
import './TPMright.css';
import {Icon,Tooltip} from 'antd';
// import "antd/dist/antd.css";
class TPMRightSection extends Component {
constructor(props) {
super(props)
this.state = {
TPMRightSection:false,
clickNewsubscripttype:false
}
}
// componentDidMount() {
// let id=this.props.match.params.shixunId;
//
// let shixunsDetailsURL=`/shixuns/`+id+`/show_right.json`;
//
// axios.get(shixunsDetailsURL).then((response)=> {
// if(response.status===200){
// this.setState({
// TPMRightSectionData: response.data
// });
// }
// }).catch((error)=>{
// console.log(error)
// });
// }
// shouldComponentUpdate(nextProps, nextState) {
// return nextProps.TPMRightSectionData !== this.state.TPMRightSectionData
// }
clickNewsubscript=(val)=>{
if(val===0){
this.setState({
TPMRightSection:true,
clickNewsubscripttype:true
})
}else{
this.setState({
TPMRightSection:false,
clickNewsubscripttype:false
})
}
}
render() {
let {TPMRightSection,clickNewsubscripttype}=this.state;
let {TPMRightSectionData}=this.props
return (
<div>
{
TPMRightSectionData===undefined?"":
<div>
<div className="edu-back-white padding40-20 mb10">
<p className="font-16 mb20">创建者</p>
<div className="df">
<a href={TPMRightSectionData===undefined?"":TPMRightSectionData.creator===undefined?"":`/users/${TPMRightSectionData.creator.login}/courses`}>
<img alt="头像" className="radius mr10" height="80" src={getImageUrl(TPMRightSectionData===undefined?"":TPMRightSectionData.creator===undefined?"":'images/'+TPMRightSectionData.creator.image_url+"?1532489442")} width="80" />
</a>
<div className="flex1">
<p className="mb20">{TPMRightSectionData===undefined?"":TPMRightSectionData.creator===undefined?"":TPMRightSectionData.creator.name}</p>
<div className="clearfix">
<span>发布 {TPMRightSectionData.user_shixuns_count}</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>
</div>
{
TPMRightSectionData === undefined ? "" :TPMRightSectionData.tags===undefined?"": TPMRightSectionData.tags.length === 0 ? "" :
<div className="edu-back-white padding40-20 mb10 relative">
<p className="font-16 mb20">技能标签 <span className="color-grey-c">{TPMRightSectionData.tags.length}</span></p>
<div className={TPMRightSection===false?"newedbox newedboxheight":"newedbox newminheight"}>
<div className="clearfix" id="boxheight">
{ TPMRightSectionData.tags.map((item,key)=>{
return(
<span className={item.status===false?"newedu-filter-btn fl":"edu-filter-btn29BD8B fl"}
style={{display:item.tag_name===" "||item.tag_name===""?"none":""}}
key={key}>{item.tag_name}</span>
)})
}
</div>
</div>
<div className={TPMRightSectionData.tags.length>15&&clickNewsubscripttype===false?"newsubscript mb9 color-grey-9":"newsubscript mb9 color-grey-9 none"}
data-tip-down="显示全部"
onClick={()=>this.clickNewsubscript(0)}><span className="mr8">...</span><Icon type="caret-down" />
</div>
<div className={clickNewsubscripttype===false?"newsubscript mb9 color-grey-9 none":"newsubscript mb9 color-grey-9"}
data-tip-down="显示全部"
onClick={()=>this.clickNewsubscript(1)}><Icon type="caret-up" />
</div>
</div>
}
<div className="padding20 edu-back-white mb10 mt10" style={{
display: TPMRightSectionData === undefined?"none":TPMRightSectionData.paths===undefined?"":TPMRightSectionData.paths.length === 0 ? "none" : "block"
}}>
<p className="mb20 font-16 clearfix">所属课程</p>
<div className="recommend-list" >
{
TPMRightSectionData===undefined?"":TPMRightSectionData.paths===undefined?"":TPMRightSectionData.paths.map((i,k)=>{
return(
<div className="recomments clearfix df" key={k}>
<a href={"/paths/"+i.id} height="96" width="128" target="_blank">
<img alt="实训" height="96" src={"/"+i.image_url} width="128" />
</a>
<div className="ml10 flex1">
<a href={"/paths/"+i.id} target="_blank" data-tip-down={i.name} className="color-grey-6 task-hide mb12 recomment-name">{i.name}</a>
<p className="clearfix mt8 font-12 color-grey-B4">
<Tooltip placement="bottom" title={"章节"}>
<span className="mr10 fl squareIconSpan"><i className="iconfont icon-shixun fl mr3"></i>{i.stages_count}</span>
</Tooltip>
{/*<Tooltip placement="bottom" title={"经验值"}>*/}
{/*<span className="mr10 fl squareIconSpan"><i className="iconfont icon-jingyan fl mr3"></i>{i.score_count}</span>*/}
{/*</Tooltip>*/}
<Tooltip placement="bottom" title={"学习人数"}>
<span className="mr10 fl squareIconSpan"><i className="iconfont icon-chengyuan fl mr3"></i>{i.members_count}</span>
</Tooltip>
</p>
</div>
</div>
)
})
}
</div>
</div>
{TPMRightSectionData === undefined?"":TPMRightSectionData.paths===undefined?"":TPMRightSectionData.paths.length === 0 ? "" :
this.props.user&&this.props.user.main_site===true?<div className="padding20 edu-back-white"
style={{
display:
TPMRightSectionData === undefined?"none":TPMRightSectionData.recommands===undefined?"none":TPMRightSectionData.recommands.length === 0 ? "none" : "block"
}}
>
<p className="mb20 font-16 clearfix">推荐实训</p>
<div className="recommend-list">
{
TPMRightSectionData===undefined?"":TPMRightSectionData.recommands===undefined?"":TPMRightSectionData.recommands.map((item,key)=>{
return(
<div className="recomments clearfix df" key={key}>
<a href={"/shixuns/"+item.identifier+"/challenges"} target="_blank">
<img alt="69?1526971094" height="96" src={"/"+item.pic} width="128"/>
</a>
<div className="ml10 flex1">
<Tooltip placement="bottom" title={item.name}>
<a href={"/shixuns/"+item.identifier+"/challenges"} target="_blank" className="color-grey-6 task-hide mb12 recomment-name">{item.name}</a>
</Tooltip>
<p className="clearfix mt8 font-12 color-grey-B4">
{item.stu_num} 人学习
</p>
<p className="edu-txt-right color-orange pr10">{item.level}</p>
</div>
</div>
)
})
}
</div>
</div>:""
}
</div>
}
</div>
)
}
}
export default TPMRightSection;

@ -1,79 +0,0 @@
/*bæ°æ ‡ç­¾*/
.newedu-filter-btn{
display: block;
float: left;
padding: 0 9px;
/*height: 28px;*/
line-height: 28px;
border-radius: 14px;
background-color: #F5F5F5;
color: #666;
margin-right: 10px;
margin-bottom: 9px;
}
.newedbox{
/*flex-wrap: wrap;*/
/*display: -webkit-flex; !* Safari *!*/
/*display: flex;*/
width: 360px;
position:relative;
overflow: hidden;
}
.newsubscript{
position: absolute;
right: 23px;
bottom: 16px;
cursor: pointer;
}
.newsubscript:hover{
color:deepskyblue;
}
.edu-filter-btn29BD8B{
display: block;
float: left;
padding: 0 9px;
height: 28px;
line-height: 28px;
border-radius: 14px;
background-color: #29BD8B;
color: #FFF;
margin-right: 10px;
margin-bottom: 9px;
}
.relative{
position:relative;
}
.newedboxheight{
max-height: 177px;
overflow-y: hidden;
}
.newminheight{
/*max-height: 670px;*/
max-height: 300px;
overflow-y: auto;
}
.delSubentry{
font-size:7px;
font-family:MicrosoftYaHei;
font-weight:400;
color:rgba(76,172,255,1);
line-height:9px;
cursor: pointer;
}
.operationalter .delSubentry{
font-size:15px !important;
line-height: 25px;
}
/*临时的tpi关闭按é®æ ·å¼*/
.headerRight a {
color: #1a3f5f;
}
/*实训做成弹窗a标签样式调整*/
.-task-list-title a:link, .-task-list-title a:visited {color: #bcc6cd;}
.-task-list-title a:hover{
color: #459be5;
}
.headerLeft .-header-right{
height: 32px;
}

@ -1,153 +0,0 @@
// import React, { useState, useEffect, memo } from 'react';
// import axios from 'axios'
// import { Modal, Input } from 'antd';
// function RepositoryChooseModal(props) {
// const [trees, setTrees] = useState([])
// const [path, setPath] = useState('')
// const [pathArray, setPathArray] = useState([{val: "根目录/", path: ""}])
// const [modalVisible, setModalVisible] = useState(true)
// useEffect(() => {
// repository('')
// }, [])
// function onOk() {
// }
// function onCancel() {
// }
// /**
// 点nav 会传入key
// 点item 会传入 newPath
// item => name, type type tree/leaf
// */
// const repository=(item, key, newPath)=>{
// let newPathArray = [] //
// //
// if (key) {
// for(var i=0; i<=key; i++){
// newPathArray.push(pathArray[i])
// }
// } else if (item) {
// newPathArray = pathArray.slice(0)
// newPathArray.push({val: item.name, path: pathArray[pathArray.length - 1] + "/" + item.name})
// }
// const path = item || key ? newPathArray[newPathArray.length - 1] : ''
// let id = props.match.params.shixunId;
// let url ="/shixuns/"+id+"/repository.json";
// axios.post(url,{
// path: path
// }).then((response) => {
// if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
// }else{
// setTrees(response.data.trees)
// setPath(path)
// pathArray(newPathArray)
// }
// }).catch((error) => {
// console.log(error)
// });
// }
// const savegetfilepath=(value)=>{
// const state = {}
// let {selectpath,saveshixunfilepath,pathtype} = state
// if(pathtype===1){
// let newselectpath;
// if(saveshixunfilepath==="shixunfilepathplay"){
// newselectpath=value
// }else{
// const type = selectpath.split('');
// let types=false;
// for(var i=0; i<type.length; i++){
// if(type[i]===value){
// types=true
// return
// }
// }
// if(types===false){
// newselectpath=selectpath+value+ ""
// }else{
// newselectpath=selectpath
// }
// }
// // this.setState({
// // // selectpatharr:newarr,
// // selectpath: newselectpath,
// // })
// }
// }
// const goblakepath=(path,key)=>{
// }
// function sendgetfilepath() {
// }
// return (
// <Modal
// keyboard={false}
// title="文件路径"
// visible={modalVisible}
// closable={false}
// footer={false}
// >
// <div className="task_popup_con">
// <div className="newupload_conbox clearfix">
// <ul id="directory_file">
// {/*文件导航*/}
// {
// pathArray.length===0?"":pathArray.map((item,key)=>{
// return(
// <a className="f14 fb" onClick={()=>goblakepath(item.path,key,item)}>{item.val}</a>
// )
// })
// }
// {/*文件*/}
// {trees === undefined || trees === null ? "" : trees.map((item, key) => {
// return(
// <li className="entry" key={key}>
// <div className="filename_no_report hidden">{
// item.type==="tree"?<a onClick={()=>sendgetfilepath(item.name,item.type,path+item.name)} data-remote="true">
// <i className="iconfont icon-wenjianjia color-blue mr2"></i>
// {path+item.name}</a>:<a data-remote="true">
// <i className="iconfont icon-zuoye color-blue mr2"></i>
// <span onClick={()=>savegetfilepath(path+item.name,item.type)}>{path+item.name}</span>
// </a>
// }
// </div>
// </li>
// )
// })}
// </ul>
// <div className="clearfix mt20">
// <label className="fl mt5 directory_filepath">选中的文件路径:</label>
// <Input id="points_tusi" placeholder="选中的文件路径" className="fl input-60-40"
// style={{width:"400px"}}
// onInput={(e)=>saveselectpath(e)}
// value={path}/>
// </div>
// <a className="task-btn task-btn-orange fr"
// style={{marginTop: '20px',marginLeft:'20px'}} id="add_path" onClick={()=>onOk()}>确定</a>
// <a className="pop_close task-btn mb10 fr"
// style={{marginTop: '20px'}} id="back_page" onClick={()=>onCancel()}>取消</a>
// </div>
// </div>
// </Modal>
// )
// }
// export default RepositoryChooseModal

File diff suppressed because it is too large Load Diff

@ -1,19 +0,0 @@
import React, { Component } from 'react';
import axios from 'axios';
export default class TPMNewshixuns extends Component {
constructor(props) {
super(props)
this.state = {
}
}
render() {
return (
);
}
}

@ -1,397 +0,0 @@
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
direction: ltr;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: -20px;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
min-height: 100%;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */ border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
padding: 0.1px; /* Force widget margins to stay inside of the container */
}
.CodeMirror-widget {}
.CodeMirror-rtl pre { direction: rtl; }
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, .4);
}
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
.radioStyle{
display: block;
height: 30px;
}
a.white-btn.use_scope-btn:hover{
}
.shixunScopeInput{
width:218px;
height:33px;
display:block;
margin-bottom:15px;
}
#memoMD .CodeMirror {
/*width: 576px !important;*/
margin-top: 31px !important;
height: 364px !important;
}
#memoMD .editormd-preview {
width: 578px !important;
top: 40px !important;
height: 364px !important;
}
.ml36{
margin-left: 26px;
}
#person-unit a.white-btn.use_scope-btn:hover {
border: 1px solid #F06200;
color:#FFF !important;
}
.shixunspanred{
margin-left: 142px;
margin-top: 5px;
margin-bottom: 5px;
}
.ml82{
margin-left: 82px;
}
.ant-btn-primary.active, .ant-btn-primary:active {
color: #fff;
background-color: #096dd9;
border-color: #096dd9;
}
.ant-btn:hover, .ant-btn:focus, .ant-btn:active, .ant-btn.active{
background-color: #4CACFF;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 720 B

@ -1,676 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { getImageUrl ,markdownToHTML, configShareForCustom} from 'educoder'
import { CircularProgress } from 'material-ui/Progress';
import { Modal, Spin, Tooltip ,message,Icon} from 'antd';
import 'antd/lib/pagination/style/index.css';
import '../shixunchildCss/Challenges.css'
import axios from 'axios';
import AccountProfile from"../../../user/AccountProfile";
const $ = window.$;
class Challenges extends Component {
constructor(props) {
super(props)
this.state = {
ChallengesDataList: undefined,
operate: true,
startbtns: false,
sumid: "",
sumidtype: false,
startshixunCombattype:false,
shixunsreplace:false,
shixunsmessage:"",
hidestartshixunsreplacevalue:"",
operationstrue:false,
isSpin:false,
}
}
ChallengesList = () => {
let id = this.props.match.params.shixunId;
let ChallengesURL = `/shixuns/` + id + `/challenges.json`;
axios.get(ChallengesURL).then((response) => {
if (response.status === 200) {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
configShareForCustom(this.props.shixunsDetails.name, response.data.description)
this.setState({
ChallengesDataList: response.data,
sumidtype: false,
});
}
}
}).catch((error) => {
console.log(error)
});
}
componentDidMount() {
setTimeout(this.ChallengesList(), 1000);
}
updatamakedown = (id) => {
setTimeout(() => {
var shixunDescr = window.editormd.markdownToHTML(id, {
htmlDecode: "style,script,iframe",
taskList: true,
tex: true,
flowChart: true,
sequenceDiagram: true
});
$("#" + id + " p:first").addClass("ReactMarkdown");
}, 200)
}
// 关卡的上移下移操作
operations = (sumid, type) => {
this.setState({
operationstrue:true
})
let { ChallengesDataList } = this.state;
let operationUrl;
if (type === "up") {
operationUrl = "/shixuns/" + ChallengesDataList.shixun_identifier + "/challenges/" + sumid + "/index_up.json";
} else if (type === "down") {
operationUrl = "/shixuns/" + ChallengesDataList.shixun_identifier + "/challenges/" + sumid + "/index_down.json";
}
if (this.state.operate) {
this.setState({
operate: false
});
axios.get(operationUrl).then((response) => {
if (response.status === 200) {
this.setState({
operate: true,
operationstrue:false
});
this.ChallengesList();
}
}).catch((error) => {
console.log(error);
this.setState({
operate: true,
operationstrue:false
});
this.ChallengesList()
})
}
}
delOperations = (sumid) => {
this.setState({
sumid: sumid,
sumidtype: true
})
}
clonedelOperationss = () => {
this.setState({
sumidtype: false
})
}
delOperationss = () => {
let { ChallengesDataList, sumid } = this.state;
let operationUrl = "/shixuns/" + ChallengesDataList.shixun_identifier + "/challenges/" + sumid+".json"
if (this.state.operate) {
this.setState({
operate: false,
sumidtype: false
})
axios.delete(operationUrl, {
withCredentials: true
}).then((response) => {
if (response.status === 200) {
this.setState({
operate: true,
sumidtype: false
});
this.ChallengesList();
}
this.ChallengesList()
}).catch((error) => {
console.log(error);
this.setState({
operate: true,
sumidtype: false
});
this.ChallengesList()
})
}
}
startgameid=(id)=>{
let url = "/shixuns/" + id + "/shixun_exec.json";
axios.get(url).then((response) => {
if (response.data.status === -2) {
this.setState({
shixunsreplace:true,
hidestartshixunsreplacevalue:response.data.message+".json"
})
} else if (response.data.status === -1) {
console.log(response)
}else if(response.data.status===-3){
this.setState({
shixunsmessage:response.data.message,
startshixunCombattype:true,
})
} else {
window.location.href = "/tasks/" + response.data.game_identifier;
// window.location.href = path
// let path="/tasks/"+response.data.game_identifier;
// this.props.history.push(path);
}
}).catch((error) => {
});
}
hidestartshixunsreplace=(url)=>{
this.setState({
isSpin:true,
})
axios.get(url).then((response) => {
if(response.status===200){
// let path="/shixuns/"+response.data.shixun_identifier+"/challenges";
// this.props.history.push(path);
message.success('重置成功,正在进入实训!');
this.startgameid(response.data.shixun_identifier);
this.setState({
shixunsreplace:false,
isSpin:false,
})
// message.success('重置成功,正在进入实训!');
// this.startshixunCombat();
}}
).catch((error) => {
});
}
//编辑实训题目选择题
EditTraining=(type, ids, path)=>{
let { ChallengesDataList } = this.state;
window.location.href = "/shixuns/" + ChallengesDataList.shixun_identifier + "/challenges/" + ids + path;
}
//开始实战按钮
startshixunCombat = (type, ids, id) => {
if(this.props.checkIfLogin()===false){
this.props.showLoginDialog()
return
}
if(this.props.checkIfProfileCompleted()===false){
this.setState({
AccountProfiletype:true
})
return
}
// if(this.props.checkIfProfessionalCertification()===false){
// this.setState({
// AccountProfiletype:true
// })
// return
// }
let { ChallengesDataList } = this.state;
// let id = this.props.match.params.shixunId;
this.setState({
startbtns: true
})
let url = "/shixuns/" + ChallengesDataList.shixun_identifier + "/shixun_exec.json?challenge_id="+id;
axios.get(url).then((response) => {
if (response.data.status === -2) {
this.setState({
startbtns:false,
shixunsreplace:true,
hidestartshixunsreplacevalue:response.data.message+".json"
})
} else if (response.data.status === -1) {
this.setState({
startbtns: false
})
console.log(response)
}else if(response.data.status===-3){
this.setState({
shixunsmessage:response.data.message,
startshixunCombattype:true,
startbtns:false
})
} else {
window.location.href = "/tasks/" + response.data.game_identifier;
// window.location.href = path
// let path="/tasks/"+response.data.game_identifier;
// this.props.history.push(path);
}
}).catch((error) => {
});
// if(path===null){
// }else{
// if (type > 4 || type === false) {
// window.location.href = path;
// } else {
//
// }
// }
}
hidestartshixunCombattype=()=>{
this.setState({
startshixunCombattype:false
})
}
hideAccountProfile=()=>{
this.setState({
AccountProfiletype:false
})
}
render() {
let { ChallengesDataList, startbtns, sumidtype ,startshixunCombattype,shixunsreplace,shixunsmessage,hidestartshixunsreplacevalue,operationstrue,AccountProfiletype} = this.state;
let { loadingContent } = this.props;
if (ChallengesDataList != undefined) {
this.updatamakedown("ReactMarkdown")
}
let id = this.props.match.params.shixunId;
const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;
return (
<React.Fragment>
{AccountProfiletype===true?<AccountProfile
hideAccountProfile={()=>this.hideAccountProfile()}
{...this.props}
{...this.state}
/>:""}
{loadingContent ?
<CircularProgress size={40} thickness={3} style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: '200px',
display: 'block'
}} /> :
<div className="mt30 pl20 pr20">
<p className="clearfix mb20">
{this.props.identity < 5 && ChallengesDataList&&ChallengesDataList.shixun_status=== 0 ?
<Link to={"/shixuns/" + id + "/challenges/new"}
className="white-btn edu-greenline-btn fr addshixuns"
// data-tip-down="新增代码编辑类型任务"
>
<Tooltip placement="bottom" title={"新增代码编辑类型任务"}>
<img src={getImageUrl("images/educoder/icon/addsmallgreen.svg")}
className="fl mr5 mt6" />
实践任务
</Tooltip>
</Link> : ""
}
{this.props.identity < 5 && ChallengesDataList&&ChallengesDataList.shixun_status=== 0 ?
<Link to={"/shixuns/" + id + "/challenges/newquestion"}
className="white-btn edu-greenline-btn fr mr20 addshixuns"
// data-tip-down="新增选择题类型任务"
>
<Tooltip placement="bottom" title={"新增选择题类型任务"}>
<img src={getImageUrl("images/educoder/icon/addsmallgreen.svg")}
className="fl mr5 mt5" />
选择题任务
</Tooltip>
</Link> : ""
}
</p>
<p className="clearfix mb20">
<span className="font-16 fl">简介</span>
<Tooltip placement="bottom" title={"编辑"}>
<a style={{ display: this.props.identity < 5 && ChallengesDataList&&ChallengesDataList.shixun_status < 3 ? "block" : 'none' }}
href={"/shixuns/" + id + "/settings?edit=1"} className="ring-green fr">
<img src={getImageUrl("images/educoder/icon/edit.svg")} className="fl mt3 ml2" />
</a>
</Tooltip>
</p>
<div className="justify break_full_word new_li "
id="challenge_editorMd_description">
<p id="ReactMarkdown" style={{overflow:'hidden'}}>
{ChallengesDataList === undefined ? "" :ChallengesDataList&&ChallengesDataList.description===null?"":
<div className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML(ChallengesDataList.description).replace(/▁/g,"▁▁▁")}}></div>
}
</p>
{/*
<span className="markdown-body" dangerouslySetInnerHTML={{__html: markdownToHTML(question_title)}}
style={{ display: 'inline-block', width:'100%' , margin: '10px 0px 15px' }}></span>
*/}
</div>
<p className="clearfix mb10 mt20">
<span className="font-16 fl">全部任务</span>
{this.props.identity < 5 && ChallengesDataList&&ChallengesDataList.shixun_status=== 0 ?
<Link to={"/shixuns/" + id + "/challenges/new"}
className="white-btn edu-greenline-btn fr addshixuns"
// data-tip-down="新增代码编辑类型任务"
>
<Tooltip placement="bottom" title={"新增代码编辑类型任务"}>
<img src={getImageUrl("images/educoder/icon/addsmallgreen.svg")}
className="fl mr5 mt6" />
实践任务
</Tooltip>
</Link> : ""
}
{this.props.identity < 5 && ChallengesDataList&&ChallengesDataList.shixun_status=== 0 ?
<Link to={"/shixuns/" + id + "/challenges/newquestion"}
className="white-btn edu-greenline-btn fr mr20 addshixuns"
// data-tip-down="新增选择题类型任务"
>
<Tooltip placement="bottom" title={"新增选择题类型任务"}>
<img src={getImageUrl("images/educoder/icon/addsmallgreen.svg")}
className="fl mr5 mt5" />
选择题任务
</Tooltip>
</Link> : ""
}
</p>
<div className="alltask">
{ChallengesDataList === undefined ? <div className="alltask">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")} />
<p className="edu-nodata-p mb20">暂时还没有相关数据哦</p>
</div>
</div> : ChallengesDataList.challenge_list === undefined ?
<div className="alltask">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")} />
<p className="edu-nodata-p mb20">暂时还没有相关数据哦</p>
</div>
</div>
: ChallengesDataList.challenge_list.length === 0 ?
<div className="alltask">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")} />
<p className="edu-nodata-p mb20">暂时还没有相关数据哦</p>
</div>
</div>
: ChallengesDataList.challenge_list.map((item, key) => {
let newstatus = 2;
if(ChallengesDataList.challenge_list[key - 1]!=undefined){
newstatus=ChallengesDataList.challenge_list[key - 1].status;
}
return (
<div className="task-item" key={key} id={"shixun_index_" + item.position}>
<div className="clearfix mb20">
<span className="fl ring-blue mr10 mt8">
{item.st === 0 ?
<Tooltip placement="bottom" title={"实训任务"}>
<img src={getImageUrl("images/educoder/icon/code.svg")} className="fl mt2 ml2" />
</Tooltip>
:
<Tooltip placement="bottom" title={"选择题任务"}>
<img src={getImageUrl("images/educoder/icon/choose.svg")} className="fl mt2 ml3" />
</Tooltip>
}
</span>
<span className="mr15 font-16 fl">{key+1}</span>
{this.props.identity<5?
item.st === 1 ?
<a onClick={() => this.EditTraining(this.props.identity, item.challenge_id, "/editquestion")}
className="font-16 color05101a">{item.name}</a>
:
<a onClick={() => this.EditTraining(this.props.identity, item.challenge_id, "/editcheckpoint")}
className="font-16 color05101a">{item.name}</a>:<span
// onClick={() => this.startshixunCombat(this.props.identity, item.challenge_id, "/editcheckpoint")}
className="font-16 color05101a">{item.name}</span>
}
<Modal
keyboard={false}
visible={startbtns}
closable={false}
footer={null}
className="startbtnModal"
>
<Spin size="large" />
</Modal>
<span className="fr mt8">
{item.delete_url != undefined &&
<Tooltip placement="bottom" title={"删除"}>
<a onClick={() => this.delOperations(item.challenge_id)}
style={{ display:this.props.user.admin===true?"block":this.props.identity < 5 && ChallengesDataList.shixun_status === 0 ? "block" : 'none' }}
className="fl ring-op-green mr25">
<img src={getImageUrl("images/educoder/icon/close.svg")}
className="fl mt5 ml5" />
</a>
</Tooltip>
}
{item.up_url != undefined &&
<Tooltip placement="bottom" title={"向上移动"}>
<a onClick={operationstrue===true?"":() => this.operations(item.challenge_id, "up")}
style={{ display:this.props.user.admin===true?"block":this.props.identity < 5 && ChallengesDataList.shixun_status === 0 ? "block" : 'none' }}
className="fl ring-op-green mr25">
<img src={getImageUrl("images/educoder/icon/moveup.svg")}
className="fl mt2 ml4" />
</a>
</Tooltip>
}
{item.down_url != undefined &&
<Tooltip placement="bottom" title={"向下移动"}>
<a onClick={operationstrue===true?"":() => this.operations(item.challenge_id, "down")}
style={{ display: this.props.user.admin===true?"block":this.props.identity < 5 && ChallengesDataList.shixun_status=== 0 ? "block" : 'none' }}
className="fl ring-op-green mr25">
<img src={getImageUrl("images/educoder/icon/movedown.svg")} className="fl mt2 ml4" />
</a>
</Tooltip>
}
{
item.st === 1 ?
<Tooltip placement="bottom" title={"编辑"}>
<a
style={{ display:this.props.user.admin===true?"block":this.props.identity < 5 && ChallengesDataList.shixun_status< 3 ? "block" : 'none' }}
href={"/shixuns/" + ChallengesDataList.shixun_identifier + "/challenges/" + item.challenge_id + "/editquestion"}
className="fl ring-green">
<img src={getImageUrl("images/educoder/icon/edit.svg")}
className="fl mt3 ml2" />
</a>
</Tooltip>
:
<Tooltip placement="bottom" title={"编辑"}>
<a
style={{ display:this.props.user.admin===true?"block":this.props.identity < 5 && ChallengesDataList.shixun_status < 3 ? "block" : 'none' }}
href={"/shixuns/" + ChallengesDataList.shixun_identifier + "/challenges/" + item.challenge_id + "/editcheckpoint"}
className="fl ring-green">
<img src={getImageUrl("images/educoder/icon/edit.svg")}
className="fl mt3 ml2" />
</a>
</Tooltip>
}
</span>
</div>
<div className="clearfix pl28">
<span className="task-colspan"><span className={"color-orange"}>{item.passed_count}</span>&nbsp;</span>
<span
className="task-colspan"><span className={"color-orange"}>{item.playing_count}</span>&nbsp;</span>
<span className="task-colspan"><span>完成挑战可获得经验值&nbsp;<span className={"color-orange"}>{item.score}</span></span></span>
{/*判断比较复杂 有排第一不能是灰色按钮*/}
{item.status === 2 ?
<a className={"edu-default-btn edu-blueline-btn fr Finish_button mtf3"}
onClick={()=>this.startshixunCombat(false,undefined, item.challenge_id)}
// onClick={() => this.startshixunCombat(false)}
title={"查看挑战关卡"}
>已完成</a> : ""
}
{
ChallengesDataList.allow_skip === true && item.status === 1?
<a className={"edu-default-btn edu-blueback-btn fr Finish_button"}
title={"直接挑战"}
style={{marginTop: '-2px'}}
onClick={()=>this.startshixunCombat(false,undefined, item.challenge_id)}
// onClick={() => this.startshixunCombat(false)}
>直接挑战</a> : ""
}
{
ChallengesDataList.allow_skip === false ? item.status === 1?
<Tooltip placement="bottom" title={"直接挑战"}>
<a className={"edu-default-btn edu-blueback-btn fr Finish_button"}
onClick={()=>this.startshixunCombat(false,undefined, item.challenge_id)}
style={{marginTop: '-2px'}}>直接挑战</a>
</Tooltip>:"":""
}
{
item.status === 0 ?
<Tooltip placement="bottom" title={"请先完成前序关卡"}>
<a className={"edu-default-btn edu-greyback-btn fr Finish_button"}
// onClick={this.props.identity<5&&item.open_game!=""?()=>this.startshixunCombat(false,undefined, item.challenge_id):""}
style={{marginTop: '-2px'}}>直接挑战</a>
</Tooltip>:""
}
</div>
</div>
)
})}
</div>
<Modal
keyboard={false}
title="提示"
visible={sumidtype}
closable={false}
footer={null}
>
<div className="task-popup-content">
<p className="task-popup-text-center font-16">
<span className="font-17 mt10">是否删除该关卡</span>
</p>
<p className="task-popup-text-center font-16 mt30">
<a className="pop_close task-btn mr20"
onClick={() => this.clonedelOperationss()}
>取消</a>
<a onClick={() => this.delOperationss()}
className="task-btn task-btn-orange ">确定</a>
</p>
</div>
</Modal>
<Modal
keyboard={false}
title="提示"
visible={startshixunCombattype}
closable={false}
footer={null}
>
<div className="task-popup-content">
<p className="task-popup-text-center font-16 pb20">目前该实训项目尚在内测中将于{shixunsmessage}之后开放谢谢 </p>
</div>
<div className="task-popup-submit clearfix">
{/*<a onClick={this.hidestartshixunCombattype} className="task-btn fl">取消</a>*/}
<a className="task-btn task-btn-orange fr mr51" onClick={this.hidestartshixunCombattype}>知道了啦</a>
</div>
{/*<p className="inviteTipbtn with100 fl">*/}
{/*<a onClick={this.hidestartshixunCombattype}>知道了</a>*/}
{/*</p>*/}
</Modal>
<Modal
keyboard={false}
title="提示"
visible={shixunsreplace}
closable={false}
footer={null}
>
<Spin indicator={antIcon} spinning={this.state.isSpin}>
<div className="task-popup-content">
<p className="task-popup-text-center font-16 pb20">实训已经更新了正在为您重置!</p>
</div>
<div className="task-popup-submit clearfix">
<a className="task-btn task-btn-orange fr mr51"
onClick={() => this.hidestartshixunsreplace(hidestartshixunsreplacevalue)}>知道了</a>
</div>
</Spin>
</Modal>
</div>
}
</React.Fragment>
)
}
}
export default Challenges;
// {
// ChallengesDataList.allow_skip === false ? item.status === 1 && newstatus === 2 ?
// <Tooltip placement="bottom" title={"直接挑战"}>
// <a className={"edu-default-btn edu-blueback-btn fr Finish_button"}
// onClick={()=>this.startshixunCombat(false,undefined, item.challenge_id)}
// style={{marginTop: '-2px'}}>直接挑战</a>
// </Tooltip>
//
// : item.status === 1 && newstatus === 1 ?
// <Tooltip placement="bottom" title={"直接挑战"}>
// <a className={"edu-default-btn edu-blueback-btn fr Finish_button"}
// onClick={()=>this.startshixunCombat(false,undefined, item.challenge_id)}
// style={{marginTop: '-2px'}}>直接挑战</a>
// </Tooltip> : "" : ""
//
// }

@ -1,9 +0,0 @@
.height40 {
height: 30px;
line-height: 30px;
}
.line27{
line-height: 27px;
vertical-align: 1px;
}

@ -1,658 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import {Modal, Button, Radio, Input, Checkbox,message,Spin, Icon} from 'antd';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { CircularProgress } from 'material-ui/Progress';
import { getImageUrl, toPath } from 'educoder'
import axios from 'axios';
import NoneData from "../../../courses/coursesPublic/NoneData";
import './Collaborators.css';
const $ = window.$;
const RadioGroup = Radio.Group;
const Search = Input.Search;
class Collaborators extends Component {
constructor(props) {
super(props)
this.state = {
collaboratorList: [],
Collaboratorsvisible: false,
Collaboratorsvisibleadmin: false,
value: 1,
page: 1,
Searchadmin: undefined,
allChangechecked: false,
Collaboratorslist: [],
Collaboratorslisttype: false,
collaborators_deletetype: false,
collaborators_deletevalue: null,
onSearchcalue:"",
collaboratorListsum:10,
collaboratorListsumtype:true,
user_name:undefined,
school_name:undefined,
spinnings:false,
useristrue:false
}
}
componentDidMount() {
let id=this.props.match.params.shixunId;
let collaborators=`/shixuns/`+id+`/collaborators.json`;
axios.get(collaborators).then((response)=> {
if(response.status===200){
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
this.setState({
collaboratorList: response.data
});
}
}
}).catch((error)=>{
console.log(error)
});
}
updatacomponentDiddata = () => {
let id = this.props.match.params.shixunId;
let collaborators = `/shixuns/` + id + `/collaborators.json`;
axios.get(collaborators).then((response) => {
if (response.status === 200) {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
this.setState({
collaboratorList: response.data
});
}
}
}).catch((error) => {
console.log(error)
});
}
CollaboratorsshowModal = (type) => {
if (type === "cooperation") {
this.setState({
Collaboratorsvisibleadmin: false,
Collaboratorslist:[],
Searchadmin:[]
});
} else if (type === "admin") {
this.setState({
Collaboratorsvisible: false,
Collaboratorslist:[],
Searchadmin:[]
});
} else if (type === "collaborators_deletetype") {
this.setState({
collaborators_deletetype: false,
});
}
}
showCollaboratorsvisible = (type) => {
this.setState({
Collaboratorslist: [],
Searchadmin:undefined,
onSearchcalue:""
})
let admintype = this.props.identity;
if (admintype>4) {
this.props.showSnackbar("您没有权限");
return
}
if (type === "cooperation") {
this.setState({
Collaboratorsvisibleadmin: true,
});
} else if ("admin") {
let id = this.props.match.params.shixunId;
let url = "/shixuns/" + id + "/change_manager.json";
axios.get(url).then((response) => {
if (response.status === 200) {
// this.setState({
// Collaboratorsvisible: true
// })
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
this.setState({
Collaboratorsvisible: true,
Collaboratorslist: response.data
})
}
}
}).catch((error) => {
console.log(error)
});
}
}
onChange = (e) => {
this.setState({
value: e.target.value,
});
}
onSearchadmins=(e)=>{
this.setState({
onSearchcalue:e.target.value
})
}
onSearchadmin = (value) => {
let {collaboratorList,user_name,school_name} = this.state;
this.setState({
// Searchadmin: undefined,
spinnings:true,
})
// if (value === "") {
// this.setState({
// Searchadmin: [],
// collaboratorList: collaboratorList
// })
// } else {
//
// }
let id = this.props.match.params.shixunId;
let url = "/shixuns/" + id + "/add_collaborators.json";
axios.get(url,{params:{
user_name:user_name ,
school_name:school_name,
}}).then((response) => {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
this.setState({
spinnings:false
})
}else{
let newlist = response.data.users;
for (var i = 0; i < newlist.length; i++) {
newlist[i].checked = false
}
this.setState({
Searchadmin: newlist,
collaboratorList: collaboratorList,
spinnings:false
})
}
}).catch((error) => {
console.log(error)
});
}
selectChangenickname = (e, key) => {
let {Searchadmin} = this.state;
let newlist = Searchadmin;
for (var i = 0; i < newlist.length; i++) {
newlist[key].checked = e.target.checked
}
let arrlist = [];
let alltype = false;
for (var z = 0; z < newlist.length; z++) {
if (newlist[z].checked === true) {
arrlist.push(newlist[z])
}
}
if (Searchadmin.length === arrlist.length) {
alltype = true
} else {
alltype = false
}
if(newlist.length===0){
this.setState({
Searchadmin: newlist,
allChangechecked: alltype,
})
}else{
this.setState({
Searchadmin: newlist,
allChangechecked: alltype,
useristrue:false
})
}
}
allChange = (e) => {
let {Searchadmin} = this.state;
let newlist = Searchadmin;
for (var i = 0; i < newlist.length; i++) {
newlist[i].checked = e.target.checked
}
this.setState({
Searchadmin: newlist,
allChangechecked: e.target.checked
})
}
submit_add_collaborators_form = () => {
let id = this.props.match.params.shixunId;
let {Searchadmin,collaboratorList} = this.state;
let newlist = Searchadmin;
let user_ids = []
if (newlist.length === 0) {
this.setState({
Collaboratorslisttype: true
})
return
}
for (var i = 0; i < newlist.length; i++) {
if (newlist[i].checked === true) {
user_ids.push(newlist[i].user_id)
}
}
for(var i=0; i<user_ids.length;i++){
for(var j=0; j<collaboratorList.length;j++){
if(user_ids[i]===collaboratorList[j].user.user_id){
message.error("添加失败,重复添加!");
return
}
}
}
if(user_ids.length===0){
this.setState({
useristrue:true
})
return
}
let url = "/shixuns/" + id + "/shixun_members_added.json";
axios.post(url, {
user_ids: user_ids
}).then((response) => {
this.updatacomponentDiddata();
this.props.showSnackbar(response.data.message);
this.setState({
Collaboratorsvisibleadmin: false,
Collaboratorslist:[],
Searchadmin:[]
})
}).catch((error) => {
console.log(error)
});
}
addadminredio = (e) => {
this.setState({
addadminrediovalue: e
})
}
submit_addadminredio = () => {
let {addadminrediovalue} = this.state;
let id = this.props.match.params.shixunId;
let url = "/shixuns/" + id + "/change_manager.json";
if(addadminrediovalue===undefined){
this.setState({
Collaboratorsvisible: false,
Collaboratorslist:[],
Searchadmin:[]
});
this.props.showSnackbar("所选人员为空,没有更换成功");
this.CollaboratorsshowModal("admin")
return
}
axios.post(url, {
user_id: addadminrediovalue
}).then((response) => {
this.setState({
Collaboratorsvisible: false,
Collaboratorslist:[],
Searchadmin:[]
});
this.updatacomponentDiddata();
this.props.showSnackbar(response.data.message);
}).catch((error) => {
console.log(error)
});
}
collaborators_delete = (value) => {
this.setState({
collaborators_deletetype: true,
collaborators_deletevalue: value
})
}
collaborators_deletes = () => {
let {collaborators_deletevalue} = this.state;
if (collaborators_deletevalue === null) {
return
}
let id = this.props.match.params.shixunId;
let url = "/shixuns/" + id + "/collaborators_delete.json?user_id=" + collaborators_deletevalue;
axios.delete(url).then((response) => {
if (this.props.current_user.user_id == collaborators_deletevalue) {
this.props.history.push('/shixuns')
return;
}
this.props.showSnackbar(response.data.message);
this.updatacomponentDiddata();
this.setState({
collaborators_deletetype: false
})
}).catch((error) => {
console.log(error)
});
}
loadMore=()=>{
let {collaboratorList}=this.state;
this.setState({
collaboratorListsum:collaboratorList.length,
collaboratorListsumtype:false
})
}
contentViewScrolledit=(e)=>{
//滑动到底判断
let newscrollTop=parseInt(e.currentTarget.scrollTop);
let allclientHeight=e.currentTarget.clientHeight+newscrollTop;
if(e.currentTarget.scrollHeight-allclientHeight===0||e.currentTarget.scrollHeight-allclientHeight===1||e.currentTarget.scrollHeight-allclientHeight===-1){
let {page,collaboratorList,user_name,school_name,Searchadmin} = this.state;
let newpage=page+1;
let newSearchadmin=Searchadmin
let id = this.props.match.params.shixunId;
let url = "/shixuns/" + id + "/add_collaborators.json";
axios.get(url,{params:{
user_name:user_name ,
school_name:school_name,
page:newpage
}}).then((response) => {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
let newlist = response.data.users;
for (var i = 0; i < newlist.length; i++) {
newlist[i].checked = false
newSearchadmin.push(newlist[i])
}
this.setState({
Searchadmin: newSearchadmin,
collaboratorList: collaboratorList,
page:newpage
})
}
}).catch((error) => {
console.log(error)
});
}
}
render() {
let {
collaboratorList,
Collaboratorsvisible,
Collaboratorsvisibleadmin,
Searchadmin,
allChangechecked,
Collaboratorslist,
Collaboratorslisttype,
collaborators_deletetype,
onSearchcalue,
collaboratorListsum,
collaboratorListsumtype,
user_name,
school_name,
useristrue
} = this.state;
let {loadingContent} = this.props;
const radioStyle = {
display: 'block',
height: '30px',
lineHeight: '30px',
};
const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;
console.log(Searchadmin)
return (
<React.Fragment>
<p className="clearfix mt30"
style={{display:this.props.identity<5?"block":"none"}}
>
<a onClick={() => this.showCollaboratorsvisible("cooperation")}
className="edu-default-btn edu-greenback-btn fr mr20 height40"
data-remote="true">
<span className={"line27"}>+ </span>
</a>
<a onClick={() => this.showCollaboratorsvisible("admin")}
style={{display:this.props.identity===1?"block":"none"}}
data-remote="true"
className="edu-default-btn edu-greenback-btn fr mr20 height40">更换管理员</a>
</p>
<Modal
keyboard={false}
title="更换管理员"
visible={Collaboratorsvisible}
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">
<RadioGroup onChange={this.onChange} value={this.state.value}>
{
Collaboratorslist.length === 0 ? "" : Collaboratorslist.map((item, key) => {
return (
<Radio key={key} style={radioStyle} value={item.user_id}
onClick={() => this.addadminredio(item.user_id)}>{item.name}</Radio>
)
})
}
</RadioGroup>
</li>
</ul>
</div>
<div className="clearfix edu-txt-center mt20">
<a className="pop_close task-btn mb10 mr40 colorFFF"
onClick={() => this.CollaboratorsshowModal("admin")}>取消</a>
<a className="task-btn task-btn-orange"
onClick={this.submit_addadminredio}>确定</a>
</div>
</Modal>
{Collaboratorsvisibleadmin===true?<Modal
keyboard={false}
title="添加合作者"
visible={Collaboratorsvisibleadmin}
closable={false}
footer={null}
width={800}
>
{/*<Search*/}
{/*placeholder="输入用户的姓名、昵称、邮箱进行搜索"*/}
{/*value={onSearchcalue}*/}
{/*onSearch={(value) => this.onSearchadmin(value)}*/}
{/*onInput={this.onSearchadmins}*/}
{/*style={{width: '100%'}}*/}
{/*/>*/}
<span className="mr10">姓名或手机号:</span>
<Input placeholder="请输入姓名或手机号码搜索" value={user_name} onInput={(e) => {this.setState({user_name: e.target.value})}}
style={{ width: '215px'}}
></Input>
<span className="label ml10 " style={{ minWidth: '36px' }}>单位:</span>
<Input placeholder="请输入单位名称" className="ml10" value={school_name} onInput={(e) => {this.setState({school_name: e.target.value})}}
style={{ width: '215px'}}
>
</Input>
<a className="task-btn task-btn-orange ml20" onClick={() => this.onSearchadmin()}
style={{ height: '30px', lineHeight: '30px', width: '70px'}}
>搜索</a>
<p className="clearfix pl35 mt20">
<span className="fl edu-txt-w100 task-hide font-bd ml10 edu-txt-left">姓名</span>
<span className="fl edu-txt-w100 task-hide font-bd">职业</span>
<span className="fl edu-txt-w180 task-hide font-bd ml80">单位</span>
</p>
<div className="mt5" style={{background: '#f7f9fd'}}>
<Spin indicator={antIcon} spinning={this.state.spinnings}>
<div className="clearfix">
<ul className="upload_select_box fl" id="search_not_teachers_list" onScroll={this.contentViewScrolledit}>
{Searchadmin === undefined ? <li style={{textAlign: 'center'}}>
<span>请试试搜索一下</span>
</li>:Searchadmin.length === 0 ?<NoneData/>: Searchadmin.map((item, key) => {
return (
<li key={key} style={{display: item.identify === "专业人士" ? "none" : "block"}}>
<Checkbox className="fl mr20" checked={item.checked}
onChange={(e) => this.selectChangenickname(e, key)}
id={item.user_id}></Checkbox>
<a className="task-hide color-grey3 fl span1 edu-txt-w80 edu-txt-left">{item.nickname}</a>
<span className="task-hide fl color-grey edu-txt-w80 span2">{item.identify}</span>
<span
title={item.school_name}
style={{width: '150px'}}
className="span3 color-grey fl edu-txt-w260 task-hide ml50 task-hide" >{item.school_name}</span>
</li>
)
})
}
</ul>
</div>
</Spin>
</div>
<div className="mt10 clearfix">
<span className="fl mr15">
<Checkbox className="fl" checked={allChangechecked} onChange={this.allChange}>全选</Checkbox>
<div className="fl" style={{height: '27px'}}>
<span className="color-orange fl" id="add_teacher_notice"
style={{display: Collaboratorslisttype === true ? 'inline' : 'none'}}>请至少选择一个用户</span>
</div>
</span>
</div>
{useristrue===true?<span className={"color-red"}>请先选择用户</span>:""}
<div className="clearfix edu-txt-center mt20">
<a className="pop_close task-btn mb10 mr40 colorFFF"
onClick={() => this.CollaboratorsshowModal("cooperation")}>取消</a>
<a className="task-btn task-btn-orange"
onClick={() => this.submit_add_collaborators_form()}>确定</a>
</div>
</Modal>:""}
<div className="pl20" id="collaborators_list_info">
{
collaboratorList===undefined?"":collaboratorList.map((item,key)=>{
if(key<collaboratorListsum){
return(
<div className="collaborators-item clearfix" key={key}>
<a href={item.user.user_url} target="_blank" className="mr20 fl">
<img alt="用户头像" className="radius" height="80" src={getImageUrl("images/"+item.user.image_url)} width="80"/></a>
<div className="fl collaborators-item-middle">
<p className="mb10">
<a href={item.user.user_url} target="_blank">{item.user.name}</a>
<span className="ml20" style={{display:this.props.power===false?"none":"inline-block"}}>{item.user.shixun_manager === true ? "(管理员)" : ""}</span>
</p>
<p className="color-grey-B2 font-12 mb10"><span className="mr20">{item.user.identity}</span><span>{item.user.school_name}</span></p>
<p className="mb10">
<span className="mr20">发布&nbsp;&nbsp;{item.user.user_shixuns_count}</span>
{/*<span>粉丝&nbsp;&nbsp;*/}
{/*<span id="user_h_fan_count">{item.user.fans_count}</span>*/}
{/*</span>*/}
</p>
{/* <p className="color-grey-B2 task-hide">{item.user.brief_introduction}</p> */}
</div>
{item.user.shixun_manager === true ? "" : <a className="fr color-grey-c mr40 mt35 font-16"
style={{display: this.props.power === false ? "none" : "block"}}
onClick={() => this.collaborators_delete(item.user.user_id)}>删除</a>}
{/*<a href="/watchers/unwatch?object_id=3039&amp;object_type=user&amp;shixun_id=61&amp;target_id=3039" className="fr user_default_btn user_private_btn mt30 font-16 mr20" data-method="post" data-remote="true" rel="nofollow">取消关注</a>*/}
</div>
)
}
})
}
<Modal
keyboard={false}
title="提示"
visible={collaborators_deletetype}
closable={false}
footer={null}
>
<div className="task-popup-content">
<div className="task-popup-text-center font-14">确定要删除吗</div>
</div>
<div className="task-popup-submit clearfix">
<a className="pop_close task-btn mb10 mr40 colorFFF"
onClick={() => this.CollaboratorsshowModal("collaborators_deletetype")}>取消</a>
<a className="task-btn task-btn-orange fr" onClick={this.collaborators_deletes}>确定</a>
</div>
</Modal>
</div>
<div
className={collaboratorList.length>10&&collaboratorListsumtype===true?"":"none"}
style={{textAlign:'center',borderTop:'1px solid #eee'}}>
<a className="loadMore" onClick={this.loadMore}>加载更多</a>
</div>
</React.Fragment>
);
}
}
export default Collaborators;

@ -1,114 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { getImageUrl, toPath } from 'educoder';
import { Tooltip } from 'antd';
import axios from 'axios';
import { CircularProgress } from 'material-ui/Progress';
const $ = window.$;
class Propaedeutics extends Component {
constructor(props) {
super(props)
this.state={
PropaedeuticsListcontent:undefined,
shixunId:undefined
}
}
componentDidMount() {
let id = this.props.match.params.shixunId;
this.setState({
shixunId:id
})
let url="/shixuns/"+id+"/propaedeutics.json";
axios.get(url).then((response) => {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
if(response.data.content!=null){
this.setState({
PropaedeuticsListcontent:response.data.content
})
}else{
this.setState({
PropaedeuticsListcontent:""
})
}
}
}).catch((error) => {
console.log(error)
});
}
updatamakedown=(id)=>{
setTimeout(()=>{
var shixunDescr = window.editormd.markdownToHTML(id, {
htmlDecode: "style,script,iframe",
taskList: true,
tex: true,
flowChart: true,
sequenceDiagram: true
});
$("#"+id+" p:first").addClass("ReactMarkdown");
$('#collaborators_list_info').show()
}, 200)
}
render() {
let {loadingContent} = this.props;
let {PropaedeuticsListcontent,shixunId}=this.state
if(PropaedeuticsListcontent!=undefined){
this.updatamakedown("ReactMarkdown")
}
return (
<React.Fragment>
<p className="clearfix mb10 pl20 pr20" style={{display:this.props.identity<5&&this.props.status<3?"block":'none'}} >
<Tooltip placement="bottom" title={"编辑"}>
<a href={"/shixuns/"+shixunId +"/update_propaedeutics"}className="ring-green fr mt8" id="edit_propaedeutics">
<img src={getImageUrl("images/educoder/icon/edit.svg")} className="fl mt3 ml2" /></a>
</Tooltip>
</p>
{
loadingContent ?
<CircularProgress size={40} thickness={3}
style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
<div className="pl20" id="collaborators_list_info" style={{display: 'none',minHeight: '640px',padding:'10px'}}>
{PropaedeuticsListcontent===undefined?"":
<p id="ReactMarkdown">
{PropaedeuticsListcontent === undefined ||PropaedeuticsListcontent === ""?
<div className="alltask">
<div className="alltask">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb20">暂时还没有相关数据哦</p>
</div>
</div>
</div>
:<textarea>{PropaedeuticsListcontent}</textarea>}
</p>
}
</div>
}
</React.Fragment>
);
}
}
export default Propaedeutics;

@ -1,145 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { getImageUrl, toPath } from 'educoder';
import { CircularProgress } from 'material-ui/Progress';
import axios from 'axios';
const $ = window.$;
class Ranking_list extends Component {
constructor(props) {
super(props)
this.state = {
Ranking_listData:[]
}
}
Ranking_listList = (id) => {
let Ranking_listURL = `/shixuns/` + id + `/ranking_list.json`;
axios.get(Ranking_listURL).then((response) => {
if (response.status === 200) {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
this.setState({
Ranking_listData: response.data
});
}
}
}).catch((error) => {
console.log(error)
});
}
componentDidMount() {
let id = this.props.match.params.shixunId;
setTimeout(this.Ranking_listList(id), 1000);
}
checkAddZone=(num)=>{
return num<10 ? '0' + num.toString() : num
}
dateTimeFormatter=(t)=> {
if (!t) return ''
t = new Date(t).getTime()
t = new Date(t)
var year = t.getFullYear()
var month = (t.getMonth() + 1)
month = this.checkAddZone(month)
var date = t.getDate()
date = this.checkAddZone(date)
var hour = t.getHours()
hour = this.checkAddZone(hour)
var min = t.getMinutes()
min = this.checkAddZone(min)
return year + '-' + month + '-' + date + ' ' + hour + ':' + min
}
formatSeconds=(value)=> {
var theTime = parseInt(value);// 秒
var theTime1 = 0;// 分
var theTime2 = 0;// 小时
if(theTime > 60) {
theTime1 = parseInt(theTime/60);
theTime = parseInt(theTime%60);
if(theTime1 > 60) {
theTime2 = parseInt(theTime1/60);
theTime1 = parseInt(theTime1%60);
}
}
var result = ""+parseInt(theTime)+"秒";
if(theTime1 > 0) {
result = ""+parseInt(theTime1)+"分"+result;
}
if(theTime2 > 0) {
result = ""+parseInt(theTime2)+"小时"+result;
}
return result;
}
render() {
let { Ranking_listData } = this.state;
let { loadingContent } = this.props;
// console.log(Ranking_listData)
return (
<React.Fragment>
{ loadingContent ?
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
<div className="padding20 edu-back-white" style={{minHeight: '640px'}}>
{Ranking_listData===undefined||Ranking_listData.length===0?
<div className="edu-txt-center mt100">
<img src={getImageUrl("images/educoder/gold-big.png")} style={{width:"115px",height:"145px"}} />
<p className="color-grey-9 mt20">我们在等你不轻言放弃</p>
</div>
:Ranking_listData.map((item,key)=>{
var keys=key+1
return(
<div className="mt20 clearfix rankings">
<li className="fl edu-txt-left with25 ml50">
<img src={getImageUrl("images/educoder/gold"+keys+".png")}
style={{display:key<3?"block":"none"}}
width="24px" height="30px" className="mr20 fl mt5"/>
<span className="mr20 fl rankingindex"
style={{display:key>2?"block":"none"}}
>{key+1}</span>
<a href={item.users.user_url} className="mr10 fl" target="_blank">
<img alt="头像" className="radius" height="40" src={getImageUrl("images/"+item.users.image_url+"?1515212398")} width="40"/>
</a>
<a href={item.users.user_url} className="color-grey-6 task-hide" style={{maxWidth: '90px', display: 'block'}} target="_blank">{item.users.name}</a>
</li>
<li className="fl with23 edu-txt-center color-grey-9">{this.dateTimeFormatter(item.time)}通关</li>
{/*<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 with14 edu-txt-center color-yellow">+{item.gold}金币 </li>
</div>
)
})}
</div>
}
</React.Fragment>
);
}
}
export default Ranking_list;

@ -1,266 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import axios from 'axios';
import { trace, trace_collapse ,getImageUrl, toPath} from "educoder";
import RepositoryDirectories from './RepositoryDirectories'
import { ActionBtn , NoneData } from 'educoder'
import RepositoryCombinePath from './RepositoryCombinePath'
const $ = window.$;
// 点击按钮复制功能
function jsCopy(){
var e = document.getElementById("copy_rep_content");
e.select();
document.execCommand("Copy");
}
/**
提交记录
使用指南
*/
class Repository extends Component {
constructor(props) {
super(props);
this.state={
}
}
componentDidMount() {
}
onRepoFileClick = (item) => {
this.props.fetchRepo(item)
}
render() {
let { match, author, git_url, lastest_commit,repositoryLoading, commits,trees,pathArray , TPMRightSectionData } = this.props;
if (!author) {
author = {}
}
let userauthority=false;
if(this.props.author!=undefined){
userauthority=this.props.author.login===""||this.props.author.user_id===""||this.props.author.login===null||this.props.author.user_id===null;
}
return (
<React.Fragment>
{/* jfinalshop/WebRoot */}
{/* <div className="pt30 pl20 pr20 pb30 mb10 clearfix" style={{background: '#fff'}}>
<span className="fl color-grey-6 font-16 cdefault mt1">
<i className="iconfont icon-fenzhi fl mr5"></i>
<span className="fl mt2">分支&nbsp;1</span>
</span>
<a href="https://www.educoder.net/forums/2784" target="_blank"
className="fr edu-default-btn edu-greenback-btn">Git使用指南</a>
</div> */}
{ repositoryLoading ? <div style={{ minHeight: '500px'}}></div> :
<div className="" id="collaborators_list_info">
<div className="clearfix edu-back-white">
<div className="padding30-20 clearfix">
<div className="fl1 clearfix1 mr201">
<div className="repositorytitle">
{/* <form acceptCharset="UTF-8" action="/shixuns/uznmbg54/repository/uznmbg54"
id="revision_selector" method="get">
<div style={{margin:0, padding:0, display:'inline'}}>
<input name="utf8" type="hidden" value="✓"></input>
</div>
<label className="font-16 fl mr5">分支:</label>
<select className="winput-120-35 fl" id="branch" name="branch" defaultValue="master">
<option value="master">master</option>
</select>
<input id="rev" name="rev" size="8" type="hidden" value=""></input>
</form> */}
<a href="/forums/2784" target="_blank"
className=" guideBtn" >Git使用指南</a>
{
this.props.current_user && (this.props.current_user.admin ==true || (TPMRightSectionData && TPMRightSectionData.creator && TPMRightSectionData.creator.login == this.props.current_user.login)) ?
!this.props.secret_repository_tab &&
<ActionBtn style="orangeLine" className="ml20" to={`/shixuns/${match.params.shixunId}/repository/add_file`}>+添加文件</ActionBtn>
:""
}
<div className="fr font-12 color-grey-9 pr">
<label className="fl mt2">网址克隆</label>
<input type="text" id="copy_rep_content" className="fl url-input mt2"
defaultValue={ git_url } style={{width: 313}}/>
<a onClick={() => {
jsCopy()
}} data-tip-down="点击复制版本库地址"
className="fl ml5">
<i className="iconfont icon-wangzhikelong color-orange-tip" style={{lineHeight: '18px'}}></i>
</a>
<style>
{`
.top-black-trangle {
right: 68px;
}
a.guideBtn {
color: #4CACFF !important;
margin-left: 4px;
}
a.guideBtn:hover {
text-decoration: underline;
}
#repository_url_tip {
top: 30px !important;
left:132px !important;
width: 292px !important;
}
`}
</style>
{/* <a href="https://www.educoder.net/forums/2784" target="_blank"
className="fr edu-default-btn edu-greenback-btn">Git使用指南</a> */}
<a
onClick={() => { $('#repository_url_tip').css('display') === 'none'
? $('#repository_url_tip').show()
: $('#repository_url_tip').hide() }}
className="fl ml6 mt1">
<img src={getImageUrl("images/educoder/problem.png")}/>
<div className="invite-tip clearfix none" id="repository_url_tip"
style={{top: '33px', right: '-10px', width: '300px', display: 'none'}}>
<span className="top-black-trangle" style={{"right":"9px"}}></span>
<div className="padding20 invitecontent clearfix">
<p className="font-12 edu-txt-left">请上传当前实训中各个关卡涉及的所有文件<br/>
包括任务文件执行文件以及其他的必须文件<br/><br/>
提交代码的方法<br/>
1在电脑上安装Git tortoise客户端<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;或者其它熟悉的Git客户端<br/>
2在Git客户端上向左侧的地址提交代码<br/><br/>
注意<br/>
请在Git客户端要求填写时按照如下说明填写<br/>
* 用户名使用您在本平台绑定的邮箱<br/>
* 口令使用您在本平台的登录口令
</p>
</div>
<p className="inviteTipbtn with100"><a
onClick={() => { $('#repository_url_tip').css('display') === 'none'}}>知道了</a></p>
</div>
</a>
</div>
</div>
{this.props.secret_repository_tab && <RepositoryCombinePath {...this.props}>
</RepositoryCombinePath>}
</div>
</div>
<style>
{`
.va_sub {
vertical-align: sub;
}
`}
</style>
{/* 用户、最近提交时间 */}
{
trees === undefined || trees === null ||trees.length===0? <NoneData></NoneData>:
<div>
{commits===undefined?"":commits===null||commits.length===0?"":<div className="edu-back-skyblue padding10-20 clearfix">
<img alt={author.name} className="radius fl mr10"
height="30"
src={getImageUrl(`images/`+commits[0].author.image_url)}
style={{display:userauthority===true?"none":"block"}}
width="30"/>
<a href={author.user_url} className="mr5 va_sub" target="_blank">{commits[0].author.name}</a>
<span className="color-grey-6 va_sub">提交于
<acronym title={commits[0].time}>
{commits===undefined?"":commits[0].time}
</acronym> {commits===undefined?"":commits[0].title}
</span>
<a href={`/shixuns/${match.params.shixunId}/${this.props.secret_repository_tab ? 'secret_repository' : 'repository'}/${match.params.shixunId}/commits`}
className="color-grey-6 fr font-16 ">
<i className="iconfont icon-tijiaojilu font-18 fl mr5"></i>
<span className="fl mt2">提交记录</span>
</a>
</div>}
<div className="padding20" style={{minHeight: '372px'}}>
<div className="bor-grey-e">
{/* 当前目录位置 */}
<RepositoryDirectories {...this.props}></RepositoryDirectories>
<div className="versionFileList">
{ trees === undefined ?"": trees === null || trees.length===0?"":trees.map((item, index) => {
return (
<li id={`file${index}`} key={index} className=" file padding5-10">
<span style={{marginLeft: '0px'}} className="task-hide">
<i className={`${item.type === 'tree' ? 'icon-wenjianjia' : 'icon-zuoye'}
iconfont color-blue`}></i>
<a
onClick={() => this.onRepoFileClick(item)}>
&nbsp;{item.name}
</a>
</span>
</li>
)
})}
</div>
</div>
</div>
</div>
}
{/* 当前分支的文件 */}
</div>
</div>
}
</React.Fragment>
);
}
}
/*
提交记录
<div className="pl20" id="collaborators_list_info">
{ RepositoryList===undefined?"":RepositoryList.commits.map((item,key)=>{
// {"email":"李暾","title":"2\n","id":"80cb6fc55a14bdd64a9c99913f416966238ed3de","time":"49年前"}
return(
<div>
<div>{item.email}</div>
<div>{item.title}</div>
<div>{item.id}</div>
<div>{item.time}</div>
</div>
)
}) }
</div>
<li id="dd422c22b14b69b3452f4953ff33bb67" className=" file padding5-10">
<span style={{marginLeft: '0px'}} className="task-hide">
<i className="iconfont icon-zuoye color-blue"></i>
<a href="/shixuns/uznmbg54/repository/uznmbg54/master/shixun_entry/1-1.py">1-1.py</a>
</span>
</li>
*/
export default Repository;

@ -1,198 +0,0 @@
import React, { Component } from 'react';
import { ActionBtn } from 'educoder'
import { Form , Modal , Input , Breadcrumb , Button } from 'antd'
import { Link } from 'react-router-dom'
import axios from 'axios'
/**
---------------------------- START
*/
function getModeByMirrorName(mirror_name) {
let mode = 'javascript'
if (mirror_name && mirror_name.length) {
for (let i = 0; i < mirror_name.length; i++) {
let modeVal = mirrorNameModeMap[mirror_name[i]];
if (modeVal) {
mode = modeVal;
break;
}
}
}
return mode;
}
const _extraKeys = {"Alt-/": "autocomplete"};
function createCMOptions(mirror_name) {
let mode = getModeByMirrorName(mirror_name)
let cmOptions = {
lineNumbers: true,
mode: mode,
theme: "railscasts",
indentUnit:4,
matchBrackets: true,
autoRefresh: true,
smartIndent: true,//智能换行
extraKeys: _extraKeys,
autofocus: true,
styleActiveLine: true,
lint: true,
gutters: ["CodeMirror-linenumbers", "breakpoints", "CodeMirror-lint-markers"]
};
return cmOptions;
}
const mirrorNameModeMap = {
'JFinal': 'text/x-java',
'Java': 'text/x-java',
'Kotlin': 'text/x-kotlin',
'C/C++' : 'text/x-c++src',
'MachineLearning': {
name: "python",
version: 3,
singleLineStringErrors: false
},
'Python2.7': {
name: "python",
version: 3,
singleLineStringErrors: false
},
'Python3.6': {
name: "python",
version: 3,
singleLineStringErrors: false
},
}
/**
---------------------------- END
*/
class RepositoryAddFile extends Component {
constructor(props) {
super(props);
}
componentDidMount(){
let cmOptions = createCMOptions(this.props.mirror_name)
const extend_editor = window.CodeMirror.fromTextArea(window.$('#codemirror-file-edit')[0]
, cmOptions);
// tpi没setValue也可以
extend_editor.setValue('')
extend_editor.refresh();
// 拖拽也需要用 window.editor_CodeMirror.refresh()
window.editor_tempCodeMirror = extend_editor;
this.extend_editor = extend_editor;
}
checkPath= (rule, value, callback) =>{
if(!value){
callback('文件名不能为空');
}else if (value == "/" || value.indexOf('.') == -1 ) {
callback('请输入正确的文件路径src/HelloWorld.java');
}else{
callback();
}
}
handleSubmit = () =>{
this.props.form.validateFieldsAndScroll((err, values) => {
if(!err){
let shixunId = this.props.match.params.shixunId;
let url = `/shixuns/${shixunId}/add_file.json`
axios.post(url,{
path:values.path,
message:values.message,
content:this.extend_editor.getValue()
}).then((result)=>{
if(result){
this.props.history.push(`${result.data.url}`)
}
}).catch((error)=>{
console.log(error);
})
}
})
}
render(){
const {getFieldDecorator} = this.props.form;
let { shixunId } = this.props.match.params;
return(
<div className="educontent">
<style>
{`
.formStyle .ant-form-item{
margin-bottom:10px!important;
}
.formStyle .ant-col.ant-form-item-label{
margin-left:-10px;
line-height:30px;
margin-bottom:10px;
}
.breadcrumb .ant-breadcrumb-separator{
margin:0px 2px;
}
/*.filecode .CodeMirror.cm-s-railscasts{
border:1px solid #E5E5E5;
}
.filecode .CodeMirror.cm-s-railscasts .CodeMirror-sizer,.filecode .CodeMirror-gutters,.filecode .CodeMirror-scroll{
background:#fff;
}
.filecode .CodeMirror-linenumber{
text-align:center
}*/
`}
</style>
<p className="mt10 mb10">
<Breadcrumb separator='>' className="breadcrumb">
<Breadcrumb.Item href='/shixuns'>实训项目</Breadcrumb.Item>
<Breadcrumb.Item href={`/shixuns/${shixunId}/repository`}>版本库</Breadcrumb.Item>
<Breadcrumb.Item>添加新文件</Breadcrumb.Item>
</Breadcrumb>
</p>
<Form onSubmit={this.handleSubmit} className="formStyle">
<div className="edu-back-white padding20-30 mb10">
<Form.Item label="文件名">
{getFieldDecorator('path', {
rules: [
{
validator:this.checkPath
}]
})(
<Input placeholder="输入文件路径名src/HelloWorld.java" className="winput-300-35 fl"/>
)}
</Form.Item>
</div>
<div className="edu-back-white padding30">
<p className="ant-form-item-label">
<label>内容</label>
</p>
<div className="mt10 mb25 repoCMWrapper filecode">
<textarea className="" id="codemirror-file-edit" style={{display:'none'}} name="content"></textarea>
</div>
<Form.Item label="提交信息">
{getFieldDecorator('message', {
rules: [{required: true, message: "请输入提交信息"}],
})(
<textarea className="winput-100-130 fl"></textarea>
)}
</Form.Item>
</div>
<div className="clearfix mt30 edu-txt-right mb30">
<Button type="primary" className="defalutSubmitbtn fr ml20" onClick={this.handleSubmit}>提交</Button>
<Link className="defalutCancelbtn fr" to={`/shixuns/${shixunId}/repository`}>取消</Link>
</div>
</Form>
</div>
)
}
}
const WrappedRepositoryAddFile = Form.create({name: 'taskRepositoryAddFile'})(RepositoryAddFile);
// RouteHOC()
export default (WrappedRepositoryAddFile);

@ -1,185 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import axios from 'axios';
import RepositoryDirectories from './RepositoryDirectories'
import { trace_collapse } from 'educoder'
import Popconfirm from 'antd/lib/popconfirm';
import 'antd/lib/popconfirm/style/css';
import { message } from 'antd';
require('codemirror/lib/codemirror.css');
const $ = window.$;
/**
---------------------------- START
*/
function getModeByMirrorName(mirror_name) {
let mode = 'javascript'
if (mirror_name && mirror_name.length) {
for (let i = 0; i < mirror_name.length; i++) {
let modeVal = mirrorNameModeMap[mirror_name[i]];
if (modeVal) {
mode = modeVal;
break;
}
}
}
return mode;
}
const _extraKeys = {"Alt-/": "autocomplete"};
function createCMOptions(mirror_name) {
let mode = getModeByMirrorName(mirror_name)
let cmOptions = {
lineNumbers: true,
mode: mode,
theme: "railscasts",
indentUnit:4,
matchBrackets: true,
autoRefresh: true,
smartIndent: true,//智能换行
extraKeys: _extraKeys,
autofocus: true,
styleActiveLine: true,
lint: true,
gutters: ["CodeMirror-linenumbers", "breakpoints", "CodeMirror-lint-markers"]
};
return cmOptions;
}
const mirrorNameModeMap = {
'JFinal': 'text/x-java',
'Java': 'text/x-java',
'Kotlin': 'text/x-kotlin',
'C/C++' : 'text/x-c++src',
'MachineLearning': {
name: "python",
version: 3,
singleLineStringErrors: false
},
'Python2.7': {
name: "python",
version: 3,
singleLineStringErrors: false
},
'Python3.6': {
name: "python",
version: 3,
singleLineStringErrors: false
},
}
/**
---------------------------- END
*/
class RepositoryCodeEditor extends Component {
constructor(props) {
super(props)
this.state = {
codeSaving: false
}
}
componentDidUpdate = (prevProps, prevState) => {
if (this.props.fileContent && this.props.fileContent != prevProps.fileContent) {
// window.setTimeout(() => {
this.extend_editor.setValue(this.props.fileContent)
// }, 2000)
}
}
componentDidMount(){
let cmOptions = createCMOptions(this.props.mirror_name)
const extend_editor = window.CodeMirror.fromTextArea(window.$('#codemirror-file-edit')[0]
, cmOptions);
// tpi没setValue也可以
extend_editor.setValue('')
extend_editor.refresh();
// 拖拽也需要用 window.editor_CodeMirror.refresh()
window.editor_tempCodeMirror = extend_editor;
this.extend_editor = extend_editor;
}
saveCode = () => {
const { shixunId, pathArray } = this.props;
const url = `/shixuns/${shixunId}/update_file.json`
const path = pathArray.join('/')
this.setState({ codeSaving: true })
axios.post(url, {
secret_repository: this.props.secret_repository_tab,
content: this.extend_editor.getValue(),
// type: forTest === true ? 1 : 0,
path: path
}
).then((response) => {
if (response.data.content) {
message.success('保存成功');
this.setState({ codeSaving: false })
}
})
}
render() {
const { fileContent, match, saveCode } = this.props;
const { codeSaving } = this.state;
return (
<React.Fragment>
<div className="tpmComment educontent clearfix mt30">
<RepositoryDirectories {...this.props}></RepositoryDirectories>
<div className="edu-back-skyblue padding5-10 clearfix">
<div className="fl">
</div>
<div id="file_action" className="recordBanner fr">
{ codeSaving ?
<a href="javascript:void(0);"
className="fr mt12 mr20 color-grey">保存中...</a>
: <Popconfirm title="确定要保存修改后的代码吗?"
placement="bottom"
onConfirm={() => this.saveCode(this.extend_editor.getValue())}
okText="确定" cancelText="取消">
{/* onClick={this.saveCode}
onClick={() => saveCode(this.extend_editor.getValue())}
*/}
<a href="javascript:void(0);"
className="fr mt12 mr20 color-blue">保存</a>
</Popconfirm> }
</div>
<div className="cl"></div>
</div>
<style>
{`
.repoCMWrapper .CodeMirror {
height: 500px;
}
`}
</style>
<div className="padding10-20 repoCMWrapper">
<textarea className="" id="codemirror-file-edit"
style={{display:'none'}}
name="content">{fileContent}</textarea>
</div>
</div>
</React.Fragment>
);
}
}
export default RepositoryCodeEditor;

@ -1,82 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import axios from 'axios';
import { trace_collapse, WordsBtn } from 'educoder'
import { message, Input } from 'antd';
const $ = window.$;
class RepositoryCombinePath extends Component {
constructor(props) {
super(props)
this.state = {
value: this.props.secret_dir_path || '',
isEdit: false,
}
}
onSave = () => {
const { shixunId, pathArray } = this.props;
const url = `/shixuns/${shixunId}/set_secret_dir.json`
this.setState({ codeSaving: true })
axios.post(url, {
secret_dir_path: this.state.value
}
).then((response) => {
if (response.data) {
message.success('保存成功');
this.setState({isEdit: false})
}
})
}
onChange = (e) => {
const { value } = e.target;
this.setState({ value })
}
onEdit = () => {
this.setState({isEdit: true}, () => {
window.$('.combinePathEditRow input')[0].focus()
});
}
render() {
const { fileContent, match, saveCode } = this.props;
const { isEdit, value } = this.state;
return (
<div className="df combinePathEditRow">
<style>{`
.combinePathEditRow {
margin: 4px 0;
}
.combinePathEditRow input {
flex: 0 0 300px;
border: none;
}
.combinePathEditRow .wordsBtn {
margin-left: 24px;
}
`}</style>
<span>第一版本库合并路径</span>
<Input disabled={!isEdit} value={value} onChange={this.onChange}></Input>
{!isEdit && <WordsBtn className="wordsBtn" onClick={this.onEdit} style="blue">修改</WordsBtn>}
{isEdit && <WordsBtn className="wordsBtn" onClick={this.onSave} style="blue">保存</WordsBtn>}
</div>
);
}
}
export default RepositoryCombinePath;

@ -1,66 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import axios from 'axios';
import { trace_collapse } from 'educoder'
const $ = window.$;
class RepositoryDirectories extends Component {
constructor(props) {
super(props)
this.state = {
}
}
componentDidMount() {
}
render() {
const { match, pathArray, fetchRepo
} = this.props;
let { RepositoryList } = this.state;
return (
<React.Fragment>
{ pathArray.length !== 0 &&
<div className="bor-bottom-greyE padding5-10 font-14 ">
<a className="color-blue"
onClick={() => fetchRepo(0)}
>
{match.params.shixunId}
</a>
<span className="ml3 mr3">/</span>
{ pathArray.map((item, index) => {
// /shixuns/3ozvy5f8/repository/3ozvy5f8/master/shixun_show/src
return (
<React.Fragment>
{ this.props.nameTypeMap[item] === 'tree' || item.indexOf('.') === -1
? <a
onClick={() => fetchRepo(index + 1)}
className="color-blue">
{item}</a>
:
<a >
{item}</a>
}
{index !== pathArray.length - 1 && <span className="ml3 mr3">/</span>}
</React.Fragment>
)
})
}
</div> }
</React.Fragment>
);
}
}
export default RepositoryDirectories;

@ -1,145 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import axios from 'axios';
import TPMNav from '../../component/TPMNav'
import TPMRightSection from '../../component/TPMRightSection'
import { CircularProgress } from 'material-ui/Progress';
import { trace_collapse } from 'educoder'
const $ = window.$;
// 点击按钮复制功能
function jsCopy(){
var e = document.getElementById("copy_rep_content");
e.select();
document.execCommand("Copy");
}
class TPMRepositoryCommits extends Component {
constructor(props) {
super(props)
this.state = {
RepositoryList: undefined,
}
}
componentDidMount() {
let id = this.props.match.params.shixunId;
let collaborators=`/shixuns/`+id+`/commits.json`;
axios.post(collaborators, {
secret_repository: this.props.secret_repository_tab
}).then((response)=> {
if(response.status===200){
this.setState({
RepositoryList: response.data
});
}
trace_collapse('repo commits res', response.data)
}).catch((error)=>{
console.log(error)
});
}
render() {
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
aboutFocus, user, match
} = this.props;
let { RepositoryList } = this.state;
return (
<React.Fragment>
<div className="tpmComment educontent clearfix mt30 mb80">
{/* 可能会影响到其他页面的样式,需要测试、协商 */}
<div className="with65 fl edu-back-white commentsDelegateParent"
style={{background: 'transparent'}}>
<TPMNav
match={match}
user={user}
shixun={shixun}
{...this.props}
></TPMNav>
{ loadingContent ?
<CircularProgress size={40} thickness={3}
style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/>
:
<div className="" >
<div className="edu-back-white font-16 mb10 clearfix padding20">
<span className="fl"><i className="iconfont icon-tijiaojilu mr5"></i>
提交记录
</span>
{/* &nbsp;35 */}
<span className="color-grey-9 fr">
<Link to={`/shixuns/${match.params.shixunId}/repository/${match.params.repoId}`}
className="font-14 color-grey-9">返回</Link>
</span>
</div>
<style>
{`
a.pullreques_name:hover {
color: #666 !important
}
`}
</style>
<div className="edu-back-white font-16 mb10 clearfix padding20">
<ul className="pullreques_pull_list">
{ RepositoryList === undefined ? "" : RepositoryList.commits.map( (item, key)=>{
return (
<li className="clear" key={ key }>
<a
style={{ cursor: 'inherit' }}
className="fl color-grey-6 font-16 pullreques_name task-hide"
target="_blank">{item.email}</a>
<p className="pullreques_pull_txt ml10 fl" style={{lineHeight: '32px'}}>
{item.title}
</p>
<a style={{ cursor: 'inherit' }}
className="fr mr15 color-blue">{item.time}</a>
<div className="cl"></div>
</li>)
})
}
</ul>
</div>
</div>
}
</div>
<div className="with35 fr pl20">
<TPMRightSection {...this.props}></TPMRightSection>
</div>
</div>
</React.Fragment>
);
}
}
/**
{ RepositoryList === undefined ? "" : RepositoryList.commits.map( (item, key)=>{
// {"email":"李暾","title":"2\n","id":"80cb6fc55a14bdd64a9c99913f416966238ed3de","time":"49年前"}
return (
<div>
<div>{item.email}</div>
<div>{item.title}</div>
<div>{item.id}</div>
<div>{item.time}</div>
</div>
)
})
*/
export default TPMRepositoryCommits;

@ -1,170 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { getImageUrl, toPath } from 'educoder'
import axios from 'axios';
const $ = window.$;
class ShixunDiscuss extends Component {
constructor(props) {
super(props)
this.state = {
TPMRightSectionData: undefined
}
}
getshixunsDetailsList = (id) => {
let shixunsDetailsURL = `/shixuns/` + id + `/discusses.json`;
axios.get(shixunsDetailsURL).then((response) => {
if (response.status === 200) {
this.setState({
TPMRightSectionData: response.data
});
}
}).catch((error) => {
console.log(error)
});
}
componentDidMount() {
let id = this.props.match.params.shixunId;
setTimeout(this.getshixunsDetailsList(id), 1000);
}
render() {
let { TPMRightSectionData } = this.state;
return (
<div className="mt30">
<div id="no_data">
<div className="justify markdown-body editormd-html-preview" id="challenge_editorMd_propaedeutics">
{
TPMRightSectionData===undefined?"":TPMRightSectionData.map((item,key)=>{
return(
<div className="comment_item_cont df clearfix" key={key}>
<div className="J_Comment_Face fl">
<a href={item.user.user_url} target="_blank">
<img alt="用户头像" height="50" src={getImageUrl("images/"+item.user.image_url)} width="50" />
</a>
</div>
<div className="t_content fl" style={{width:'100%'}}>
<div className="J_Comment_Reply">
<div className="comment_orig_content" style={{margin: '0px'}}>
<div className="J_Comment_Info clearfix mt3">
<div className="t_info fl">
<a href={item.user.user_url} className="content-username hide fl">{item.user.name}</a>
<span className="t_area fl">{item.time}</span>
<span className="fl color-light-green font-14 ml15">[{item.round}]</span>
</div>
</div>
<div className="comment_content clearfix" id="reply_content_3783">
<div className="color-grey-3" id="reply_content_3783"><div>
<p>{item.content}</p>
</div>
<div className="cl"></div>
</div>
</div>
{
item.replies.map((i,k)=>{
return(
<div className="childrenCommentsView" key={k} style={{width:'100%'}}>
<div className="trangle"></div>
<div className="childComment">
<div className="J_Comment_Info clearfix mt3">
<div className="t_info fl">
<a href={i.user.user_url} className="content-username hide fl">{i.user.name}</a>
<span className="t_area fl">{i.time}</span>
</div>
<p className="fr orig_reply lineh-20">
<span id="hidden_discuss_btn_952"></span>
<a className="color-grey-8">
<i className="iconfont icon-jiangli fl mt2"></i>
</a>
<a className="color-grey-8" id="delete_reply_118_952">
<i className="iconfont icon-shanchu mr5"></i>
</a>
</p>
</div>
<div className="comment_content clearfix" id="reply_content_3800">
<div className="color-grey-3" id="reply_content_3800">
<div>
<p>{i.content}</p>
</div>
<div className="cl"></div>
</div>
</div>
</div>
</div>
)
})
}
<p className="fr orig_reply">
<span id="hidden_discuss_btn_952"></span>
<a className="color-grey-8">
<i className="iconfont icon-jiangli mr5 fl"></i>
</a>
<a className="color-grey-8 fl mt2">
<i className=" fa fa-eye mr5"></i>
</a>
<a className="color-grey-8">
<i className="iconfont icon-shanchu mr5"></i>
</a>
<a className="color-grey-8">
<i className="iconfont icon-huifu1 mr5"></i>
</a>
<span className="reply_praise_count_952">
<a className="fr mr5 color-grey-8">
<i className="iconfont icon-dianzan-xian mr5"></i>
<span className="fr font-14">3</span>
</a>
</span>
</p>
<div className="commentItemMDEditorView commentItemMDEditorView_4220" style={{display:'none'}}>
<div className="homepagePostReplyPortrait mr15 fl imageFuzzy" id="reply_image_3097" style={{marginTop: '28px', marginRight: '0px'}}>
<a href="/users/innov" target="_blank" alt="用户头像">
<img alt="0?1442652658" height="33" src="/images/avatars/User/1" width="33"/>
</a>
</div>
<div id="reply_message_4220" className="reply_to_message commentItemMDEditor" style={{paddingTop: '0px', paddingBottom: '20px'}}>
<div id="reply_message_editorMd_4220" className="editorMD" style={{marginBottom: '0px'}}>
<textarea></textarea>
</div>
<div className="editor__resize" >调整高度</div>
<a id="commitBtn_4220" className="commentsbtn task-btn task-btn-blue fr ">发送</a>
</div>
</div>
</div>
</div>
</div>
</div>
)
})
}
</div>
</div>
</div>
)
}
}
export default ShixunDiscuss;

@ -1,69 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link} from "react-router-dom";
import { Switch } from 'antd';
import PropTypes from 'prop-types';
import classNames from 'classnames'
import { TPMIndexHOC } from '../TPMIndexHOC'
import { SnackbarHOC } from 'educoder'
import ShixunCard from '.././shixuns/ShixunCard';
import { Pagination,Row,Col,Rate } from 'antd';
import './shixunchildCss/Shixunfork_list.css';
import 'antd/lib/rate/style/index.css';
const $ = window.$;
class Shixunforklist extends Component {
constructor(props) {
super(props)
this.state = {
}
}
handleChange = (value) => {
console.log('Page: ', value);
// this.setState({ value });
}
//JSX
render() {
const { match, history } = this.props
return (
<div className="newMain clearfix">
<div className="educontent">
<div className="edu-back-white padding20 clearfix mb20 mt30">
<span className="fl font-16">Fork实训列表</span>
<Link to="/shixunchild" className="font-16 color-grey-9 fr">返回</Link>
</div>
<ShixunCard/>
<div className="educontent edu-txt-center mb80">
<div className="inline pages_user_show">
<ul>
</ul>
<div className="cl"></div>
</div>
</div>
</div>
</div>
);
}
}
export default SnackbarHOC() (TPMIndexHOC ( Shixunforklist ));

@ -1,28 +0,0 @@
.editormd-html-preview, .editormd-preview-container {
width: 95% !important;
}
.Finish_button{
height: 30px;
line-height: 30px;
margin-top: -8px;
}
.startbtnModal .ant-modal-content{
background: transparent;
box-shadow: 0 4px 12px transparent;
}
.startbtnModal .ant-modal-content .ant-modal-body .ant-spin-spinning{
margin-left: 45%;
}
.color05101a{
color:#05101a;
}
.mtf3{
margin-top: -3px;
}
.addshixuns{
height: 27px;
line-height: 25px;
}

@ -1,6 +0,0 @@
.ant-rate{
color: #FFAA05 !important;
}
.ant-pagination-options-quick-jumper input{
height: 22 !important;
}

@ -1,200 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { Rating ,Pagination} from "@icedesign/base";
import {getImageUrl,setImagesUrl, toPath,getUrl} from 'educoder';
import { Spin,Icon,Tooltip ,Rate} from 'antd';
import LoadingSpin from '../../../common/LoadingSpin';
import './shixunCss/shixunCard.css';
// 引入业务组件样式
import axios from 'axios';
const $ = window.$;
class ShixunCard extends Component {
constructor(props) {
super(props)
this.state = {
startValue:[],
order_by:"",
page:1,
limit:16,
keyword:"",
status:0,
diff:0,
hideme:false,
tag_level:3,
tag_id:''
}
}
PaginationonChange=(pageNumber)=> {
this.props.shixunsPage(pageNumber);
}
render() {
let {middleshixundata, pagination, typepvisible, pages, totalcount} = this.props;
const MyRate = ({ defaultValue, ...rest }) => {
let myValue = defaultValue;
// console.log(myValue-Math.floor(myValue))
// if (myValue < Math.ceil(myValue)) {
// myValue = Math.floor(myValue) + 0.5;
// }
return <Rating {...rest} value={myValue} />;
};
return (
<div className="educontent mb80">
<Spin spinning={typepvisible} tip="正在获取相关数据..." size="large" style={{marginTop:'15%'}}>
{ middleshixundata === undefined?"":middleshixundata.length === 0 ?<div className="edu-tab-con-box clearfix edu-txt-center">
<style>
{`
.edu-tab-con-box{
padding:100px 0px;
}
.ant-modal-body .edu-tab-con-box{
padding:0px!important;
}
img.edu-nodata-img{
margin: 40px auto 20px;
}
`}
</style>
<img className="edu-nodata-img mb20" src={getUrl("/images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb20">暂时还没有相关数据哦</p>
</div>:""}
<div className="mt10 mb20 clearfix"
// style={{display: middleshixundata === undefined || middleshixundata.length === 0 ? "none" : "block"}}
>
<div className="shixun_list_content">
<div className="square-list clearfix">
{middleshixundata === undefined || middleshixundata.length === 0?" ":middleshixundata.map((item,key)=>{
return(
<div className="square-Item" key={key} id={item.id}>
<style>
{
`
.tag-green {
position: absolute;
left: 10px;
bottom: 125px;
}
`
}
</style>
{
item.tag_name === null ? "":
<div className="tag-green">
<span className="tag-name"> {item.tag_name}</span>
{/*<img style={{display:'block',height: '28px'}} src={require(`./shixunCss/tag2.png`)}/>*/}
</div>
}
<div className={item.power === false ? "closeSquare" : "none"}>
<img src={getImageUrl("images/educoder/icon/lockclose.svg")}
className="mt80 mb25"/>
<p className="font-14 color-white">非试用内容需要授权</p>
</div>
<a href={"/shixuns/"+item.identifier+"/challenges"} className="square-img">
{/*<img src={getImageUrl("images/"+item.pic+"?1540534846")}/>*/}
<img src={setImagesUrl(`${item.pic}`)}/>
</a>
{/*target="_blank"*/}
<div className="square-main">
<p className="task-hide">
<a href={"/shixuns/"+item.identifier+"/challenges"} className="justify color-grey-name" title={item.name}>
{item.name}
</a>
</p>
{/*target="_blank"*/}
{/*<style>*/}
{/*{*/}
{/*`*/}
{/*.anticon-star{*/}
{/*font-size:16px;*/}
{/*}*/}
{/*.pathInfo{*/}
{/*margin-right:-5px;*/}
{/*}*/}
{/*.ant-rate{*/}
{/*color: #FFA800;*/}
{/*}*/}
{/*`*/}
{/*}*/}
{/*</style>*/}
<p className="clearfix mt8 ml-3">
<span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
{/*<Rate allowHalf value={item.score_info===null?5:item.score_info} disabled key={key} />*/}
<MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/>
</span>
<span className="fl ml25 font-12 color-grey-9 lineh-12 mt5">{item.score_info===null?"5分":item.score_info+"分"}</span>
</p>
<p className="clearfix mt8 font-12 color-grey-B4">
<Tooltip placement="bottom" title={"关卡"}>
<span className="mr10 fl squareIconSpan">
<i className="iconfont icon-shixunguanqia fl mr3"></i>{item.challenges_count}
</span>
</Tooltip>
{/*<Tooltip placement="bottom" title={"经验值"}>*/}
{/*<span className="mr10 fl squareIconSpan">*/}
{/*<i className="iconfont icon-jingyan fl mr3"></i>{item.exp}*/}
{/*</span>*/}
{/*</Tooltip>*/}
<Tooltip placement="bottom" title={"学习人数"}>
<span className="mr10 fl squareIconSpan" style={{display:item.stu_num===0?"none":"block"}}>
<i className="iconfont icon-chengyuan fl mr3"></i>{item.stu_num}
</span>
</Tooltip>
<span className="fr color-grey-B3 squareIconSpan">{item.level}</span>
</p>
</div>
</div>
)
})
}
</div>
<div className="both"></div>
{/*totalcount*/}
<div className={"ml425"}
//className={totalcount < 22 ? "ml425" : "ml425"}
style={{display: pagination ? "block" : "none"}}>
{/*<Pagination showQuickJumper defaultCurrent={1} current={pages} total={totalcount} pageSize={12} onChange={this.PaginationonChange} />*/}
{/* 不加参数请求的时候,没返回总数了。加了个比较大的数字,让他可以翻页 */}
<Pagination defaultCurrent={1} current={pages} total={ totalcount || 1299 } type="mini" pageSize={16} onChange={this.PaginationonChange} />
</div>
</div>
</div>
</Spin>
</div>
)
}
}
export default ShixunCard;

@ -1,253 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route} from "react-router-dom";
import { Switch ,Input,Tooltip,Icon} from 'antd';
import PropTypes from 'prop-types';
import classNames from 'classnames'
import 'antd/lib/switch/style/index.css'
import './shixunCss/ShixunCardList.css';
import { on, off } from 'educoder'
const $ = window.$;
const Search = Input.Search;
class ShixunCardList extends Component {
constructor(props) {
super(props);
this.state={
allevent:"desc",
mine:0,
InputValue: props.keyword || "",
typemy:0,
hots:0,
news:0,
shixunid:"",
upcircle:false,
typekeyid:undefined,
}
}
componentDidUpdate = (prevProps, prevState) => {
if (this.props.keyword != prevProps.keyword) {
this.setState({
InputValue: this.props.keyword
})
}
}
componentDidMount = () => {
on('searchKeywordChange', (event, data) => {
// console.log(data)
this.Input_search(data)
})
}
componentWillUnmount = () => {
off('searchKeywordChange')
}
latestHot=(e,key)=>{
let{upcircle,typekeyid}=this.state;
let id = e.target.id;
$("#"+id).siblings().removeClass("active");
$("#"+id).addClass("active");
let type;
// if(id==="all"){
// type="publish_time";
// }
if(id==="hot"){
type="hot";
}else if(id==="new"){
type="new";
}
if(typekeyid===key){
if(upcircle===true){
this.setState({
upcircle:false,
})
this.props.Shixunsupcircles("desc")
}else if(upcircle===false){
this.setState({
upcircle:true,
})
this.props.Shixunsupcircles("asc")
}
}else{
this.setState({
typekeyid:key
})
}
//allevent
this.props.ShixunsState(false,type);
}
onSwitchChange=(e,key)=>{
let id=e.target.id
$("#"+id).siblings().removeClass("active");
$("#"+id).addClass("active");
let {typemy,upcircle,typekeyid}=this.state;
if(typekeyid===key){
if(upcircle===true){
this.setState({
upcircle:false,
})
this.props.Shixunsupcircles("desc")
}else if(upcircle===false){
this.setState({
upcircle:true
})
this.props.Shixunsupcircles("asc")
}
}else{
this.setState({
typekeyid:key
})
}
if(typemy===0){
this.setState({
typemy:1
})
}else{
this.setState({
typemy:0
})
}
// allevent
this.props.ShixunsSwitch();
}
//输入框搜索
Input_search = (value) => {
this.setState({
InputValue: value
})
this.props.OnSearchInput(value,true);
}
Input_searchs = (e) => {
this.setState({
InputValue: e.target.value
})
this.props.OnSearchInput(e.target.value,false);
}
upcircles=(val)=>{
if(val==="asc"){
this.setState({
upcircle:false,
})
this.props.Shixunsupcircles("desc")
}else if(val==="desc"){
this.setState({
upcircle:true
})
this.props.Shixunsupcircles("asc")
}
}
render(){
let {mine,InputValue,upcircle}=this.state;
return (
<div className="educontent mt20">
<div className="clearfix">
{/*<div className="fl mr20 font-16 bestChoose shixun_repertoire active"*/}
{/*id={"all"}*/}
{/*onClick={(e)=>this.latestHot(e,1)}>全部*/}
{/*</div>*/}
{/*<div className="fl mr20 font-16 bestChoose shixun_repertoire"*/}
{/*id={mine}*/}
{/*onClick={(e)=>this.onSwitchChange(e,2)}>我的*/}
{/*</div>*/}
<div className="fl mr20 font-16 bestChoose shixun_repertoire active"
id="new"
onClick={(e)=>this.latestHot(e,4)}>最新
</div>
<div className="fl font-16 bestChoose shixun_repertoire"
id="hot"
onClick={(e)=>this.latestHot(e,3)}>最热
</div>
{/*<div className="fl font-16 bestChoose shixun_repertoire ml20 mt1"*/}
{/*style={{display:upcircle===true?"block":"none"}}*/}
{/*// onClick={()=>this.upcircles("asc")}*/}
{/*>*/}
{/*<Tooltip placement="bottom" title={"升序"}>*/}
{/*<Icon type="up-circle" theme="twoTone" />*/}
{/*/!*<Icon type="sort-descending" />*!/*/}
{/*</Tooltip>*/}
{/*</div>*/}
{/*<div className="fl font-16 bestChoose shixun_repertoire ml20 mt1"*/}
{/*// onClick={()=>this.upcircles("desc")}*/}
{/*style={{display:upcircle===true?"none":"block"}}*/}
{/*>*/}
{/*<Tooltip placement="bottom" title={"降序"}>*/}
{/*<Icon type="down-circle" theme="twoTone" />*/}
{/*/!*<Icon type="sort-ascending" />*!/*/}
{/*</Tooltip>*/}
{/*</div>*/}
{/*<div className="fr mt3">*/}
{/*<Search*/}
{/*style={{ width: 300 }}*/}
{/*className="search-new-input fl"*/}
{/*placeholder="请输入创建者/实训/关卡名称进行搜索"*/}
{/*value={InputValue}*/}
{/*onInput={this.Input_searchs}*/}
{/*onSearch={value => this.Input_search(value)}*/}
{/*enterButton*/}
{/*/>*/}
{/* <Search
style={{ width: 300 }}
className="fl"
placeholder="请输入创建者/实训/关卡名称进行搜索"
value={InputValue}
onInput={this.Input_searchs}
onSearch={value => this.Input_search(value)}
autoComplete="off"
></Search> */}
{/*</div>*/}
{/*<div className="fr">*/}
{/*<span className="fl color-grey-6 mr30 font-16 mt5" id="search_name">{*/}
{/*this.props.search_tags === null ? "" : this.props.search_tags*/}
{/*}</span>*/}
{/*<div className="fl mr5" style={{marginTop:'1px'}}>*/}
{/*/!* <div className="controlblue"></div>*/}
{/*<span className="controlring"></span> *!/*/}
{/*<Switch*/}
{/*className="controlbtn mr10 mt10 pr"*/}
{/*size="small"*/}
{/*style={{marginTop:'1px'}}*/}
{/*onChange={this.onSwitchChange}*/}
{/*/>*/}
{/*</div>*/}
{/*<span className="fl font-16 cdefault" data-tip-down="隐藏我学习的实训">隐藏我的</span>*/}
{/*</div>*/}
{/*<span className="fr color-grey-6 mr30 font-16" id="search_name"></span>*/}
</div>
</div>
);
}
}
export default ShixunCardList;

@ -1,292 +0,0 @@
import React, { Component } from 'react';
import { Select, Input,Menu, Dropdown } from 'antd';
import 'antd/lib/style/index.css';
import 'antd/lib/select/style/index.css';
import 'antd/lib/input/style/index.css';
import './shixunCss/ShixunSearchBar.css';
import axios from 'axios';
const $ = window.$;
const Option = Select.Option;
const Search = Input.Search;
class ShixunSearchBar extends Component {
constructor(props) {
super(props)
this.state = {
status: undefined,
diff: 0,
InputValue: undefined,
shixunhoverData: [],
shixunchildValues:'',
shixunsearchAllvalue:"a",
openStatus:false,
openLevel:false
}
}
//状态筛选
status_search = (value) => {
let newvalue = value;
if (newvalue === "0") {
newvalue = " "
} else if (newvalue === "1") {
newvalue = 2
} else if (newvalue === "2") {
newvalue = 1
} else if (newvalue === "3") {
newvalue = 3
}
this.setState({
status: newvalue,
openStatus:false
})
let list = [{'type': 1}, {'value': newvalue}];
this.props.StatusEnquiry(list);
}
//难度筛选
diff_search = (value) => {
this.setState({
diff: value,
openLevel:false
})
let list=[{'type':2},{'value':value}];
this.props.StatusEnquiry(list);
}
//输入框搜索
Input_search = (value) => {
this.setState({
InputValue: value
})
this.props.OnSearchInput(value);
}
//查询
shixunsearchAll = (e) => {
let{shixunsearchAllvalue}=this.state;
let id = e.target.value;
if(shixunsearchAllvalue===id){
return
}
if(id===0){
id=" "
this.setState({
InputValue: " "
})
this.props.OnSearchInput("");
}
let list=[{'tag_level':1},{'tag_id':id}];
if(id!=undefined){
this.setState({
shixunsearchAllvalue:id,
shixunchildValues:""
})
this.props.Updatasearchlist(list);
}
}
shixunsearchall=(e)=>{
let{shixunsearchAllvalue}=this.state;
let id = "a";
if(shixunsearchAllvalue===id){
return
}
this.setState({
shixunsearchAllvalue:"a",
shixunchildValues:""
})
this.props.allUpdatashixunlist();
}
//选择Tab页详情
getshixunchildValue = (e) => {
debugger
let id = e.target.name;
let newid=e.target.id;
let list=[{'tag_level':2},{'tag_id':id}];
if(id!=undefined||newid!=undefined){
this.setState({
shixunsearchAllvalue:newid
})
this.props.Updatasearchlist(list);
}
}
getshixunchildValues = (e) => {
let id = e.target.id;
let newid=e.target.name;
let list=[{'tag_level':3},{'tag_id':id}];
if(id!=undefined||newid!=undefined){
this.setState({
shixunchildValues:id,
shixunsearchAllvalue:newid
})
this.props.Updatasearchlist(list);
}
}
componentDidMount() {
let hoverUrlArr = [];
let hoverUrl = `/shixuns/menus.json`;
axios.get(hoverUrl
).then((response) => {
hoverUrlArr = response.data;
// hoverUrlArr.reverse();
this.setState({
shixunhoverData: hoverUrlArr
})
}).catch((error) => {
console.log(error)
})
}
render() {
let {shixunhoverData, shixunchildValues, shixunsearchAllvalue, InputValue,openStatus,openLevel} = this.state;
let {typepvisible} = this.props;
// //实训首页筛选的移入和点击事件
// $(".shaiItem").hover(function(){
// var hei=parseInt($(".shaiAllItem").height())-2;
// $(this).find(".subshaicontent").css("top", '34px');
// $(this).find(".subshaicontent").show();
// },function(){
// $(this).find(".subshaicontent").hide();
// });
//
// $(".shaiItem").live("click",function(){
// $(".shaiItem").removeClass("active");
// $(this).addClass("active");
// $(".subshaicontent").hide();
// });
//
// $(".subshaicontent").live("click", function(event){
// $(".subshaicontent").hide();
// event.stopPropagation();
// });
let overlaymenu=(item,id)=>(
<Menu>
{
item.map((list,k)=>{
return(
<Menu.Item>
<div className="mt5 subshaicontent-part" key={k}>
<a style={{ height: '20px' }} className={ "mb15 shixun_repertoire color-dark"} name={list.id} id={id} onClick={this.getshixunchildValue}>{list.name}</a>
<div className="sub-Item clearfix">
{
list.tags.map((tag,e)=>{
return(
<a className={parseInt(shixunchildValues)===tag.id?"shixun_repertoire active":"shixun_repertoire"} key={e} id={tag.id} name={id} rel="subshaicontent" onClick={this.getshixunchildValues}>{tag.name}</a>
)
})
}
</div>
</div>
</Menu.Item>
)
})
}
</Menu>
)
return (
<div className="edu-back-white" >
<div className="educontent">
<div className="pt40 pb40">
<div className="clearfix mb30 shaiContent">
<span className="shaiTitle fl mt3">方向</span>
<div className="fl pr shaiAllItem">
<li className={shixunsearchAllvalue==="a"?"shaiItem shixun_repertoire active":"shaiItem shixun_repertoire"} value= "a" onClick={this.shixunsearchall}>全部</li>
<style>
{
`
.ant-dropdown{
width: 800px;
}
.shixun_repertoire{
cursor: pointer;
float: left;
margin-right: 20px;
color: #999;
cursor: pointer;
margin-bottom: 10px;
}
.ant-dropdown-menu-item, .ant-dropdown-menu-submenu-title{
padding: 0px 12px;
}
.ant-dropdown-menu-item:hover, .ant-dropdown-menu-submenu-title:hover{
background:transparent !important;
}
`
}
</style>
{
shixunhoverData.map((item,key)=>{
return(
<Dropdown overlay={overlaymenu(item.sub_repertoires,item.id)} key={key} >
<li key={key} className={parseInt(shixunsearchAllvalue)===item.id?"shaiItem shixun_repertoire active":"shaiItem shixun_repertoire"} value={item.id} onClick={this.shixunsearchAll}>
{item.name}
</li>
</Dropdown>
)
})
}
</div>
</div>
<div className="clearfix">
<span className="shaiTitle fl mt6">筛选</span>
{
<style>
{`
.shaiItems{
padding: 3px 15px;
float: left;
border-radius: 4px;
color: #4C4C4C;
cursor: pointer;
margin-right: 15px;
display: block;
float:left;
}
.shaiItems.active {
background-color: #4CACFF!important;
color: #fff!important;
}
`}
</style>
}
<div className="fl pr shaiAllItem mt1">
<li className={this.state.diff===0?"shaiItems shixun_repertoire active":"shaiItems shixun_repertoire"} onClick={()=>this.diff_search(0)}>全部难度</li>
<li className={this.state.diff===1?"shaiItems shixun_repertoire active":"shaiItems shixun_repertoire"} onClick={()=>this.diff_search(1)}>初级学员</li>
<li className={this.state.diff===2?"shaiItems shixun_repertoire active":"shaiItems shixun_repertoire"} onClick={()=>this.diff_search(2)}>中级学员</li>
<li className={this.state.diff===3?"shaiItems shixun_repertoire active":"shaiItems shixun_repertoire"} onClick={()=>this.diff_search(3)}>高级学员</li>
<li className={this.state.diff===4?"shaiItems shixun_repertoire active":"shaiItems shixun_repertoire"} onClick={()=>this.diff_search(4)}>顶级学员</li>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default ShixunSearchBar;

@ -1,422 +0,0 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import axios from 'axios';
import { Spin } from 'antd';
import { TPMIndexHOC } from '../TPMIndexHOC';
import { SnackbarHOC } from 'educoder';
import ShixunCardList from './ShixunCardList';
import ShixunSearchBar from './ShixunSearchBar';
import ShixunCard from './ShixunCard';
import UpgradeModals from '../../modals/UpgradeModals';
const queryString = require('query-string');
const $ = window.$;
class ShixunsIndex extends Component {
constructor(props) {
super(props)
this.state={
order_by: "new",
page:1,
limit:16,
keyword:"",
status:0,
diff:0,
tag_level: 1,
tag_id:'',
middleshixundata:[],
typepvisible:true,
pages:1,
search_tags:null,
parsedid:undefined,
newtag_level:undefined,
newpalce:undefined,
sort:"desc"
}
}
componentDidMount(){
const upsystem=`/users/system_update.json`;
axios.get(upsystem).then((response)=>{
let updata=response.data;
this.setState({
updata:updata
})
}).catch((error)=>{
console.log(error);
})
let _keyword;
if (window.__headSearchKeyword) {
this.setState({ keyword: window.__headSearchKeyword })
_keyword = window.__headSearchKeyword
delete window.__headSearchKeyword
}
const parsed = queryString.parse(this.props.location.search);
if(parsed.id===undefined&&parsed.type===undefined){
let {order_by, tag_level, tag_id, page, limit, keyword, status, diff} = this.state;
let params={
order_by:order_by,
tag_level:tag_level,
tag_id:tag_id,
page:page,
limit:limit,
keyword: _keyword || keyword ,
status:status,
diff:diff,
sort: "desc"
}
this.shixunresultend(params);
}else{
let {order_by,page, limit, keyword, status, diff} = this.state;
let nawparsed=parsed.type;
let newpalce=parsed.palce;
if(nawparsed==="rep"){
nawparsed=1
}
else if(nawparsed==="sub"){
nawparsed=2
}else if(nawparsed==="tag"){
nawparsed=3
}
let params={
order_by:order_by,
tag_level:nawparsed,
tag_id:parsed.id,
page:page,
limit:limit,
keyword: _keyword || keyword,
status:status,
diff:diff,
sort: "desc"
}
this.setState({
parsedid:parsed.id,
newtag_level:nawparsed,
newpalce:newpalce
})
this.shixunresultend(params);
}
}
allUpdatashixunlist=()=>{
let{sort,order_by}=this.state;
this.setState({
tag_level: 1,
tag_id:'',
page: 1,
limit: 16,
keyword:'',
status: 0,
diff: 0,
})
let params={
order_by:order_by,
tag_level: 1,
tag_id:'',
page: 1,
limit: 16,
keyword:'',
status: 0,
diff: 0,
sort:sort
}
this.shixunresultend(params)
}
Updatasearchlist=(value)=>{
if (value[1].tag_id === " ") {
this.setState({
keyword: ""
})
}
this.setState({
tag_level:value[0].tag_level,
tag_id:value[1].tag_id,
typepvisible:true
})
let {order_by, sort, limit, keyword, status, diff} = this.state;
let params={
order_by:order_by,
tag_level:value[0].tag_level,
tag_id:value[1].tag_id,
page:1,
limit:limit,
keyword:keyword,
status:status,
diff:diff,
sort:sort
}
this.shixunresultend(params)
}
StatusEnquiry=(key)=>{
let Vrl=`/shixuns.json`;
let newstatus;
let newdiff;
if(key[0].type===1){
this.setState({
status: key[1].value,
typepvisible:true
})
newstatus=key[1].value;
newdiff=this.state.diff;
}else if(key[0].type===2){
this.setState({
diff: key[1].value,
typepvisible:true
})
newdiff=key[1].value;
newstatus=this.state.status;
}
let params= {
order_by:this.state.order_by,
tag_level:this.state.tag_level,
tag_id:this.state.tag_id,
page:1,
limit:this.state.limit,
keyword:this.state.keyword,
status:newstatus,
diff:newdiff,
}
this.shixunresultend(params)
}
OnSearchInput=(value,type)=>{
if(type===true){
this.setState({
keyword:value,
typepvisible:true,
pages:1
})
let {order_by, tag_level, tag_id, sort, limit, status, diff} = this.state;
let params= {
order_by:order_by,
tag_level:tag_level,
tag_id:tag_id,
page:1,
limit:limit,
keyword:value,
status:status,
diff:diff,
sort:sort
}
this.shixunresultend(params)
}else{
this.setState({
keyword:value,
pages:1
})
}
}
ShixunsSwitch=()=>{
//types
this.setState({
order_by:"mine",
typepvisible:true,
pages:1,
})
let{tag_level,tag_id,page,limit,keyword,status,diff,sort}=this.state;
let newsort=sort;
if(newsort===undefined){
newsort="desc"
}
let params= {
order_by:"mine",
tag_level:tag_level,
tag_id:tag_id,
page:1,
limit:limit,
keyword:keyword,
status:status,
diff:diff,
sort:newsort
}
this.shixunresultend(params)
}
shixunsPage=(value)=>{
this.setState({
page:value,
typepvisible:true,
pages:value
})
let {order_by, tag_level, tag_id, limit, keyword, status, diff,sort} = this.state;
let params= {
order_by:order_by,
tag_level:tag_level,
tag_id:tag_id,
page:value,
limit:limit,
keyword:keyword,
status:status,
diff:diff,
sort:sort
}
let Url=`/shixuns.json`;
axios.get(Url,{
params
}).then((response)=> {
if(response.status===200){
this.setState({
middleshixundata: response.data,
typepvisible:false,
});
}
}).catch((error)=>{
console.log(error)
});
}
ShixunsState=(val,type)=>{
// sort,
let {tag_level, tag_id, page, limit, keyword, status, diff,sort} = this.state;
let newsort=sort;
this.setState({
order_by:type,
typepvisible:true,
pages:1,
// sort:sort
})
let params
// let vals=false
if(newsort===undefined){
newsort="desc"
}
params= {
order_by:type,
tag_level:tag_level,
tag_id:tag_id,
page:1,
limit:limit,
keyword:keyword,
status:status,
diff:diff,
sort:newsort
}
this.shixunresultend(params)
}
Shixunsupcircles=(sort)=>{
console.log(sort)
this.setState({
sort:sort
})
let {
order_by,
tag_level,
tag_id,
limit,
keyword,
status,
diff,
} = this.state;
let params= {
order_by:order_by,
tag_level:tag_level,
tag_id:tag_id,
page:1,
limit:limit,
keyword:keyword,
status:status,
diff:diff,
sort:sort
}
this.shixunresultend(params)
}
shixunresultend=(params)=>{
let Url=`/shixuns.json`;
axios.get(Url,{
params
}).then((response)=> {
// TODO 有keyword返回值时 显示一共有多少条记录
if(response.status===200){
this.setState({
search_tags:response.data.search_tags,
middleshixundata: response.data,
typepvisible:false,
pages:1
});
}
}).catch((error)=>{
console.log(error)
});
}
render() {
let {middleshixundata, typepvisible, pages, search_tags, keyword,parsedid,newtag_level,newpalce} = this.state;
// console.log(this.state.updata)
return (
<div className="newMain clearfix backFAFAFA">
{this.state.updata===undefined?"":<UpgradeModals
{...this.state}
/>}
{/*<Spin spinning={typepvisible} size="large" style={{marginTop:'15%'}}>*/}
<ShixunSearchBar
Updatasearchlist={this.Updatasearchlist.bind(this)}
allUpdatashixunlist={this.allUpdatashixunlist}
StatusEnquiry={this.StatusEnquiry.bind(this)}
OnSearchInput={this.OnSearchInput.bind(this)}
keyword={keyword}
parsedid={parsedid}
newtag_level={newtag_level}
newpalce={newpalce}
/>
<ShixunCardList
ShixunsState={this.ShixunsState.bind(this)}
ShixunsSwitch={this.ShixunsSwitch.bind(this)}
Shixunsupcircles={this.Shixunsupcircles.bind(this)}
allUpdatashixunlist={this.allUpdatashixunlist}
{...this.state}
OnSearchInput={this.OnSearchInput.bind(this)}
/>
<ShixunCard
typepvisible={typepvisible}
middleshixundata={middleshixundata.shixuns}
totalcount={middleshixundata.total_count}
pagination={middleshixundata.pagination}
pages={pages}
shixunsPage={this.shixunsPage.bind(this)}
/>
{/*</Spin>*/}
</div>
);
}
}
export default SnackbarHOC() (TPMIndexHOC ( ShixunsIndex ));

@ -1,114 +0,0 @@
.shixunsdiffcult{
width: 40px;
height: 21px;
overflow: hidden;
margin-left: 8px;
}
.rateYo{
text-align: center;
cursor: default;
width: 111px;
}
a:link, a:visited {
color: #05101a;
}
a:link{text-decoration:none;}
a:visited{text-decoration:none;}
a:hover{text-decoration:none;}
a:active{text-decoration:none;}
.next-rating-overlay .next-icon{
color: #FFA800!important;
}
.displayblock{
display:block;
text-align: center;
margin-bottom: 20px;
}
.totalScore{
justify-content: center;
align-items: center;
display: -webkit-flex;
height: 100%;
}
.next-progress-line{
width: 210px !important;
margin-left: 10px;
margin-top: 4px;
}
.next-progress-line-overlay-normal{
background-color: #FFA800 !important;
}
.next-rating-base-disabled{
cursor: default!important;
}
/*#challenge_begin {*/
/*!*height: 40px !important;*!*/
/*line-height: 30px;*/
/*}*/
.ant-modal-title{
font-size: 16px;
font-weight: bold !important;
color: #333;
}
.ml60{
margin-left:20px;
}
.marginauto{
margin:0 auto;
}
.margin152{
margin-left: 152px;
}
.margin-tp26{
margin-top: -26px;
}
.edu-h315{
height:315px;
}
.height39 {
height: 39px !important;
}
#commentsStar{
margin-top: -7px;
width: 90px;
height: 80px;
}
.startbtnModal .ant-modal-content{
background: transparent;
box-shadow: 0 4px 12px transparent;
}
.startbtnModal .ant-modal-content .ant-modal-body .ant-spin-spinning{
margin-left: 45%;
}
.mr51{
margin-right:51px;
}
.flexbannerright{
display: flex;
justify-content: flex-end;
}
.width360{
width:360px;
}

@ -1,13 +0,0 @@
#myshixuns_count{
text-decoration:none !important;
}
#created_at{
text-decoration:none !important;
}
.shixun_repertoire{
cursor: pointer ;
}
.next-btn-medium:hover{
color: #4CACFF;
border:1px solid #4CACFF;
}

@ -1,20 +0,0 @@
.iconfontShixunSearchBar{
z-index: 1000;
position: absolute;
right: 3px;
top: 0px;
}
.diffSelect{
margin-left:20px !important;
}
.ant-input-search-button{
/*margin-right: 10px;*/
border: 1px solid transparent;
}
.Mousebox{
width: 800px !important;
}
.subshaicontent a{
height:30px;
}

@ -1,42 +0,0 @@
.ml350 {
margin-left: 40%;
}
.ml32 {
margin-left: 32%;
}
.square-img{
min-height: 210px;
}
.task-hide{
margin-bottom: 0em;
}
.backFAFAFA{
background:#FAFAFA;
}
.demo {
width: 500px;
background-color: #0dcecb;
text-align: center;
padding:50px;
}
.next-loading {
margin-bottom: 5px;
width:100%;
}
.next-rating-overlay .next-icon{
color: #FFA800!important;
}
.custom-pagination {
display: inline-block;
margin-left: 10px;
}
.ml425{
margin-left:42.5%;
margin-top:20px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

@ -1,142 +0,0 @@
const $ = window.$;
$(function(){
//实训首页筛选的移入和点击事件
$(".shaiItem").hover(function(){
var hei=parseInt($(".shaiAllItem").height())-2;
$(this).find(".subshaicontent").css("top",hei);
$(this).find(".subshaicontent").show();
},function(){
$(this).find(".subshaicontent").hide();
});
$(".shaiItem").live("click",function(){
$(".shaiItem").removeClass("active");
$(this).addClass("active");
$(".subshaicontent").hide();
});
$(".subshaicontent").live("click", function(event){
$(".subshaicontent").hide();
event.stopPropagation();
});
//最新、最热
$(".bestChoose").click(function(){
$(".bestChoose").removeClass("active");
$(this).addClass("active");
})
//实训路径选择导航条
$(".path-nav li a").live("click",function(){
$(".path-nav li").removeClass("active");
$(this).parent().addClass("active");
})
});
//隐藏我的学习
function clickControl(item, type){
var wid=$(item).width();
var wid1=$(".controlring").width();
var hidden_course = 1;
if($(".controlring").css("left")=="1px"){
$(".controlring").animate({left:parseInt(wid-wid1-1)+"px"});
$(".controlblue").animate({width:wid+"px"});
$("input[name='hidden_learn']").val('1');
}else{
$(".controlring").animate({left:"1px"});
$(".controlblue").animate({width:"0px"});
$("input[name='hidden_learn']").val('');
hidden_course = 0;
}
if(type == "l_shixun"){
$("#shixun_search_condition").submit();
} else{
$.get("/courses?select="+$("#select_type").val()+"&order="+$("#select_order").val()+"&hidden="+hidden_course);
}
}
// 清空条件
function clear_style(){
$("#shixun_search_condition").find('input[type=hidden]').each(function() {
$(this).val('');
});
}
// 精选实训的搜索 #type参数( status实训状态 diff实训难度 search实训搜索 order最新最热排序)
function filter_search(values, type){
switch(type){
case "status":
$("input[name='status']").val(values);
break;
case "diff":
$("input[name='diff']").val(values);
break;
case "search":
$("input[name='search']").val(values);
break;
}
$("#shixun_search_condition").submit();
}
// 点击实训体系名称 # type参数rep体系大类别 sub体系子类别 tags 实训标签; order: 排序)
// # name参数 列表显示使用
// # values参数 赋值给表单的值
$(".shixun_repertoire").live("click", function(event){
var type = $(this).attr("data-type");
var name = $(this).attr("data-name");
var values = $(this).attr("data-values");
if(type != 'order'){
$(".subshaicontent a").removeClass("active");
$(".shaiItem").removeClass("active");
$("input[name='repertoire'], input[name='sub_repertoire'], input[name='tag_repertoire']").val('');
}
$(this).closest(".shaiItem").addClass("active");
$(".subshaicontent").hide();
$("#search_name").html(name);
switch(type){
case "rep":
$("input[name='repertoire']").val(values);
$("#shixun_search_input").val("");
$("input[name='search']").val("");
break;
case "sub":
$("input[name='sub_repertoire']").val(values);
break;
case "tag":
$("input[name='tag_repertoire']").val(values);
break;
case "order":
var $sort = $("input[name='sort']");
var oldValue = $("input[name='order']").val();
$("input[name='order']").val(values);
var newValue = $("input[name='order']").val();
if(oldValue != newValue){
$("input[name='sort']").val("desc");
}else {
if($sort.val() == "desc"){
$sort.val("asc");
}else{
$sort.val("desc");
}
}
break;
}
$(this).addClass("active"); // 因为order需要判断样式因此写在switch之后
$("#shixun_search_condition").submit();
event.stopPropagation();
});
// 实训首页回车搜索
$("#shixun_search_input").live("keyup", function(e){
// 兼容FF和IE和Opera
var theEvent = e || window.event;
var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
if (code == 13) {
//回车执行查询
filter_search($(this).val(), "search");
}
});
Loading…
Cancel
Save