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 :name, maximum: 60, message: "不能超过60个字符"
validates_length_of :description, maximum: 5000, message: "不能超过5000个字符" validates_length_of :description, maximum: 5000, message: "不能超过5000个字符"
validates :description, presence: { message: "描述不能为空" } validates_presence_of :description, message: "描述不能为空"
validates :name, presence: { message: "名称不能为空" } validates_presence_of :name, message: "名称不能为空"
# 测试集 # 测试集
has_many :hack_sets, ->{order("position asc")}, :dependent => :destroy 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_length_of :output, maximum: 1000, message: "不能超过1000个字符"
#validates :input, presence: { message: "测试集输入不能为空" } #validates :input, presence: { message: "测试集输入不能为空" }
validates_presence_of :output, 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 belongs_to :hack
end end

@ -1,7 +1,7 @@
/* /*
* @Description: 评论表单 * @Description: 评论表单
* @Author: tangjiang * @Author: tangjiang
* @Github: * @Github:
* @Date: 2019-12-17 17:32:55 * @Date: 2019-12-17 17:32:55
* @LastEditors : tangjiang * @LastEditors : tangjiang
* @LastEditTime : 2020-01-06 18:42:09 * @LastEditTime : 2020-01-06 18:42:09
@ -18,7 +18,7 @@ function CommentForm (props) {
const { const {
onCancel, onCancel,
onSubmit, onSubmit,
form, form,
type type
} = props; } = props;
@ -47,7 +47,7 @@ function CommentForm (props) {
setShowQuill(false); setShowQuill(false);
setCtx(''); setCtx('');
props.form.resetFields(); props.form.resetFields();
onCancel && onCancel(); onCancel && onCancel();
} }
// 编辑器内容变化时 // 编辑器内容变化时
@ -98,7 +98,7 @@ function CommentForm (props) {
{ required: true, message: '评论内容不能为空'} { required: true, message: '评论内容不能为空'}
], ],
})( })(
<Input <Input
onClick={() => handleInputClick(type)} onClick={() => handleInputClick(type)}
placeholder="说点儿什么~" placeholder="说点儿什么~"
className={showQuill ? '' : 'show_input'} className={showQuill ? '' : 'show_input'}
@ -110,13 +110,13 @@ function CommentForm (props) {
/> />
) )
} }
<QuillForEditor <QuillForEditor
imgAttrs={{width: '60px', height: '30px'}} imgAttrs={{width: '60px', height: '30px'}}
wrapStyle={{ wrapStyle={{
height: showQuill ? 'auto' : '0px', height: showQuill ? 'auto' : '0px',
opacity: showQuill ? 1 : 0, opacity: showQuill ? 1 : 0,
overflow: showQuill ? 'none' : 'hidden', overflow: showQuill ? 'none' : 'none',
transition: 'all 0.3s' transition: 'all 0.3s'
}} }}
autoFocus={focus} autoFocus={focus}

@ -9,15 +9,13 @@
import './index.scss'; import './index.scss';
import React, { useState, useRef, useEffect } from 'react'; import React, { useState, useRef, useEffect } from 'react';
import { Drawer, Tooltip, Badge } from 'antd'; import { Drawer, Tooltip, Badge } from 'antd';
import { fromStore, CNotificationHOC } from 'educoder'; import { fromStore, CNotificationHOC } from 'educoder';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import MonacoEditor from '@monaco-editor/react'; import MonacoEditor from '@monaco-editor/react';
import SettingDrawer from '../../components/monacoSetting'; import SettingDrawer from '../../components/monacoSetting';
import CONST from '../../../../constants'; import CONST from '../../../../constants';
import MyIcon from '../../../../common/components/MyIcon'; import MyIcon from '../../../../common/components/MyIcon';
// import actions from '../../../../redux/actions';
const { fontSetting, opacitySetting } = CONST; const { fontSetting, opacitySetting } = CONST;
const maps = { const maps = {
'c': 'main.c', 'c': 'main.c',
@ -26,15 +24,15 @@ const maps = {
'python': 'main.py' 'python': 'main.py'
}; };
function MyMonacoEditor (props, ref) { function MyMonacoEditor(props, ref) {
const { const {
code, code,
notice, notice,
language, language,
identifier, identifier,
hadCodeUpdate, hadCodeUpdate,
showOrHideControl, showOrHideControl,
// saveUserInputCode, // saveUserInputCode,
onCodeChange, onCodeChange,
onRestoreInitialCode, onRestoreInitialCode,
@ -42,21 +40,16 @@ function MyMonacoEditor (props, ref) {
} = props; } = props;
const [showDrawer, setShowDrawer] = useState(false); // 控制配置滑框 const [showDrawer, setShowDrawer] = useState(false); // 控制配置滑框
// const [editCode, setEditCode] = useState('');
// const [curLang, setCurLang] = useState('C');
const [fontSize, setFontSize] = useState(() => { // 字体 const [fontSize, setFontSize] = useState(() => { // 字体
return +fromStore('oj_fontSize') || 14; return +fromStore('oj_fontSize') || 14;
}); });
const [theme, setTheme] = useState(() => { // 主题 theme const [theme, setTheme] = useState(() => { // 主题 theme
return fromStore('oj_theme') || 'dark'; return fromStore('oj_theme') || 'dark';
}); });
const [ height, setHeight ] = useState('calc(100% - 56px)'); const [height, setHeight] = useState('calc(100% - 56px)');
const editorRef = useRef(null); const editorRef = useRef(null);
console.log(language, code, '-------========----------')
// useEffect(() => {
// setEditCode(props.code || '');
// }, [props]);
useEffect(() => { useEffect(() => {
setHeight(showOrHideControl ? 'calc(100% - 378px)' : 'calc(100% - 56px)'); setHeight(showOrHideControl ? 'calc(100% - 378px)' : 'calc(100% - 56px)');
}, [showOrHideControl]); }, [showOrHideControl]);
@ -78,45 +71,38 @@ function MyMonacoEditor (props, ref) {
setTheme(value); setTheme(value);
} }
// 文本框内容变化时,记录文本框内容 // 文本框内容变化时,记录文本框内容
const handleEditorChange = (origin, monaco) => { const handleEditorChange = (_, monaco) => {
editorRef.current = monaco; // 获取当前monaco实例 editorRef.current = monaco; // 获取当前monaco实例
// setEditCode(origin); // 保存编辑器初始值
editorRef.current.onDidChangeModelContent(e => { // 监听编辑器内容的变化
// TODO 需要优化 节流
const val = editorRef.current.getValue();
// setEditCode(val);
// console.log('编辑器代码====>>>>', val);
onCodeChange(val);
// 值一变化保存当前代码值
// saveUserInputCode(val);
});
} }
useEffect(() => {
if (editorRef.current) {
editorRef.current.onDidChangeModelContent(e => { // 监听编辑器内容的变化
const val = editorRef.current.getValue();
onCodeChange(val);
});
}
}, [
editorRef.current
])
// 配置编辑器属性 // 配置编辑器属性
const editorOptions = { const editorOptions = {
selectOnLineNumbers: true, selectOnLineNumbers: true,
automaticLayout: true, automaticLayout: true,
fontSize: `${fontSize}px` fontSize: `${fontSize}px`
} }
// 恢复初始代码 // 恢复初始代码
const handleRestoreCode = () => { const handleRestoreCode = () => {
props.confirm({ props.confirm({
title: '提示', title: '提示',
content: '确定要恢复代码吗?', content: '确定要恢复代码吗?',
onOk () { onOk() {
onRestoreInitialCode && onRestoreInitialCode(); onRestoreInitialCode && onRestoreInitialCode();
} }
}) })
// Modal.confirm({
// content: '确定要恢复代码吗?',
// okText: '确定',
// cancelText: '取消',
// onOk () {
// onRestoreInitialCode && onRestoreInitialCode();
// }
// })
} }
const handleUpdateNotice = () => { const handleUpdateNotice = () => {
@ -124,49 +110,38 @@ function MyMonacoEditor (props, ref) {
onUpdateNotice && onUpdateNotice(); onUpdateNotice && onUpdateNotice();
} }
} }
// const renderRestore = identifier ? (
// <MyIcon type="iconzaicizairu" />
// ) : '';
// lex_has_save ${hadCodeUpdate} ? : ''
const _classnames = hadCodeUpdate ? `flex_strict flex_has_save` : 'flex_strict'; const _classnames = hadCodeUpdate ? `flex_strict flex_has_save` : 'flex_strict';
return ( return (
<React.Fragment> <React.Fragment>
<div className={"monaco_editor_area"}> <div className={"monaco_editor_area"}>
<div className="code_title"> <div className="code_title">
{/* 未保存时 ? '学员初始代码文件' : main.x */} {/* 未保存时 ? '学员初始代码文件' : main.x */}
<span className='flex_strict' style={{ color: '#ddd'}}>{identifier ? language ? maps[language.toLowerCase()] : '' : '学员初始代码文件'}</span> <span className='flex_strict' style={{ color: '#ddd' }}>{identifier ? language ? maps[language.toLowerCase()] : '' : '学员初始代码文件'}</span>
<span className={_classnames}>{hadCodeUpdate ? '已保存' : ''}</span> <span className={_classnames}>{hadCodeUpdate ? '已保存' : ''}</span>
{/* <Tooltip
style={{ background: 'gold' }}
className="tooltip_style"
title="通知"
placement="bottom"
> */}
<Tooltip <Tooltip
placement="bottom" placement="bottom"
title="通知" title="通知"
> >
<Badge <Badge
className="flex_normal" className="flex_normal"
style={{ color: '#666'}} style={{ color: '#666' }}
dot={notice} dot={notice}
onClick={handleUpdateNotice} onClick={handleUpdateNotice}
> >
{/* <Icon type="bell" /> */} {/* <Icon type="bell" /> */}
<MyIcon type="iconxiaoxi1" style={{fontSize: '18px'}}/> <MyIcon type="iconxiaoxi1" style={{ fontSize: '18px' }} />
</Badge> </Badge>
</Tooltip> </Tooltip>
<Tooltip <Tooltip
placement="bottom" placement="bottom"
title="恢复" title="恢复"
> >
<MyIcon <MyIcon
className="flex_normal" className="flex_normal"
onClick={handleRestoreCode} onClick={handleRestoreCode}
type="iconzaicizairu" type="iconzaicizairu"
style={{ display: identifier ? 'inline-block' : 'none', fontSize: '18px'}} style={{ display: identifier ? 'inline-block' : 'none', fontSize: '18px' }}
/> />
{/* <span onClick={handleRestoreCode} className="flex_normal" style={{ display: identifier ? 'inline-block' : 'none'}}>{renderRestore}</span> */} {/* <span onClick={handleRestoreCode} className="flex_normal" style={{ display: identifier ? 'inline-block' : 'none'}}>{renderRestore}</span> */}
</Tooltip> </Tooltip>
@ -174,18 +149,18 @@ function MyMonacoEditor (props, ref) {
placement="bottom" placement="bottom"
title="设置" title="设置"
> >
<MyIcon className='code-icon' type="iconshezhi" onClick={handleShowDrawer} style={{fontSize: '18px'}}/> <MyIcon className='code-icon' type="iconshezhi" onClick={handleShowDrawer} style={{ fontSize: '18px' }} />
</Tooltip> </Tooltip>
</div> </div>
<MonacoEditor <MonacoEditor
height={height} height={height}
width="100%" width="100%"
language={language && language.toLowerCase()} language={language && language.toLowerCase()}
value={code || ''} value={code || ''}
options={editorOptions} options={editorOptions}
theme={theme} // dark || light theme={theme} // dark || light
editorDidMount={handleEditorChange} editorDidMount={handleEditorChange}
/> />
</div> </div>
<Drawer <Drawer
@ -194,12 +169,12 @@ function MyMonacoEditor (props, ref) {
onClose={handleDrawerClose} onClose={handleDrawerClose}
visible={showDrawer} visible={showDrawer}
> >
<SettingDrawer <SettingDrawer
{...fontSetting} {...fontSetting}
onChangeFontSize={handleChangeFontSize} onChangeFontSize={handleChangeFontSize}
onChangeTheme={handleChangeTheme} onChangeTheme={handleChangeTheme}
/> />
<SettingDrawer {...opacitySetting}/> <SettingDrawer {...opacitySetting} />
</Drawer> </Drawer>
</React.Fragment> </React.Fragment>
) )
@ -212,12 +187,6 @@ const mapStateToProps = (state) => {
} }
}; };
// const mapDispatchToProps = (dispatch) => ({
// // saveUserInputCode: (code) => dispatch(actions.saveUserInputCode(code)),
// });
// MyMonacoEditor = React.forwardRef(MyMonacoEditor);
export default connect( export default connect(
mapStateToProps, mapStateToProps,
// mapDispatchToProps )(CNotificationHOC()(MyMonacoEditor));
)(CNotificationHOC() (MyMonacoEditor));

@ -8,23 +8,19 @@
import './index.scss'; import './index.scss';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { connect } from 'react-redux'; 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 { Button } from 'antd';
import LeftPane from './leftpane'; import LeftPane from './leftpane';
import RightPane from './rightpane'; import RightPane from './rightpane';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { toStore, CNotificationHOC } from 'educoder'; import { toStore, CNotificationHOC } from 'educoder';
import UserInfo from '../components/userInfo'; import UserInfo from '../components/userInfo';
// import RightPane from './rightpane/index';
import actions from '../../../redux/actions'; import actions from '../../../redux/actions';
// import {ModalConfirm} from '../../../common/components/ModalConfirm';
const NewOrEditTask = (props) => { const NewOrEditTask = (props) => {
const { const {
publishLoading, publishLoading,
handlePublish, handlePublish,
// testCases = [],
// ojTestCaseValidate = [],
identifier, identifier,
isPublish, isPublish,
userInfo, userInfo,
@ -38,15 +34,10 @@ const NewOrEditTask = (props) => {
getQuestion, getQuestion,
saveSearchParams, saveSearchParams,
setOjInitialValue, setOjInitialValue,
courseQuestions
// updateTestAndValidate,
} = props; } = props;
// 表单提交
const handleSubmitForm = () => { const handleSubmitForm = () => {
// 改变loading状态
changeSubmitLoadingStatus(true); changeSubmitLoadingStatus(true);
// 调用输入表单验证功能
if (props.identifier) { if (props.identifier) {
props.handleUpdateOjForm(props); props.handleUpdateOjForm(props);
} else { } else {
@ -54,12 +45,10 @@ const NewOrEditTask = (props) => {
} }
}; };
const id = props.match.params.id;
useEffect(() => { useEffect(() => {
// 获取用户信息 // 获取用户信息
getUserInfoForNew(); getUserInfoForNew();
// console.log('获取路由参数: ====', props.match.params);
const id = props.match.params.id;
// 保存OJForm的id号指明是编辑还是新增
props.saveOJFormId(id); props.saveOJFormId(id);
// 获取地址栏查询参数 // 获取地址栏查询参数
const $searchs = window.location.search && window.location.search.substring(1); const $searchs = window.location.search && window.location.search.substring(1);
@ -80,21 +69,16 @@ const NewOrEditTask = (props) => {
tag_discipline_id: tag_arrs tag_discipline_id: tag_arrs
}); });
} }
saveSearchParams({searchParams: $searchs, curPage: obj['pages']}); saveSearchParams({ searchParams: $searchs, curPage: obj['pages'] });
} }
// 获取课程列表 // 获取课程列表
getQuestion({ getQuestion({
source: 'question' source: 'question'
}); });
if (id) { // id号即 identifier if (id) { // id号即 identifier
// TODO id 存在时, 编辑, 获取 store 中的记录数
props.getOJFormById(id); props.getOJFormById(id);
} else {
// 清空store中的测试用例集合
// props.clearOJFormStore();
} }
return () => {} }, [id])
}, []);
// 模拟挑战 // 模拟挑战
const imitationChallenge = () => { const imitationChallenge = () => {
@ -107,11 +91,9 @@ const NewOrEditTask = (props) => {
// 开始挑战 // 开始挑战
const startChallenge = () => { const startChallenge = () => {
// 调用 start 接口, 成功后跳转到开启实战 // 调用 start 接口, 成功后跳转到开启实战
// TODO
identifier && validateOjForm(props, 'challenge', () => { identifier && validateOjForm(props, 'challenge', () => {
startProgramQuestion(identifier, props); startProgramQuestion(identifier, props);
}); });
// identifier && startProgramQuestion(identifier, props);
} }
// 取消 // 取消
@ -120,20 +102,15 @@ const NewOrEditTask = (props) => {
props.clearOJFormStore(); props.clearOJFormStore();
// 清空描述信息 // 清空描述信息
toStore('oj_description', ''); toStore('oj_description', '');
// props.history.push('/problems');
props.history.push(`/problemset?${props.searchParams}`); props.history.push(`/problemset?${props.searchParams}`);
} }
// 发布 // 发布
const handleClickPublish = () => { const handleClickPublish = () => {
// ModalConfirm('提示', (<p>发布后即可应用到自己管理的课堂<br /> 是否确认发布?</p>), () => {
// changePublishLoadingStatus(true);
// handlePublish(props, 'publish');
// });
props.confirm({ props.confirm({
title: '提示', title: '提示',
content: (<p>发布后即可应用到自己管理的课堂<br /> 是否确认发布?</p>), content: (<p>发布后即可应用到自己管理的课堂<br /> 是否确认发布?</p>),
onOk () { onOk() {
changePublishLoadingStatus(true); changePublishLoadingStatus(true);
handlePublish(props, 'publish'); handlePublish(props, 'publish');
} }
@ -141,14 +118,10 @@ const NewOrEditTask = (props) => {
} }
// 撤销发布 // 撤销发布
const handleClickCancelPublish = () => { const handleClickCancelPublish = () => {
// ModalConfirm('提示', (<p>是否确认撤销发布?</p>), () => {
// changePublishLoadingStatus(true);
// handleCancelPublish(props, identifier);
// });
props.confirm({ props.confirm({
title: '提示', title: '提示',
content: ((<p>是否确认撤销发布?</p>)), content: ((<p>是否确认撤销发布?</p>)),
onOk () { onOk() {
changePublishLoadingStatus(true); changePublishLoadingStatus(true);
handleCancelPublish(props, identifier); handleCancelPublish(props, identifier);
} }
@ -174,33 +147,33 @@ const NewOrEditTask = (props) => {
// 发布/模拟挑战 // 发布/模拟挑战
const renderPubOrFight = () => { const renderPubOrFight = () => {
const pubButton = isPublish const pubButton = isPublish
? (<Button ? (<Button
style={{ background: 'rgba(102,102,102,1)', border: 'none' }} style={{ background: 'rgba(102,102,102,1)', border: 'none' }}
type="primary" type="primary"
loading={publishLoading} loading={publishLoading}
onClick={handleClickCancelPublish} onClick={handleClickCancelPublish}
>撤销发布</Button>) >撤销发布</Button>)
: (<Button : (<Button
type="primary" type="primary"
loading={publishLoading} loading={publishLoading}
onClick={handleClickPublish} onClick={handleClickPublish}
>立即发布</Button>); >立即发布</Button>);
// 未发布: 模拟挑战 已发布: 开始挑战 // 未发布: 模拟挑战 已发布: 开始挑战
const challengeBtn = isPublish ? ( const challengeBtn = isPublish ? (
<Button type="primary" onClick={startChallenge}>开始挑战</Button> <Button type="primary" onClick={startChallenge}>开始挑战</Button>
) : ( ) : (
<Button type="primary" onClick={imitationChallenge}>模拟挑战</Button> <Button type="primary" onClick={imitationChallenge}>模拟挑战</Button>
); );
if (isPublish) { if (isPublish) {
return ( return (
<React.Fragment> <React.Fragment>
{pubButton} {pubButton}
<Button <Button
type="primary" type="primary"
loading={submitLoading} loading={submitLoading}
onClick={handleSubmitForm} onClick={handleSubmitForm}
>保存</Button> >保存</Button>
{challengeBtn} {challengeBtn}
</React.Fragment> </React.Fragment>
); );
@ -208,10 +181,10 @@ const NewOrEditTask = (props) => {
return ( return (
<React.Fragment> <React.Fragment>
<Button <Button
type="primary" type="primary"
loading={submitLoading} loading={submitLoading}
onClick={handleSubmitForm} onClick={handleSubmitForm}
>保存</Button> >保存</Button>
{pubButton} {pubButton}
{challengeBtn} {challengeBtn}
</React.Fragment> </React.Fragment>
@ -233,9 +206,9 @@ const NewOrEditTask = (props) => {
return ( return (
<div className={'new_add_task_wrap'}> <div className={'new_add_task_wrap'}>
<div className={'task_header'}> <div className={'task_header'}>
<UserInfo userInfo={userInfo}/> <UserInfo userInfo={userInfo} />
<p className={'header_title'}>{props.name || ''}</p> <p className={'header_title'}>{props.name || ''}</p>
{ renderQuit() } {renderQuit()}
</div> </div>
<div className="split-pane-area"> <div className="split-pane-area">
<SplitPane className='outer-split-pane' split="vertical" minSize={350} maxSize={-350} defaultSize="40%"> <SplitPane className='outer-split-pane' split="vertical" minSize={350} maxSize={-350} defaultSize="40%">
@ -243,18 +216,17 @@ const NewOrEditTask = (props) => {
<LeftPane /> <LeftPane />
</div> </div>
<SplitPane split="vertical" defaultSize="100%" allowResize={false}> <SplitPane split="vertical" defaultSize="100%" allowResize={false}>
<RightPane onSubmitForm={handleSubmitForm}/> <RightPane onSubmitForm={handleSubmitForm} />
<div /> <div />
</SplitPane> </SplitPane>
</SplitPane> </SplitPane>
</div> </div>
{/* 控制台 */}
<div className='new_add_task_ctl'> <div className='new_add_task_ctl'>
{ {
/* 录入时: 取消 保存 */ /* 录入时: 取消 保存 */
/* 保存未发布: 立即发布 模拟挑战 */ /* 保存未发布: 立即发布 模拟挑战 */
} }
{ !identifier ? renderSaveOrCancel() : renderPubOrFight() } {!identifier ? renderSaveOrCancel() : renderPubOrFight()}
</div> </div>
</div> </div>
) )
@ -313,4 +285,4 @@ const mapDispatchToProps = (dispatch) => ({
export default withRouter(connect( export default withRouter(connect(
mapStateToProps, mapStateToProps,
mapDispatchToProps mapDispatchToProps
)(CNotificationHOC() (NewOrEditTask))); )(CNotificationHOC()(NewOrEditTask)));

@ -20,27 +20,24 @@ import { toStore } from 'educoder'; // 保存和读取store值
import QuillForEditor from '../../../../../common/quillForEditor'; import QuillForEditor from '../../../../../common/quillForEditor';
import KnowLedge from '../../../components/knowledge'; import KnowLedge from '../../../components/knowledge';
const scrollIntoView = require('scroll-into-view'); const scrollIntoView = require('scroll-into-view');
const {jcLabel} = CONST; const { jcLabel } = CONST;
const FormItem = Form.Item; const FormItem = Form.Item;
const { Option } = Select; const { Option } = Select;
const maps = { const maps = {
language: [ language: [
{ title: (<span style={{ color: 'rgba(0, 0, 0, 0.35)' }}>请选择</span>), key: '' },
{ title: 'C', key: 'C' }, { title: 'C', key: 'C' },
{ title: 'C++', key: 'C++' }, { title: 'C++', key: 'C++' },
{ title: 'Python', key: 'Python' }, { title: 'Python', key: 'Python' },
{ title: 'Java', key: 'Java' } { title: 'Java', key: 'Java' }
], ],
difficult: [ difficult: [
{ title: (<span style={{ color: 'rgba(0, 0, 0, 0.35)' }}>请选择</span>), key: '' },
{ title: '简单', key: '1' }, { title: '简单', key: '1' },
{ title: '中等', key: '2'}, { title: '中等', key: '2' },
{ title: '困难', key: '3' } { title: '困难', key: '3' }
], ],
category: [ category: [
{ title: (<span style={{ color: 'rgba(0, 0, 0, 0.35)' }}>请选择</span>), key: '' },
{ title: '程序设计', key: '1' }, { title: '程序设计', key: '1' },
{ title: '算法', key: '2'} { title: '算法', key: '2' }
], ],
openOrNot: [ openOrNot: [
{ title: '公开', key: '1' }, { title: '公开', key: '1' },
@ -49,7 +46,7 @@ const maps = {
} }
class EditTab extends React.Component { class EditTab extends React.Component {
constructor (props) { constructor(props) {
super(props); super(props);
// this.editorRef = React.createRef(); // this.editorRef = React.createRef();
this.scrollRef = React.createRef(); this.scrollRef = React.createRef();
@ -61,13 +58,13 @@ class EditTab extends React.Component {
top: 500, top: 500,
bottom: 20, bottom: 20,
offsetTop: 0, offsetTop: 0,
showAdd: props.tag_discipline_id || false showAdd: props.tag_discipline_id || false
// knowledges: [], // knowledges: [],
// coursers: [] // 选中的课程 // coursers: [] // 选中的课程
} }
} }
componentDidMount () { componentDidMount() {
const oWrap = document.getElementById('textCase'); const oWrap = document.getElementById('textCase');
const scrollHeight = oWrap.offsetHeight; const scrollHeight = oWrap.offsetHeight;
@ -103,14 +100,14 @@ class EditTab extends React.Component {
} }
// this.scrollRef.current.scrollTo(1000); // this.scrollRef.current.scrollTo(1000);
this.props.addTestCase({testCase: obj, tcValidate: validateObj}); this.props.addTestCase({ testCase: obj, tcValidate: validateObj });
} }
// componentDidUpdate (nextProp) { // componentDidUpdate (nextProp) {
// console.log(nextProp); // console.log(nextProp);
// } // }
componentWillUnmount (nextPro) { componentWillUnmount(nextPro) {
this.state.scrollEl.removeEventListener('scroll', this.handleScroll, false); this.state.scrollEl.removeEventListener('scroll', this.handleScroll, false);
} }
@ -120,12 +117,12 @@ class EditTab extends React.Component {
const tOffsetTop = oTarget.offsetTop; const tOffsetTop = oTarget.offsetTop;
const tOffsetHeight = oTarget.offsetHeight; const tOffsetHeight = oTarget.offsetHeight;
const scrollTop = e.target.scrollTop; const scrollTop = e.target.scrollTop;
const { scrollHeight, offsetTop} = this.state; const { scrollHeight, offsetTop } = this.state;
// 滚动距离 + 元素的高度 大于 offsetTop值时 添加 fix_top 样式 // 滚动距离 + 元素的高度 大于 offsetTop值时 添加 fix_top 样式
// console.log(tOffsetTop, tOffsetHeight, scrollTop, scrollHeight, offsetTop); // console.log(tOffsetTop, tOffsetHeight, scrollTop, scrollHeight, offsetTop);
if ((scrollTop + tOffsetHeight > tOffsetTop) && (tOffsetTop >= offsetTop)) { if ((scrollTop + tOffsetHeight > tOffsetTop) && (tOffsetTop >= offsetTop)) {
oTarget.className = `test_demo_title fix_top`; oTarget.className = `test_demo_title fix_top`;
} else if ((scrollHeight + scrollTop < offsetTop) && (scrollHeight <= offsetTop)){ } else if ((scrollHeight + scrollTop < offsetTop) && (scrollHeight <= offsetTop)) {
oTarget.className = `test_demo_title`; oTarget.className = `test_demo_title`;
} else if ((tOffsetTop < offsetTop) && (tOffsetTop + tOffsetHeight + scrollTop) < offsetTop) { } else if ((tOffsetTop < offsetTop) && (tOffsetTop + tOffsetHeight + scrollTop) < offsetTop) {
oTarget.className = `test_demo_title`; oTarget.className = `test_demo_title`;
@ -188,7 +185,7 @@ class EditTab extends React.Component {
scrollIntoView(this.scrollRef.current); scrollIntoView(this.scrollRef.current);
} }
render () { render() {
const { showAdd } = this.state; const { showAdd } = this.state;
const { const {
@ -243,19 +240,19 @@ class EditTab extends React.Component {
const renderTestCase = () => { const renderTestCase = () => {
return this.props.testCases.map((item, i) => { return this.props.testCases.map((item, i) => {
return <AddTestDemo return <AddTestDemo
key={`${i}`} key={`${i}`}
isOpen={openTestCodeIndex.includes(i)} isOpen={openTestCodeIndex.includes(i)}
onSubmitTest={handleSubmitTest} onSubmitTest={handleSubmitTest}
onDeleteTest={handleDeleteTest} onDeleteTest={handleDeleteTest}
testCase={item} testCase={item}
testCaseValidate={testCasesValidate[i]} testCaseValidate={testCasesValidate[i]}
index={i} index={i}
/> />
}); });
}; };
// 添加测试用例 // 添加测试用例
const handleAddTest = () => { const handleAddTest = () => {
const {position, testCases = []} = this.props; const { position, testCases = [] } = this.props;
if (testCases.length >= 50) { if (testCases.length >= 50) {
notification.warning({ notification.warning({
message: '提示', message: '提示',
@ -281,7 +278,7 @@ class EditTab extends React.Component {
} }
// this.scrollRef.current.scrollTo(1000); // this.scrollRef.current.scrollTo(1000);
addTestCase({testCase: obj, tcValidate: validateObj}); addTestCase({ testCase: obj, tcValidate: validateObj });
// TODO 点击新增时,需要滚到到最底部 // TODO 点击新增时,需要滚到到最底部
this.scrollToBottom(); this.scrollToBottom();
} }
@ -300,12 +297,12 @@ class EditTab extends React.Component {
} }
// 编辑器配置信息 // 编辑器配置信息
const quillConfig = [ const quillConfig = [
{ header: 1}, {header: 2}, { header: 1 }, { header: 2 },
// {size: ['12px', '14px', '16px', '18px', '20px', false]}, // {size: ['12px', '14px', '16px', '18px', '20px', false]},
'bold', 'italic', 'underline', 'strike', // 切换按钮 'bold', 'italic', 'underline', 'strike', // 切换按钮
'blockquote', 'code-block', // 代码块 'blockquote', 'code-block', // 代码块
{align: []}, { 'list': 'ordered' }, { 'list': 'bullet' }, // 列表 { align: [] }, { 'list': 'ordered' }, { 'list': 'bullet' }, // 列表
{ 'script': 'sub'}, { 'script': 'super' }, { 'script': 'sub' }, { 'script': 'super' },
{ 'color': [] }, { 'background': [] }, // 字体颜色与背景色 { 'color': [] }, { 'background': [] }, // 字体颜色与背景色
// {font: []}, // {font: []},
'image', 'formula', // 数学公式、图片、视频 'image', 'formula', // 数学公式、图片、视频
@ -316,7 +313,7 @@ class EditTab extends React.Component {
const renderCourseQuestion = (arrs) => { const renderCourseQuestion = (arrs) => {
const tempArr = []; const tempArr = [];
const sub_id = this.props.ojForm.sub_discipline_id; const sub_id = this.props.ojForm.sub_discipline_id;
function loop (arrs, tempArr) { function loop(arrs, tempArr) {
arrs.forEach(item => { arrs.forEach(item => {
const obj = {}; const obj = {};
obj.value = item.id; obj.value = item.id;
@ -360,7 +357,7 @@ class EditTab extends React.Component {
} }
// 知识点 // 知识点
const handleKnowledgeChange = (values= []) => { const handleKnowledgeChange = (values = []) => {
const _result = []; const _result = [];
values.forEach(v => { values.forEach(v => {
_result.push(v.id); _result.push(v.id);
@ -374,8 +371,8 @@ class EditTab extends React.Component {
const handleAddKnowledge = (values) => { const handleAddKnowledge = (values) => {
// console.log('调用了新增知识点并返回了结果: ', values); // console.log('调用了新增知识点并返回了结果: ', values);
// 获取课程id // 获取课程id
const {sub_discipline_id} = this.props.ojForm; const { sub_discipline_id } = this.props.ojForm;
const obj = Object.assign({}, values, {sub_discipline_id}) const obj = Object.assign({}, values, { sub_discipline_id })
tagDisciplines(obj); tagDisciplines(obj);
} }
@ -387,7 +384,7 @@ class EditTab extends React.Component {
label={<span>{myLabel(jcLabel['difficult'])}</span>} label={<span>{myLabel(jcLabel['difficult'])}</span>}
validateStatus={ojFormValidate.difficult.validateStatus} validateStatus={ojFormValidate.difficult.validateStatus}
help={ojFormValidate.difficult.errMsg} help={ojFormValidate.difficult.errMsg}
colon={ false } colon={false}
> >
<Select onChange={this.handleChangeDifficult} value={`${ojForm.difficult}`}> <Select onChange={this.handleChangeDifficult} value={`${ojForm.difficult}`}>
{getOptions('difficult')} {getOptions('difficult')}
@ -399,7 +396,7 @@ class EditTab extends React.Component {
label={<span>{myLabel(jcLabel['sub_discipline_id'], '合理的课程分类有利于快速检索')}</span>} label={<span>{myLabel(jcLabel['sub_discipline_id'], '合理的课程分类有利于快速检索')}</span>}
validateStatus={ojFormValidate.sub_discipline_id.validateStatus} validateStatus={ojFormValidate.sub_discipline_id.validateStatus}
help={ojFormValidate.sub_discipline_id.errMsg} help={ojFormValidate.sub_discipline_id.errMsg}
colon={ false } colon={false}
> >
{/* <Select onChange={this.handleChangeCategory} value={`${ojForm.category}`}> {/* <Select onChange={this.handleChangeCategory} value={`${ojForm.category}`}>
{getOptions('category')} {getOptions('category')}
@ -409,11 +406,11 @@ class EditTab extends React.Component {
expandTrigger="hover" expandTrigger="hover"
onChange={this.handleChangeCategory} onChange={this.handleChangeCategory}
/> */} /> */}
{ renderCourseQuestion(courseQuestions)} {renderCourseQuestion(courseQuestions)}
</FormItem> </FormItem>
<FormItem <FormItem
colon={ false } colon={false}
className='input_area flex_100' className='input_area flex_100'
label={<span>{myLabel(jcLabel['knowledge'], '', 'nostar')}</span>} label={<span>{myLabel(jcLabel['knowledge'], '', 'nostar')}</span>}
> >
@ -431,9 +428,9 @@ class EditTab extends React.Component {
label={<span>{myLabel(jcLabel['timeLimit'], '程序允许时间限制时长,单位:秒')}</span>} label={<span>{myLabel(jcLabel['timeLimit'], '程序允许时间限制时长,单位:秒')}</span>}
validateStatus={ojFormValidate.timeLimit.validateStatus} validateStatus={ojFormValidate.timeLimit.validateStatus}
help={ojFormValidate.timeLimit.errMsg} help={ojFormValidate.timeLimit.errMsg}
colon={ false } colon={false}
> >
<InputNumber value={ojForm.timeLimit} min={0} max={5} style={{ width: '100%' }} onChange={this.handleTimeLimitChange}/> <InputNumber value={ojForm.timeLimit} min={0} max={5} style={{ width: '100%' }} onChange={this.handleTimeLimitChange} />
</FormItem> </FormItem>
<FormItem <FormItem
@ -441,9 +438,9 @@ class EditTab extends React.Component {
label={<span>{myLabel(jcLabel['language'])}</span>} label={<span>{myLabel(jcLabel['language'])}</span>}
validateStatus={ojFormValidate.language.validateStatus} validateStatus={ojFormValidate.language.validateStatus}
help={ojFormValidate.language.errMsg} help={ojFormValidate.language.errMsg}
colon={ false } colon={false}
> >
<Select onChange={this.handleLanguageChange} value={`${ojForm.language}`}> <Select onChange={this.handleLanguageChange} defaultValue={'C'} value={`${ojForm.language}`}>
{getOptions('language')} {getOptions('language')}
</Select> </Select>
</FormItem> </FormItem>
@ -453,7 +450,7 @@ class EditTab extends React.Component {
label={<span>{myLabel(jcLabel['name'])}</span>} label={<span>{myLabel(jcLabel['name'])}</span>}
validateStatus={ojFormValidate.name.validateStatus} validateStatus={ojFormValidate.name.validateStatus}
help={ojFormValidate.name.errMsg} help={ojFormValidate.name.errMsg}
colon={ false } colon={false}
> >
<Input <Input
maxLength={60} maxLength={60}
@ -469,30 +466,18 @@ class EditTab extends React.Component {
label={<span>{myLabel(jcLabel['description'])}</span>} label={<span>{myLabel(jcLabel['description'])}</span>}
validateStatus={ojFormValidate.description.validateStatus} validateStatus={ojFormValidate.description.validateStatus}
help={ojFormValidate.description.errMsg} help={ojFormValidate.description.errMsg}
colon={ false } colon={false}
> >
<QuillForEditor <QuillForEditor
autoFocus={true} autoFocus={true}
style={{ height: '200px' }} style={{ height: '200px' }}
placeholder="请输入描述信息" placeholder="请输入描述信息"
onContentChange={handleContentChange} onContentChange={handleContentChange}
options={quillConfig} options={quillConfig}
value={ojForm.description} value={ojForm.description}
/> />
</FormItem> </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> </Form>
{/* 添加测试用例 */} {/* 添加测试用例 */}
@ -501,10 +486,10 @@ class EditTab extends React.Component {
<Button type="primary" ghost onClick={handleAddTest}>添加测试用例</Button> <Button type="primary" ghost onClick={handleAddTest}>添加测试用例</Button>
</div> </div>
<div className="test_demo_ctx"> <div className="test_demo_ctx">
{ renderTestCase() } {renderTestCase()}
</div> </div>
<div style={ {float:"left", clear: "both", background: 'red' } } ref={this.scrollRef}></div> <div style={{ float: "left", clear: "both", background: 'red' }} ref={this.scrollRef}></div>
</div> </div>
) )
} }

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

@ -6,22 +6,19 @@
* @LastEditors : tangjiang * @LastEditors : tangjiang
* @LastEditTime : 2020-01-02 14:23:43 * @LastEditTime : 2020-01-02 14:23:43
*/ */
import React, { useState, useEffect } from 'react'; import React, { useState } from 'react';
import {connect} from 'react-redux'; import { connect } from 'react-redux';
import MyMonacoEditor from '../../components/myMonacoEditor'; import MyMonacoEditor from '../../components/myMonacoEditor';
import ControlSetting from '../../components/controlSetting'; import ControlSetting from '../../components/controlSetting';
import actions from '../../../../redux/actions'; import actions from '../../../../redux/actions';
// import QuillForEditor from '../../../../common/quillForEditor';
// import TextArea from 'antd/lib/input/TextArea';
import { Input, Form, Button } from 'antd'; import { Input, Form, Button } from 'antd';
// import FormItem from 'antd/lib/form/FormItem';
const { TextArea } = Input; const { TextArea } = Input;
const FormItem = Form.Item; const FormItem = Form.Item;
const RightPane = (props) => { const RightPane = (props) => {
const { const {
identifier, identifier,
submitInput, submitInput,
submitUserCode, submitUserCode,
input, input,
hack, hack,
@ -33,54 +30,34 @@ const RightPane = (props) => {
updateNotice, updateNotice,
saveUserInputCode, saveUserInputCode,
restoreInitialCode, restoreInitialCode,
// saveOpacityType,
saveUserCodeForInterval, saveUserCodeForInterval,
addNotes, addNotes,
changeLoadingState changeLoadingState
} = props; } = props;
// const [editorCode, setEditorCode] = useState(editor_code || hack.code);
const [noteClazz, setNoteClazz] = useState('editor_nodte_area'); const [noteClazz, setNoteClazz] = useState('editor_nodte_area');
const [noteCount] = useState(5000); 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 = () => { const handleSubmitForm = () => {
// 提交时, 先调用提交接口,提交成功后,循环调用测评接口
// saveOpacityType('submit');
submitUserCode(identifier, submitInput, 'submit'); submitUserCode(identifier, submitInput, 'submit');
// // 提交时,先调用评测接口, 评测通过后才调用保存接口
// updateCode(identifier, submitInput, 'submit');
} }
let timer = null; // 定时器 let timer = null; // 定时器
// 代码块内容变化时 // 代码块内容变化时
const handleCodeChange = (value) => { const handleCodeChange = (value) => {
// console.log('编辑器代码 ======》》》》》》》》》++++++++++', value);
saveUserInputCode(value); saveUserInputCode(value);
// setEditorCode(value);
if (!timer) { if (!timer) {
timer = setInterval(function () { timer = setInterval(function () {
clearInterval(timer); clearInterval(timer);
timer = null; timer = null;
saveUserCodeForInterval(identifier); saveUserCodeForInterval(identifier);
}, 3000); }, 10000);
} }
} }
// 代码调试 // 代码调试
const handleDebuggerCode = (value) => { const handleDebuggerCode = (value) => {
// 调用保存代码块接口,成功后,调用调试接口
// saveOpacityType('debug');
updateCode(identifier, value, 'debug'); updateCode(identifier, value, 'debug');
} }
// 恢复初始代码 // 恢复初始代码
@ -101,7 +78,7 @@ const RightPane = (props) => {
props.form.resetFields(); props.form.resetFields();
setNoteClazz('editor_nodte_area'); setNoteClazz('editor_nodte_area');
} }
const handleSubmitNote = () => { const handleSubmitNote = () => {
props.form.validateFields((err, values) => { props.form.validateFields((err, values) => {
if (!err) { if (!err) {
@ -113,7 +90,6 @@ const RightPane = (props) => {
} }
}); });
} }
const { getFieldDecorator } = props.form; const { getFieldDecorator } = props.form;
return ( return (
<div className={'right_pane_code_wrap'}> <div className={'right_pane_code_wrap'}>
@ -121,7 +97,7 @@ const RightPane = (props) => {
<MyMonacoEditor <MyMonacoEditor
notice={notice} notice={notice}
identifier={identifier} identifier={identifier}
language={hack.language} language={hack.language}
code={editor_code || hack.code} code={editor_code || hack.code}
hadCodeUpdate={hadCodeUpdate} hadCodeUpdate={hadCodeUpdate}
onCodeChange={handleCodeChange} onCodeChange={handleCodeChange}
@ -129,11 +105,11 @@ const RightPane = (props) => {
onRestoreInitialCode={handleRestoreInitialCode} onRestoreInitialCode={handleRestoreInitialCode}
/> />
<span <span
className="iconfont icon-biji student_notes" className="iconfont icon-biji student_notes"
onClick={handleClickNote} onClick={handleClickNote}
></span> ></span>
{/* <div className="student_notes"> {/* <div className="student_notes">
<TextArea rows={5} /> <TextArea rows={5} />
</div> */} </div> */}
@ -141,7 +117,7 @@ const RightPane = (props) => {
<Form> <Form>
<FormItem> <FormItem>
{ {
getFieldDecorator('notes',{ getFieldDecorator('notes', {
rules: [ rules: [
{ required: true, message: '笔记不能为空' }, { required: true, message: '笔记不能为空' },
{ max: noteCount, message: `笔记最大字数为${noteCount}` } { max: noteCount, message: `笔记最大字数为${noteCount}` }
@ -153,7 +129,7 @@ const RightPane = (props) => {
rows="5" rows="5"
/>) />)
} }
</FormItem> </FormItem>
<FormItem style={{ textAlign: 'right' }}> <FormItem style={{ textAlign: 'right' }}>
<Button loading={loading} style={{ marginRight: '10px' }} onClick={handleCancelNote}>取消</Button> <Button loading={loading} style={{ marginRight: '10px' }} onClick={handleCancelNote}>取消</Button>
@ -161,12 +137,12 @@ const RightPane = (props) => {
</FormItem> </FormItem>
</Form> </Form>
</div> </div>
<ControlSetting <ControlSetting
identifier={identifier} identifier={identifier}
inputValue={input} inputValue={input}
onDebuggerCode={handleDebuggerCode} onDebuggerCode={handleDebuggerCode}
onSubmitForm={handleSubmitForm}/> onSubmitForm={handleSubmitForm} />
</div> </div>
); );
} }
@ -174,10 +150,10 @@ const RightPane = (props) => {
const mapStateToProps = (state) => { const mapStateToProps = (state) => {
const { const {
user_program_identifier, user_program_identifier,
hack, hack,
userTestInput, userTestInput,
editor_code, editor_code,
notice, notice,
hadCodeUpdate hadCodeUpdate
} = state.ojForUserReducer; } = state.ojForUserReducer;
@ -192,7 +168,7 @@ const mapStateToProps = (state) => {
hadCodeUpdate, hadCodeUpdate,
editor_code, editor_code,
input: userTestInput, input: userTestInput,
submitInput: hack.input, submitInput: hack.input,
identifier: user_program_identifier identifier: user_program_identifier
}; };
} }

@ -25,11 +25,10 @@ import { notification } from "antd";
// 进入编程页面时,首先调用开启编程题接口 // 进入编程页面时,首先调用开启编程题接口
export const startProgramQuestion = (id, props) => { export const startProgramQuestion = (id, props) => {
return (dispatch, getState) => { return (dispatch, getState) => {
const {searchParams} = getState().ojFormReducer;
fetchStartProgram(id).then(res => { fetchStartProgram(id).then(res => {
const { status, data } = res; const { status, data } = res;
if (status === 200) { if (status === 200) {
const {identifier} = data; const { identifier } = data;
dispatch({ dispatch({
type: types.SAVE_USER_PROGRAM_ID, type: types.SAVE_USER_PROGRAM_ID,
payload: identifier payload: identifier
@ -41,13 +40,6 @@ export const startProgramQuestion = (id, props) => {
}); });
// 跳转至开启编程 // 跳转至开启编程
if (identifier) { 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({ props.history.push({
pathname: `/myproblems/${identifier}`, pathname: `/myproblems/${identifier}`,
}); });
@ -115,24 +107,18 @@ export const saveUserCodeForInterval = (identifier, code) => {
type: types.AUTO_UPDATE_CODE, type: types.AUTO_UPDATE_CODE,
payload: true payload: true
}); });
// console.log('+++', userCode);
fetchUpdateCode(identifier, { fetchUpdateCode(identifier, {
code: Base64.encode(userCode) code: Base64.encode(userCode)
}).then(res => { }).then(res => {
if (res.data.status === 401) { if (res.data.status === 401) {
return; return;
}; };
// dispatch({
// type: types.RESTORE_INITIAL_CODE,
// payload: userCode
// });
setTimeout(() => { setTimeout(() => {
dispatch({ dispatch({
type: types.AUTO_UPDATE_CODE, type: types.AUTO_UPDATE_CODE,
payload: false payload: false
}) })
}, 1000); }, 1000);
// console.log('代码保存成功', res);
}).catch(() => { }).catch(() => {
dispatch({ dispatch({
type: types.AUTO_UPDATE_CODE, type: types.AUTO_UPDATE_CODE,
@ -190,7 +176,7 @@ export const codeEvaluate = (dispatch, identifier, type, time_limit, hackStatus,
* @param {*} count 执行次数 * @param {*} count 执行次数
* @param {*} timer 定时器 * @param {*} timer 定时器
*/ */
function getCodeSubmit (intervalTime, finalTime, count, timer){ function getCodeSubmit(intervalTime, finalTime, count, timer) {
const excuteTime = (count++) * intervalTime; // 当前执行时间 const excuteTime = (count++) * intervalTime; // 当前执行时间
fetchCodeSubmit(identifier, { mode: type }).then(res => { fetchCodeSubmit(identifier, { mode: type }).then(res => {
const { status } = res.data; // 评测返回结果 const { status } = res.data; // 评测返回结果
@ -290,7 +276,7 @@ export const codeEvaluate = (dispatch, identifier, type, time_limit, hackStatus,
* @param {*} inputValue 输入值: 自定义 | 系统返回的 * @param {*} inputValue 输入值: 自定义 | 系统返回的
* @param {*} type 测评类型 debug | submit * @param {*} type 测评类型 debug | submit
*/ */
export const debuggerCode = (identifier,value, type) => { export const debuggerCode = (identifier, value, type) => {
return (dispatch, getState) => { return (dispatch, getState) => {
// 调用之前 先保存 code // 调用之前 先保存 code
// TODO // TODO
@ -337,19 +323,26 @@ export const debuggerCode = (identifier,value, type) => {
// 获取提交记录 // 获取提交记录
export const getUserCommitRecord = (identifier) => { export const getUserCommitRecord = (identifier) => {
return (dispatch, getState) => { return (dispatch, getState) => {
const { pages: { limit, page } } = getState().ojForUserReducer; try {
fetchUserCommitRecord(identifier, { const { pages: { limit, page } } = getState().ojForUserReducer;
limit, fetchUserCommitRecord(identifier, {
page limit,
}).then(res => { page
const {status, data} = res; }).then(res => {
if (status === 200) { if (res) {
dispatch({ const { status, data } = res;
type: types.COMMIT_RECORD, if (status === 200) {
payload: data dispatch({
}) type: types.COMMIT_RECORD,
} payload: data
}); })
}
}
})
} catch (error) {
console.log(error, '-------')
}
;
} }
} }
// 获取提交记录详情 // 获取提交记录详情
@ -401,11 +394,10 @@ export const changeUserCodeTab = (key) => {
*/ */
export const submitUserCode = (identifier, inputValue, type) => { export const submitUserCode = (identifier, inputValue, type) => {
return (dispatch, getState) => { return (dispatch, getState) => {
const { userCode, isUpdateCode, hack} = getState().ojForUserReducer; const { userCode, isUpdateCode, hack } = getState().ojForUserReducer;
function userCodeSubmit () { function userCodeSubmit() {
fetchUserCodeSubmit(identifier).then(res => { fetchUserCodeSubmit(identifier).then(res => {
// console.log('用户提交代码成功======》》》》》', res);
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 401) { if (res.data.status === 401) {
dispatch({ dispatch({
@ -415,7 +407,6 @@ export const submitUserCode = (identifier, inputValue, type) => {
return; return;
}; };
// 测评 // 测评
console.log('hack=====', hack);
codeEvaluate(dispatch, identifier, type, hack.time_limit, hack.status, hack.score, hack.passed); codeEvaluate(dispatch, identifier, type, hack.time_limit, hack.status, hack.score, hack.passed);
} }
}).catch(() => { }).catch(() => {
@ -427,10 +418,9 @@ export const submitUserCode = (identifier, inputValue, type) => {
} }
if (isUpdateCode) { if (isUpdateCode) {
fetchUpdateCode(identifier, { fetchUpdateCode(identifier, {
code: userCode code: Base64.encode(userCode)
}).then(res => { }).then(res => {
// 是否更新了代码, 目的是当代码没有更新时不调用更新代码接口,目录没有实现 // 是否更新了代码, 目的是当代码没有更新时不调用更新代码接口,目录没有实现
// TODO 需要优化
if (res.data.status === 401) { if (res.data.status === 401) {
dispatch({ dispatch({
type: types.SUBMIT_LOADING_STATUS, type: types.SUBMIT_LOADING_STATUS,
@ -460,8 +450,7 @@ export const restoreInitialCode = (identifier, msg) => {
return (dispatch) => { return (dispatch) => {
fetchRestoreInitialCode(identifier).then(res => { fetchRestoreInitialCode(identifier).then(res => {
if (res.data.status === 401) return; if (res.data.status === 401) return;
// console.log('恢复初始代码====》》》》', res); const { status, data } = res;
const {status, data} = res;
if (status === 200) { if (status === 200) {
dispatch({ dispatch({
type: types.RESTORE_INITIAL_CODE, type: types.RESTORE_INITIAL_CODE,
@ -515,7 +504,6 @@ export const changeRecordPagination = (page) => {
export const addNotes = (identifier, params, cb) => { export const addNotes = (identifier, params, cb) => {
return (dispatch) => { return (dispatch) => {
fetchAddNotes(identifier, params).then(res => { fetchAddNotes(identifier, params).then(res => {
// console.log('添加笔记成功===>>', res);
dispatch({ dispatch({
type: types.LOADING_STATUS, type: types.LOADING_STATUS,
payload: false payload: false

@ -12,9 +12,9 @@ import types from '../actions/actionTypes';
const init = { const init = {
ojForm: { ojForm: {
name: '', // 任务名称 name: '', // 任务名称
language: '', language: 'C',
description: '', description: '',
difficult: '', difficult: '1',
sub_discipline_id: '', // 方向 sub_discipline_id: '', // 方向
// category: '', // category: '',
// openOrNot: 1, // openOrNot: 1,
@ -114,7 +114,7 @@ const ojFormReducer = (state = initialState, action) => {
}; };
} }
switch (action.type) { switch (action.type) {
case types.VALIDATE_OJ_FORM: case types.VALIDATE_OJ_FORM:
// 验证成功后,调用后台接口 // 验证成功后,调用后台接口
return returnState(state, ojForm, ojFormValidate); return returnState(state, ojForm, ojFormValidate);
case types.SAVE_OJ_FORM_CODE: case types.SAVE_OJ_FORM_CODE:
@ -278,7 +278,7 @@ const ojFormReducer = (state = initialState, action) => {
// 更新验证消息 // 更新验证消息
const curIOjTestValidate = state.testCasesValidate.map((tc, i) => { const curIOjTestValidate = state.testCasesValidate.map((tc, i) => {
if (i === action.payload.index) { if (i === action.payload.index) {
return Object.assign({}, tc, {input}); return Object.assign({}, tc, { input });
} }
return tc; return tc;
}); });
@ -294,20 +294,20 @@ const ojFormReducer = (state = initialState, action) => {
testCases: [...curITestValues] testCases: [...curITestValues]
} }
case types.TEST_CASE_OUTPUT_CHANGE: case types.TEST_CASE_OUTPUT_CHANGE:
const { output } = action.payload; const { output } = action.payload;
// 更新验证消息 // 更新验证消息
const curOOjTestValidate = state.testCasesValidate.map((tc, i) => { const curOOjTestValidate = state.testCasesValidate.map((tc, i) => {
if (i === action.payload.index) { if (i === action.payload.index) {
return Object.assign({}, tc, {output}); return Object.assign({}, tc, { output });
} }
return tc; return tc;
}); });
let curOTestValues = state.testCases.map((tc, i) => { let curOTestValues = state.testCases.map((tc, i) => {
if (i === action.payload.index) { if (i === action.payload.index) {
return Object.assign({}, tc, { output: action.payload.value }) return Object.assign({}, tc, { output: action.payload.value })
} }
return tc; return tc;
}); });
return { return {
...state, ...state,
testCasesValidate: [...curOOjTestValidate], testCasesValidate: [...curOOjTestValidate],
@ -355,7 +355,7 @@ const ojFormReducer = (state = initialState, action) => {
console.log(_p.tag_discipline_id); console.log(_p.tag_discipline_id);
return { return {
...state, ...state,
ojForm: Object.assign({}, state.ojForm, {difficult: _p.difficult, sub_discipline_id: _p.sub_discipline_id}), ojForm: Object.assign({}, state.ojForm, { difficult: _p.difficult, sub_discipline_id: _p.sub_discipline_id }),
tag_discipline_id: _p.tag_discipline_id || [] tag_discipline_id: _p.tag_discipline_id || []
} }
case types.SET_SEARCH_PARAMS: case types.SET_SEARCH_PARAMS:

Loading…
Cancel
Save