diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index 0b5eca189..464d0b8e1 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -126,7 +126,7 @@ export function initAxiosInterceptors(props) { let timestamp = Date.parse(new Date())/1000; if (window.location.port === "3007") { // let timestamp=railsgettimes(proxy); - console.log(timestamp) + // console.log(timestamp) railsgettimes(`${proxy}/api/main/first_stamp.json`); let newopens=md5(opens+timestamp) config.url = `${proxy}${url}`; diff --git a/public/react/src/modules/tpm/TPMIndex.js b/public/react/src/modules/tpm/TPMIndex.js index 86d0e9637..af9e17a4b 100644 --- a/public/react/src/modules/tpm/TPMIndex.js +++ b/public/react/src/modules/tpm/TPMIndex.js @@ -20,6 +20,8 @@ import TPMShixunDiscussContainer from './TPMShixunDiscussContainer'; import TPMRepositoryComponent from './TPMRepositoryComponent'; +import TPMRepositoryComponentdetails from './TPMRepositoryComponentdetails'; + import TPMRepositoryCommits from './shixunchild/Repository/TPMRepositoryCommits'; import TPMsettings from './TPMsettings/TPMsettings'; @@ -133,6 +135,11 @@ const AddFile = Loadable({ loader: () => import('./shixunchild/Repository/RepositoryAddFile'), loading: Loading, }) +// 版本库上传文件 +const Uploadfile= Loadable({ + loader: () => import('./shixunchild/Repository/RepositoryAddFileupload_file'), + loading: Loading, +}) const interceptorUrlArray = ['repository.json', 'commits.json', 'propaedeutics.json' , 'challenges.json', 'discusses.json', 'ranking_list.json', 'collaborators.json'] @@ -267,23 +274,23 @@ class TPMIndex extends Component { }); }); - 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); - }); + // 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) => { @@ -387,7 +394,8 @@ class TPMIndex extends Component { render() { let url = window.location.href; - let flag = url.indexOf("add_file")>-1; + let flag =false; + // url.indexOf("add_file")>-1; return (
@@ -509,20 +517,50 @@ class TPMIndex extends Component { />) }> + () + }> + () }> + () + }> + + () + }> + + + () + }> + + () + }> + + () + (props) => () }> + + () + (props) => () }> + {/* */}
{/* 可能会影响到其他页面的样式,需要测试、协商 */} -
- - {/* */} + { loadingContent ? : - { !isContentWidth100 &&
+ { isflag &&
}
diff --git a/public/react/src/modules/tpm/TPMRepositoryComponent.js b/public/react/src/modules/tpm/TPMRepositoryComponent.js index af3930b74..713af8d97 100644 --- a/public/react/src/modules/tpm/TPMRepositoryComponent.js +++ b/public/react/src/modules/tpm/TPMRepositoryComponent.js @@ -39,7 +39,6 @@ class TPMRepositoryComponent extends Component { componentDidMount = () => { - this.fetchRepo() } setContentWidth100 = (flag) => { @@ -114,6 +113,7 @@ class TPMRepositoryComponent extends Component { } // listItem 如果是num,则是通过面包屑点击过来的,取pathArray的子集 fetchRepo = (listItem) => { + const { pathArray } = this.state; let newPathArray = pathArray.slice(0) @@ -191,33 +191,27 @@ class TPMRepositoryComponent extends Component { render() { const { isContentWidth100 } = this.state; + let matchpath =this.props.match.path; + let flag =false; + if(matchpath==="/shixuns/:shixunId/repository"){ + flag =true; + }else if(matchpath==="/shixuns/:shixunId/secret_repository"){ + flag =true; + } // 需要重构 return ( - { !isContentWidth100 ? - : -
- {/* 可能会影响到其他页面的样式,需要测试、协商 */} -
- -
-
+ :"" }
diff --git a/public/react/src/modules/tpm/TPMRepositoryComponentdetails.js b/public/react/src/modules/tpm/TPMRepositoryComponentdetails.js new file mode 100644 index 000000000..9783882dd --- /dev/null +++ b/public/react/src/modules/tpm/TPMRepositoryComponentdetails.js @@ -0,0 +1,231 @@ +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 TPMRepositoryComponentdetails 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; + let matchpath =this.props.match.path; + let flag =false; + if(matchpath==="/shixuns/:shixunId/repository"){ + flag =true; + }else if(matchpath==="/shixuns/:shixunId/secret_repository"){ + flag =true; + } + + // 需要重构 + return ( + + { flag ? "" + : +
+ {/* 可能会影响到其他页面的样式,需要测试、协商 */} +
+ +
+
+ } + +
+ + + ); + } +} + +export default TPMRepositoryComponentdetails ; diff --git a/public/react/src/modules/tpm/shixunchild/Repository/Repository.css b/public/react/src/modules/tpm/shixunchild/Repository/Repository.css index 158666548..a8aeeb8b3 100644 --- a/public/react/src/modules/tpm/shixunchild/Repository/Repository.css +++ b/public/react/src/modules/tpm/shixunchild/Repository/Repository.css @@ -56,4 +56,8 @@ } .padding040pxRepository{ padding: 40px 40px 0px 40px; +} + +.color888{ + color:#888888 } \ No newline at end of file diff --git a/public/react/src/modules/tpm/shixunchild/Repository/Repository.js b/public/react/src/modules/tpm/shixunchild/Repository/Repository.js index 4a78a85e4..d53b0c8d3 100644 --- a/public/react/src/modules/tpm/shixunchild/Repository/Repository.js +++ b/public/react/src/modules/tpm/shixunchild/Repository/Repository.js @@ -1,17 +1,14 @@ import React, { Component } from 'react'; - -import axios from 'axios'; - -import { trace, trace_collapse ,getImageUrl, toPath} from "educoder"; - +import {getImageUrl} from "educoder"; import RepositoryDirectories from './RepositoryDirectories'; -import { Button } from "antd"; +import { Button ,Tree,Icon} from "antd"; import {Link} from 'react-router-dom'; import RepositoryCombinePath from './RepositoryCombinePath'; import RepositoryNoneData from './RepositoryNoneData'; +import Repositoryfile from './Repositoryfile'; import './Repository.css'; const $ = window.$; - +const { TreeNode, DirectoryTree } = Tree; // 点击按钮复制功能 function jsCopy(){ var e = document.getElementById("copy_rep_content"); @@ -26,19 +23,39 @@ class Repository extends Component { constructor(props) { super(props); this.state={ - + evaluationvisible:false, } } + componentDidMount() { + } - onRepoFileClick = (item) => { + onRepoFileClick = (item) => { this.props.fetchRepo(item) + } + + NewFolder=()=>{ + this.setState({ + evaluationvisible:true + }) + } + hideNewFolder=()=>{ + this.setState({ + evaluationvisible:false + }) } + render() { let { match, author, git_url, lastest_commit,repositoryLoading, commits,trees,pathArray , TPMRightSectionData } = this.props; - + let matchpath =this.props.match.path; + let Repositoryflag =""; + if(matchpath==="/shixuns/:shixunId/repository"){ + Repositoryflag ="repository"; + }else if(matchpath==="/shixuns/:shixunId/secret_repository"){ + Repositoryflag ="secret_repository"; + } if (!author) { author = {} } @@ -48,6 +65,12 @@ class Repository extends Component { } return ( + {this.state.evaluationvisible===true?this.hideNewFolder()} + setfilepath={(path)=>this.setfilepath(path)} + />:""} { repositoryLoading ?
:
@@ -126,18 +149,21 @@ class Repository extends Component { (
- + + +
) @@ -215,6 +241,13 @@ class Repository extends Component { ) })}
+ + + }> + } /> + }/> + +
diff --git a/public/react/src/modules/tpm/shixunchild/Repository/RepositoryAddFile.js b/public/react/src/modules/tpm/shixunchild/Repository/RepositoryAddFile.js index e074908e3..3dc19d0dd 100644 --- a/public/react/src/modules/tpm/shixunchild/Repository/RepositoryAddFile.js +++ b/public/react/src/modules/tpm/shixunchild/Repository/RepositoryAddFile.js @@ -6,6 +6,7 @@ import { Form , Modal , Input , Breadcrumb , Button } from 'antd' import { Link } from 'react-router-dom' import axios from 'axios' +import Bottomsubmit from "../../../modals/Bottomsubmit"; /** ---------------------------- START @@ -121,7 +122,8 @@ class RepositoryAddFile extends Component { const {getFieldDecorator} = this.props.form; let { shixunId } = this.props.match.params; return( -
+
+
+ {/*

*/} + {/* */} + {/* 实训项目*/} + {/* 版本库*/} + {/* 添加新文件*/} + {/* */} + {/*

*/} +
+
+ +

+

上传文件
+

+ + + + {getFieldDecorator('message', { + rules: [{ + required: true, message: '请输入名称', + },{ + whitespace: true, message: '请勿输入空格' + }], + })( + + )} + + + +

+

{this.state.filspath} 选择文件目录
+

+ + {/*
*/} + + {/* */} + {/*
*/} + + + + +

+ +

+ +

+ 拖拽文件或 点击此处上传 +

+
+ + {/**/} + {/* {getFieldDecorator('message', {*/} + {/* rules: [{required: true, message: "请输入提交信息"}],*/} + {/* })(*/} + {/* */} + {/* )}*/} + {/**/} + +
+ +
+ this.handleSubmit()}/> +
+ ) + } +} +const RepositoryAddFileupload_file = Form.create({name: 'RepositoryAddFileupload_files'})(RepositoryAddFileupload_files); +// RouteHOC() +export default (RepositoryAddFileupload_file); \ No newline at end of file diff --git a/public/react/src/modules/tpm/shixunchild/Repository/Repositoryfile.js b/public/react/src/modules/tpm/shixunchild/Repository/Repositoryfile.js new file mode 100644 index 000000000..cea92b3ee --- /dev/null +++ b/public/react/src/modules/tpm/shixunchild/Repository/Repositoryfile.js @@ -0,0 +1,239 @@ +import React, { Component } from 'react'; +import {Modal,Input,Form} from "antd"; +import axios from 'axios'; +import {TPMIndexHOC} from "../../TPMIndexHOC"; +class Repositoryfile extends Component{ + constructor(props) { + super(props) + this.state={ + selectpath:"", + trees:[], + main:[], + path:"" + } + } + + // sendgetfilepath=(item)=>{ + // this.getfilepath(item.name); + // + // } + + evaluationhideModal=()=>{ + this.props.hideNewFolder(); + } + + componentDidMount() { + this.goblakepath("") + } + + goblakepath=(path,key)=>{ + let {main} =this.state; + let matchpath =this.props.match.path; + let id = this.props.match.params.shixunId; + let url =""; + if(matchpath==="/shixuns/:shixunId/repository"){ + url ="/shixuns/"+id+"/repository.json"; + }else if(matchpath==="/shixuns/:shixunId/secret_repository"){ + url ="/shixuns/"+id+"/secret_repository.json"; + } + let newmain=[] + for(var i=0;i<=key;i++){ + newmain.push(main[i]) + } + + axios.post(url,{ + path: path + }).then((response) => { + if (response.data.status === 403||response.data.status === 401||response.data.status === 500) { + + }else { + this.setState({ + trees: response.data.trees, + path: path, + main: newmain, + // selectpath:selectpath + }) + } + }).catch((error) => { + console.log(error) + }); + + + } + + sendgetfilepath=(newpath,type)=>{ + + let id = this.props.match.params.shixunId; + let{path,main}=this.state; + + let matchpath =this.props.match.path; + let url =""; + if(matchpath==="/shixuns/:shixunId/repository"){ + url ="/shixuns/"+id+"/repository.json"; + }else if(matchpath==="/shixuns/:shixunId/secret_repository"){ + url ="/shixuns/"+id+"/secret_repository.json"; + } + + let ary=main; + let paths=path; + + this.setState({ + selectpatharr:[], + }) + + if(paths===""&&type==="tree"){ + newpath=newpath+"/"; + paths=""; + if(main.length===0){ + ary.push({val:"根目录/",path:""},{val:newpath,path:paths+newpath}) + }else{ + ary.push({val:newpath,path:paths+newpath}) + } + + }else if(paths!=""&&type==="tree"){ + newpath=newpath+"/"; + ary.push({val:newpath,path:paths+newpath}) + } + + axios.post(url,{ + path: paths+newpath + }).then((response) => { + if (response.data.status === 403||response.data.status === 401||response.data.status === 500) { + + }else{ + this.setState({ + trees:response.data.trees, + path:paths+newpath, + main:ary, + // selectpath:"" + }) + } + + }).catch((error) => { + console.log(error) + }); + } + + handleSubmit = (e) => { + let {path}=this.state; + let matchpath =this.props.match.path; + let flag =false; + if(matchpath==="/shixuns/:shixunId/repository"){ + flag =false; + }else if(matchpath==="/shixuns/:shixunId/secret_repository"){ + flag =true; + } + + let url=`/shixuns/${this.props.match.params.shixunId}/upload_git_folder.json`; + this.props.form.validateFieldsAndScroll((err, values) => { + if (!err) { + console.log('Received values of form: ', values); + let paths=path+values.name; + axios.post(url,{ + path: paths, + secret_repository:flag, + }).then((result)=>{ + if(result){ + if(result.data.status===0){ + this.props.showNotification("新建成功") + } + } + }).catch((error)=>{ + console.log(error); + }) + } + }); + }; + + render(){ + const {getFieldDecorator} = this.props.form; + const {evaluationvisible} = this.props; + const {selectpath,trees,main,path}=this.state; + + + return( + evaluationvisible===true? +
+ +
+ + {/* + + + this.savegetfilepath(path+item.name,item.type)}>{item.name} + + */} +
+ +
{path}
+
+ + {getFieldDecorator('name', { + rules: [{ + required: true, message: '请输入名称', + },{ + whitespace: true, message: '请勿输入空格' + }], + })( + + )} + +
+
+ + this.evaluationenter()} + onClick={() => this.handleSubmit()}>确定 + this.evaluationhideModal()}>取消 +
+
+
:"" + ) + } +} + +const newRepositoryfile = Form.create({name: 'newRepositoryfile'})(Repositoryfile); + +export default newRepositoryfile; \ No newline at end of file