parent
b3f9dae41a
commit
12b725d215
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Description:
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-20 23:10:48
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-22 10:05:42
|
||||||
|
*/
|
||||||
|
const jcLabel = {
|
||||||
|
name: '任务名称',
|
||||||
|
language: '编程语言',
|
||||||
|
description: '描述',
|
||||||
|
difficult: '难易度',
|
||||||
|
category: '分类',
|
||||||
|
openOrNot: '公开程序',
|
||||||
|
timeLimit: '时间限制'
|
||||||
|
}
|
||||||
|
|
||||||
|
export default jcLabel;
|
@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* @Description: 添加测试用例
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-21 09:19:38
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-22 19:45:48
|
||||||
|
*/
|
||||||
|
import './index.scss';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { Collapse, Icon, Input, Form, Button, Modal } from 'antd';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
const { Panel } = Collapse;
|
||||||
|
const { TextArea } = Input;
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
const AddTestDemo = (props) => {
|
||||||
|
const {
|
||||||
|
form: { getFieldDecorator },
|
||||||
|
onSubmitTest,
|
||||||
|
onDeleteTest,
|
||||||
|
testCase,
|
||||||
|
key
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const [isEditor, setIsEditor] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
// console.log('测试用例属性: ====>>>>', props);
|
||||||
|
// 删除操作
|
||||||
|
const handleDeletePanel = (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log('点击的删除按钮')
|
||||||
|
Modal.confirm({
|
||||||
|
title: '删除',
|
||||||
|
content: '确定要删除当前测试用例吗?',
|
||||||
|
okText: '确定',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk() {
|
||||||
|
console.log('确定删除');
|
||||||
|
onDeleteTest(testCase);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 右侧删除图标
|
||||||
|
const genExtra = () => (
|
||||||
|
<Icon
|
||||||
|
type="close"
|
||||||
|
onClick={handleDeletePanel}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
// 取消操作
|
||||||
|
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 handleEditorOrSave = (e) => {
|
||||||
|
if (!isEditor) {
|
||||||
|
setIsEditor(true);
|
||||||
|
} else {
|
||||||
|
// TODO 调用修改测试用例接口
|
||||||
|
setIsEditor(false); // 保存后 设置 false
|
||||||
|
setLoading(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderSubmitBtn = () => {
|
||||||
|
const { identifier, testCase } = 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 isDisabled = (testCase) => {
|
||||||
|
return testCase.isAdd && !isEditor;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Collapse className={'collapse_area'}>
|
||||||
|
<Panel header={`测试用例${testCase.position}`} extra={genExtra()} key={key}>
|
||||||
|
<Form>
|
||||||
|
<FormItem
|
||||||
|
label='输入'
|
||||||
|
>
|
||||||
|
{
|
||||||
|
getFieldDecorator('input', {
|
||||||
|
rules: [
|
||||||
|
{ required: true, message: '输入值不能为空'}
|
||||||
|
],
|
||||||
|
initialValue: testCase && testCase.input
|
||||||
|
})(<TextArea rows={5} disabled={isDisabled(testCase)}/>)
|
||||||
|
}
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="输出">
|
||||||
|
{
|
||||||
|
getFieldDecorator('output', {
|
||||||
|
rules: [
|
||||||
|
{required: true, message: '输出值不能为空'}
|
||||||
|
],
|
||||||
|
initialValue: testCase && testCase.output
|
||||||
|
})(<Input disabled={isDisabled(testCase)}/>)
|
||||||
|
}
|
||||||
|
</FormItem>
|
||||||
|
{/* <FormItem style={{ textAlign: 'right' }}>
|
||||||
|
<Button style={{ marginRight: '20px' }} onClick={handleReset}>取消</Button>
|
||||||
|
<Button type="primary" onClick={handleSubmit}>保存</Button>
|
||||||
|
</FormItem> */}
|
||||||
|
{renderSubmitBtn()}
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
</Collapse>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
const ojFormReducer = state.ojFormReducer;
|
||||||
|
return {
|
||||||
|
identifier: ojFormReducer.identifier
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(Form.create()(AddTestDemo));
|
@ -1,41 +1,288 @@
|
|||||||
|
/*
|
||||||
|
* @Description:
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-20 10:35:40
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-22 19:10:53
|
||||||
|
*/
|
||||||
|
import './index.scss';
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { Form, Input, Button } from 'antd';
|
import { Form, Input, Select, InputNumber, Button } from 'antd';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import AddTestDemo from './AddTestDemo';
|
||||||
|
import actions from '../../../../../redux/actions';
|
||||||
|
import jcLabel from '../../../../../constants';
|
||||||
|
import MEditor from '../../../meditor/MEditor';
|
||||||
|
// import { getUrl } from 'educoder';
|
||||||
|
|
||||||
|
// const path = getUrl("/editormd/lib/")
|
||||||
|
// const mEditor = require('editor.md');
|
||||||
|
// console.log(mEditor);
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
const { Option } = Select;
|
||||||
|
const { TextArea } = Input;
|
||||||
|
const maps = {
|
||||||
|
language: [
|
||||||
|
{ title: 'C', key: 'C' },
|
||||||
|
{ title: 'C++', key: 'C++' },
|
||||||
|
{ title: 'Python', key: 'Python' },
|
||||||
|
{ title: 'Java', key: 'Java' }
|
||||||
|
],
|
||||||
|
difficult: [
|
||||||
|
{ title: '简单', key: '1' },
|
||||||
|
{ title: '中等', key: '2'},
|
||||||
|
{ title: '困难', key: '3' }
|
||||||
|
],
|
||||||
|
category: [
|
||||||
|
{ title: '程序设计', key: '1' },
|
||||||
|
{ title: '算法', key: '2'}
|
||||||
|
],
|
||||||
|
openOrNot: [
|
||||||
|
{ title: '公开', key: '1' },
|
||||||
|
{ title: '私有', key: '0' }
|
||||||
|
]
|
||||||
|
}
|
||||||
class EditTab extends PureComponent {
|
class EditTab extends PureComponent {
|
||||||
|
|
||||||
handleSubmit = (e) => {
|
constructor (props) {
|
||||||
e.preventDefault();
|
super(props);
|
||||||
this.props.form.validateFieldsAndScroll((err, value) => {
|
this.editorRef = React.createRef();
|
||||||
if (!err) {
|
}
|
||||||
console.log(value);
|
componentDidMount () {
|
||||||
}
|
// this.createEditorMd('editormd_section', '100%', 400, '', '', '', path);
|
||||||
})
|
}
|
||||||
|
// 改变任务名称
|
||||||
|
handleNameChange = (e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
const {
|
||||||
|
validateOJName,
|
||||||
|
// validateOjLanguage,
|
||||||
|
// validateOjDescription,
|
||||||
|
// validateOjDifficult,
|
||||||
|
// validateOjTimeLimit,
|
||||||
|
// validateOjCategory,
|
||||||
|
// validateOpenOrNot
|
||||||
|
} = this.props;
|
||||||
|
validateOJName(value);
|
||||||
|
}
|
||||||
|
// 改变语言
|
||||||
|
handleLanguageChange = (value) => {
|
||||||
|
this.props.validateOjLanguage(value);
|
||||||
|
}
|
||||||
|
// 改变描述信息
|
||||||
|
handleChangeDescription = (e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
this.props.validateOjDescription(value);
|
||||||
|
}
|
||||||
|
// 改变难易度
|
||||||
|
handleChangeDifficult = (value) => {
|
||||||
|
this.props.validateOjDifficult(value);
|
||||||
|
}
|
||||||
|
// 改变时间限制
|
||||||
|
handleTimeLimitChange = (value) => {
|
||||||
|
this.props.validateOjTimeLimit(value);
|
||||||
|
}
|
||||||
|
// 改变分类
|
||||||
|
handleChangeCategory = (value) => {
|
||||||
|
this.props.validateOjCategory(value);
|
||||||
|
}
|
||||||
|
// 改变公开程序
|
||||||
|
handleChangeOpenOrNot = (value) => {
|
||||||
|
this.props.validateOpenOrNot(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { form } = this.props;
|
const {
|
||||||
const { getFieldDecorator } = form;
|
ojFormReducer: {ojForm, ojFormValidate},
|
||||||
|
testCases = [], // 测试用例集合
|
||||||
|
position, // 添加的测试用例位置
|
||||||
|
addTestCase, // 添加测试用例
|
||||||
|
deleteTestCase, // 删除测试用例
|
||||||
|
} = this.props;
|
||||||
|
console.log('当前位置: ', position);
|
||||||
|
// 表单label
|
||||||
|
const myLabel = (name, subTitle) => {
|
||||||
|
if (subTitle) {
|
||||||
|
return (
|
||||||
|
<span className={'label_text'}>
|
||||||
|
{name}
|
||||||
|
<span className={'label_sub_text'}>
|
||||||
|
({subTitle})
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<span className={'label_text'}>{name}</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 编程语言
|
||||||
|
const getOptions = (key) => {
|
||||||
|
return maps[key].map((opt, i) => {
|
||||||
|
return (
|
||||||
|
<Option value={opt.key} key={`opt_${i}`}>{opt.title}</Option>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 提交测试用例
|
||||||
|
const handleSubmitTest = (obj) => {
|
||||||
|
console.log('提交的测试用例: ', obj);
|
||||||
|
};
|
||||||
|
// 删除测试用例
|
||||||
|
const handleDeleteTest = (obj) => {
|
||||||
|
console.log('删除的测试用例: ', obj);
|
||||||
|
deleteTestCase(obj);
|
||||||
|
};
|
||||||
|
const renderTestCase = () => {
|
||||||
|
return testCases.map((item, i) => (
|
||||||
|
<AddTestDemo
|
||||||
|
key={`key_${i}`}
|
||||||
|
onSubmitTest={handleSubmitTest}
|
||||||
|
onDeleteTest={handleDeleteTest}
|
||||||
|
testCase={item}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
};
|
||||||
|
// 添加测试用例
|
||||||
|
const handleAddTest = () => {
|
||||||
|
console.log('添加测试用例');
|
||||||
|
const obj = {
|
||||||
|
input: '',
|
||||||
|
output: '',
|
||||||
|
position: position,
|
||||||
|
isAdd: true // 新增的测试用例
|
||||||
|
}
|
||||||
|
addTestCase(obj);
|
||||||
|
// TODO 点击新增时,需要滚到到最底部
|
||||||
|
// this.editorRef.current.scrollTop
|
||||||
|
// const oDiv = this.editorRef.current;
|
||||||
|
// oDiv.scrollTo(oDiv.scrollLeft, 99999);
|
||||||
|
// console.log(oDiv.scrollTop);
|
||||||
|
// oDiv.scrollTop = 99999;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className={'editor_area'}>
|
<div className={'editor_area'} ref={this.editorRef}>
|
||||||
<Form onSubmit={this.handleSubmit}>
|
<Form className={'editor_form'}>
|
||||||
<FormItem label="任务名称">
|
<FormItem
|
||||||
{ getFieldDecorator('name', {
|
className={`input_area flex_60`}
|
||||||
rules: [
|
label={<span>{myLabel(jcLabel['name'])}</span>}
|
||||||
{
|
validateStatus={ojFormValidate.name.validateStatus}
|
||||||
required: true, message: '任务名称不能为空'
|
help={ojFormValidate.name.errMsg}
|
||||||
}
|
colon={ false }
|
||||||
]
|
>
|
||||||
})(<Input placeholder="请输入任务名称" />)}
|
<Input
|
||||||
|
maxLength={60}
|
||||||
|
placeholder="请输入任务名称"
|
||||||
|
value={ojForm.name}
|
||||||
|
suffix={<span style={{ fontSize: '12px', color: 'rgba(0, 0, 0, 0.45)' }}>{60 - ojForm.name.length}</span>}
|
||||||
|
onChange={this.handleNameChange}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
className={`input_area flex_40`}
|
||||||
|
label={<span>{myLabel(jcLabel['language'])}</span>}
|
||||||
|
validateStatus={ojFormValidate.language.validateStatus}
|
||||||
|
help={ojFormValidate.language.errMsg}
|
||||||
|
colon={ false }
|
||||||
|
>
|
||||||
|
<Select onChange={this.handleLanguageChange} defaultValue={`${ojForm.language}`}>
|
||||||
|
{getOptions('language')}
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
className={`input_area flex_100`}
|
||||||
|
label={<span>{myLabel(jcLabel['description'])}</span>}
|
||||||
|
validateStatus={ojFormValidate.description.validateStatus}
|
||||||
|
help={ojFormValidate.description.errMsg}
|
||||||
|
colon={ false }
|
||||||
|
>
|
||||||
|
<TextArea rows={5} onChange={this.handleChangeDescription}/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
className={`input_area flex_50 flex_50_left`}
|
||||||
|
label={<span>{myLabel(jcLabel['difficult'], '任务的难易程度')}</span>}
|
||||||
|
validateStatus={ojFormValidate.difficult.validateStatus}
|
||||||
|
help={ojFormValidate.difficult.errMsg}
|
||||||
|
colon={ false }
|
||||||
|
>
|
||||||
|
<Select onChange={this.handleChangeDifficult} defaultValue={`${ojForm.difficult}`}>
|
||||||
|
{getOptions('difficult')}
|
||||||
|
</Select>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem>
|
<FormItem
|
||||||
<Button htmlType="submit">提交</Button>
|
className={`input_area flex_50 flex_50_right`}
|
||||||
|
label={<span>{myLabel(jcLabel['timeLimit'], '程序允许时间限制时长,单位:秒')}</span>}
|
||||||
|
validateStatus={ojFormValidate.timeLimit.validateStatus}
|
||||||
|
help={ojFormValidate.timeLimit.errMsg}
|
||||||
|
colon={ false }
|
||||||
|
>
|
||||||
|
<InputNumber min={0} style={{ width: '100%' }} onChange={this.handleTimeLimitChange}/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
className={`input_area flex_50 flex_50_left`}
|
||||||
|
label={<span>{myLabel(jcLabel['category'], '任务所属分类')}</span>}
|
||||||
|
validateStatus={ojFormValidate.category.validateStatus}
|
||||||
|
help={ojFormValidate.category.errMsg}
|
||||||
|
colon={ false }
|
||||||
|
>
|
||||||
|
<Select onChange={this.handleChangeCategory} defaultValue={`${ojForm.category}`}>
|
||||||
|
{getOptions('category')}
|
||||||
|
</Select>
|
||||||
|
</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} defaultValue={`${ojForm.openOrNot}`}>
|
||||||
|
{getOptions('openOrNot')}
|
||||||
|
</Select>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
|
{/* 添加测试用例 */}
|
||||||
|
<div className="test_demo_title">
|
||||||
|
<h2>测试用例</h2>
|
||||||
|
<Button type="primary" onClick={handleAddTest}>添加测试用例</Button>
|
||||||
|
</div>
|
||||||
|
<div className="test_demo_ctx">
|
||||||
|
{ renderTestCase() }
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const EditTabForm = Form.create()(EditTab);
|
const mapStateToProps = (state) => {
|
||||||
export default EditTabForm;
|
const ojFormReducer = state.ojFormReducer;
|
||||||
|
return {
|
||||||
|
ojFormReducer,
|
||||||
|
testCases: ojFormReducer.testCases, // 测试用例
|
||||||
|
position: ojFormReducer.position, // 测试用例位置
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
// 任务名称校验
|
||||||
|
validateOJName: (value) => dispatch(actions.validateOJName(value)),
|
||||||
|
validateOjLanguage: (value) => dispatch(actions.validateOjLanguage(value)),
|
||||||
|
validateOjDescription: (value) => dispatch(actions.validateOjDescription(value)),
|
||||||
|
validateOjDifficult: (value) => dispatch(actions.validateOjDifficult(value)),
|
||||||
|
validateOjTimeLimit: (value) => dispatch(actions.validateOjTimeLimit(value)),
|
||||||
|
validateOjCategory: (value) => dispatch(actions.validateOjCategory(value)),
|
||||||
|
validateOpenOrNot: (value) => dispatch(actions.validateOpenOrNot(value)),
|
||||||
|
// 新增测试用例
|
||||||
|
addTestCase: (value) => dispatch(actions.addTestCase(value)),
|
||||||
|
// 删除测试用例
|
||||||
|
deleteTestCase: (value) => dispatch(actions.deleteTestCase(value)),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(EditTab);
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
.editor_area{
|
||||||
|
height: calc(100vh - 110px);
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 20px 0;
|
||||||
|
.editor_form{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.label_text{
|
||||||
|
position: relative;
|
||||||
|
font-size: 14px;
|
||||||
|
&::before{
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 4px;
|
||||||
|
color: #f5222d;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: SimSun,sans-serif;
|
||||||
|
line-height: 1;
|
||||||
|
content: '*';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.input_area{
|
||||||
|
display: inline-block;
|
||||||
|
&.flex_60{
|
||||||
|
padding-right: 20px;
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
&.flex_40{
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
&.flex_100{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
&.flex_50{
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
&.flex_50_left{
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
&.flex_50_right{
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.label_sub_text{
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
.test_demo_title,
|
||||||
|
.test_demo_ctx,
|
||||||
|
.editor_form{
|
||||||
|
margin: 0 30px;
|
||||||
|
}
|
||||||
|
.test_demo_title{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 60px;
|
||||||
|
border-bottom: 1px solid #d9d9d9;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse_area{
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,118 @@
|
|||||||
|
|
||||||
|
.new_add_task_wrap,
|
||||||
|
.student_study_warp{
|
||||||
|
height: 100vh;
|
||||||
|
.task_header,
|
||||||
|
.student_study_header{
|
||||||
|
height: 65px;
|
||||||
|
background:rgba(34,34,34,1);
|
||||||
|
padding:0 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task_header{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
// justify-content: space-between;
|
||||||
|
.header_btn,
|
||||||
|
.header_title{
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.header_btn{
|
||||||
|
width: 88px;
|
||||||
|
}
|
||||||
|
.header_title{
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane-area{
|
||||||
|
position: relative;
|
||||||
|
height: calc(100% - 65px);
|
||||||
|
.left_pane,
|
||||||
|
.right_pane{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.student_study_header{
|
||||||
|
position: relative;
|
||||||
|
.avator_nicker,
|
||||||
|
.study_quit,
|
||||||
|
.study_name{
|
||||||
|
color: #fff;
|
||||||
|
line-height: 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avator_nicker,
|
||||||
|
.study_quit{
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student_nicker{
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.study_quit{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.study_name{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
top: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer {
|
||||||
|
background: #000;
|
||||||
|
opacity: 0.2;
|
||||||
|
z-index: 1;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-moz-background-clip: padding;
|
||||||
|
-webkit-background-clip: padding;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer:hover {
|
||||||
|
-webkit-transition: all 2s ease;
|
||||||
|
transition: all 2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer.horizontal {
|
||||||
|
height: 11px;
|
||||||
|
margin: -5px 0;
|
||||||
|
border-top: 5px solid rgba(255, 255, 255, 0);
|
||||||
|
border-bottom: 5px solid rgba(255, 255, 255, 0);
|
||||||
|
cursor: row-resize;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer.horizontal:hover {
|
||||||
|
border-top: 5px solid rgba(0, 0, 0, 0.5);
|
||||||
|
border-bottom: 5px solid rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer.vertical {
|
||||||
|
width: 11px;
|
||||||
|
margin: 0 -5px;
|
||||||
|
border-left: 5px solid rgba(255, 255, 255, 0);
|
||||||
|
border-right: 5px solid rgba(255, 255, 255, 0);
|
||||||
|
cursor: col-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer.vertical:hover {
|
||||||
|
border-left: 5px solid rgba(0, 0, 0, 0.5);
|
||||||
|
border-right: 5px solid rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
.Resizer.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.Resizer.disabled:hover {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* @Description: 学员学习
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-23 10:53:19
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-23 11:48:10
|
||||||
|
*/
|
||||||
|
import './index.scss';
|
||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import SplitPane from 'react-split-pane';
|
||||||
|
import LeftPane from './leftpane';
|
||||||
|
import RightPane from './rightpane';
|
||||||
|
import { Button, Avatar } from 'antd';
|
||||||
|
|
||||||
|
const StudentStudy = (props) => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={'student_study_warp'}>
|
||||||
|
<div className={'student_study_header'}>
|
||||||
|
<div className={'avator_nicker'}>
|
||||||
|
<Avatar icon="user" />
|
||||||
|
<span className={'student_nicker'}>
|
||||||
|
我是昵称
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className={'study_name'}>
|
||||||
|
<span>乘积最大序列</span>
|
||||||
|
</div>
|
||||||
|
<div className={'study_quit'}>
|
||||||
|
<Button>退出</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="split-pane-area">
|
||||||
|
<SplitPane split="vertical" minSize={200} maxSize={-200} defaultSize="50%">
|
||||||
|
<div className={'split-pane-left'}>
|
||||||
|
<LeftPane />
|
||||||
|
</div>
|
||||||
|
<SplitPane split="vertical" defaultSize="100%" allowResize={false}>
|
||||||
|
<RightPane />
|
||||||
|
<div />
|
||||||
|
</SplitPane>
|
||||||
|
</SplitPane>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(StudentStudy);
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
@import '../split_pane_resizer.scss';
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* @Description:
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-23 11:33:41
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-23 11:34:18
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const LeftPane = (props) => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<h2>左侧内容</h2>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LeftPane;
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* @Description:
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-23 11:34:32
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-23 11:34:48
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const RightPane = (props) => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<h2>右侧内容</h2>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RightPane;
|
@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* @Description: 开发者社区编辑模块
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-20 16:35:46
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-22 20:07:04
|
||||||
|
*/
|
||||||
|
import types from './actionTypes';
|
||||||
|
import jcLabel from '../../constants';
|
||||||
|
import { fetchPostOjForm, fetchGetOjById } from '../../services/ojService';
|
||||||
|
|
||||||
|
// 表单字段映射
|
||||||
|
const maps = {
|
||||||
|
name: {
|
||||||
|
label: jcLabel['name'],
|
||||||
|
type: types.VALIDATE_OJ_NAME
|
||||||
|
},
|
||||||
|
language: {
|
||||||
|
label: jcLabel['language'],
|
||||||
|
type: types.VALIDATE_OJ_LANGUAGE
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
label: jcLabel['description'],
|
||||||
|
type: types.VALIDATE_OJ_DESCRIPTION
|
||||||
|
},
|
||||||
|
difficult: {
|
||||||
|
label: jcLabel['difficult'],
|
||||||
|
type: types.VALIDATE_OJ_DIFFICULT
|
||||||
|
},
|
||||||
|
timeLimit: {
|
||||||
|
label: jcLabel['timeLimit'],
|
||||||
|
type: types.VALIDATE_OJ_TIMELIMIT
|
||||||
|
},
|
||||||
|
category: {
|
||||||
|
label: jcLabel['category'],
|
||||||
|
type: types.VALIDATE_OJ_CATEGORY
|
||||||
|
},
|
||||||
|
openOrNot: {
|
||||||
|
label: jcLabel['openOrNot'],
|
||||||
|
type: types.VALIDATE_OJ_OPENORNOT
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 非空校验
|
||||||
|
const emptyValidate = (key, value) => {
|
||||||
|
if ([undefined, '', null].includes(value)) {
|
||||||
|
return {
|
||||||
|
[key]: {
|
||||||
|
validateStatus: 'error',
|
||||||
|
errMsg: `${maps[key].label}不能为空`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
[key]: {
|
||||||
|
validateStatus: '',
|
||||||
|
errMsg: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组装字段值及校验信息
|
||||||
|
const payloadInfo = (key, value, errMsg, validateInfo) => ({
|
||||||
|
ojForm: {
|
||||||
|
[key]: errMsg ? '' : value
|
||||||
|
},
|
||||||
|
ojFormValidate: {
|
||||||
|
[key]: validateInfo
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单提交验证
|
||||||
|
export const validateOjForm = () => {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const {ojForm} = getState().ojFormReducer;
|
||||||
|
let keys = Object.keys(ojForm);
|
||||||
|
// 循环判断每个字段是否为空
|
||||||
|
let hasSuccess = true;
|
||||||
|
keys.forEach(key => {
|
||||||
|
const value = ojForm[key];
|
||||||
|
const validateResult = emptyValidate(key, value);
|
||||||
|
const errMsg = validateResult[key].errMsg;
|
||||||
|
if (errMsg) {
|
||||||
|
hasSuccess = false;
|
||||||
|
dispatch(
|
||||||
|
{
|
||||||
|
type: maps[key].type,
|
||||||
|
payload: payloadInfo(key, value, errMsg, validateResult[key])
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 验证成功后,调用提交接口
|
||||||
|
if (hasSuccess) {
|
||||||
|
console.log('表单保存的数据为: ', getState());
|
||||||
|
const {ojFormReducer} = getState();
|
||||||
|
const {code, score, ojForm, testCases} = ojFormReducer;
|
||||||
|
const {category, description, difficult, language, name, openOrNot, timeLimit} = ojForm;
|
||||||
|
const params = {
|
||||||
|
hack: {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
difficult,
|
||||||
|
category,
|
||||||
|
'open_or_not': openOrNot,
|
||||||
|
'time_limit': timeLimit,
|
||||||
|
score
|
||||||
|
},
|
||||||
|
'hack_sets': testCases,
|
||||||
|
'hack_codes': {
|
||||||
|
code,
|
||||||
|
language
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fetchPostOjForm(params).then(res => {
|
||||||
|
// TODO
|
||||||
|
}).catch(err => {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
// dispatch({type: types.VALIDATE_OJ_FORM});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 保存提交的代码
|
||||||
|
export const saveOjFormCode = (value) => {
|
||||||
|
return {
|
||||||
|
type: types.SAVE_OJ_FORM_CODE,
|
||||||
|
payload: value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// 验证任务名称
|
||||||
|
export const validateOJName = (value) => {
|
||||||
|
const validate = emptyValidate('name', value)['name'];
|
||||||
|
const errMsg = validate.errMsg;
|
||||||
|
return {
|
||||||
|
type: types.VALIDATE_OJ_NAME,
|
||||||
|
payload: payloadInfo('name', value, errMsg, validate)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 验证编程语言
|
||||||
|
export const validateOjLanguage = (value) => {
|
||||||
|
const validate = emptyValidate('language', value)['language'];
|
||||||
|
const errMsg = validate.errMsg;
|
||||||
|
return {
|
||||||
|
type: types.VALIDATE_OJ_LANGUAGE,
|
||||||
|
payload: payloadInfo('language', value, errMsg, validate)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 验证描述
|
||||||
|
export const validateOjDescription = (value) => {
|
||||||
|
// createAction('description', value, types.VALIDATE_OJ_DESCRIPTION);
|
||||||
|
const validate = emptyValidate('description', value)['description'];
|
||||||
|
const errMsg = validate.errMsg;
|
||||||
|
return {
|
||||||
|
type: types.VALIDATE_OJ_DESCRIPTION,
|
||||||
|
payload: payloadInfo('description', value, errMsg, validate)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 验证难易度
|
||||||
|
export const validateOjDifficult = (value) => {
|
||||||
|
// createAction('difficult', value, types.VALIDATE_OJ_DIFFICULT);
|
||||||
|
const validate = emptyValidate('difficult', value)['difficult'];
|
||||||
|
const errMsg = validate.errMsg;
|
||||||
|
return {
|
||||||
|
type: types.VALIDATE_OJ_DIFFICULT,
|
||||||
|
payload: payloadInfo('difficult', value, errMsg, validate)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 验证时间限制
|
||||||
|
export const validateOjTimeLimit = (value) => {
|
||||||
|
// createAction('timeLimit', value, types.VALIDATE_OJ_TIMELIMIT);
|
||||||
|
const validate = emptyValidate('timeLimit', value)['timeLimit'];
|
||||||
|
const errMsg = validate.errMsg;
|
||||||
|
return {
|
||||||
|
type: types.VALIDATE_OJ_TIMELIMIT,
|
||||||
|
payload: payloadInfo('timeLimit', value, errMsg, validate)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 验证分类
|
||||||
|
export const validateOjCategory = (value) => {
|
||||||
|
// createAction('category', value, types.VALIDATE_OJ_CATEGORY);
|
||||||
|
const validate = emptyValidate('category', value)['category'];
|
||||||
|
const errMsg = validate.errMsg;
|
||||||
|
return {
|
||||||
|
type: types.VALIDATE_OJ_CATEGORY,
|
||||||
|
payload: payloadInfo('category', value, errMsg, validate)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 验证公开程序
|
||||||
|
export const validateOpenOrNot = (value) => {
|
||||||
|
const validate = emptyValidate('openOrNot', value)['openOrNot'];
|
||||||
|
const errMsg = validate.errMsg;
|
||||||
|
return {
|
||||||
|
type: types.VALIDATE_OJ_OPENORNOT,
|
||||||
|
payload: payloadInfo('openOrNot', value, errMsg, validate)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 新增测试用例
|
||||||
|
export const addTestCase = (obj) => {
|
||||||
|
return {
|
||||||
|
type: types.ADD_TEST_CASE,
|
||||||
|
payload: obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 删除测试用例
|
||||||
|
export const deleteTestCase = (obj) => {
|
||||||
|
return {
|
||||||
|
type: types.DELETE_TEST_CASE,
|
||||||
|
payload: obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 更新id号编辑OJ
|
||||||
|
export const getOJFormById = (id) => {
|
||||||
|
return (dispatch) => {
|
||||||
|
fetchGetOjById(id).then(res => {
|
||||||
|
console.log('获取OJ表单信息成功: ', res);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 保存表单 id 信息
|
||||||
|
export const saveOJFormId = (id) => {
|
||||||
|
return {
|
||||||
|
type: types.SAVE_OJ_FORM_ID,
|
||||||
|
payload: id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 清空测试用例集合
|
||||||
|
export const clearOJFormStore = () => {
|
||||||
|
return {
|
||||||
|
type: types.CLEAR_JSFORM_STORE
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* @Description: 开发者社区action
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-20 10:48:24
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-22 16:44:44
|
||||||
|
*/
|
||||||
|
import types from './actionTypes';
|
||||||
|
import { fetchOJList } from '../../services/ojService';
|
||||||
|
|
||||||
|
export const getOJList = (params) => {
|
||||||
|
return (dispatch) => {
|
||||||
|
fetchOJList(params).then((res) => {
|
||||||
|
console.log('获取列表信息成功: ', res);
|
||||||
|
const { data } = res;
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_OJ_LIST,
|
||||||
|
payload: data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* @Description:
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-20 16:40:32
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-22 20:08:07
|
||||||
|
*/
|
||||||
|
import types from '../actions/actionTypes';
|
||||||
|
|
||||||
|
const init = {
|
||||||
|
ojForm: {
|
||||||
|
name: '', // 任务名称
|
||||||
|
language: '',
|
||||||
|
description: '',
|
||||||
|
difficult: 1,
|
||||||
|
category: 1,
|
||||||
|
openOrNot: 1,
|
||||||
|
timeLimit: ''
|
||||||
|
},
|
||||||
|
ojFormValidate: {
|
||||||
|
name: {
|
||||||
|
validateStatus: '',
|
||||||
|
errMsg: ''
|
||||||
|
},
|
||||||
|
language: {
|
||||||
|
validateStatus: '',
|
||||||
|
errMsg: ''
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
validateStatus: '',
|
||||||
|
errMsg: ''
|
||||||
|
},
|
||||||
|
difficult: {
|
||||||
|
validateStatus: '',
|
||||||
|
errMsg: ''
|
||||||
|
},
|
||||||
|
category: {
|
||||||
|
validateStatus: '',
|
||||||
|
errMsg: ''
|
||||||
|
},
|
||||||
|
openOrNot: {
|
||||||
|
validateStatus: '',
|
||||||
|
errMsg: ''
|
||||||
|
},
|
||||||
|
timeLimit: {
|
||||||
|
validateStatus: '',
|
||||||
|
errMsg: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
testCases: [
|
||||||
|
// {
|
||||||
|
// input: "11 22",
|
||||||
|
// output: "33",
|
||||||
|
// position: 1, // 当前测试用例位置
|
||||||
|
// isAdd: true // 是否是新增
|
||||||
|
// }
|
||||||
|
], // 测试用例集合
|
||||||
|
position: 1, // TODO 每次加载信息时同步指定positio值
|
||||||
|
score: 200, // 分值: 选择难易度后自动计算分值 200 | 500 | 1000
|
||||||
|
code: '', // 提交的代码
|
||||||
|
identifier: '' // OJ表单id
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState = Object.assign({}, init);
|
||||||
|
|
||||||
|
const ojFormReducer = (state = initialState, action) => {
|
||||||
|
let ojFormValidate = {};
|
||||||
|
let ojForm = {};
|
||||||
|
if (action.payload) {
|
||||||
|
ojFormValidate = action.payload.ojFormValidate;
|
||||||
|
ojForm = action.payload.ojForm;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const returnState = (state, ojForm, ojFormValidate) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
ojFormValidate: Object.assign({}, state.ojFormValidate, ojFormValidate),
|
||||||
|
ojForm: Object.assign({}, state.ojForm, ojForm)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
switch (action.type) {
|
||||||
|
case types.VALIDATE_OJ_FORM:
|
||||||
|
// 验证成功后,调用后台接口
|
||||||
|
return returnState(state, ojForm, ojFormValidate);
|
||||||
|
case types.SAVE_OJ_FORM_CODE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
code: action.payload
|
||||||
|
}
|
||||||
|
case types.VALIDATE_OJ_NAME:
|
||||||
|
// 验证任务名称
|
||||||
|
return returnState(state, ojForm, ojFormValidate);
|
||||||
|
case types.VALIDATE_OJ_DESCRIPTION:
|
||||||
|
return returnState(state, ojForm, ojFormValidate);
|
||||||
|
case types.VALIDATE_OJ_LANGUAGE:
|
||||||
|
return returnState(state, ojForm, ojFormValidate);
|
||||||
|
case types.VALIDATE_OJ_DIFFICULT:
|
||||||
|
const difficult = action.payload.ojForm.difficult.trim();
|
||||||
|
if (action.payload.ojForm.difficult) {
|
||||||
|
state.score = scoreMaps[`${difficult}`];
|
||||||
|
}
|
||||||
|
return returnState(state, ojForm, ojFormValidate);
|
||||||
|
case types.VALIDATE_OJ_CATEGORY:
|
||||||
|
return returnState(state, ojForm, ojFormValidate);
|
||||||
|
case types.VALIDATE_OJ_OPENORNOT:
|
||||||
|
return returnState(state, ojForm, ojFormValidate);
|
||||||
|
case types.VALIDATE_OJ_TIMELIMIT:
|
||||||
|
return returnState(state, ojForm, ojFormValidate);
|
||||||
|
case types.ADD_TEST_CASE:
|
||||||
|
state.testCases.push(action.payload);
|
||||||
|
state.position++; // 位置递增
|
||||||
|
return {
|
||||||
|
...state
|
||||||
|
};
|
||||||
|
case types.DELETE_TEST_CASE:
|
||||||
|
const { position } = action.payload;
|
||||||
|
const { testCases } = state;
|
||||||
|
// 根据 position 去查找当前元素在数组中的位置
|
||||||
|
const index = testCases.findIndex((item) => item.position === position);
|
||||||
|
if (index > -1) {
|
||||||
|
testCases.splice(index, 1); // 删除当前元素
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...state
|
||||||
|
};
|
||||||
|
case types.SAVE_OJ_FORM_ID:
|
||||||
|
state.identifier = action.payload;
|
||||||
|
return {
|
||||||
|
...state
|
||||||
|
}
|
||||||
|
case types.CLEAR_JSFORM_STORE:
|
||||||
|
state = Object.assign({}, init);
|
||||||
|
return {
|
||||||
|
...state
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ojFormReducer;
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* @Description:
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-21 22:17:03
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-22 09:17:59
|
||||||
|
*/
|
||||||
|
import types from '../actions/actionTypes';
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
hacks_list: [],
|
||||||
|
top_data: {},
|
||||||
|
hacks_count: 0 // 总条数
|
||||||
|
};
|
||||||
|
|
||||||
|
const ojListReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_OJ_LIST:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...action.payload
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ojListReducer;
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* @Description: 开发者社区接口
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-11-20 10:55:38
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-11-22 16:48:35
|
||||||
|
*/
|
||||||
|
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export async function fetchOJList (params) {
|
||||||
|
console.log('传递的参数: ', params);
|
||||||
|
const obj = {};
|
||||||
|
Object.keys(params).forEach(key => {
|
||||||
|
if (params[key]) {
|
||||||
|
obj[key] = params[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return axios.get('/problems.json', { params: obj });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
export async function fetchPostOjForm (params) {
|
||||||
|
const url = `/problems.json`;
|
||||||
|
return axios.post(url, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据id号获取OJ信息
|
||||||
|
export async function fetchGetOjById (id) {
|
||||||
|
const url = `/problems/${id}/edit.json`;
|
||||||
|
return axios.get(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in new issue