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

video_transcode
dinglink 5 years ago
commit 1d2c420144

@ -25,7 +25,7 @@ module GitHelper
decode_content = decode_content =
if cd["encoding"] == 'GB18030' && cd['confidence'] > 0.8 if cd["encoding"] == 'GB18030' && cd['confidence'] > 0.8
content.encode('UTF-8', 'GBK', {:invalid => :replace, :undef => :replace, :replace => ' '}) content.encode('UTF-8', 'GBK', {:invalid => :replace, :undef => :replace, :replace => ' '})
elsif cd['encoding'].blank? elsif cd['encoding'].blank? && !content.blank?
raise("ERROR_UTF8") raise("ERROR_UTF8")
else else
content.force_encoding('UTF-8') content.force_encoding('UTF-8')
@ -36,7 +36,7 @@ module GitHelper
rescue Exception => e rescue Exception => e
Rails.logger.error(e.message) Rails.logger.error(e.message)
error_msg = e.message == "ERROR_UTF8" ? "文件无法预览" : "文档内容获取异常" error_msg = e.message == "ERROR_UTF8" ? "文件编码异常请将文件编码设置为UTF-8" : "文档内容获取异常"
error_status = e.message == "ERROR_UTF8" ? -2 : -1 error_status = e.message == "ERROR_UTF8" ? -2 : -1
raise Educoder::TipException.new(error_status, error_msg) raise Educoder::TipException.new(error_status, error_msg)
end end

@ -64,7 +64,7 @@ class HacksController < ApplicationController
render_ok({identifier: hack.identifier}) render_ok({identifier: hack.identifier})
rescue => e rescue => e
logger.error("########create_hack_error: #{e.message}") logger.error("########create_hack_error: #{e.message}")
render_error("创建失败: #{e.message}") render_error("#{e.message}")
end end
end end
@ -96,7 +96,7 @@ class HacksController < ApplicationController
render_ok render_ok
rescue Exception => e rescue Exception => e
logger.error("####update_hack_error: #{e.message}") logger.error("####update_hack_error: #{e.message}")
render_error("更新失败: #{e.message}") render_error("#{e.message}")
end end
end end

@ -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

@ -2,7 +2,7 @@ desc "同步学院或者单位评测数"
namespace :sync_evaluate do namespace :sync_evaluate do
task outpus_count: :environment do task outpus_count: :environment do
School.find_in_batches(batch_size: 500) do |school| School.find_each do |school|
Parallel.each_with_index(school, in_processes: 5) do |s| Parallel.each_with_index(school, in_processes: 5) do |s|
puts "school_id:#{s.id}" puts "school_id:#{s.id}"
evaluate_count = Game.find_by_sql("select sum(g.evaluate_count) as e_count from games g, user_extensions ue where evaluate_count = Game.find_by_sql("select sum(g.evaluate_count) as e_count from games g, user_extensions ue where

@ -22,7 +22,7 @@
<meta name=”Description” Content=”EduCoder实训项目为单个知识点关卡实践训练帮助学生巩固单一弱点强化学习。 > <meta name=”Description” Content=”EduCoder实训项目为单个知识点关卡实践训练帮助学生巩固单一弱点强化学习。 >
<meta name=”Description” Content=”EduCoder实践教学平台各类大赛为进一步提高各类学生综合运用高级语言程序设计能力培养创新意识和实践探索精神发掘优秀软件人才。 > <meta name=”Description” Content=”EduCoder实践教学平台各类大赛为进一步提高各类学生综合运用高级语言程序设计能力培养创新意识和实践探索精神发掘优秀软件人才。 >
<!-- <meta name="viewport" id="viewport" content="width=device-width, initial-scale=0.3, maximum-scale=0.3, user-scalable=no">--> <!-- <meta name="viewport" id="viewport" content="width=device-width, initial-scale=0.3, maximum-scale=0.3, user-scalable=no">-->
<meta name="viewport" id="viewport" content="width=device-width, initial-scale=0.3, maximum-scale=0.3"> <!-- <meta name="viewport" id="viewport" content="width=device-width, initial-scale=0.3, maximum-scale=0.3">-->
<meta name="theme-color" content="#000000"> <meta name="theme-color" content="#000000">
<!--<meta http-equiv="cache-control" content="no-cache,no-store, must-revalidate" />--> <!--<meta http-equiv="cache-control" content="no-cache,no-store, must-revalidate" />-->

@ -895,7 +895,7 @@ class College extends Component {
共建实训 共建实训
</p> </p>
<p className="yslstatistic-base-item-label"> <p className="yslstatistic-base-item-label">
报告 报告
</p> </p>
<p className="yslstatistic-base-item-label"> <p className="yslstatistic-base-item-label">
学员实战时间 学员实战时间

@ -116,7 +116,7 @@ function CommentForm (props) {
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}

@ -435,7 +435,8 @@ a.white-btn.use_scope-btn:hover{
.maxwidth190{max-width: 190px; color:#666666;font-size: 14px;} .maxwidth190{max-width: 190px; color:#666666;font-size: 14px;}
.color05101A{color:#05101A;} .color05101A{color:#05101A;}
.liactive{border-left: 1px solid #4CACFF;} .liactive{border-left: 1px solid #4CACFF;}
.ant-btn-lg{height: 39px;} .xaxisreverseorder .ant-input-group-addon .ant-btn-lg{height: 38px;}
.ant-input-group-addon .ant-btn-lg{height: 39px;border-radius: 0px 3px 3px 0px!important;border: none!important;}
.bannername{ .bannername{
max-width: 907px; max-width: 907px;
overflow: hidden; overflow: hidden;

@ -77,7 +77,7 @@ function InitTabCtx (props, ref) {
const _handleTestCodeFormSubmit = (cb) => { const _handleTestCodeFormSubmit = (cb) => {
const {form} = props; const {form} = props;
form.validateFields((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { // 表单验证通过时,调用测试接口 if (!err) { // 表单验证通过时,调用测试接口
cb && cb(); // 调用回调函数,切换 tab cb && cb(); // 调用回调函数,切换 tab
onDebuggerCode && onDebuggerCode(values); onDebuggerCode && onDebuggerCode(values);

@ -76,7 +76,7 @@ class InitTabCtx extends PureComponent {
handleTestCodeFormSubmit = (cb) => { handleTestCodeFormSubmit = (cb) => {
const {form, debuggerCode} = this.props; const {form, debuggerCode} = this.props;
console.log(debuggerCode); console.log(debuggerCode);
form.validateFields((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { // 表单验证通过时,调用测试接口 if (!err) { // 表单验证通过时,调用测试接口
cb && cb(); // 调用回调函数,切换 tab cb && cb(); // 调用回调函数,切换 tab
console.log('表单值:', values); console.log('表单值:', values);

@ -22,7 +22,7 @@ const SettingDrawer = (props) => {
return +fromStore('oj_fontSize') || 14; return +fromStore('oj_fontSize') || 14;
}); });
const [theme, setTheme] = useState(() => { const [theme, setTheme] = useState(() => {
return fromStore('oj_theme') || 'dark'; return fromStore('oj_theme') || 'vs-dark';
}); });
const { title, type = 'label', content = [] } = props; const { title, type = 'label', content = [] } = props;
@ -78,7 +78,8 @@ const SettingDrawer = (props) => {
> >
{opt.text} {opt.text}
</option> </option>
)}); )
});
renderResult = ( renderResult = (
<div className={'setting_desc'} key={`sel_${index}`}> <div className={'setting_desc'} key={`sel_${index}`}>
<span className={'flex_item'}>{ctx.text}</span> <span className={'flex_item'}>{ctx.text}</span>

@ -16,8 +16,6 @@ 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',
@ -42,8 +40,6 @@ 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;
}); });
@ -52,10 +48,7 @@ function MyMonacoEditor (props, ref) {
}); });
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)');
@ -79,19 +72,20 @@ function MyMonacoEditor (props, ref) {
} }
// 文本框内容变化时,记录文本框内容 // 文本框内容变化时,记录文本框内容
const handleEditorChange = (origin, monaco) => { const handleEditorChange = (_, monaco) => {
editorRef.current = monaco; // 获取当前monaco实例 editorRef.current = monaco; // 获取当前monaco实例
// setEditCode(origin); // 保存编辑器初始值 }
useEffect(() => {
if (editorRef.current) {
editorRef.current.onDidChangeModelContent(e => { // 监听编辑器内容的变化 editorRef.current.onDidChangeModelContent(e => { // 监听编辑器内容的变化
// TODO 需要优化 节流
const val = editorRef.current.getValue(); const val = editorRef.current.getValue();
// setEditCode(val);
// console.log('编辑器代码====>>>>', val);
onCodeChange(val); onCodeChange(val);
// 值一变化保存当前代码值
// saveUserInputCode(val);
}); });
} }
}, [
editorRef.current
])
// 配置编辑器属性 // 配置编辑器属性
const editorOptions = { const editorOptions = {
@ -109,14 +103,6 @@ function MyMonacoEditor (props, ref) {
onRestoreInitialCode && onRestoreInitialCode(); onRestoreInitialCode && onRestoreInitialCode();
} }
}) })
// Modal.confirm({
// content: '确定要恢复代码吗?',
// okText: '确定',
// cancelText: '取消',
// onOk () {
// onRestoreInitialCode && onRestoreInitialCode();
// }
// })
} }
const handleUpdateNotice = () => { 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'; const _classnames = hadCodeUpdate ? `flex_strict flex_has_save` : 'flex_strict';
return ( return (
<React.Fragment> <React.Fragment>
@ -138,12 +119,6 @@ function MyMonacoEditor (props, ref) {
{/* 未保存时 ? '学员初始代码文件' : 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="通知"
@ -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));

@ -1,13 +1,14 @@
.monaco_editor_area { .monaco_editor_area {
height: 100%; height: 100%;
background-color: rgba(7,15,25,1);
.code_title { .code_title {
display: flex; display: flex;
align-items: center; align-items: center;
background-color: rgba(18,28,36,1);
color: #fff; color: #fff;
height: 56px; height: 56px;
background-color: rgba(18, 28, 36, 1);
padding: 0 20px; padding: 0 20px;
.flex_strict { .flex_strict {
flex: 1; flex: 1;
} }
@ -17,9 +18,11 @@
cursor: pointer; cursor: pointer;
margin-right: 20px; margin-right: 20px;
} }
.code-icon { .code-icon {
cursor: pointer; cursor: pointer;
} }
.flex_strict, .flex_strict,
.flex_normal, .flex_normal,
.code-icon { .code-icon {
@ -27,23 +30,13 @@
} }
} }
// .margin,
// .margin-view-overlays,
// .current-line{
// width: 40px !important;
// }
// .monaco-editor .margin-view-overlays .line-numbers{
// text-align: center;
// }
// .monaco-scrollable-element{
// left: 40px !important;
// }
} }
.setting_drawer { .setting_drawer {
.ant-drawer-close { .ant-drawer-close {
color: #ffffff; color: #ffffff;
} }
.ant-drawer-content { .ant-drawer-content {
top: 120px; top: 120px;
bottom: 56px; bottom: 56px;
@ -51,6 +44,7 @@
// background: #333333; // background: #333333;
background: rgba(7, 15, 25, 1); background: rgba(7, 15, 25, 1);
color: #fff; color: #fff;
.setting_h2 { .setting_h2 {
color: #fff; color: #fff;
} }
@ -62,6 +56,7 @@
// line-height: 24px; // line-height: 24px;
margin-top: 4px; margin-top: 4px;
} }
select option { select option {
background: gold; background: gold;
color: #fff; color: #fff;
@ -76,21 +71,8 @@
animation-iteration-count: 3; animation-iteration-count: 3;
} }
// .monaco-editor, .monaco-editor-background, .monaco-editor .inputarea.ime-input,
// .monaco-editor .margin,
// .minimap slider-mouseover,
// .minimap-decorations-layer{
// background:rgba(3,19,40,1) !important;
// }
@keyframes blink { @keyframes blink {
50% { 50% {
color: #fff; color: #fff;
} }
} }
.monaco-editor, .monaco-editor-background, .monaco-editor .inputarea.ime-input,
.monaco-editor .margin,
.minimap .minimap-decorations-layer{
background-color: transparent !important;
}

@ -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);
@ -87,14 +76,9 @@ const NewOrEditTask = (props) => {
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,16 +102,11 @@ 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>),
@ -141,10 +118,6 @@ 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>)),
@ -248,7 +221,6 @@ const NewOrEditTask = (props) => {
</SplitPane> </SplitPane>
</SplitPane> </SplitPane>
</div> </div>
{/* 控制台 */}
<div className='new_add_task_ctl'> <div className='new_add_task_ctl'>
{ {
/* 录入时: 取消 保存 */ /* 录入时: 取消 保存 */

@ -150,7 +150,7 @@ const AddTestDemo = (props) => {
<Panel header={`测试用例${props.index + 1}`} extra={props.index===0?false:genExtra()} key="1"> <Panel header={`测试用例${props.index + 1}`} extra={props.index===0?false:genExtra()} key="1">
<Form> <Form>
<FormItem <FormItem
label={<span className={'label_text'}>输入</span>} label={<span className={''}>输入</span>}
colon={ false } colon={ false }
> >
<TextArea <TextArea

@ -25,20 +25,17 @@ 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' }
], ],
@ -365,15 +362,11 @@ class EditTab extends React.Component {
values.forEach(v => { values.forEach(v => {
_result.push(v.id); _result.push(v.id);
}); });
// console.log('下拉选择的值:===>>>', _result);
// 保存选择的知识点
this.props.saveTagDisciplineId(_result); this.props.saveTagDisciplineId(_result);
} }
// 新增知识点 // 新增知识点
const handleAddKnowledge = (values) => { const handleAddKnowledge = (values) => {
// console.log('调用了新增知识点并返回了结果: ', values);
// 获取课程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);
@ -401,14 +394,6 @@ class EditTab extends React.Component {
help={ojFormValidate.sub_discipline_id.errMsg} help={ojFormValidate.sub_discipline_id.errMsg}
colon={false} colon={false}
> >
{/* <Select onChange={this.handleChangeCategory} value={`${ojForm.category}`}>
{getOptions('category')}
</Select> */}
{/* <Cascader
options={courseQuestions}
expandTrigger="hover"
onChange={this.handleChangeCategory}
/> */}
{renderCourseQuestion(courseQuestions)} {renderCourseQuestion(courseQuestions)}
</FormItem> </FormItem>
@ -443,7 +428,7 @@ class EditTab extends React.Component {
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>
@ -481,18 +466,6 @@ class EditTab extends React.Component {
/> />
</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>
{/* 添加测试用例 */} {/* 添加测试用例 */}

@ -90,7 +90,7 @@ function EditTab (props, ref) {
// 向外暴露的方法 // 向外暴露的方法
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
validateForm () { validateForm () {
props.form.validateFields((err, values) => { props.form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
getFormData(() => { getFormData(() => {
return values; return values;

@ -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 { const { code, language = 'C', saveOjFormCode } = props;
// 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>
) )
} }

@ -76,7 +76,7 @@ class InitTabCtx extends PureComponent {
handleTestCodeFormSubmit = (cb) => { handleTestCodeFormSubmit = (cb) => {
const {form, debuggerCode} = this.props; const {form, debuggerCode} = this.props;
// console.log(debuggerCode); // console.log(debuggerCode);
form.validateFields((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { // 表单验证通过时,调用测试接口 if (!err) { // 表单验证通过时,调用测试接口
cb && cb(); // 调用回调函数,切换 tab cb && cb(); // 调用回调函数,切换 tab
// console.log('表单值:', values); // console.log('表单值:', values);

@ -65,7 +65,6 @@ function RecordDetail (props) {
const handleEditorCode = (identifier, code) => { const handleEditorCode = (identifier, code) => {
if (identifier) { if (identifier) {
console.log(code);
saveEditorCodeForDetail(code); saveEditorCodeForDetail(code);
props.history.push(`/myproblems/${identifier}`); props.history.push(`/myproblems/${identifier}`);
} }

@ -1,55 +1,68 @@
@import '../split_pane_resizer.scss'; @import '../split_pane_resizer.scss';
.result_code_area .monaco-editor, .monaco-editor-background, .monaco-editor .inputarea.ime-input{
background-color: #f9f9f9!important;
}
.result_code_area .monaco-editor .line-numbers { .result_code_area .monaco-editor .line-numbers {
color: #999 !important; color: #999 !important;
} }
.result_code_area .monaco-editor .current-line~.line-numbers { .result_code_area .monaco-editor .current-line~.line-numbers {
color: #0b216f !important; color: #0b216f !important;
} }
.result_code_area .minimap-decorations-layer { .result_code_area .minimap-decorations-layer {
background: rgba(225, 225, 225, 0.2) !important; background: rgba(225, 225, 225, 0.2) !important;
} }
.result_code_area .monaco-editor .margin { .result_code_area .monaco-editor .margin {
background-color: #eee !important; background-color: #eee !important;
} }
.record_detail_area { .record_detail_area {
background: #fff; background: #fff;
.record_detail_ctx { .record_detail_ctx {
padding: 0 20px; padding: 0 20px;
.detail_ctx_header { .detail_ctx_header {
position: relative; position: relative;
height: 56px; height: 56px;
} }
.header_h2 { .header_h2 {
line-height: 56px; line-height: 56px;
} }
.header_btn { .header_btn {
position: absolute; position: absolute;
right: 0; right: 0;
top: 14px; top: 14px;
} }
.detail_ctx_status { .detail_ctx_status {
height: 18px; height: 18px;
line-height: 18px; line-height: 18px;
.status_label { .status_label {
color: rgba(153, 153, 153, 1); color: rgba(153, 153, 153, 1);
margin-right: 40px; margin-right: 40px;
} }
.status_label_error { .status_label_error {
color: #E51C24; color: #E51C24;
} }
.status_label_success { .status_label_success {
color: #28BD8B; color: #28BD8B;
} }
.status_label_sub { .status_label_sub {
color: #333333; color: #333333;
} }
.pass_case { .pass_case {
float: right; float: right;
margin-right: 0; margin-right: 0;
} }
.pass_case_span { .pass_case_span {
margin-right: 10px; margin-right: 10px;
} }
@ -59,6 +72,7 @@
// height: 500px; // height: 500px;
height: calc(100vh - 360px); height: calc(100vh - 360px);
} }
.result_error_area { .result_error_area {
margin-top: 15px; margin-top: 15px;
background: rgba(250, 250, 250, 1); background: rgba(250, 250, 250, 1);

@ -12,13 +12,10 @@ import { connect } from 'react-redux';
import SplitPane from 'react-split-pane'; import SplitPane from 'react-split-pane';
import LeftPane from './leftpane'; import LeftPane from './leftpane';
import RightPane from './rightpane'; import RightPane from './rightpane';
// import { Link } from 'react-router-dom';
// import { getImageUrl } from 'educoder'
// import RightPane from '../newOrEditTask/rightpane';
import { Icon } from 'antd'; import { Icon } from 'antd';
import UserInfo from '../components/userInfo'; import UserInfo from '../components/userInfo';
import actions from '../../../redux/actions'; import actions from '../../../redux/actions';
import { fromStore, CNotificationHOC} from 'educoder'; import { CNotificationHOC } from 'educoder';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
function StudentStudy(props) { function StudentStudy(props) {
@ -27,8 +24,6 @@ function StudentStudy (props) {
const { const {
hack, hack,
userInfo, userInfo,
// hack_identifier,
// user_program_identifier,
restoreInitialCode, restoreInitialCode,
changeUserCodeTab, changeUserCodeTab,
changeShowOrHideControl, changeShowOrHideControl,
@ -47,10 +42,6 @@ function StudentStudy (props) {
useEffect(() => { useEffect(() => {
// 保存当前的id // 保存当前的id
saveUserProgramIdentifier(id); saveUserProgramIdentifier(id);
// startProgramQuestion(id);
// console.log("getUserProgramDetail(id)");
// console.log(id);
// console.log(id.charAt(id.length-1));
try { try {
if (id.charAt(id.length - 1) === "?") { if (id.charAt(id.length - 1) === "?") {
id = id.substring(0, id.length - 1); id = id.substring(0, id.length - 1);
@ -74,17 +65,14 @@ function StudentStudy (props) {
changeUserCodeTab(tab); changeUserCodeTab(tab);
} }
}, []); }, []);
useEffect(() => { useEffect(() => {
const { hack = {} } = props; if (hack && hack.modify_code && hasUpdate) { // 代码更改,提示是否需要更新代码
if (hack.modify_code && hasUpdate) { // 代码更改,提示是否需要更新代码
setHasUpdate(false); setHasUpdate(false);
handleUpdateNotice(); handleUpdateNotice();
} }
}, [props, hasUpdate, setHasUpdate]); }, [hack, hack.modify_code, hasUpdate]);
const handleUpdateNotice = () => { const handleUpdateNotice = () => {
console.log(props);
props.confirm({ props.confirm({
title: '提示', title: '提示',
content: ( content: (
@ -97,22 +85,7 @@ function StudentStudy (props) {
restoreInitialCode(id, '更新成功'); restoreInitialCode(id, '更新成功');
} }
}) })
// Modal.confirm({
// title: '提示',
// content: (
// <p>
// 代码文件有更新啦 <br />
// 还未提交的代码,请自行保存
// </p>
// ),
// okText: '立即更新',
// cancelText: '稍后再说',
// onOk () {
// restoreInitialCode(id, '更新成功');
// }
// });
} }
// const _hack_id = hack_identifier || fromStore('hack_identifier');
// 处理编辑 // 处理编辑
const handleClickEditor = (identifier) => { const handleClickEditor = (identifier) => {
if (!identifier) return; if (!identifier) return;

@ -6,15 +6,12 @@
* @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) => {
@ -33,25 +30,13 @@ 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 = () => {
@ -73,7 +58,7 @@ const RightPane = (props) => {
clearInterval(timer); clearInterval(timer);
timer = null; timer = null;
saveUserCodeForInterval(identifier); saveUserCodeForInterval(identifier);
}, 3000); }, 5000);
} }
} }
@ -103,7 +88,7 @@ const RightPane = (props) => {
} }
const handleSubmitNote = () => { const handleSubmitNote = () => {
props.form.validateFields((err, values) => { props.form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
changeLoadingState(true); changeLoadingState(true);
addNotes(identifier, values, function () { addNotes(identifier, values, function () {
@ -113,7 +98,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'}>

@ -194,7 +194,7 @@ class Paperreview_single extends Component {
</div> </div>
<div id={"titessone"} className="ml10 lh28 listjihetixingstit markdown-body cretitlecolrlist " style={{wordBreak: "break-word",fontWeight:"bold"}} <div id={"titessone"} className="ml10 lh28 listjihetixingstit markdown-body cretitlecolrlist " style={{wordBreak: "break-word",fontWeight:"bold"}}
dangerouslySetInnerHTML={{__html: markdownToHTML(fenshul+objectsingle.name).replace(/▁/g, "▁▁▁")}}> dangerouslySetInnerHTML={{__html: markdownToHTML(objectsingle.name).replace(/▁/g, "▁▁▁")}}>
</div> </div>
</div> </div>

@ -331,7 +331,7 @@ export default class Shixuninformation extends Component {
<Checkbox <Checkbox
checked={this.state.test_set_permission} checked={this.state.test_set_permission}
onChange={this.Checktest_set_permission}></Checkbox> onChange={this.Checktest_set_permission}></Checkbox>
<label style={{top: '6px'}} className="color-grey-9 ml10">选中则允许学员允许学员通过金币解锁查看隐藏测试集的内容</label> <label style={{top: '6px'}} className="color-grey-9 ml10">选中则允许学员通过金币解锁查看隐藏测试集的内容</label>
</span> </span>
</div> </div>

@ -362,11 +362,11 @@ class Repository extends Component {
{commits===undefined?"":commits[0].time} {commits===undefined?"":commits[0].time}
</acronym> {commits===undefined?"":commits[0].title} </acronym> {commits===undefined?"":commits[0].title}
</span> </span>
<a href={`/shixuns/${match.params.shixunId}/${this.props.secret_repository_tab ? 'secret_repository' : 'repository'}/${match.params.shixunId}/commits`} <Link to={`/shixuns/${match.params.shixunId}/${this.props.secret_repository_tab ? 'secret_repository' : 'repository'}/${match.params.shixunId}/commits`}
className="color-grey-8 fr font-16 mt3"> className="color-grey-8 fr font-16 mt3">
<i className="iconfont icon-tijiaojilu font-18 fl mr5"></i> <i className="iconfont icon-tijiaojilu font-18 fl mr5"></i>
<span className="fl color-grey-8 ">提交记录</span> <span className="fl color-grey-8 ">提交记录</span>
</a> </Link>
</div>} </div>}

@ -218,7 +218,7 @@ class RepositoryAddFile extends Component {
{ {
` `
.padding20-30{ .padding20-30{
padding:20px 30px 5px 30px; padding:20px 30px 60px 30px;
} }
.formStyle .ant-form-item{ .formStyle .ant-form-item{
margin-bottom:0px !important; margin-bottom:0px !important;
@ -231,31 +231,20 @@ class RepositoryAddFile extends Component {
<p className="ant-form-item-label"> <p className="ant-form-item-label">
<div className={"font-20 color-black"}>新建文件</div> <div className={"font-20 color-black"}>新建文件</div>
</p> </p>
<Form.Item label="提交信息">
{getFieldDecorator('message', {
rules: [{
required: true, message: '请输入提交信息',
},{
whitespace: true, message: '请勿输入空格'
}],
})(
<Input placeholder="必填描述主要修改内容相当于Git Commit message的Header" size="large" className="winput-300-35 fl "/>
)}
</Form.Item>
<div className={"mt50"}> <div className={" mb50"}>
<Form.Item> <Form.Item label="文件名称或文件路径">
{getFieldDecorator('path', { {getFieldDecorator('path', {
rules: [{ rules: [{
required: true, message: '请输入提交信息', required: true, message: '请输入文件名称或文件路径',
},{ },{
whitespace: true, message: '请勿输入空格' whitespace: true, message: '请勿输入空格'
}], }],
})( })(
<span> <span>
<span> </span><span><Input value={this.state.path} placeholder="文件名称或文件路径" className="fl" style={{ width: 200 }} size="large" onInput={(e)=>this.setinput(e)}/></span><span className={" ml10 fl"}> <span> </span><span><Input value={this.state.path} placeholder="请输入文件名称或文件路径" className="fl" style={{ width: 240 }} size="large" onInput={(e)=>this.setinput(e)}/></span><span className={" ml10 fl"}>
提示1.输入文件名可以创建一个新文件2.输入新文件夹名/新文件名可以创建新文件夹和新文件</span> 提示1.输入文件名可以创建一个新文件2.输入新文件夹名/新文件名可以创建新文件夹和新文件step1/HelloWorld.java</span>
</span> </span>
)} )}
</Form.Item> </Form.Item>
@ -276,7 +265,18 @@ class RepositoryAddFile extends Component {
<div className="mt10 mb25 repoCMWrapper filecode"> <div className="mt10 mb25 repoCMWrapper filecode">
<textarea className="" id="codemirror-file-edit" style={{display:'none'}} name="content"></textarea> <textarea className="" id="codemirror-file-edit" style={{display:'none'}} name="content"></textarea>
</div> </div>
<Form.Item label="提交信息">
{getFieldDecorator('message', {
rules: [{
required: true, message: '请输入提交信息',
},{
whitespace: true, message: '请勿输入空格'
}],
})(
<Input placeholder="请输入本次提交的主要信息,合理的描述信息有利于代码历史记录的管理" size="large" className="winput-300-35 fl "/>
)}
</Form.Item>
{/*<Form.Item label="提交信息">*/} {/*<Form.Item label="提交信息">*/}
{/* {getFieldDecorator('message', {*/} {/* {getFieldDecorator('message', {*/}
{/* rules: [{required: true, message: "请输入提交信息"}],*/} {/* rules: [{required: true, message: "请输入提交信息"}],*/}

@ -266,23 +266,14 @@ class RepositoryAddFileupload_files extends Component {
<div className={"font-20 color-black"}>上传文件</div> <div className={"font-20 color-black"}>上传文件</div>
</p> </p>
<Form.Item label="提交信息">
{getFieldDecorator('message', {
rules: [{
required: true, message: '请输入提交信息',
},{
whitespace: true, message: '请勿输入空格'
}],
})(
<Input placeholder="必填描述主要修改内容相当于Git Commit message的Header" onInput={this.FormInput} className="winput-300-35 fl"/>
)}
</Form.Item>
<div>
<p className="ant-form-item-label"> <p className="ant-form-item-label">
<div className={"color888 font-16"}>当前目录{this.state.filspath===""?"/":"/"+this.state.filspath} <span className={"color-blue pointer"} onClick={this.Selectfiledirectory}>选择文件目录</span></div> <div className={"color888 font-16"}>当前目录{this.state.filspath===""?"/":"/"+this.state.filspath} <span className={"color-blue pointer"} onClick={this.Selectfiledirectory}>选择文件目录</span></div>
</p> </p>
</div>
{/*<div className="mt10 mb25 repoCMWrapper filecode">*/} {/*<div className="mt10 mb25 repoCMWrapper filecode">*/}
@ -308,7 +299,18 @@ class RepositoryAddFileupload_files extends Component {
{/* <textarea className="winput-100-130 fl"></textarea>*/} {/* <textarea className="winput-100-130 fl"></textarea>*/}
{/* )}*/} {/* )}*/}
{/*</Form.Item>*/} {/*</Form.Item>*/}
<Form.Item label="提交信息">
{getFieldDecorator('message', {
rules: [{
required: true, message: '请输入提交信息',
},{
whitespace: true, message: '请勿输入空格'
}],
})(
<Input placeholder="必填描述主要修改内容相当于Git Commit message的Header" onInput={this.FormInput} className="winput-300-35 fl"/>
)}
</Form.Item>
</div> </div>
</Form> </Form>
</div> </div>

@ -9,6 +9,7 @@ import UpgradeModals from '../../modals/UpgradeModals';
import GotoQQgroup from '../../../modal/GotoQQgroup' import GotoQQgroup from '../../../modal/GotoQQgroup'
import btnUrl from './btn-new.png' import btnUrl from './btn-new.png'
const queryString = require('query-string'); const queryString = require('query-string');
class ShixunsIndex extends Component { class ShixunsIndex extends Component {
constructor(props) { constructor(props) {
super(props) super(props)

@ -25,7 +25,6 @@ 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) {
@ -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,
@ -337,11 +323,13 @@ export const debuggerCode = (identifier,value, type) => {
// 获取提交记录 // 获取提交记录
export const getUserCommitRecord = (identifier) => { export const getUserCommitRecord = (identifier) => {
return (dispatch, getState) => { return (dispatch, getState) => {
try {
const { pages: { limit, page } } = getState().ojForUserReducer; const { pages: { limit, page } } = getState().ojForUserReducer;
fetchUserCommitRecord(identifier, { fetchUserCommitRecord(identifier, {
limit, limit,
page page
}).then(res => { }).then(res => {
if (res) {
const { status, data } = res; const { status, data } = res;
if (status === 200) { if (status === 200) {
dispatch({ dispatch({
@ -349,7 +337,12 @@ export const getUserCommitRecord = (identifier) => {
payload: data payload: data
}) })
} }
}); }
})
} catch (error) {
console.log(error, '-------')
}
;
} }
} }
// 获取提交记录详情 // 获取提交记录详情
@ -405,7 +398,6 @@ export const submitUserCode = (identifier, inputValue, type) => {
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,7 +450,6 @@ 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({
@ -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

@ -168,6 +168,39 @@ export const validateOjForm = (props, type, cb) => {
tcValidResult.push(tempObj); tcValidResult.push(tempObj);
}); });
try {
if(ojForm.sub_discipline_id.length===0){
hasSuccess = false;
notification['error']({
message: '提示',
description: '课程必须选择!'
});
}else if(ojForm.timeLimit===null){
hasSuccess = false;
notification['error']({
message: '提示',
description: '时间限制必须输入!'
});
} else if(ojForm.name.length===0){
hasSuccess = false;
notification['error']({
message: '提示',
description: '任务名称必须输入!'
});
}else if(ojForm.description.length===0){
hasSuccess = false;
notification['error']({
message: '提示',
description: '描述必须输入!'
});
}
}catch (e) {
}
// if (testCases.length === 0) { // if (testCases.length === 0) {
// hasSuccess = false; // hasSuccess = false;
// notification['error']({ // notification['error']({

@ -137,6 +137,7 @@ const ojForUserReducer = (state = initialState, action) => {
} else { } else {
curHack['code'] = ''; curHack['code'] = '';
} }
curHack['modify_code'] = false
return { return {
...state, ...state,
hack: Object.assign({}, state.hack, curHack), hack: Object.assign({}, state.hack, curHack),

@ -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,

Loading…
Cancel
Save