Merge branch 'develop' of http://bdgit.educoder.net/Hjqreturn/educoder into develop
commit
8f8ca3475b
@ -0,0 +1,5 @@
|
||||
class AddVipToShixun < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :shixuns, :vip, :boolean, default: 0
|
||||
end
|
||||
end
|
@ -0,0 +1,7 @@
|
||||
class ModifyTypeForTestSets < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
change_column :test_sets, :input, :longtext
|
||||
change_column :test_sets, :output, :longtext
|
||||
|
||||
end
|
||||
end
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 74 KiB |
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* @Description: 引入阿里图标库
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2019-12-10 09:03:48
|
||||
* @LastEditors: tangjiang
|
||||
* @LastEditTime: 2019-12-10 09:05:41
|
||||
*/
|
||||
import { Icon } from 'antd';
|
||||
|
||||
const MyIcon = Icon.createFromIconfontCN({
|
||||
scriptUrl: '//at.alicdn.com/t/font_1535266_ss6796i6f6j.js'
|
||||
});
|
||||
|
||||
export default MyIcon;
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* @Description: 用户头像及昵称
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2019-12-09 17:11:28
|
||||
* @LastEditors: tangjiang
|
||||
* @LastEditTime: 2019-12-09 17:36:55
|
||||
*/
|
||||
import './index.scss';
|
||||
import React from 'react';
|
||||
import { getImageUrl } from 'educoder'
|
||||
|
||||
function UserInfo (props) {
|
||||
const {image_url, name} = props.userInfo;
|
||||
return (
|
||||
<div className={'avator_nicker'}>
|
||||
<img alt="用户头像" className={'student_img'} src={getImageUrl(`images/${image_url}` || 'images/educoder/headNavLogo.png?1526520218')} />
|
||||
<span className={'student_nicker'}>
|
||||
{name || ''}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default UserInfo
|
||||
export {
|
||||
UserInfo
|
||||
};
|
@ -0,0 +1,25 @@
|
||||
|
||||
.avator_nicker{
|
||||
position: absolute;
|
||||
color: #fff;
|
||||
line-height: 65px;
|
||||
// height: 65px;
|
||||
.student_img,
|
||||
.student_nicker{
|
||||
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.student_nicker{
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.student_img{
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,18 @@
|
||||
@import '../split_pane_resizer.scss';
|
||||
|
||||
.new_add_task_wrap {
|
||||
.split-pane-area{
|
||||
height: calc(100vh - 121px);
|
||||
}
|
||||
}
|
||||
.new_add_task_ctl{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 56px;
|
||||
background: #333333;
|
||||
> button{
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* @Description: 右侧代码块
|
||||
* @Author: tangjiang
|
||||
* @Date: 2019-11-18 08:42:04
|
||||
* @Last Modified by: tangjiang
|
||||
* @Last Modified time: 2019-11-20 00:00:34
|
||||
*/
|
||||
|
||||
import './index.scss';
|
||||
|
||||
import React, { Fragment, useState, useRef, useEffect } from 'react';
|
||||
import { Icon, Drawer, Tabs, Button, notification } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import MonacoEditor from '@monaco-editor/react';
|
||||
import { connect } from 'react-redux';
|
||||
import InitTabCtx from './initTabCtx';
|
||||
import SettingDrawer from '../../components/monacoSetting';
|
||||
import CONST from '../../../../constants';
|
||||
import actions from '../../../../redux/actions';
|
||||
|
||||
const { fontSetting, opacitySetting } = CONST;
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
const RightPaneCode = (props) => {
|
||||
|
||||
const [showDrawer, setShowDrawer] = useState(false); // 控制配置滑框
|
||||
const [defaultActiveKey, setDefaultActiveKey] = useState('1'); // 当前选中的tab
|
||||
const [showTextResult, setShowTextResult] = useState(false); // 是否点击控制台按钮
|
||||
const [editCode, setEditCode] = useState(()=> {
|
||||
return '#include <stdio.h>';
|
||||
}); // monaco编辑器内容
|
||||
const [language, setLanguage] = useState('C')
|
||||
const [fontSize,setFontSize] = useState(12);
|
||||
const editorRef = useRef(null); // 编辑器ref
|
||||
|
||||
useEffect(() => {
|
||||
if (props.language) {
|
||||
// console.log('当前输入的代码:', editCode);
|
||||
// console.log('当前输入的语言:', props.language);
|
||||
setLanguage(props.language)
|
||||
}
|
||||
}, [props.language]);
|
||||
|
||||
useEffect(() => {
|
||||
}, [props.testCases]);
|
||||
|
||||
useEffect(() => {
|
||||
}, [editCode]);
|
||||
|
||||
// 监听store中编辑器内容变化
|
||||
useEffect(() => {
|
||||
setEditCode(props.code);
|
||||
}, [props.code]);
|
||||
|
||||
// 打开设置
|
||||
const handleShowDrawer = (e) => {
|
||||
e.preventDefault();
|
||||
setShowDrawer(true);
|
||||
}
|
||||
|
||||
// 关闭设置
|
||||
const handleDrawerClose = (e) => {
|
||||
e.preventDefault();
|
||||
setShowDrawer(false);
|
||||
}
|
||||
|
||||
// 切换tab
|
||||
const handleTabChange = (key) => {
|
||||
setDefaultActiveKey(key);
|
||||
}
|
||||
|
||||
// 显示/隐藏tab
|
||||
const handleShowControl = () => {
|
||||
setShowTextResult(!showTextResult);
|
||||
}
|
||||
|
||||
// 侧边栏改变字体大小
|
||||
const handleFontSizeChange = (value) => {
|
||||
setFontSize(value);
|
||||
}
|
||||
// 文本框内容变化时,记录文本框内容
|
||||
const handleEditorChange = (origin, monaco) => {
|
||||
editorRef.current = monaco; // 获取当前monaco实例
|
||||
setEditCode(origin); // 保存编辑器初始值
|
||||
editorRef.current.onDidChangeModelContent(e => { // 监听编辑器内容的变化
|
||||
// TODO 需要优化 节流
|
||||
const val = editorRef.current.getValue();
|
||||
setEditCode(val);
|
||||
// 保存当前代码
|
||||
props.saveOjFormCode(val);
|
||||
});
|
||||
}
|
||||
|
||||
// 提交按钮点击
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
if (!editCode) {
|
||||
notification['error']({
|
||||
message: '必填',
|
||||
description: '代码块内容必须输入!'
|
||||
});
|
||||
editorRef.current.focus();
|
||||
return;
|
||||
}
|
||||
props.changePublishLoadingStatus(true);
|
||||
const { onSubmitForm } = props;
|
||||
onSubmitForm(editCode);
|
||||
}
|
||||
|
||||
// 调试测试代码
|
||||
// const handleTestCode = () => {
|
||||
// // 打开控制台信息
|
||||
// setShowTextResult(true);
|
||||
// this.formRef.handleTestCodeFormSubmit(() => {
|
||||
// // 当验证通过后 切换tab 到代码执行结果
|
||||
// setDefaultActiveKey('2');
|
||||
// });
|
||||
// }
|
||||
|
||||
// 控制台点击时 添加active属性
|
||||
const classNames = `control_tab ${showTextResult ? 'move_up move_up_final' : 'move_down_final'}`;
|
||||
|
||||
// 配置编辑器属性
|
||||
const editorOptions = {
|
||||
selectOnLineNumbers: true,
|
||||
automaticLayout: true,
|
||||
fontSize: `${fontSize}px`
|
||||
}
|
||||
|
||||
// 返回渲染值
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={'right_pane_code_wrap'}>
|
||||
<div className={'code-title'}>
|
||||
<span></span>
|
||||
<Icon className={'code-icon'} type="setting" onClick={handleShowDrawer}/>
|
||||
</div>
|
||||
{/** 代码编辑器 */}
|
||||
<MonacoEditor
|
||||
height={showTextResult ? 'calc(100% - 382px)' : 'calc(100% - 112px)'}
|
||||
width="100%"
|
||||
language={language.toLowerCase()}
|
||||
value={editCode}
|
||||
options={editorOptions}
|
||||
theme="dark"
|
||||
editorDidMount={handleEditorChange}
|
||||
/>
|
||||
{/* 控制台信息 */}
|
||||
<div className="pane_control_area">
|
||||
<Tabs
|
||||
className={classNames}
|
||||
activeKey={defaultActiveKey}
|
||||
tabBarStyle={{ backgroundColor: '#000', color: '#fff' }}
|
||||
onChange={handleTabChange}
|
||||
>
|
||||
<TabPane tab={'自定义测试用例'} key={'1'} style={{ height: '280px', overflowY: 'auto' }}>
|
||||
<InitTabCtx wrappedComponentRef={(form) => this.formRef = form }/>
|
||||
</TabPane>
|
||||
<TabPane tab={'代码执行结果'} key={'2'} style={{ height: '280px', overflowY: 'auto' }}>
|
||||
<h2>代码执行结果</h2>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<div className="pane_control_opts">
|
||||
<Button type="link" style={{ color: '#fff' }} onClick={handleShowControl}>控制台 <Icon type={ showTextResult ? "down" : "up" } /></Button>
|
||||
<p>
|
||||
{/* <Button ghost
|
||||
style={{ marginRight: '10px', color: '#28BD8B', borderColor: '#28BD8B' }}
|
||||
onClick={handleTestCode}
|
||||
disabled={!props.identifier || props.testCases.length === 0}
|
||||
>调试代码</Button> */}
|
||||
<Button
|
||||
loading={props.submitLoading}
|
||||
type="primary"
|
||||
onClick={handleSubmit}
|
||||
>{props.identifier ? '更新' : '提交'}</Button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Drawer
|
||||
className={'setting_drawer'}
|
||||
placement="right"
|
||||
closable={false}
|
||||
onClose={handleDrawerClose}
|
||||
visible={showDrawer}
|
||||
>
|
||||
<SettingDrawer {...fontSetting} onChangeFontSize={handleFontSizeChange}/>
|
||||
<SettingDrawer {...opacitySetting}/>
|
||||
</Drawer>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { ojForm, testCases, identifier, code } = state.ojFormReducer;
|
||||
const { submitLoading } = state.commonReducer;
|
||||
return {
|
||||
language: ojForm.language,
|
||||
testCases,
|
||||
identifier,
|
||||
code,
|
||||
submitLoading
|
||||
}
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
saveOjFormCode: (code) => dispatch(actions.saveOjFormCode(code)),
|
||||
changePublishLoadingStatus: (flag) => dispatch(actions.changeSubmitLoadingStatus(flag))
|
||||
});
|
||||
//
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(RightPaneCode);
|
@ -1,4 +0,0 @@
|
||||
.quill_editor_area{
|
||||
height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
Loading…
Reference in new issue