Merge remote-tracking branch 'origin/dev_aliyun' into dev_aliyun

chromesetting
杨树明 5 years ago
commit e1869554ef

@ -41,7 +41,9 @@ json.top do
json.old_url @old_domain
# 云上实验室管理权限
json.laboratory_user current_laboratory.laboratory_users.exists?(user_id: @user&.id) || @user&.admin_or_business?
laboratory_user = current_laboratory.laboratory_users.exists?(user_id: @user&.id) || @user&.admin_or_business?
json.laboratory_user laboratory_user
json.laboratory_admin_url laboratory_user ? "/cooperative" : nil
end
json.down do

@ -45,11 +45,13 @@ class College extends Component {
align: 'center',
className: "edu-txt-center font-14 maxnamewidth340",
render: (text, record) => (
<span className="maxnamewidth340">
<a className="maxnamewidth340" title={record.teachers} style={{
color:'#05101A'
}}>
{
record.teachers
}
</span>
</a >
)
},
{

@ -7,7 +7,7 @@
background-color: rgba(18,28,36,1);
color: #fff;
height: 56px;
padding: 0 30px;
padding: 0 20px;
.flex_strict{
flex: 1;
}

@ -4,11 +4,11 @@
* @Github:
* @Date: 2019-11-21 09:19:38
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-19 17:54:28
* @LastEditTime: 2019-12-20 09:23:07
*/
import './index.scss';
import React, { useState } from 'react';
import { Collapse, Icon, Input, Form, Button } from 'antd';
import { Collapse, Icon, Input, Form } from 'antd';
import { connect } from 'react-redux';
import actions from '../../../../../redux/actions';
import { CNotificationHOC} from 'educoder';
@ -18,14 +18,14 @@ const FormItem = Form.Item;
const AddTestDemo = (props) => {
const {
key,
onSubmitTest,
// onSubmitTest,
onDeleteTest,
testCase,
testCaseValidate,
isOpen
} = props;
const [isEditor, setIsEditor] = useState(false); // 是否是编辑
// const [isEditor, setIsEditor] = useState(false); // 是否是编辑
// 删除操作
const handleDeletePanel = (e) => {
@ -73,54 +73,54 @@ const AddTestDemo = (props) => {
)
// 取消操作
const handleReset = (e) => {
e.preventDefault();
props.form.resetFields();
}
// const handleReset = (e) => {
// e.preventDefault();
// props.form.resetFields();
// }
// 保存
const handleSubmit = (e) => {
e.preventDefault();
props.form.validateFields((err, values) => {
if (err) {
return;
}
console.log('提交表单: ', values);
onSubmitTest(values);
});
}
// const handleSubmit = (e) => {
// e.preventDefault();
// props.form.validateFields((err, values) => {
// if (err) {
// return;
// }
// console.log('提交表单: ', values);
// onSubmitTest(values);
// });
// }
// 编辑后保存
const handleEditorOrSave = (e) => {
if (!isEditor) {
setIsEditor(true);
} else {
// TODO 调用修改测试用例接口
setIsEditor(false); // 保存后 设置 false
}
}
// const handleEditorOrSave = (e) => {
// if (!isEditor) {
// setIsEditor(true);
// } else {
// // TODO 调用修改测试用例接口
// setIsEditor(false); // 保存后 设置 false
// }
// }
// 渲染提交按钮
const renderSubmitBtn = () => {
const { identifier, testCase, loading } = props;
// console.log('========', identifier);
// 1. 新增时,不显示按钮
if (identifier) {
if (testCase.isAdd) {
return (
<FormItem style={{ textAlign: 'right' }}>
<Button style={{ marginRight: '20px' }} onClick={handleReset}>取消</Button>
<Button type="primary" onClick={handleSubmit}>保存</Button>
</FormItem>
);
} else {
return (
<FormItem style={{ textAlign: 'right' }}>
<Button onClick={handleEditorOrSave} loading={loading}>{isEditor ? '保存' : (loading ? '保存' : '编辑')}</Button>
</FormItem>
);
}
}
}
// const renderSubmitBtn = () => {
// const { identifier, testCase, loading } = props;
// // console.log('========', identifier);
// // 1. 新增时,不显示按钮
// if (identifier) {
// if (testCase.isAdd) {
// return (
// <FormItem style={{ textAlign: 'right' }}>
// <Button style={{ marginRight: '20px' }} onClick={handleReset}>取消</Button>
// <Button type="primary" onClick={handleSubmit}>保存</Button>
// </FormItem>
// );
// } else {
// return (
// <FormItem style={{ textAlign: 'right' }}>
// <Button onClick={handleEditorOrSave} loading={loading}>{isEditor ? '保存' : (loading ? '保存' : '编辑')}</Button>
// </FormItem>
// );
// }
// }
// }
/**
* 文本输入框可编辑的情况
@ -128,9 +128,9 @@ const AddTestDemo = (props) => {
* 2. isAdd false isEditor 为true
* @param {*} testCase
*/
const isDisabled = (testCase) => {
return !testCase.isAdd && !isEditor;
};
// const isDisabled = (testCase) => {
// return !testCase.isAdd && !isEditor;
// };
// const {input = {}, output = {}} = (testCasesValidate[index] = {});
const activePane = {
@ -158,7 +158,8 @@ const AddTestDemo = (props) => {
rows={5}
value={testCase.input}
onChange={handleInputChange}
disabled={isDisabled(testCase)}/>
// disabled={isDisabled(testCase)}
/>
</FormItem>
<FormItem
label={<span className={'label_text'}>输出</span>}
@ -170,9 +171,10 @@ const AddTestDemo = (props) => {
rows={5}
value={testCase.output}
onChange={handleOutputChange}
disabled={isDisabled(testCase)}/>
// disabled={isDisabled(testCase)}
/>
</FormItem>
{renderSubmitBtn()}
{/* {renderSubmitBtn()} */}
</Form>
</Panel>
</Collapse>

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-20 10:35:40
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-19 17:23:10
* @LastEditTime: 2019-12-19 20:16:32
*/
import './index.scss';
// import 'katex/dist/katex.css';
@ -311,7 +311,7 @@ class EditTab extends React.Component {
<div style={{ marginTop: '15px'}}>
<QuillForEditor
style={{ height: '200px', 'overflowY': 'auto' }}
placeholder="init content"
placeholder="请输入描述信息"
onContentChange={handleContentChange}
options={quillConfig}
value={ojForm.description}

@ -48,7 +48,7 @@
.test_demo_title,
.test_demo_ctx,
.editor_form{
margin: 0 30px;
margin: 0 20px;
.ant-form-explain{
margin-top: 5px;
@ -68,7 +68,7 @@
top: 43px;
left: -30px;
right: -30px;
padding: 0 30px;
padding: 0 20px;
// background: gold;
background: rgb(249,249,249);
z-index: 1000;
@ -77,5 +77,9 @@
.collapse_area{
margin-bottom: 20px;
.ant-form-item{
margin-bottom: 0px;
}
}
}

@ -17,7 +17,7 @@
}
.code-title,
.pane_control_opts{
padding: 0 30px;
padding: 0 20px;
}
.code-title{

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-04 08:36:21
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-10 18:55:02
* @LastEditTime: 2019-12-20 10:38:00
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
@ -79,7 +79,7 @@ function RecordDetail (props) {
</div>
<div className="detail_ctx_status">
<span className="status_label">
状态: <span className="status_label_error">{reviewResult[detail.status]}</span>
状态: <span className={detail.status === 0 ? 'status_label_success' : 'status_label_error'}>{reviewResult[detail.status]}</span>
</span>
<span className="status_label">
提交时间: <span className="status_label_sub">
@ -89,6 +89,7 @@ function RecordDetail (props) {
<span className="status_label">
语言: <span className="status_label_sub">C</span>
</span>
{/* <span className> */}
</div>
<div className="result_error_area">
<ErrorResult detail={detail}/>

@ -2,7 +2,7 @@
.record_detail_area{
.record_detail_ctx{
padding: 0 30px;
padding: 0 20px;
.detail_ctx_header{
position: relative;
height: 56px;

@ -88,7 +88,7 @@
.add_editor_list_area{
background: #fff;
padding: 0 30px;
padding: 0 20px;
margin: 0;
.add_editor_item{
display: inline-block;

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 09:49:33
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-05 10:38:49
* @LastEditTime: 2019-12-20 09:35:00
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
@ -79,6 +79,9 @@ const CommitRecord = (props) => {
const [pagination, setPagination] = useState(paginationConfig);
const [tableData, setTableData] = useState([]);
let clipboard;
// const [recordDetail, setRecordDetail] = useState({});
const [renderCtx, setRenderCtx] = useState(() => {
return function () {
@ -89,14 +92,14 @@ const CommitRecord = (props) => {
const renderRecordDetail = () => {
const {
id,
error_line,
error_msg,
execute_memory,
execute_time,
input,
output,
// error_line,
// error_msg,
// execute_memory,
// execute_time,
// input,
// output,
status,
expected_output
// expected_output
} = commitRecordDetail;
if (Object.keys(commitRecordDetail).length > 0) {
console.log('当前状态====》》》', status);
@ -146,9 +149,12 @@ const CommitRecord = (props) => {
setRenderCtx(() => (renderRecordDetail))
}, [commitRecordDetail]);
// 复制功能
useEffect(() => {
if (!clipboard) {
clipboard = new ClipboardJS('.copy_error');
}
if (commitRecordDetail.status !== 0) {
const clipboard = new ClipboardJS('.copy_error');
clipboard.on('success', (e) => {
message.success('复制成功');
e.clearSelection();

@ -1,6 +1,6 @@
.commit_record_area{
// padding: 20px 30px;
padding: 0 30px;
padding: 0 20px;
.record_header{
display: flex;
// justify-content: space-between;

@ -16,7 +16,7 @@
box-sizing: border-box;
border-top: 1px solid rgba(244,244,244,1);
// background: pink;
padding: 0 30px;
padding: 0 20px;
// background-color: rgba(250,250,250,1);
background: #fff;
@ -32,7 +32,7 @@
}
.commit_record_area{
padding: 0 30px;
padding: 0 20px;
// height: calc(100vh - 178px);
// overflow-y: auto;
}
@ -40,6 +40,7 @@
.task_desc_area{
height: calc(100vh - 242px);
overflow-y: auto;
padding: 0 0 0 15px;
}
.desc_area_header{
@ -47,7 +48,7 @@
justify-content: space-between;
align-items: center;
height: 64px;
padding: 0 30px;
padding: 0 20px;
.header_flex{
font-size: 14px;
.flex_label{

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 09:49:30
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-19 09:22:52
* @LastEditTime: 2019-12-20 09:39:35
*/
import '../index.scss';
import React from 'react';
@ -41,7 +41,7 @@ const TaskDescription = (props) => {
</p>
</div>
<div className="task_desc_area">
<QuillForEditor
<QuillForEditor
readOnly={true}
value={description}
/>

@ -1218,7 +1218,7 @@ submittojoinclass=(value)=>{
}
{
this.props.Headertop && this.props.Headertop.laboratory_user &&
<li><a href="/cooperative">后台管理</a></li>
<li><a href={this.props.Headertop.laboratory_admin_url}>后台管理</a></li>
}
<li><a href={`/account/profile`}>账号管理</a></li>

@ -461,7 +461,7 @@ class TPMDataset extends Component {
const uploadProps = {
width: 600,
fileList,
multiple: false,
multiple: true,
//multiple 是否支持多选 查重的时候不能多选 不然弹许多框出来
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。

@ -6,7 +6,7 @@
line-height: 44px;
// background-color: #EEEEEE;
background: #fff;
padding: 0 30px;
padding: 0 20px;
font-size: 16px;
// box-size: border-box;
box-sizing: border-box;

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 13:42:11
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-19 15:11:56
* @LastEditTime: 2019-12-20 10:25:42
*/
import types from "./actionTypes";
import { Base64 } from 'js-base64';
@ -171,6 +171,94 @@ export const updateCode = (identifier, inputValue, type) => {
}
}
// 代码评测
export const codeEvaluate = (dispatch, identifier, type, time_limit) => {
// 调试代码成功后,调用轮循接口, 注意: 代码执行的时间要小于设置的时间限制
const intervalTime = 500;
let count = 1;
/**
* @param {*} excuteTime 执行时间
* @param {*} finalTime 总时间
* @param {*} count 执行次数
* @param {*} timer 定时器
*/
function getCodeSubmit (intervalTime, finalTime, count, timer){
const excuteTime = (count++) * intervalTime; // 当前执行时间
fetchCodeSubmit(identifier, { mode: type }).then(res => {
const { status } = res.data; // 评测返回结果
// 清除定时器条件: 评测通过或者评测时间大于指定时间
if (+status === 0 || (excuteTime / 1000) > (finalTime + 1)) {
clearInterval(timer); // 清除定时器
timer = null;
let returnData = null;
if (status === 1) { // 结果没有返回
returnData = {
error_line: -1,
error_msg: '',
execute_memory: '',
execute_time: finalTime,
input: '',
output: '',
status: 2,
expected_output: ''
};
} else { // 成功返回结果
returnData = res.data.data;
}
// 返回评测结果
dispatch({
type: types.COMMIT_RECORD_DETAIL,
payload: returnData
});
if (!type || type === 'debug') {
dispatch({ // 改变 loading 值
type: types.LOADING_STATUS,
payload: false
});
// 保存执行状态
dispatch({
type: types.TEST_CODE_STATUS,
payload: 'finish'
});
} else {
// 回滚提交按钮状态
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
// 改变tab值至提交记录(只在提交时才跳转,测评时,切换到代码执行结果就可以了)
dispatch({
type: types.CHANGE_USER_CODE_TAB,
payload: 'record'
});
// 重新调用一下提交记录接口
dispatch(getUserCommitRecord(identifier));
}
}
}).catch(err => { // 评测异常时
// 清除定时器
clearInterval(timer);
timer = null;
// 回滚按钮状态
if (!type || type === 'debug') {
dispatch({ // 改变 loading 值
type: types.LOADING_STATUS,
payload: false
});
} else { // 回滚提交按钮状态
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
}
});
}
// 开启定时器,调用监听接口
let timer = setInterval(() => {
getCodeSubmit(intervalTime, time_limit, count++, timer);
}, intervalTime);
}
/**
* @description 调试代码
* @param {*} identifier
@ -194,15 +282,6 @@ export const debuggerCode = (identifier,value, type) => {
// console.log('调用调试代码成功并返回结果: ', res);
const { status } = res;
if (status === 200) {
// 调试代码成功后,调用轮循接口, 注意: 代码执行的时间要小于设置的时间限制
const intervalTime = 500;
let count = 1;
/**
* @param {*} excuteTime 执行时间
* @param {*} finalTime 总时间
* @param {*} count 执行次数
* @param {*} timer 定时器
*/
if (res.data.status === 401) {
dispatch({ // 改变 loading 值
type: types.LOADING_STATUS,
@ -210,81 +289,8 @@ export const debuggerCode = (identifier,value, type) => {
});
return;
};
function getCodeSubmit (intervalTime, finalTime, count, timer){
const excuteTime = (count++) * intervalTime; // 当前执行时间
fetchCodeSubmit(identifier, { mode: type }).then(res => {
const { status } = res.data; // 评测返回结果
// 清除定时器条件: 评测通过或者评测时间大于指定时间
if (+status === 0 || (excuteTime / 1000) > (finalTime + 1)) {
clearInterval(timer); // 清除定时器
timer = null;
let returnData = null;
if (status === 1) { // 结果没有返回
returnData = {
error_line: -1,
error_msg: '',
execute_memory: '',
execute_time: finalTime,
input: '',
output: '',
status: 2,
expected_output: ''
};
} else { // 成功返回结果
returnData = res.data.data;
}
// 返回评测结果
dispatch({
type: types.COMMIT_RECORD_DETAIL,
payload: returnData
});
if (!type || type === 'debug') {
dispatch({ // 改变 loading 值
type: types.LOADING_STATUS,
payload: false
});
// 保存执行状态
dispatch({
type: types.TEST_CODE_STATUS,
payload: 'finish'
});
} else {
// 回滚提交按钮状态
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
// 改变tab值至提交记录(只在提交时才跳转,测评时,切换到代码执行结果就可以了)
dispatch({
type: types.CHANGE_USER_CODE_TAB,
payload: 'record'
});
// 重新调用一下提交记录接口
dispatch(getUserCommitRecord(identifier));
}
}
}).catch(err => { // 评测异常时
// 清除定时器
clearInterval(timer);
timer = null;
// 回滚按钮状态
if (!type || type === 'debug') {
dispatch({ // 改变 loading 值
type: types.LOADING_STATUS,
payload: false
});
} else { // 回滚提交按钮状态
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
}
});
}
// 开启定时器,调用监听接口
let timer = setInterval(() => {
getCodeSubmit(intervalTime, time_limit, count++, timer);
}, intervalTime);
// 测评
codeEvaluate(dispatch, identifier, type, time_limit);
}
}).catch(() => {
dispatch({
@ -362,7 +368,8 @@ export const changeUserCodeTab = (key) => {
*/
export const submitUserCode = (identifier, inputValue, type) => {
return (dispatch, getState) => {
const { userCode, isUpdateCode } = getState().ojForUserReducer;
const { userCode, isUpdateCode, hack: {time_limit = 0} } = getState().ojForUserReducer;
function userCodeSubmit () {
fetchUserCodeSubmit(identifier).then(res => {
// console.log('用户提交代码成功======》》》》》', res);
@ -374,12 +381,8 @@ export const submitUserCode = (identifier, inputValue, type) => {
});
return;
};
// 将编辑代码清空
dispatch({
type: types.SAVE_EDITOR_CODE,
payload: ''
});
dispatch(debuggerCode(identifier, inputValue, type || 'submit'));
// 测评
codeEvaluate(dispatch, identifier, type, time_limit);
}
}).catch(() => {
dispatch({

@ -4,11 +4,10 @@
* @Github:
* @Date: 2019-11-20 10:55:38
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-17 14:10:37
* @LastEditTime: 2019-12-20 10:10:53
*/
import axios from 'axios';
import { func } from 'prop-types';
export async function fetchOJList (params) {
console.log('传递的参数: ', params);

Loading…
Cancel
Save