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

video_transcode
caicai8 5 years ago
commit 8fa8059f96

@ -4,8 +4,8 @@ class Hack < ApplicationRecord
# 编程题
validates_length_of :name, maximum: 60, message: "不能超过60个字符"
validates_length_of :description, maximum: 5000, message: "不能超过5000个字符"
validates :description, presence: { message: "描述不能为空" }
validates :name, presence: { message: "名称不能为空" }
validates_presence_of :description, message: "描述不能为空"
validates_presence_of :name, message: "名称不能为空"
# 测试集
has_many :hack_sets, ->{order("position asc")}, :dependent => :destroy
# 代码

@ -3,7 +3,7 @@ class HackSet < ApplicationRecord
validates_length_of :output, maximum: 1000, message: "不能超过1000个字符"
#validates :input, presence: { message: "测试集输入不能为空" }
validates_presence_of :output, message: "不能为空"
validates_uniqueness_of :input, scope: [:hack_id, :input], message: "多个测试集的输入不能相同"
#validates_uniqueness_of :input, scope: [:hack_id, :input], message: "多个不能相同"
# 编程题测试集
belongs_to :hack
end

@ -116,7 +116,7 @@ function CommentForm (props) {
wrapStyle={{
height: showQuill ? 'auto' : '0px',
opacity: showQuill ? 1 : 0,
overflow: showQuill ? 'none' : 'hidden',
overflow: showQuill ? 'none' : 'none',
transition: 'all 0.3s'
}}
autoFocus={focus}

@ -16,8 +16,6 @@ import SettingDrawer from '../../components/monacoSetting';
import CONST from '../../../../constants';
import MyIcon from '../../../../common/components/MyIcon';
// import actions from '../../../../redux/actions';
const { fontSetting, opacitySetting } = CONST;
const maps = {
'c': 'main.c',
@ -42,8 +40,6 @@ function MyMonacoEditor (props, ref) {
} = props;
const [showDrawer, setShowDrawer] = useState(false); // 控制配置滑框
// const [editCode, setEditCode] = useState('');
// const [curLang, setCurLang] = useState('C');
const [fontSize, setFontSize] = useState(() => { // 字体
return +fromStore('oj_fontSize') || 14;
});
@ -52,10 +48,7 @@ function MyMonacoEditor (props, ref) {
});
const [height, setHeight] = useState('calc(100% - 56px)');
const editorRef = useRef(null);
// useEffect(() => {
// setEditCode(props.code || '');
// }, [props]);
console.log(language, code, '-------========----------')
useEffect(() => {
setHeight(showOrHideControl ? 'calc(100% - 378px)' : 'calc(100% - 56px)');
@ -79,19 +72,20 @@ function MyMonacoEditor (props, ref) {
}
// 文本框内容变化时,记录文本框内容
const handleEditorChange = (origin, monaco) => {
const handleEditorChange = (_, monaco) => {
editorRef.current = monaco; // 获取当前monaco实例
// setEditCode(origin); // 保存编辑器初始值
}
useEffect(() => {
if (editorRef.current) {
editorRef.current.onDidChangeModelContent(e => { // 监听编辑器内容的变化
// TODO 需要优化 节流
const val = editorRef.current.getValue();
// setEditCode(val);
// console.log('编辑器代码====>>>>', val);
onCodeChange(val);
// 值一变化保存当前代码值
// saveUserInputCode(val);
});
}
}, [
editorRef.current
])
// 配置编辑器属性
const editorOptions = {
@ -109,14 +103,6 @@ function MyMonacoEditor (props, ref) {
onRestoreInitialCode && onRestoreInitialCode();
}
})
// Modal.confirm({
// content: '确定要恢复代码吗?',
// okText: '确定',
// cancelText: '取消',
// onOk () {
// onRestoreInitialCode && onRestoreInitialCode();
// }
// })
}
const handleUpdateNotice = () => {
@ -125,11 +111,6 @@ function MyMonacoEditor (props, ref) {
}
}
// const renderRestore = identifier ? (
// <MyIcon type="iconzaicizairu" />
// ) : '';
// lex_has_save ${hadCodeUpdate} ? : ''
const _classnames = hadCodeUpdate ? `flex_strict flex_has_save` : 'flex_strict';
return (
<React.Fragment>
@ -138,12 +119,6 @@ function MyMonacoEditor (props, ref) {
{/* 未保存时 ? '学员初始代码文件' : main.x */}
<span className='flex_strict' style={{ color: '#ddd' }}>{identifier ? language ? maps[language.toLowerCase()] : '' : '学员初始代码文件'}</span>
<span className={_classnames}>{hadCodeUpdate ? '已保存' : ''}</span>
{/* <Tooltip
style={{ background: 'gold' }}
className="tooltip_style"
title="通知"
placement="bottom"
> */}
<Tooltip
placement="bottom"
title="通知"
@ -212,12 +187,6 @@ const mapStateToProps = (state) => {
}
};
// const mapDispatchToProps = (dispatch) => ({
// // saveUserInputCode: (code) => dispatch(actions.saveUserInputCode(code)),
// });
// MyMonacoEditor = React.forwardRef(MyMonacoEditor);
export default connect(
mapStateToProps,
// mapDispatchToProps
)(CNotificationHOC()(MyMonacoEditor));

@ -8,23 +8,19 @@
import './index.scss';
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import SplitPane from 'react-split-pane';// import { Form } from 'antd';
import SplitPane from 'react-split-pane';
import { Button } from 'antd';
import LeftPane from './leftpane';
import RightPane from './rightpane';
import { withRouter } from 'react-router';
import { toStore, CNotificationHOC } from 'educoder';
import UserInfo from '../components/userInfo';
// import RightPane from './rightpane/index';
import actions from '../../../redux/actions';
// import {ModalConfirm} from '../../../common/components/ModalConfirm';
const NewOrEditTask = (props) => {
const {
publishLoading,
handlePublish,
// testCases = [],
// ojTestCaseValidate = [],
identifier,
isPublish,
userInfo,
@ -38,15 +34,10 @@ const NewOrEditTask = (props) => {
getQuestion,
saveSearchParams,
setOjInitialValue,
courseQuestions
// updateTestAndValidate,
} = props;
// 表单提交
const handleSubmitForm = () => {
// 改变loading状态
changeSubmitLoadingStatus(true);
// 调用输入表单验证功能
if (props.identifier) {
props.handleUpdateOjForm(props);
} else {
@ -54,12 +45,10 @@ const NewOrEditTask = (props) => {
}
};
const id = props.match.params.id;
useEffect(() => {
// 获取用户信息
getUserInfoForNew();
// console.log('获取路由参数: ====', props.match.params);
const id = props.match.params.id;
// 保存OJForm的id号指明是编辑还是新增
props.saveOJFormId(id);
// 获取地址栏查询参数
const $searchs = window.location.search && window.location.search.substring(1);
@ -87,14 +76,9 @@ const NewOrEditTask = (props) => {
source: 'question'
});
if (id) { // id号即 identifier
// TODO id 存在时, 编辑, 获取 store 中的记录数
props.getOJFormById(id);
} else {
// 清空store中的测试用例集合
// props.clearOJFormStore();
}
return () => {}
}, []);
}, [id])
// 模拟挑战
const imitationChallenge = () => {
@ -107,11 +91,9 @@ const NewOrEditTask = (props) => {
// 开始挑战
const startChallenge = () => {
// 调用 start 接口, 成功后跳转到开启实战
// TODO
identifier && validateOjForm(props, 'challenge', () => {
startProgramQuestion(identifier, props);
});
// identifier && startProgramQuestion(identifier, props);
}
// 取消
@ -120,16 +102,11 @@ const NewOrEditTask = (props) => {
props.clearOJFormStore();
// 清空描述信息
toStore('oj_description', '');
// props.history.push('/problems');
props.history.push(`/problemset?${props.searchParams}`);
}
// 发布
const handleClickPublish = () => {
// ModalConfirm('提示', (<p>发布后即可应用到自己管理的课堂<br /> 是否确认发布?</p>), () => {
// changePublishLoadingStatus(true);
// handlePublish(props, 'publish');
// });
props.confirm({
title: '提示',
content: (<p>发布后即可应用到自己管理的课堂<br /> 是否确认发布?</p>),
@ -141,10 +118,6 @@ const NewOrEditTask = (props) => {
}
// 撤销发布
const handleClickCancelPublish = () => {
// ModalConfirm('提示', (<p>是否确认撤销发布?</p>), () => {
// changePublishLoadingStatus(true);
// handleCancelPublish(props, identifier);
// });
props.confirm({
title: '提示',
content: ((<p>是否确认撤销发布?</p>)),
@ -248,7 +221,6 @@ const NewOrEditTask = (props) => {
</SplitPane>
</SplitPane>
</div>
{/* 控制台 */}
<div className='new_add_task_ctl'>
{
/* 录入时: 取消 保存 */

@ -25,20 +25,17 @@ const FormItem = Form.Item;
const { Option } = Select;
const maps = {
language: [
{ title: (<span style={{ color: 'rgba(0, 0, 0, 0.35)' }}>请选择</span>), key: '' },
{ title: 'C', key: 'C' },
{ title: 'C++', key: 'C++' },
{ title: 'Python', key: 'Python' },
{ title: 'Java', key: 'Java' }
],
difficult: [
{ title: (<span style={{ color: 'rgba(0, 0, 0, 0.35)' }}>请选择</span>), key: '' },
{ title: '简单', key: '1' },
{ title: '中等', key: '2' },
{ title: '困难', key: '3' }
],
category: [
{ title: (<span style={{ color: 'rgba(0, 0, 0, 0.35)' }}>请选择</span>), key: '' },
{ title: '程序设计', key: '1' },
{ title: '算法', key: '2' }
],
@ -443,7 +440,7 @@ class EditTab extends React.Component {
help={ojFormValidate.language.errMsg}
colon={false}
>
<Select onChange={this.handleLanguageChange} value={`${ojForm.language}`}>
<Select onChange={this.handleLanguageChange} defaultValue={'C'} value={`${ojForm.language}`}>
{getOptions('language')}
</Select>
</FormItem>
@ -481,18 +478,6 @@ class EditTab extends React.Component {
/>
</FormItem>
{/* <FormItem
className={`input_area flex_50 flex_50_right`}
label={<span>{myLabel(jcLabel['openOrNot'], '社区:您的任务将向整个社会公开')}</span>}
validateStatus={ojFormValidate.openOrNot.validateStatus}
help={ojFormValidate.openOrNot.errMsg}
colon={ false }
>
<Select onChange={this.handleChangeOpenOrNot} value={`${ojForm.openOrNot}`}>
{getOptions('openOrNot')}
</Select>
</FormItem> */}
</Form>
{/* 添加测试用例 */}

@ -7,55 +7,25 @@
* @LastEditTime : 2019-12-27 19:33:50
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
import React from 'react';
import { connect } from 'react-redux';
import MyMonacoEditor from '../../components/myMonacoEditor';
// import ControlSetting from '../../components/controlSetting';
import actions from '../../../../redux/actions';
function RightPane (props, ref) {
function RightPane(props) {
const {
// identifier,
code,
showCode,
language,
// onSubmitForm,
saveOjFormCode
} = props;
const { code, language = 'C', saveOjFormCode } = props;
// let timer = null;
// 代码改变时,保存
const handleCodeChange = (updateCode) => {
// if (props.identifier) {
// // 保存用户输入的代码
// if (!timer) {
// timer = setInterval(() => {
// clearInterval(timer);
// timer = null;
// }, 3000);
// }
// }
saveOjFormCode(updateCode);
}
// 启动调试代码
// const handleDebuggerCode = (value) => {
// console.log('调用的代码调试====', value);
// }
return (
<div className={'right_pane_code_wrap'}>
<MyMonacoEditor
language={language}
code={showCode}
code={code}
onCodeChange={handleCodeChange} />
{/* <ControlSetting
// identifier={identifier}
inputValue={props.input}
onSubmitForm={onSubmitForm}
// onDebuggerCode={handleDebuggerCode}
/> */}
</div>
)
}

@ -6,15 +6,12 @@
* @LastEditors : tangjiang
* @LastEditTime : 2020-01-02 14:23:43
*/
import React, { useState, useEffect } from 'react';
import React, { useState } from 'react';
import { connect } from 'react-redux';
import MyMonacoEditor from '../../components/myMonacoEditor';
import ControlSetting from '../../components/controlSetting';
import actions from '../../../../redux/actions';
// import QuillForEditor from '../../../../common/quillForEditor';
// import TextArea from 'antd/lib/input/TextArea';
import { Input, Form, Button } from 'antd';
// import FormItem from 'antd/lib/form/FormItem';
const { TextArea } = Input;
const FormItem = Form.Item;
const RightPane = (props) => {
@ -33,54 +30,34 @@ const RightPane = (props) => {
updateNotice,
saveUserInputCode,
restoreInitialCode,
// saveOpacityType,
saveUserCodeForInterval,
addNotes,
changeLoadingState
} = props;
// const [editorCode, setEditorCode] = useState(editor_code || hack.code);
const [noteClazz, setNoteClazz] = useState('editor_nodte_area');
const [noteCount] = useState(5000);
// const [code, setCode] = useState(editor_code || hack.code);
// let initFlag = true;
// useEffect(() => {
// if (editor_code) {
// setEditorCode(editor_code);
// } else {
// setEditorCode(hack.code);
// }
// }, [hack, editor_code]);
const handleSubmitForm = () => {
// 提交时, 先调用提交接口,提交成功后,循环调用测评接口
// saveOpacityType('submit');
submitUserCode(identifier, submitInput, 'submit');
// // 提交时,先调用评测接口, 评测通过后才调用保存接口
// updateCode(identifier, submitInput, 'submit');
}
let timer = null; // 定时器
// 代码块内容变化时
const handleCodeChange = (value) => {
// console.log('编辑器代码 ======》》》》》》》》》++++++++++', value);
saveUserInputCode(value);
// setEditorCode(value);
if (!timer) {
timer = setInterval(function () {
clearInterval(timer);
timer = null;
saveUserCodeForInterval(identifier);
}, 3000);
}, 10000);
}
}
// 代码调试
const handleDebuggerCode = (value) => {
// 调用保存代码块接口,成功后,调用调试接口
// saveOpacityType('debug');
updateCode(identifier, value, 'debug');
}
// 恢复初始代码
@ -113,7 +90,6 @@ const RightPane = (props) => {
}
});
}
const { getFieldDecorator } = props.form;
return (
<div className={'right_pane_code_wrap'}>

@ -25,7 +25,6 @@ import { notification } from "antd";
// 进入编程页面时,首先调用开启编程题接口
export const startProgramQuestion = (id, props) => {
return (dispatch, getState) => {
const {searchParams} = getState().ojFormReducer;
fetchStartProgram(id).then(res => {
const { status, data } = res;
if (status === 200) {
@ -41,13 +40,6 @@ export const startProgramQuestion = (id, props) => {
});
// 跳转至开启编程
if (identifier) {
// let data = Object.assign({}, props);
// const path = {
// pathname: `/myproblems/${identifier}`,
// state: data
// }
// console.log(path);
// props.history.push(`/myproblems/${identifier}`);
props.history.push({
pathname: `/myproblems/${identifier}`,
});
@ -115,24 +107,18 @@ export const saveUserCodeForInterval = (identifier, code) => {
type: types.AUTO_UPDATE_CODE,
payload: true
});
// console.log('+++', userCode);
fetchUpdateCode(identifier, {
code: Base64.encode(userCode)
}).then(res => {
if (res.data.status === 401) {
return;
};
// dispatch({
// type: types.RESTORE_INITIAL_CODE,
// payload: userCode
// });
setTimeout(() => {
dispatch({
type: types.AUTO_UPDATE_CODE,
payload: false
})
}, 1000);
// console.log('代码保存成功', res);
}).catch(() => {
dispatch({
type: types.AUTO_UPDATE_CODE,
@ -337,11 +323,13 @@ export const debuggerCode = (identifier,value, type) => {
// 获取提交记录
export const getUserCommitRecord = (identifier) => {
return (dispatch, getState) => {
try {
const { pages: { limit, page } } = getState().ojForUserReducer;
fetchUserCommitRecord(identifier, {
limit,
page
}).then(res => {
if (res) {
const { status, data } = res;
if (status === 200) {
dispatch({
@ -349,7 +337,12 @@ export const getUserCommitRecord = (identifier) => {
payload: data
})
}
});
}
})
} catch (error) {
console.log(error, '-------')
}
;
}
}
// 获取提交记录详情
@ -405,7 +398,6 @@ export const submitUserCode = (identifier, inputValue, type) => {
function userCodeSubmit() {
fetchUserCodeSubmit(identifier).then(res => {
// console.log('用户提交代码成功======》》》》》', res);
if (res.status === 200) {
if (res.data.status === 401) {
dispatch({
@ -415,7 +407,6 @@ export const submitUserCode = (identifier, inputValue, type) => {
return;
};
// 测评
console.log('hack=====', hack);
codeEvaluate(dispatch, identifier, type, hack.time_limit, hack.status, hack.score, hack.passed);
}
}).catch(() => {
@ -427,10 +418,9 @@ export const submitUserCode = (identifier, inputValue, type) => {
}
if (isUpdateCode) {
fetchUpdateCode(identifier, {
code: userCode
code: Base64.encode(userCode)
}).then(res => {
// 是否更新了代码, 目的是当代码没有更新时不调用更新代码接口,目录没有实现
// TODO 需要优化
if (res.data.status === 401) {
dispatch({
type: types.SUBMIT_LOADING_STATUS,
@ -460,7 +450,6 @@ export const restoreInitialCode = (identifier, msg) => {
return (dispatch) => {
fetchRestoreInitialCode(identifier).then(res => {
if (res.data.status === 401) return;
// console.log('恢复初始代码====》》》》', res);
const { status, data } = res;
if (status === 200) {
dispatch({
@ -515,7 +504,6 @@ export const changeRecordPagination = (page) => {
export const addNotes = (identifier, params, cb) => {
return (dispatch) => {
fetchAddNotes(identifier, params).then(res => {
// console.log('添加笔记成功===>>', res);
dispatch({
type: types.LOADING_STATUS,
payload: false

@ -12,9 +12,9 @@ import types from '../actions/actionTypes';
const init = {
ojForm: {
name: '', // 任务名称
language: '',
language: 'C',
description: '',
difficult: '',
difficult: '1',
sub_discipline_id: '', // 方向
// category: '',
// openOrNot: 1,

Loading…
Cancel
Save