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

dev_jupyter
cxt 5 years ago
commit 452d713f00

@ -1,4 +1,5 @@
class Admins::CustomersController < Admins::BaseController
# skip_before_action :check_sign
helper_method :current_partner
def index

@ -1,4 +1,5 @@
class PartnersController < ApplicationController
skip_before_action :check_sign
include Base::PaginateHelper
include Admins::RenderHelper

@ -18,9 +18,9 @@ class ShixunsController < ApplicationController
before_action :find_repo_name, only: [:repository, :commits, :file_content, :update_file, :shixun_exec, :copy,
:add_file, :jupyter_exec]
before_action :allowed, only: [:update, :close, :update_propaedeutics, :settings, :publish, :apply_public,
before_action :allowed, only: [:update, :close, :update_propaedeutics, :settings, :publish, :apply_public, :upload_git_folder,
:shixun_members_added, :change_manager, :collaborators_delete, :upload_git_file,
:cancel_apply_public, :cancel_publish, :add_collaborators, :add_file]
:cancel_apply_public, :cancel_publish, :add_collaborators, :add_file, :delete_git_file]
before_action :portion_allowed, only: [:copy]
before_action :special_allowed, only: [:send_to_course, :search_user_courses]
@ -896,6 +896,15 @@ class ShixunsController < ApplicationController
render_ok
end
def upload_git_folder
render_ok
end
def delete_git_file
render_ok
end
def add_collaborators
member_ids = "(" + @shixun.shixun_members.map(&:user_id).join(',') + ")"
user_name = "%#{params[:user_name].to_s.strip}%"

@ -8,7 +8,8 @@ module JupyterService
uri = "#{shixun_tomcat}/bridge/jupyter/get"
tpiID = "tpm#{shixun.id}"
mount = shixun.data_sets.present?
params = {tpiID: tpiID, identifier: shixun.identifier, needMount: mount, gitUrl: '',
gitUrl = "#{edu_setting('git_address_domain')}/#{shixun.repo_path}"
params = {tpiID: tpiID, identifier: shixun.identifier, needMount: mount, gitUrl: gitUrl,
:containers => "#{Base64.urlsafe_encode64(shixun_container_limit(shixun))}"}
logger.info "test_juypter: uri->#{uri}, params->#{params}"

@ -315,6 +315,8 @@ Rails.application.routes.draw do
post :commits
post :file_content
post :upload_git_file
post :upload_git_folder
delete :delete_git_file
post :update_file
post :close
post :add_file

@ -82,8 +82,8 @@ export function initAxiosInterceptors(props) {
// proxy = "https://testeduplus2.educoder.net"
//proxy="http://47.96.87.25:48080"
proxy="https://pre-newweb.educoder.net"
proxy="https://test-newweb.educoder.net"
// proxy="https://test-jupyterweb.educoder.net"
// proxy="https://test-newweb.educoder.net"
proxy="https://test-jupyterweb.educoder.net"
//proxy="http://192.168.2.63:3001"
// 在这里使用requestMap控制避免用户通过双击等操作发出重复的请求
@ -123,7 +123,10 @@ export function initAxiosInterceptors(props) {
}
}
if(`${config[0]}`!=`true`){
let timestamp = Date.parse(new Date())/1000;
if (window.location.port === "3007") {
// let timestamp=railsgettimes(proxy);
console.log(timestamp)
railsgettimes(`${proxy}/api/main/first_stamp.json`);
let newopens=md5(opens+timestamp)
config.url = `${proxy}${url}`;

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-16 15:50:45
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 15:07:11
* @LastEditTime : 2019-12-31 13:59:02
*/
import Quill from "quill";
@ -50,6 +50,7 @@ export default class ImageBlot extends BlockEmbed {
return node;
}
// 获取节点值
static value (node) {
return {

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-18 08:49:30
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 16:49:25
* @LastEditTime : 2019-12-31 15:11:37
*/
import './index.scss';
import 'quill/dist/quill.core.css'; // 核心样式
@ -18,10 +18,18 @@ import deepEqual from './deepEqual.js'
import { fetchUploadImage } from '../../services/ojService.js';
import { getImageUrl } from 'educoder'
import ImageBlot from './ImageBlot';
const Size = Quill.import('attributors/style/size');
const Font = Quill.import('formats/font');
// const Color = Quill.import('attributes/style/color');
Size.whitelist = ['12px', '14px', '16px', '18px', '20px', false];
Font.whitelist = ['SimSun', 'SimHei','Microsoft-YaHei','KaiTi','FangSong','Arial','Times-New-Roman','sans-serif'];
window.Quill = Quill;
window.katex = katex;
Quill.register(ImageBlot);
Quill.register(Size);
Quill.register(Font, true);
// Quill.register(Color);
function QuillForEditor ({
placeholder,
@ -38,15 +46,16 @@ function QuillForEditor ({
}) {
// toolbar 默认值
const defaultConfig = [
['bold', 'italic', 'underline'],
[{align: []}, {list: 'ordered'}, {list: 'bullet'}], // 列表
[{script: 'sub'}, {script: 'super'}],
[{ 'color': [] }, { 'background': [] }],
[{header: [1,2,3,4,5,false]}],
['blockquote', 'code-block'],
['link', 'image', 'video'],
['formula'],
['clean']
'bold', 'italic', 'underline',
{size: ['12px', '14px', '16px', '18px', '20px']},
{align: []}, {list: 'ordered'}, {list: 'bullet'}, // 列表
{script: 'sub'}, {script: 'super'},
{ 'color': [] }, { 'background': [] },
{header: [1,2,3,4,5,false]},
'blockquote', 'code-block',
'link', 'image', 'video',
'formula',
'clean'
];
const editorRef = useRef(null);

@ -7,4 +7,107 @@
cursor: pointer;
}
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="12px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="12px"]::before {
content: '12px';
font-size: 12px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="14px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]::before {
content: '14px';
font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="16px"]::before {
content: '16px';
font-size: 16px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="18px"]::before {
content: '18px';
font-size: 18px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="20px"]::before {
content: '20px';
font-size: 20px;
}
//
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: '14px';
font-size: 14px;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
content: "宋体";
font-family: "SimSun";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
content: "黑体";
font-family: "SimHei";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
content: "微软雅黑";
font-family: "Microsoft YaHei";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
content: "楷体";
font-family: "KaiTi";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
content: "仿宋";
font-family: "FangSong";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
content: "Arial";
font-family: "Arial";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
content: "Times New Roman";
font-family: "Times New Roman";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
content: "sans-serif";
font-family: "sans-serif";
}
.ql-font-SimSun {
font-family: "SimSun";
}
.ql-font-SimHei {
font-family: "SimHei";
}
.ql-font-Microsoft-YaHei {
font-family: "Microsoft YaHei";
}
.ql-font-KaiTi {
font-family: "KaiTi";
}
.ql-font-FangSong {
font-family: "FangSong";
}
.ql-font-Arial {
font-family: "Arial";
}
.ql-font-Times-New-Roman {
font-family: "Times New Roman";
}
.ql-font-sans-serif {
font-family: "sans-serif";
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: "微软雅黑";
font-family: "Microsoft YaHei";
}
}

@ -3,8 +3,8 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-11-20 23:10:48
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-06 15:53:27
* @LastEditors : tangjiang
* @LastEditTime : 2020-01-02 14:57:02
*/
const CONST = {
jcLabel: {
@ -12,9 +12,11 @@ const CONST = {
language: '编程语言',
description: '描述',
difficult: '难易度',
category: '分类',
category: '课程',
openOrNot: '公开程序',
timeLimit: '时间限制'
timeLimit: '时间限制',
knowledge: '知识点',
sub_discipline_id: '课程'
},
fontSetting: {
title: '代码格式',

@ -253,22 +253,22 @@ class Fileslistitem extends Component{
{discussMessage.is_publish===false?<CoursesListType typelist={["未发布"]} typesylename={""}/>:""}
{this.props.isAdmin?
<span className={"fr mr10 mt2"} onClick={(event)=>this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<span className={"fr mt2"} onClick={(event)=>this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 ml20 fr">
<a className="btn colorblue fontweight400"
onClick={()=>this.settingList()}>设置</a>
</WordsBtn>
</span>:""}
{this.props.isStudent===true&&this.props.current_user.login===discussMessage.author.login?
<span className={"fr mr10 mt2"} onClick={(event)=>this.eventStop(event)}>
<span className={"fr mt2"} onClick={(event)=>this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<WordsBtn style="blue" className="colorblue font-16 ml20 fr">
<a className="btn colorblue fontweight400"
onClick={()=>this.settingList()}>设置</a>
</WordsBtn>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<WordsBtn style="blue" className="colorblue font-16 ml20 fr">
<a className="btn colorblue fontweight400"
onClick={()=>this.onDelete(discussMessage.id)}>删除</a>
</WordsBtn>
@ -329,7 +329,7 @@ class Fileslistitem extends Component{
{ discussMessage.publish_time===null?"":discussMessage.is_publish===true?moment(discussMessage.publish_time).fromNow():moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm')}
</span>
</span>
{discussMessage&&discussMessage.category_name===null?"":this.props.child===false?<div className="color-grey9 task-hide fr mr60" title={discussMessage&&discussMessage.category_name}
{discussMessage&&discussMessage.category_name===null?"":this.props.child===false?<div className="color-grey9 task-hide fr mr30" title={discussMessage&&discussMessage.category_name}
style={{"max-width":"268px"}}>所属目录{discussMessage&&discussMessage.category_name}
</div>:""}
</p>

@ -106,12 +106,11 @@ class Selectsetting extends Component{
savecouseShixunModal=()=>{
let {fileList,is_public,description,datatime,Radiovalue}=this.state;
let newfileList=[];
if(fileList!=undefined&&fileList.length>0){
for(var list of fileList){
fileList.map((list,key)=>{
newfileList.push(list.response.id)
}
})
}

@ -131,9 +131,9 @@ class Sendresource extends Component{
let newfileList=[];
if(fileList!=undefined&&fileList.length>0){
for(var list of fileList){
fileList.map((list,key)=>{
newfileList.push(list.response.id)
}
})
}

@ -370,11 +370,11 @@ class ShixunWorkReport extends Component {
{this.props.isAdmin() ?<a
className=" color-blue font-14 fr ml20 mt15"
onClick={()=>this.confirmysl(`/student_works/${homeworkid}/export_shixun_work_report.pdf`)}
> <Spin size="small" spinning={this.state.isspinning}>导出实训报告数据</Spin></a>:
> <Spin size="small" spinning={this.state.isspinning}>导出实训报告</Spin></a>:
parseInt(this.props&&this.props.user.user_id)===parseInt(data&&data.user_id)?<a
className=" color-blue font-14 fr ml20 mt15"
onClick={()=>this.confirmysl(`/student_works/${homeworkid}/export_shixun_work_report.pdf`)}
> <Spin size="small" spinning={this.state.isspinning}>导出实训报告数据</Spin></a>:""
> <Spin size="small" spinning={this.state.isspinning}>导出实训报告</Spin></a>:""
}
{/*{this.props.isAdmin() ?work_comment_hidden===true? "":<a*/}
{/*className=" color-blue font-14 fr ml20 mt15"*/}
@ -465,22 +465,22 @@ class ShixunWorkReport extends Component {
</div>
<div className={"fl edu-back-white ml39 "}>
<p className={"back_font"}>{data&&data.username}</p>
<p className={"back_font mt10"}>{data&&data.username}</p>
<p className={"mb16"}>
<span className={"passbox"}>
<div className={"passfont"}><span className={"color999"}>通过关卡</span> <span className={"colorCF3B3B"}>{data&&data.complete_count}/{data&&data.challenges_count}</span></div>
<p className={"mb16 mt10"}>
<span className={"passbox "}>
<div className={"passfont mb5"}><span className={"color999"}>当前完成关卡</span> <span className={"colorCF3B3B"}>{data&&data.complete_count}/{data&&data.challenges_count}</span></div>
<div className={"passfontbom"}><span className={"color999"}>经验值</span> <span className={"color333"}>{data&&data.myself_experience}/{data&&data.total_experience}</span></div>
</span>
<span className={"passbox"}>
<div className={"passfontmid"}><span className={"color999"}>课堂最高完成效率</span> <span className={data&&data.max_efficiency===null?"color999":"color333"}>{data&&data.max_efficiency===null?'--':data&&data.max_efficiency}</span></div>
<div className={"passfontbommid"}><span className={"color999"}>完成效率</span> <span className={data&&data.efficiency===null?"color999":"color333"}>{data&&data.efficiency===null?'--':data&&data.efficiency}</span></div>
<div className={"passfontbommid mb5"}><span className={"color999"}>完成效率</span> <span className={data&&data.efficiency===null?"color999":"color333"}>{data&&data.efficiency===null?'--':data&&data.efficiency}</span></div>
<div className={"passfontmid "}><span className={"color999"}>课堂最高完成效率</span> <span className={data&&data.max_efficiency===null?"color999":"color333"}>{data&&data.max_efficiency===null?'--':data&&data.max_efficiency}</span></div>
</span>
<span className={"passbox"}>
<div><span className={"color999"}>通关时间</span> <span className={data&&data.passed_time===null?"color999":"color333"}>{data&&data.passed_time===null||data&&data.passed_time=== "--"?'--':moment(data&&data.passed_time).format('YYYY-MM-DD HH:mm')}</span></div>
<div><span className={"color999"}>实战耗时</span> <span className={data&&data.efficiency===null?"color999":"color333"}>{data&&data.time_consuming===null?'--':data&&data.time_consuming}</span></div>
{/*<div><span className={"color999"}>实战耗时:</span> <span className={data&&data.efficiency===null?"color999":"color333"}>{data&&data.time_consuming===null?'--':data&&data.time_consuming}</span></div>*/}
</span>
</p>

@ -2671,14 +2671,14 @@ class Trainingjobsetting extends Component {
className="ml15 font-14" style={{textAlign: "left", color: "#FF8204"}}>(总分值 = 效率分+ 关卡任务总分)</span>
</div>
<div className="yslflexhome">
<div style={{width: "700px"}}>
<div className="yslflexhomes mt9" style={{width: "802px", lineHeight: "35px", marginLeft: "114px"}}>
<div >
<div className="yslflexhomes mt9" style={{width: "1000px", lineHeight: "35px", marginLeft: "114px"}}>
<div className=" clearfix edu-back-white poll_list mt10">
<Checkbox disabled={!flagPageEdit} className=" font-16 mt10"
onChange={this.onChangeeffectiveness}
checked={this.state.work_efficiencys} style={{color: "#666666"}}>效率分<span
className={"font-14 color-grey-c font-16 ml15"}
style={{textAlign: "left"}}>(选中则学生最终成绩包含效率分)</span>
className={"font-13 color-grey-c ml15"}
style={{textAlign: "left"}}>(选中则学生最终成绩包含效率分效率分在作业截止或者补交结束后由系统自动生成)</span>
</Checkbox>
<div>
@ -2686,7 +2686,7 @@ class Trainingjobsetting extends Component {
</div>
<div>
<div className="yslflexhomes invite-tipysl">
<div className="yslflexhomes invite-tipysl" style={{width: "399px"}}>
<span className="to-back-left"></span>
<div className="padding20 invitecontent clearfix" style={{backgroundColor: " #FAFAFA"}}>
<p className="font-12 edu-txt-left">

@ -66,7 +66,7 @@ class ConclusionEvaluation extends Component {
</span>
),
},{
title: '最终成绩',
title: '当前成绩',
dataIndex: 'grade',
key: 'grade',
render: (text, record) => (
@ -81,7 +81,7 @@ class ConclusionEvaluation extends Component {
</span>
),
}, {
title: '实战耗时',
title: '实战耗时',
key: 'elapsed',
dataIndex: 'elapsed',

@ -0,0 +1,127 @@
/*
* @Description: 知识点
* @Author: tangjiang
* @Github:
* @Date: 2019-12-30 13:51:19
* @LastEditors : tangjiang
* @LastEditTime : 2020-01-03 09:32:24
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
import { Select, notification } from 'antd';
const { Option } = Select;
function KnowLedge (props) {
const {
options = [], // 下拉选项
values = [], // 已选择的下拉项
onChange // 获取选择的值
} = props;
useEffect(() => {
const _options = [];
const _selects = [];
options.forEach(opt => {
if (!values.includes(opt.id)) {
_options.push(opt);
} else {
_selects.push(opt);
}
});
setSelectOptions(_options || []);
setSelectValue(_selects || []);
}, [props]);
// 显示的下拉项
const [selectOptions, setSelectOptions] = useState(options);
// 已选择的下拉项
const [selectValue, setSelectValue] = useState([]);
//
const [value] = useState([]);
// 渲染下拉选项
const renderOptions = (options = []) => {
return options.map((opt, i) => (
<Option key={`opt_${i}`} value={`${opt.id}`}>{opt.name}</Option>
));
}
// 过滤下拉列表项
const handleSelectChange = (value) => {
value = +value.join('');
const tempArr = [...selectValue];
const _result = selectOptions.filter(item => {
if (item.id === value && tempArr.findIndex(t => t.id === value) === -1) {
tempArr.push(item);
}
return item.id !== value;
});
if (tempArr.length > 50) {
notification.warning({
message: '提示',
description: '知识点不能超过50个'
});
return;
}
setSelectValue(tempArr);
setSelectOptions(_result);
// 将选择值返回
onChange && onChange(tempArr);
}
// 删除
const handleRemoveResult = (item) => {
// console.log('点击了删除按钮===>>>>', item);
// 将删除的值重新加入到列表中
const tempOptions = [...selectOptions];
const tempValue = selectValue.filter(t => t.id !== item.id);
// console.log(selectValue);
tempOptions.push(item);
setSelectOptions(tempOptions);
setSelectValue(tempValue);
// 将选择值返回
onChange && onChange(tempValue);
}
// 渲染下拉结果
const renderResult = (arrs) => {
return arrs.map((item) => (
<span className="knowledge-item" key={`item_${item.name}`}>
{item.name}
<span
onClick={() => handleRemoveResult(item)}
className="iconfont icon-roundclose knowledge-close"
></span>
</span>
));
}
// 渲染下拉列表
const renderSelect = (options = []) => {
// console.log('+++++', options);
// setSelectValue(_selects);
return (
<Select
value={value}
mode="tags"
placeholder="请选择"
style={{ width: '100%' }}
onChange={handleSelectChange}
>
{renderOptions(options)}
</Select>
)
}
return (
<div className="knowledge-select-area">
{ renderSelect(selectOptions) }
{/* 渲染下拉选择项 */}
<div className="knowledge-result">
{ renderResult(selectValue) }
</div>
</div>
);
}
export default KnowLedge;

@ -0,0 +1,42 @@
.knowledge-select-area{
.ant-select-selection__rendered{
margin-bottom: 0 !important;
}
.ant-select-search--inline{
margin-left: 5px;
margin-top: 2px;
}
.knowledge-result{
display: flex;
flex-direction: row;
flex-wrap: wrap;
// margin-top: 15px;
.knowledge-item{
position: relative;
border: 1px solid #DDDDDD;
border-radius: 3px;
padding: 10px;
background: #fff;
margin-right: 10px;
margin-top: 10px;
// margin-bottom: 10px;
.knowledge-close{
display: none;
position: absolute;
right: -10px;
top: -10px;
background-color: rgba(250,250,250,1);
cursor: pointer;
}
&:hover{
.knowledge-close{
display: block;
}
}
}
}
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 15:02:52
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 20:49:46
* @LastEditTime : 2020-01-02 13:59:38
*/
import './index.scss';
import React, { useState, useRef, useEffect } from 'react';

@ -35,6 +35,7 @@ const NewOrEditTask = (props) => {
getUserInfoForNew,
handleCancelPublish,
validateOjForm,
getQuestion
// updateTestAndValidate,
} = props;
@ -53,6 +54,10 @@ const NewOrEditTask = (props) => {
useEffect(() => {
// 获取用户信息
getUserInfoForNew();
// 获取课程列表
getQuestion({
source: 'question'
});
// console.log('获取路由参数: ====', props.match.params);
const id = props.match.params.id;
// 保存OJForm的id号指明是编辑还是新增
@ -273,7 +278,8 @@ const mapDispatchToProps = (dispatch) => ({
startProgramQuestion: (id, props) => dispatch(actions.startProgramQuestion(id, props)),
// 新建时获取信息
getUserInfoForNew: () => dispatch(actions.getUserInfoForNew()),
validateOjForm: (props, type, cb) => dispatch(actions.validateOjForm(props, type, cb))
validateOjForm: (props, type, cb) => dispatch(actions.validateOjForm(props, type, cb)),
getQuestion: (params) => dispatch(actions.getQuestion(params))
});
export default withRouter(connect(

@ -4,12 +4,12 @@
* @Github:
* @Date: 2019-11-20 10:35:40
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 14:30:55
* @LastEditTime : 2020-01-03 09:20:12
*/
import './index.scss';
// import 'katex/dist/katex.css';
import React from 'react';
import { Form, Input, Select, InputNumber, Button } from 'antd';
import { Form, Input, Select, InputNumber, Button, Cascader, notification } from 'antd';
import { connect } from 'react-redux';
import AddTestDemo from './AddTestDemo';
// import QuillEditor from '../../../quillEditor';
@ -18,6 +18,7 @@ import CONST from '../../../../../constants';
import { toStore } from 'educoder'; // 保存和读取store值
// import Wrapper from '../../../../../common/reactQuill';
import QuillForEditor from '../../../../../common/quillForEditor';
import KnowLedge from '../../../components/knowledge';
const scrollIntoView = require('scroll-into-view');
const {jcLabel} = CONST;
const FormItem = Form.Item;
@ -59,7 +60,9 @@ class EditTab extends React.Component {
scrollHeight: 0, // 滚动元素的高度
top: 500,
bottom: 20,
offsetTop: 0
offsetTop: 0,
// knowledges: [],
// coursers: [] // 选中的课程
}
}
@ -77,9 +80,17 @@ class EditTab extends React.Component {
}, () => {
this.state.scrollEl.addEventListener('scroll', this.handleScroll, false);
});
// 获取题库
// this.props.getQuestion({
// source: 'question'
// });
}
componentWillUnmount () {
// componentDidUpdate (nextProp) {
// console.log(nextProp);
// }
componentWillUnmount (nextPro) {
this.state.scrollEl.removeEventListener('scroll', this.handleScroll, false);
}
@ -125,9 +136,26 @@ class EditTab extends React.Component {
handleTimeLimitChange = (value) => {
this.props.validateOjTimeLimit(value);
}
// 改变分类
handleChangeCategory = (value) => {
this.props.validateOjCategory(value);
// 改变方向
handleChangeSubDisciplineId = (value) => {
// 课程下拉值变化时, 同步更新知识点
const { courseQuestions, saveKnowledge } = this.props;
saveKnowledge([]);
// 获取当前分类下的知识点
courseQuestions.forEach(item => {
if (value[0] && item.id === value[0]) {
item.sub_disciplines && item.sub_disciplines.forEach(c => {
if (value[1] && c.id === value[1]) {
saveKnowledge(c.tag_disciplines)
console.log(c.tag_disciplines);
} else if (!value[1]) {
saveKnowledge([]);
}
});
}
});
// this.props.validateOjCategory(value[1] || '');
this.props.validateOjSubDisciplineId(value[1] || '');
}
// 改变公开程序
handleChangeOpenOrNot = (value) => {
@ -146,13 +174,18 @@ class EditTab extends React.Component {
addTestCase, // 添加测试用例
deleteTestCase, // 删除测试用例
testCasesValidate,
openTestCodeIndex = []
openTestCodeIndex = [],
courseQuestions,
tag_discipline_id,
knowledges
} = this.props;
console.log('knowledge======>>>>>>', knowledges);
// const {knowledges} = this.state;
// 表单label
const myLabel = (name, subTitle) => {
const myLabel = (name, subTitle, nostar) => {
if (subTitle) {
return (
<span className={'label_text'}>
<span className={`label_text ${nostar}`}>
{name}
<span className={'label_sub_text'}>
({subTitle})
@ -161,7 +194,7 @@ class EditTab extends React.Component {
)
} else {
return (
<span className={'label_text'}>{name}</span>
<span className={`label_text ${nostar}`}>{name}</span>
)
}
};
@ -197,7 +230,14 @@ class EditTab extends React.Component {
};
// 添加测试用例
const handleAddTest = () => {
const {position} = this.props;
const {position, testCases = []} = this.props;
if (testCases.length >= 50) {
notification.warning({
message: '提示',
description: '测试用例不能超过50个'
});
return;
}
const obj = { // 测试用例参数
input: '',
output: '',
@ -235,16 +275,75 @@ class EditTab extends React.Component {
}
// 编辑器配置信息
const quillConfig = [
[{ header: [1, 2, 3, 4, 5, 6, false] }],
['bold', 'italic', 'underline', 'strike'], // 切换按钮
['blockquote', 'code-block'], // 代码块
[{align: []}, { 'list': 'ordered' }, { 'list': 'bullet' }], // 列表
[{ 'script': 'sub'}, { 'script': 'super' }],
[{ 'color': [] }, { 'background': [] }], // 字体颜色与背景色
['image', 'formula'], // 数学公式、图片、视频
['clean'], // 清除格式
{ header: 1}, {header: 2},
// {size: ['12px', '14px', '16px', '18px', '20px', false]},
'bold', 'italic', 'underline', 'strike', // 切换按钮
'blockquote', 'code-block', // 代码块
{align: []}, { 'list': 'ordered' }, { 'list': 'bullet' }, // 列表
{ 'script': 'sub'}, { 'script': 'super' },
{ 'color': [] }, { 'background': [] }, // 字体颜色与背景色
// {font: []},
'image', 'formula', // 数学公式、图片、视频
'clean', // 清除格式
];
const renderCourseQuestion = (arrs) => {
const tempArr = [];
const sub_id = this.props.ojForm.sub_discipline_id;
function loop (arrs, tempArr) {
arrs.forEach(item => {
const obj = {};
obj.value = item.id;
obj.label = item.name;
// 当item下还有子元素时递归调用
if (item.sub_disciplines) {
arrs = item.sub_disciplines;
obj.children = [];
loop(arrs, obj.children);
}
tempArr.push(obj);
});
}
loop(arrs, tempArr);
// 获取选中的下拉值
let choid_ids = [];
// let tempKnowledges = [];
tempArr.forEach(t => {
// debugger;
if (sub_id && t.children) {
t.children.forEach(c => {
if (c.value === sub_id) {
choid_ids = [t.value, c.value];
// tempKnowledges = c.children || [];
}
});
}
});
console.log(choid_ids);
return (
<Cascader
options={tempArr}
expandTrigger="hover"
value={choid_ids}
// onChange={this.handleChangeCategory}
onChange={this.handleChangeSubDisciplineId}
/>
)
}
// 知识点
const handleKnowledgeChange = (values= []) => {
const _result = [];
values.forEach(v => {
_result.push(v.id);
});
console.log('下拉选择的值:===>>>', _result);
// 保存选择的知识点
this.props.saveTagDisciplineId(_result);
}
return (
<div className={'editor_area'} id="textCase">
<Form className={'editor_form'}>
@ -262,14 +361,32 @@ class EditTab extends React.Component {
<FormItem
className={`input_area flex_50 flex_50_right`}
label={<span>{myLabel(jcLabel['category'], '合理的分类有利于快速检索')}</span>}
validateStatus={ojFormValidate.category.validateStatus}
help={ojFormValidate.category.errMsg}
label={<span>{myLabel(jcLabel['sub_discipline_id'], '合理的课程分类有利于快速检索')}</span>}
validateStatus={ojFormValidate.sub_discipline_id.validateStatus}
help={ojFormValidate.sub_discipline_id.errMsg}
colon={ false }
>
<Select onChange={this.handleChangeCategory} value={`${ojForm.category}`}>
{/* <Select onChange={this.handleChangeCategory} value={`${ojForm.category}`}>
{getOptions('category')}
</Select>
</Select> */}
{/* <Cascader
options={courseQuestions}
expandTrigger="hover"
onChange={this.handleChangeCategory}
/> */}
{ renderCourseQuestion(courseQuestions)}
</FormItem>
<FormItem
colon={ false }
className='input_area flex_100'
label={<span>{myLabel(jcLabel['knowledge'], '', 'nostar')}</span>}
>
<KnowLedge
options={knowledges}
values={tag_discipline_id}
onChange={handleKnowledgeChange}
/>
</FormItem>
<FormItem
@ -317,7 +434,6 @@ class EditTab extends React.Component {
help={ojFormValidate.description.errMsg}
colon={ false }
>
<div style={{ marginTop: '15px'}}>
<QuillForEditor
style={{ height: '200px' }}
placeholder="请输入描述信息"
@ -325,8 +441,6 @@ class EditTab extends React.Component {
options={quillConfig}
value={ojForm.description}
/>
</div>
</FormItem>
{/* <FormItem
@ -366,14 +480,21 @@ const mapStateToProps = (state) => {
testCases,
openTestCodeIndex,
testCasesValidate,
ojFormValidate} = ojFormReducer;
ojFormValidate,
courseQuestions,
tag_discipline_id,
knowledges
} = ojFormReducer;
return {
ojForm,
testCases,
testCasesValidate,
ojFormValidate,
position,
openTestCodeIndex
openTestCodeIndex,
courseQuestions,
tag_discipline_id,
knowledges
};
};
@ -386,10 +507,15 @@ const mapDispatchToProps = (dispatch) => ({
validateOjTimeLimit: (value) => dispatch(actions.validateOjTimeLimit(value)),
validateOjCategory: (value) => dispatch(actions.validateOjCategory(value)),
validateOpenOrNot: (value) => dispatch(actions.validateOpenOrNot(value)),
validateOjSubDisciplineId: (value) => dispatch(actions.validateOjSubDisciplineId(value)),
saveTagDisciplineId: (value) => dispatch(actions.saveTagDisciplineId(value)),
// 新增测试用例
addTestCase: (value) => dispatch(actions.addTestCase(value)),
// 删除测试用例
deleteTestCase: (value) => dispatch(actions.deleteTestCase(value)),
saveKnowledge: (value) => dispatch(actions.saveKnowledge(value))
// 获取题库
// getQuestion: (params) => dispatch(actions.getQuestion(params))
});
export default connect(

@ -18,6 +18,12 @@
line-height: 1;
content: '*';
}
&.nostar{
&::before {
content: ''
}
}
}
.input_area{
display: inline-block;

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-04 08:36:21
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 21:18:39
* @LastEditTime : 2020-01-02 13:48:02
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
@ -57,7 +57,9 @@ function RecordDetail (props) {
const handleReturn = (identifier) => {
if (identifier) {
saveEditorCodeForDetail('');
setTimeout(() => {
props.history.push(`/myproblems/${identifier}`);
}, 300);
}
}

@ -23,6 +23,8 @@
}
.header_title{
font-size: 16px;
font-weight: bold;
text-align: center;
}
@ -82,6 +84,8 @@
bottom: 0;
top: 0;
text-align: center;
font-size: 16px;
font-weight: bold;
}
}
}
@ -158,6 +162,22 @@
-moz-background-clip: padding;
-webkit-background-clip: padding;
background-clip: padding-box;
// &::before{
// position: absolute;
// width: 24px;
// height: 24px;
// border-radius: 50%;
// margin-top: -12px;
// top: 50%;
// right: -12px;
// font-family: 'iconfont';
// background: gold;
// content: '\e711';
// font-size: 18px;
// text-align: center;
// line-height: 24px;
// }
}
.Resizer:hover {

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-23 11:33:41
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 16:03:04
* @LastEditTime : 2020-01-02 13:51:22
// */
import './index.scss';
import React, { useState, useEffect, useMemo } from 'react';
@ -51,8 +51,6 @@ const LeftPane = (props) => {
comment: (<Comment />)
};
console.log('======>>>>>>>', props);
useEffect(() => {
setDefaultActiveKey(userCodeTab);
}, [userCodeTab])

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 14:59:51
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 19:23:46
* @LastEditTime : 2020-01-02 14:23:43
*/
import React, { useState, useEffect } from 'react';
import {connect} from 'react-redux';
@ -39,7 +39,7 @@ const RightPane = (props) => {
changeLoadingState
} = props;
const [editorCode, setEditorCode] = useState(editor_code || hack.code);
// const [editorCode, setEditorCode] = useState(editor_code || hack.code);
const [noteClazz, setNoteClazz] = useState('editor_nodte_area');
const [noteCount] = useState(5000);
// const [code, setCode] = useState(editor_code || hack.code);
@ -65,8 +65,9 @@ const RightPane = (props) => {
let timer = null; // 定时器
// 代码块内容变化时
const handleCodeChange = (value) => {
// console.log('编辑器代码 ======》》》》》》》》》++++++++++', value);
saveUserInputCode(value);
setEditorCode(value);
// setEditorCode(value);
if (!timer) {
timer = setInterval(function () {
clearInterval(timer);
@ -116,6 +117,7 @@ const RightPane = (props) => {
const { getFieldDecorator } = props.form;
return (
<div className={'right_pane_code_wrap'}>
<MyMonacoEditor
notice={notice}
identifier={identifier}

@ -510,7 +510,7 @@ class DetailCards extends Component{
{this.props.current_user&&this.props.current_user.admin===true||this.props.current_user&&this.props.current_user.business===true?
item.shixuns_list && item.shixuns_list.map((line,index)=>{
return(
<div className="clearfix paragraph lineh-30" onMouseEnter={()=>this.showparagraph(key,index)} onMouseLeave={this.hideparagraph}>
<div className="clearfix paragraph lineh-30" onMouseEnter>
<li className="fl li-width63">

@ -17,7 +17,7 @@ import NoneData from './component/NoneData';
import './questioncss/questioncom.css';
import '../tpm/newshixuns/css/Newshixuns.css';
import Paperreview_single from './Paperreview_single';
import {DragDropContext,Draggable, Droppable} from 'react-beautiful-dnd';
import {DragDropContext, Draggable, Droppable} from 'react-beautiful-dnd';
import PaperDeletModel from './component/PaperDeletModel';
import PaperDeletModels from './component/PaperDeletModels';
import Paperreview_itemModel from './component/Paperreview_itemModel';
@ -36,14 +36,19 @@ class Paperreview_item extends Component {
super(props);
this.state = {
questions:0,
totalscore:0,
total:0,
modalsTypedel:false,
modalsTypey:false,
modalsTypedels:false,
titilesm:"",
titilesms:"",
questions: 0,
totalscore: 0,
total: 0,
modalsTypedel: false,
modalsTypey: false,
modalsTypedels: false,
titilesm: "",
titilesms: "",
singlebool: false,
multiplebool: false,
judgmentbool: false,
programbool: false,
paperreviewsingleindex: "无"
}
}
@ -52,8 +57,6 @@ class Paperreview_item extends Component {
componentDidMount() {
}
@ -64,8 +67,6 @@ class Paperreview_item extends Component {
preservation = () => {
}
@ -73,14 +74,14 @@ class Paperreview_item extends Component {
}
onDragEnd=(result)=>{
onDragEnd = (result) => {
const ids=this.props.single_questions.questions[result.source.index].id;
const positions=this.props.single_questions.questions[result.destination.index].position;
const ids = this.props.single_questions.questions[result.source.index].id;
const positions = this.props.single_questions.questions[result.destination.index].position;
const url=`/item_baskets/${ids}/adjust_position.json`
var data={
position:positions
const url = `/item_baskets/${ids}/adjust_position.json`
var data = {
position: positions
}
axios.post(url, data)
.then((result) => {
@ -93,13 +94,13 @@ class Paperreview_item extends Component {
})
}
onDragEnds=(result)=>{
onDragEnds = (result) => {
const ids=this.props.multiple_questions.questions[result.source.index].id;
const positions=this.props.multiple_questions.questions[result.destination.index].position;
const url=`/item_baskets/${ids}/adjust_position.json`
var data={
position:positions
const ids = this.props.multiple_questions.questions[result.source.index].id;
const positions = this.props.multiple_questions.questions[result.destination.index].position;
const url = `/item_baskets/${ids}/adjust_position.json`
var data = {
position: positions
}
axios.post(url, data)
.then((result) => {
@ -115,12 +116,12 @@ class Paperreview_item extends Component {
}
onDragEndss=(result)=>{
const ids=this.props.judgement_questions.questions[result.source.index].id;
const positions=this.props.judgement_questions.questions[result.destination.index].position;
const url=`/item_baskets/${ids}/adjust_position.json`
var data={
position:positions
onDragEndss = (result) => {
const ids = this.props.judgement_questions.questions[result.source.index].id;
const positions = this.props.judgement_questions.questions[result.destination.index].position;
const url = `/item_baskets/${ids}/adjust_position.json`
var data = {
position: positions
}
axios.post(url, data)
.then((result) => {
@ -134,13 +135,13 @@ class Paperreview_item extends Component {
}
onDragEndsss=(result)=>{
onDragEndsss = (result) => {
const ids=this.props.judgement_questions.questions[result.source.index].id;
const positions=this.props.judgement_questions.questions[result.destination.index].position;
const url=`/item_baskets/${ids}/adjust_position.json`
var data={
position:positions
const ids = this.props.judgement_questions.questions[result.source.index].id;
const positions = this.props.judgement_questions.questions[result.destination.index].position;
const url = `/item_baskets/${ids}/adjust_position.json`
var data = {
position: positions
}
axios.post(url, data)
.then((result) => {
@ -153,27 +154,27 @@ class Paperreview_item extends Component {
})
}
Singlemagazine=(name,bool)=>{
if(bool===true){
Singlemagazine = (name, bool) => {
if (bool === true) {
this.setState({
modalsTypey:true,
titilesm:name
modalsTypey: true,
titilesm: name
})
}else {
} else {
this.setState({
modalsTypey:false,
titilesm:""
modalsTypey: false,
titilesm: ""
})
}
}
setDownloady=(fenshu)=>{
const url ="/item_baskets/batch_set_score.json";
var data ={
score:fenshu,
item_type:this.state.titilesm==="单选题"?"SINGLE":this.state.titilesm==="多选题"?"MULTIPLE":this.state.titilesm==="判断题"?"JUDGMENT":this.state.titilesm==="编程题"?"PROGRAM":'',
setDownloady = (fenshu) => {
const url = "/item_baskets/batch_set_score.json";
var data = {
score: fenshu,
item_type: this.state.titilesm === "单选题" ? "SINGLE" : this.state.titilesm === "多选题" ? "MULTIPLE" : this.state.titilesm === "判断题" ? "JUDGMENT" : this.state.titilesm === "编程题" ? "PROGRAM" : '',
}
axios.post(url, data)
@ -181,47 +182,49 @@ class Paperreview_item extends Component {
if (result.data.status == 0) {
this.props.showNotification(`调分成功`);
this.props.getdata({});
this.Singlemagazine("",false);
this.Singlemagazine("", false);
}
}).catch((error) => {
console.log(error);
})
}
setmodalsTypedel=(bool,type,names)=>{
if(type===1){
setmodalsTypedel = (bool, type, names) => {
if (type === 1) {
this.setState({
modalsTypedel:bool,
titilesms:names
modalsTypedel: bool,
titilesms: names
})
}else{
} else {
this.setState({
modalsTypedel:bool,
modalsTypedels:true,
titilesms:names
modalsTypedel: bool,
modalsTypedels: true,
titilesms: names
})
}
}
setmodalsTypedels=(bool,type)=>{
if(type===1){
setmodalsTypedels = (bool, type) => {
if (type === 1) {
this.setState({
modalsTypedels:bool,
titilesms:""
modalsTypedels: bool,
titilesms: ""
})
}else {
} else {
//确定
const url=`/item_baskets/delete_item_type.json`;
axios.delete((url), { data: {
item_type:this.state.titilesms
}})
const url = `/item_baskets/delete_item_type.json`;
axios.delete((url), {
data: {
item_type: this.state.titilesms
}
})
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('删除成功');
this.props.getdata({});
this.setState({
titilesms:""
titilesms: ""
})
}
})
@ -230,63 +233,150 @@ class Paperreview_item extends Component {
});
this.setState({
modalsTypedels:bool,
modalsTypedels: bool,
})
}
}
hideparagraph = (name) => {
console.log("hideparagraph");
}
hideparagraphs = () => {
this.setState({
singlebool: false,
multiplebool: false,
judgmentbool: false,
programbool: false,
})
}
showparagraph = (name) => {
console.log("showparagraph");
if (name === "SINGLE") {
this.setState({
singlebool: true,
multiplebool: false,
judgmentbool: false,
programbool: false,
})
} else if (name === "MULTIPLE") {
this.setState({
singlebool: false,
multiplebool: true,
judgmentbool: false,
programbool: false,
})
} else if (name === "JUDGMENT") {
this.setState({
singlebool: false,
multiplebool: false,
judgmentbool: true,
programbool: false,
})
} else if (name === "PROGRAM") {
this.setState({
singlebool: false,
multiplebool: false,
judgmentbool: false,
programbool: true,
})
}
}
jixuxuantioncli = () => {
this.props.history.replace("/question");
}
showparagraphs = (e) => {
console.log("showparagraphs");
console.log(e);
this.setState({
paperreviewsingleindex: e,
})
}
render() {
let {questions,totalscore,total,modalsTypedel,modalsTypey,modalsTypedels} = this.state;
let {single_questions,multiple_questions,judgement_questions,program_questions,all_score}=this.props;
let {
questions, totalscore, total, modalsTypedel, modalsTypey, modalsTypedels,
singlebool,
multiplebool,
judgmentbool,
programbool,
paperreviewsingleindex
} = this.state;
let {single_questions, multiple_questions, judgement_questions, program_questions, all_score} = this.props;
return (
<div className=" clearfix educontent Contentquestionbankstyle w100s w1200wuh mt19">
{
modalsTypedel===true?
<PaperDeletModel {...this.state} {...this.props} setmodalsTypedel={(bool,type,name)=>this.setmodalsTypedel(bool,type,name)}></PaperDeletModel>
:""
modalsTypedel === true ?
<PaperDeletModel {...this.state} {...this.props}
setmodalsTypedel={(bool, type, name) => this.setmodalsTypedel(bool, type, name)}></PaperDeletModel>
: ""
}
{
modalsTypey===true?
<Paperreview_itemModel {...this.state} {...this.props} setDownloady={(fs)=>this.setDownloady(fs)} Singlemagazine={(name,bool)=>this.Singlemagazine(name,bool)}></Paperreview_itemModel>
:""
modalsTypey === true ?
<Paperreview_itemModel {...this.state} {...this.props} setDownloady={(fs) => this.setDownloady(fs)}
Singlemagazine={(name, bool) => this.Singlemagazine(name, bool)}></Paperreview_itemModel>
: ""
}
{
modalsTypedels===true?
<PaperDeletModels {...this.state} {...this.props} setmodalsTypedels={(bool,type)=>this.setmodalsTypedels(bool,type)}></PaperDeletModels>
:""
modalsTypedels === true ?
<PaperDeletModels {...this.state} {...this.props}
setmodalsTypedels={(bool, type) => this.setmodalsTypedels(bool, type)}></PaperDeletModels>
: ""
}
<div className="w100s mt20 mb20 backgroudwhites" style={{
position:"relative",
position: "relative",
}}>
<div className="w100s sortinxdirection">
<p className="questionstishu">题数{this.props.all_score}</p>
<p className="ml58 questionstotal">总分{this.props.all_questions_count}</p>
<div className="w70s sortinxdirection">
<p className="questionstishu lh34">题数{this.props.all_score}</p>
<p className="ml58 questionstotal lh34">总分{this.props.all_questions_count}</p>
</div>
<div className="w30s xaxisreverseorder">
<div className="jixuxuanti xiaoshou" onClick={() => this.jixuxuantioncli()}>
继续选题
</div>
</div>
</div>
<div className="questiontypeheng w100s mt19 mb19"></div>
<div className="w100s sortinxdirection">
<div className="pagertdstcolor w50s sortinxdirection">拖动试题可调整排序</div>
<div className="pagertdstcolor w50s xaxisreverseorder">{single_questions&&single_questions.questions_count}个试题</div>
<div
className="pagertdstcolor w50s xaxisreverseorder">{single_questions && single_questions.questions_count}个试题
</div>
</div>
{/*单选题*/}
{
single_questions&&single_questions?
single_questions && single_questions ?
<div className="backgroudwhites" style={{
position: "relative",
}}>
<div className="w100s mt20 mb20 postitonrelati">
<div className="w100s sortinxdirection">
<p className="yldxtit">单选题</p> <p className="ml15 yldxtits">{single_questions&&single_questions.questions_count}{single_questions&&single_questions.questions_score}</p>
</div>
<div className="postitonrelatis xaxisreverseorder">
<div className="scd xiaoshou" onClick={()=>this.setmodalsTypedel(true,1,"SINGLE")}>删除</div>
<div className="szdfd xiaoshou" onClick={()=>this.Singlemagazine("单选题",true)} >设置得分</div>
<div
className={singlebool === true ? "w100s sortinxdirection borderwdswuhques intermediatecenterysls" : "w100s sortinxdirection intermediatecenterysls"}
onMouseEnter={() => this.showparagraph("SINGLE")} onMouseLeave={() => this.hideparagraph("SINGLE")}>
<p className={singlebool === true ? "ml18 yldxtit" : "yldxtit"}>单选题</p> <p
className="ml15 yldxtits">{single_questions && single_questions.questions_count}{single_questions && single_questions.questions_score}</p>
</div>
<DragDropContext onDragEnd={this.onDragEnd} >
{
singlebool === true ?
<div className="postitonrelatiss xaxisreverseorder">
<div className="scd xiaoshou" onClick={() => this.setmodalsTypedel(true, 1, "SINGLE")}>删除</div>
<div className="szdfd xiaoshou" onClick={() => this.Singlemagazine("单选题", true)}>批量设置得分</div>
</div> : ""
}
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId={"0"}>
{(provided, snapshot) => (
<div
@ -296,7 +386,7 @@ class Paperreview_item extends Component {
onScroll={this.contentViewScrolledit}
>
{
single_questions&&single_questions.questions.map((object, index) => {
single_questions && single_questions.questions.map((object, index) => {
return (
<Draggable
key={object.id}
@ -311,7 +401,18 @@ class Paperreview_item extends Component {
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<Paperreview_single objectsingle={object}></Paperreview_single>
<div className="xaxisreverseorder mt25 mr2">
<div className="scd xiaoshou">删除</div>
<div className="szdfd xiaoshou">设置得分</div>
</div>
<Paperreview_single paperreviewsingleindex={this.state.paperreviewsingleindex}
showparagraphs={(e) => this.showparagraphs(e)}
objectsingle={object} key={index} indexx={index + 1}
indexxy={index}
hideparagraphs={() => this.hideparagraphs()}></Paperreview_single>
</div>
)}
</Draggable>
@ -328,26 +429,39 @@ class Paperreview_item extends Component {
</div>
</div>
:""
: ""
}
{
multiple_questions&&multiple_questions?
multiple_questions && multiple_questions ?
<div className="backgroudwhites" style={{
position: "relative",
}}>
<div className="h20 lh20"></div>
<div className="w100s mb20 postitonrelati">
<div className="w100s sortinxdirection">
<p className="yldxtit">{single_questions===null?"一":"二"}多选题</p> <p className="ml15 yldxtits">{multiple_questions&&multiple_questions.questions_count}{multiple_questions&&multiple_questions.questions_score}</p>
<div
className={multiplebool === true ? "w100s sortinxdirection mt10 borderwdswuhques intermediatecenterysls" : "w100s sortinxdirection intermediatecenterysls"}
onMouseEnter={() => this.showparagraph("MULTIPLE")}
onMouseLeave={() => this.hideparagraph("MULTIPLE")}>
<p
className={multiplebool === true ? "ml18 yldxtit" : "yldxtit"}>{single_questions === null ? "一" : "二"}多选题</p>
<p
className="ml15 yldxtits">{multiple_questions && multiple_questions.questions_count}{multiple_questions && multiple_questions.questions_score}</p>
</div>
<div className="postitonrelatis xaxisreverseorder">
<div className="scd xiaoshou" onClick={()=>this.setmodalsTypedel(true,1,"MULTIPLE")}>删除</div>
<div className="szdfd xiaoshou" onClick={()=>this.Singlemagazine("多选题",true)}>设置得分</div>
{
multiplebool === true ?
<div className="postitonrelatisss xaxisreverseorder ">
<div className="scd xiaoshou" onClick={() => this.setmodalsTypedel(true, 1, "MULTIPLE")}>删除
</div>
<div className="szdfd xiaoshou" onClick={() => this.Singlemagazine("多选题", true)}>批量设置得分</div>
</div>
<DragDropContext onDragEnd={this.onDragEnds} >
: ""
}
<DragDropContext onDragEnd={this.onDragEnds}>
<Droppable droppableId={"0"}>
{(provided, snapshot) => (
<div
@ -357,7 +471,7 @@ class Paperreview_item extends Component {
onScroll={this.contentViewScrolledit}
>
{
multiple_questions&&multiple_questions.questions.map((object, index) => {
multiple_questions && multiple_questions.questions.map((object, index) => {
return (
<Draggable
key={object.id}
@ -372,7 +486,15 @@ class Paperreview_item extends Component {
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<Paperreview_single objectsingle={object}></Paperreview_single>
<div className="xaxisreverseorder mt25 mr2">
<div className="scd xiaoshou">删除</div>
<div className="szdfd xiaoshou">设置得分</div>
</div>
<Paperreview_single paperreviewsingleindex={this.state.paperreviewsingleindex}
objectsingle={object} key={index} indexx={index + 1}
indexxy={index}
hideparagraphs={() => this.hideparagraphs()}></Paperreview_single>
</div>
)}
</Draggable>
@ -393,23 +515,32 @@ class Paperreview_item extends Component {
}
{
judgement_questions&&judgement_questions?
<div className="backgroudwhites" style={{
judgement_questions && judgement_questions ?
<div className={judgmentbool === true ? "backgroudwhites " : "backgroudwhites"} style={{
position: "relative",
}}>
<div className="w100s mt20 mb20 postitonrelati">
<div className="w100s sortinxdirection">
<p className="yldxtit">{single_questions===null&&multiple_questions===null?"一":single_questions===null&&multiple_questions!==null?"二"
:single_questions!==null&&multiple_questions===null?"二"
:"三"}判断题</p> <p className="ml15 yldxtits">{judgement_questions&&judgement_questions.questions_count}{judgement_questions&&judgement_questions.questions_score}</p>
<div className="h20 lh20"></div>
<div className="w100s mb20 postitonrelati">
<div
className={judgmentbool === true ? "w100s sortinxdirection borderwdswuhques mt10 intermediatecenterysls " : "w100s sortinxdirection intermediatecenterysls "}
onMouseEnter={() => this.showparagraph("JUDGMENT")}
onMouseLeave={() => this.hideparagraph("JUDGMENT")}>
<p
className={judgmentbool === true ? "ml18 yldxtit" : "yldxtit"}>{single_questions === null && multiple_questions === null ? "一" : single_questions === null && multiple_questions !== null ? "二"
: single_questions !== null && multiple_questions === null ? "二"
: "三"}判断题</p> <p
className="ml15 yldxtits">{judgement_questions && judgement_questions.questions_count}{judgement_questions && judgement_questions.questions_score}</p>
</div>
{
judgmentbool === true ?
<div className="postitonrelatiss xaxisreverseorder">
<div className="scd xiaoshou" onClick={() => this.setmodalsTypedel(true, 1, "JUDGMENT")}>删除
</div>
<div className="postitonrelatis xaxisreverseorder">
<div className="scd xiaoshou" onClick={()=>this.setmodalsTypedel(true,1,"JUDGMENT")}>删除</div>
<div className="szdfd xiaoshou" onClick={()=>this.Singlemagazine("判断题",true)}>设置得分</div>
<div className="szdfd xiaoshou" onClick={() => this.Singlemagazine("判断题", true)}>批量设置得分</div>
</div>
: ""}
<DragDropContext onDragEnd={this.onDragEndss} >
<DragDropContext onDragEnd={this.onDragEndss}>
<Droppable droppableId={"0"}>
{(provided, snapshot) => (
<div
@ -419,7 +550,7 @@ class Paperreview_item extends Component {
onScroll={this.contentViewScrolledit}
>
{
judgement_questions&&judgement_questions.questions.map((object, index) => {
judgement_questions && judgement_questions.questions.map((object, index) => {
return (
<Draggable
key={object.id}
@ -434,7 +565,15 @@ class Paperreview_item extends Component {
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<Paperreview_single objectsingle={object}></Paperreview_single>
<div className="xaxisreverseorder mt25 mr2">
<div className="scd xiaoshou">删除</div>
<div className="szdfd xiaoshou">设置得分</div>
</div>
<Paperreview_single paperreviewsingleindex={this.state.paperreviewsingleindex}
objectsingle={object} key={index} indexx={index + 1}
indexxy={index}
hideparagraphs={() => this.hideparagraphs()}></Paperreview_single>
</div>
)}
</Draggable>
@ -448,34 +587,44 @@ class Paperreview_item extends Component {
</DragDropContext>
</div>
</div>
:""
: ""
}
{
program_questions&&program_questions?
<div className="backgroudwhites" style={{
program_questions && program_questions ?
<div className={programbool === true ? "backgroudwhites " : "backgroudwhites"} style={{
position: "relative",
}}>
<div className="w100s mt20 mb20 postitonrelati">
<div className="w100s sortinxdirection">
<p className="yldxtit">
{single_questions===null&&multiple_questions===null&&program_questions===null?"一"
:single_questions===null&&multiple_questions===null&&program_questions!==null?"二"
:single_questions!==null&&multiple_questions===null&&program_questions===null?"二"
:single_questions===null&&multiple_questions!==null&&program_questions===null?"二"
:single_questions!==null&&multiple_questions!==null&&program_questions===null?"三"
:single_questions===null&&multiple_questions!==null&&program_questions!==null?"三"
:single_questions!==null&&multiple_questions==null&&program_questions!==null?"三":
<div className="h20 lh20"></div>
<div className="w100s mb20 postitonrelati">
<div
className={programbool === true ? "w100s sortinxdirection mt10 borderwdswuhques intermediatecenterysls " : "w100s sortinxdirection intermediatecenterysls"}
onMouseEnter={() => this.showparagraph("PROGRAM")}
onMouseLeave={() => this.hideparagraph("PROGRAM")}>
<p className={programbool === true ? "ml18 yldxtit" : "yldxtit"}>
{single_questions === null && multiple_questions === null && program_questions === null ? "一"
: single_questions === null && multiple_questions === null && program_questions !== null ? "二"
: single_questions !== null && multiple_questions === null && program_questions === null ? "二"
: single_questions === null && multiple_questions !== null && program_questions === null ? "二"
: single_questions !== null && multiple_questions !== null && program_questions === null ? "三"
: single_questions === null && multiple_questions !== null && program_questions !== null ? "三"
: single_questions !== null && multiple_questions == null && program_questions !== null ? "三" :
"四"}
编程题</p> <p className="ml15 yldxtits">{program_questions&&program_questions.questions_count}{program_questions&&program_questions.questions_score}</p>
编程题</p> <p
className="ml15 yldxtits">{program_questions && program_questions.questions_count}{program_questions && program_questions.questions_score}</p>
</div>
<div className="postitonrelatis xaxisreverseorder">
<div className="scd xiaoshou" onClick={()=>this.setmodalsTypedel(true,1,"PROGRAM")}>删除</div>
<div className="szdfd xiaoshou" onClick={()=>this.Singlemagazine("编程题",true)}>设置得分</div>
{
programbool === true ?
<div className="postitonrelatiss xaxisreverseorder">
<div className="scd xiaoshou" onClick={() => this.setmodalsTypedel(true, 1, "PROGRAM")}>删除</div>
<div className="szdfd xiaoshou" onClick={() => this.Singlemagazine("编程题", true)}>批量设置得分</div>
</div>
<DragDropContext onDragEnd={this.onDragEndsss} >
: ""
}
<DragDropContext onDragEnd={this.onDragEndsss}>
<Droppable droppableId={"0"}>
{(provided, snapshot) => (
<div
@ -485,7 +634,7 @@ class Paperreview_item extends Component {
onScroll={this.contentViewScrolledit}
>
{
program_questions&&program_questions.questions.map((object, index) => {
program_questions && program_questions.questions.map((object, index) => {
return (
<Draggable
key={object.id}
@ -500,7 +649,15 @@ class Paperreview_item extends Component {
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<Paperreview_single objectsingle={object}></Paperreview_single>
<div className="xaxisreverseorder mt25 mr2">
<div className="scd xiaoshou">删除</div>
<div className="szdfd xiaoshou">设置得分</div>
</div>
<Paperreview_single paperreviewsingleindex={this.state.paperreviewsingleindex}
objectsingle={object} key={index} indexx={index + 1}
indexxy={index}
hideparagraphs={() => this.hideparagraphs()}></Paperreview_single>
</div>
)}
</Draggable>

@ -1,6 +1,6 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn, getImageUrl,markdownToHTML} from 'educoder';
import {WordsBtn, ActionBtn, getImageUrl, markdownToHTML} from 'educoder';
import axios from 'axios';
import {
notification,
@ -17,21 +17,22 @@ import Itembankstop from "./component/Itembankstop";
import NoneData from './component/NoneData';
import './questioncss/questioncom.css';
import '../tpm/newshixuns/css/Newshixuns.css';
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
//单选题
class Paperreview_single extends Component {
constructor(props) {
super(props);
this.state = {
questions:0,
totalscore:0,
total:0,
questions: 0,
totalscore: 0,
total: 0,
}
}
@ -40,8 +41,6 @@ class Paperreview_single extends Component {
componentDidMount() {
}
@ -52,34 +51,40 @@ class Paperreview_single extends Component {
preservation = () => {
}
setitem_type = (item_type) => {
}
showparagraph = (indexx) => {
setitem_type = (item_type) => {
}
setmodalsTypedels = () => {
}
Singlemagaziness = () => {
}
render() {
let {questions,totalscore,total,items} = this.state;
let {objectsingle} =this.props;
// //console.log(params);
const objectsingleid=objectsingle.id;
const objectsinglescore=`${objectsingle.score}分)`;
let {questions, totalscore, total, items} = this.state;
let {objectsingle, indexx, paperreviewsingleindex, indexxy} = this.props;
return (
<div className="w100s borderwdswuh mt25 mb20 pd20 " style={{
<div key={indexxy}
className={ "w100s borderwdswuh mb20 pd20 "}
onMouseEnter={() => this.props.showparagraphs(indexxy)} style={{
minHeight: "114px",
}}>
{/*顶部*/}
<div className="w100s sortinxdirection ">
{/*<div className=" sortinxdirection ">*/}
{/* <p className="cretitlecolrlis lh28">{objectsingleid}</p>、<p className="cretitlecolrlisobj lh28">{objectsinglescore}分)</p>*/}
{/*</div>*/}
<div className=" sortinxdirection ">
<p className="cretitlecolrlis lh28">{indexx}</p>
</div>
<style>
{
`
@ -98,7 +103,8 @@ class Paperreview_single extends Component {
`
}
</style>
<div className=" lh28 listjihetixingstit markdown-body cretitlecolrlist" style={{wordBreak: "break-word"}} dangerouslySetInnerHTML={{__html: markdownToHTML(objectsingleid+objectsinglescore+objectsingle.name).replace(/▁/g, "▁▁▁")}}>
<div className=" lh28 listjihetixingstit markdown-body cretitlecolrlist" style={{wordBreak: "break-word"}}
dangerouslySetInnerHTML={{__html: markdownToHTML(`${objectsingle.score}分) ` + objectsingle.name).replace(/▁/g, "▁▁▁")}}>
</div>
</div>
{/*内容*/}
@ -106,12 +112,12 @@ class Paperreview_single extends Component {
{
objectsingle.item_type==="JUDGMENT"?
objectsingle.item_type === "JUDGMENT" ?
<p className="w100s listjihetixingstits sortinxdirection ">
{
objectsingle === undefined ||objectsingle === null? "" : objectsingle.choices.map((object, index) => {
objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => {
return (
<p className={index===1? "sortinxdirection ml10":"sortinxdirection " } >
<p className={index === 1 ? "sortinxdirection ml10" : "sortinxdirection "}>
<Radio checked={object.is_answer}>
{object.choice_text}
</Radio>
@ -121,20 +127,22 @@ class Paperreview_single extends Component {
}
</p>
:
objectsingle.item_type==="PROGRAM"?
objectsingle.item_type === "PROGRAM" ?
<p className="w100s listjihetixingstitssy sortinxdirection ">
<p className={"sortinxdirection mt15"} >
<p style={{wordBreak: "break-word"}} dangerouslySetInnerHTML={{__html: markdownToHTML(objectsingle.program_attr.description).replace(/▁/g, "▁▁▁")}}></p>
<p className={"sortinxdirection mt15"}>
<p style={{wordBreak: "break-word"}}
dangerouslySetInnerHTML={{__html: markdownToHTML(objectsingle.program_attr.description).replace(/▁/g, "▁▁▁")}}></p>
</p>
</p>
:
<p className="w100s listjihetixingstits verticallayout ">
{
objectsingle === undefined ||objectsingle === null? "" : objectsingle.choices.map((object, index) => {
objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => {
return (
<p className={index===0?"sortinxdirection":"sortinxdirection mt15"} >
<p className={index === 0 ? "sortinxdirection" : "sortinxdirection mt15"}>
{tagArray[index]}
<p style={{wordBreak: "break-word"}} dangerouslySetInnerHTML={{__html: markdownToHTML(object.choice_text).replace(/▁/g, "▁▁▁")}}></p>
<p style={{wordBreak: "break-word"}}
dangerouslySetInnerHTML={{__html: markdownToHTML(object.choice_text).replace(/▁/g, "▁▁▁")}}></p>
</p>
)
})
@ -146,8 +154,6 @@ class Paperreview_single extends Component {
</div>
</div>
)

@ -688,26 +688,44 @@
right: 2px;
top: 11px;
}
.postitonrelatiss{
position: absolute;
right: 2px;
top: -41px;
}
.postitonrelatisss{
position: absolute;
right: 2px;
top: -39px;
}
.postitonrelatisssy{
position: absolute;
right: 1px;
top: 52px;
}
.mt50{
margin-top: 50px;
}
.szdfd{
width:88px;
height:34px;
width:100px;
height:40px;
background:rgba(51,189,140,1);
border-radius:4px 4px 0px 0px;
text-align: center;
color: #ffffff;
line-height: 32px;
line-height: 40px;
margin-right: 27px;
font-size:12px;
}
.scd{
width:88px;
height:34px;
width:100px;
height:40px;
background:#4CACFF;
border-radius:4px 4px 0px 0px;
text-align: center;
color: #ffffff;
line-height: 32px;
line-height: 40px;
font-size:12px;
}
@ -757,3 +775,35 @@
.mt7{
margin-top: 7px;
}
.ml18{
margin-left: 18px;
}
.btques{
width:1021px;
background:rgba(249,249,249,1);
border:1px solid rgba(221,221,221,1);
}
.borderwdswuhques {
width: 1020px !important;
background: #F9F9F9;
border: 1px solid #DDDDDD;
min-height: 42px;
}
.jixuxuanti{
width:106px;
height:34px;
background:rgba(51,189,140,1);
border-radius:4px;
color:#ffffff ;
line-height: 34px;
text-align: center;
}
.lh34{
line-height: 34px;
}
.mr2{
margin-right: 2px;
}

@ -160,7 +160,7 @@
.newyslusercjz{
display: inline-block;
position: absolute;
bottom: 0px;
bottom: 10px;
left: -18px;
width: 44px;
height: 18px;

@ -18,7 +18,9 @@ const types = {
VALIDATE_OJ_DIFFICULT: 'VALIDATE_OJ_DIFFICULT', // 难易度
VALIDATE_OJ_TIMELIMIT: 'VALIDATE_OJ_TIMELIMIT', // 时间限制
VALIDATE_OJ_CATEGORY: 'VALIDATE_OJ_CATEGORY', // 分类
VALIDATE_OJ_SUB_DISCIPLINE_ID: 'VALIDATE_OJ_SUB_DISCIPLINE_ID', // 方向
VALIDATE_OJ_OPENORNOT: 'VALIDATE_OJ_OPENORNOT', // 公开程序
SAVE_TAG_DISCIPLINE_ID: 'SAVE_TAG_DISCIPLINE_ID', // 保存知识点
SAVE_OJ_FORM: 'SAVE_OJ_FORM', // 保存表单
ADD_TEST_CASE: 'ADD_TEST_CASE', // 添加测试用例
DELETE_TEST_CASE: 'DELETE_TEST_CASE', // 删除测试用例
@ -32,6 +34,9 @@ const types = {
TEST_CASE_INPUT_CHANGE: 'TEST_CASE_INPUT_CHANGE', // 测试用例输入值改变时
TEST_CASE_OUTPUT_CHANGE: 'TEST_CASE_OUTPUT_CHANGE', // 测试用例输出值改变时
DEBUGGER_CODE: 'DEBUGGER_CODE', // 调试代码
GET_COURSE_QUESTION: 'GET_COURSE_QUESTION', // 获取编辑题
CHANGE_KNOWLEDGES: 'CHANGE_KNOWLEDGES', // 保存所选择的知识点
// study
SAVE_USER_PROGRAM_ID: 'SAVE_USER_PROGRAM_ID',// 保存用户编程题id值
USER_PROGRAM_DETAIL: 'USER_PROGRAM_DETAIL', // 用户编程题详情
SHOW_OR_HIDE_CONTROL: 'SHOW_OR_HIDE_CONTROL', // 显示或隐藏控制台

@ -25,6 +25,8 @@ import {
validateOjTimeLimit,
validateOjCategory,
validateOpenOrNot,
validateOjSubDisciplineId,
saveTagDisciplineId,
addTestCase,
deleteTestCase,
testCaseInputChange,
@ -32,6 +34,8 @@ import {
updateTestAndValidate,
updateOpenTestCaseIndex,
handleClickCancelPublish,
getQuestion,
saveKnowledge
} from './ojForm';
import {
@ -109,7 +113,12 @@ export default {
validateOjTimeLimit,
validateOjCategory,
validateOpenOrNot,
validateOjSubDisciplineId,
saveTagDisciplineId,
handleClickCancelPublish,
getQuestion,
saveKnowledge,
//
addTestCase,
deleteTestCase,
testCaseInputChange,

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 13:42:11
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 11:06:09
* @LastEditTime : 2020-01-02 14:17:49
*/
import types from "./actionTypes";
import { Base64 } from 'js-base64';
@ -116,16 +116,15 @@ export const saveUserCodeForInterval = (identifier, code) => {
});
// console.log('+++', userCode);
fetchUpdateCode(identifier, {
code: userCode
code: Base64.encode(userCode)
}).then(res => {
if (res.data.status === 401) {
return;
};
dispatch({
type: types.RESTORE_INITIAL_CODE,
payload: userCode
});
// dispatch({
// type: types.RESTORE_INITIAL_CODE,
// payload: userCode
// });
setTimeout(() => {
dispatch({
type: types.AUTO_UPDATE_CODE,
@ -342,7 +341,7 @@ export const getUserCommitRecord = (identifier) => {
export const getUserCommitRecordDetail = (identifier) => {
return (dispatch) => {
fetchUserCommitRecordDetail(identifier).then(res => {
console.log('提交记录详情======》》》》', res);
// console.log('提交记录详情======》》》》', res);
const { data } = res;
if (data.status === 401) return;
dispatch({

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-20 16:35:46
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 22:19:15
* @LastEditTime : 2020-01-02 17:38:12
*/
import types from './actionTypes';
import CONST from '../../constants';
@ -12,7 +12,8 @@ import {
fetchPostOjForm,
fetchGetOjById,
publishTask,
cancelPublicTask
cancelPublicTask,
fetchQuestion
} from '../../services/ojService';
import { Base64 } from 'js-base64';
import { notification } from 'antd';
@ -45,6 +46,10 @@ const maps = {
label: jcLabel['category'],
type: types.VALIDATE_OJ_CATEGORY
},
sub_discipline_id: {
label: jcLabel['sub_discipline_id'],
type: types.VALIDATE_OJ_SUB_DISCIPLINE_ID
},
openOrNot: {
label: jcLabel['openOrNot'],
type: types.VALIDATE_OJ_OPENORNOT
@ -105,10 +110,12 @@ export const validateOjForm = (props, type, cb) => {
const {ojForm, testCases, identifier, code } = getState().ojFormReducer;
// console.log('code', code);
/** 表单验证开始 */
let keys = Object.keys(ojForm);
// let keys = Object.keys(ojForm).filter(k => k !== '');
let keys = Object.keys(ojForm)
// 循环判断每个字段是否为空
let hasSuccess = true;
keys.forEach(key => {
if (!['category'].includes(key)) {
const value = ojForm[key];
const validateResult = emptyValidate(key, value);
const errMsg = validateResult[key].errMsg;
@ -121,6 +128,7 @@ export const validateOjForm = (props, type, cb) => {
}
)
}
}
});
// 验证测试用例中的数组是否都有对应的值
const tcValidResult = [];
@ -197,8 +205,8 @@ export const validateOjForm = (props, type, cb) => {
if (hasSuccess) {
// console.log('表单保存的数据为: ', getState());
const {ojFormReducer} = getState();
const {code, score, ojForm, testCases = []} = ojFormReducer;
const {category, description, difficult, language, name, openOrNot, timeLimit} = ojForm;
const {code, score, ojForm, testCases = [], tag_discipline_id = []} = ojFormReducer;
const {category, description, difficult, language, name, openOrNot, timeLimit, sub_discipline_id} = ojForm;
let paramsObj = {};
const hack = { // 编程题干
name,
@ -207,6 +215,8 @@ export const validateOjForm = (props, type, cb) => {
category,
'open_or_not': openOrNot,
'time_limit': timeLimit,
sub_discipline_id,
// tag_discipline_id,
score
};
@ -223,7 +233,8 @@ export const validateOjForm = (props, type, cb) => {
paramsObj['params'] = {
hack,
hack_sets: tempTc,
hack_codes
hack_codes,
tags: tag_discipline_id
}
paramsObj['submitType'] = 'add';
} else { // 存在时调用更新接口
@ -242,7 +253,8 @@ export const validateOjForm = (props, type, cb) => {
hack,
hack_sets,
hack_codes,
update_hack_sets
update_hack_sets,
tags: tag_discipline_id
}
paramsObj['submitType'] = 'update';
paramsObj['identifier'] = identifier;
@ -483,6 +495,15 @@ export const validateOjCategory = (value) => {
payload: payloadInfo('category', value, errMsg, validate)
}
};
// 验证方向
export const validateOjSubDisciplineId = (value) => {
const validate = emptyValidate('sub_discipline_id', value)['sub_discipline_id'];
const errMsg = validate.errMsg;
return {
type: types.VALIDATE_OJ_SUB_DISCIPLINE_ID,
payload: payloadInfo('sub_discipline_id', value, errMsg, validate)
}
};
// 验证公开程序
export const validateOpenOrNot = (value) => {
const validate = emptyValidate('openOrNot', value)['openOrNot'];
@ -492,6 +513,14 @@ export const validateOpenOrNot = (value) => {
payload: payloadInfo('openOrNot', value, errMsg, validate)
}
};
// 保存知识点
export const saveTagDisciplineId = (value) => {
// console.log('====????????????', value);
return {
type: types.SAVE_TAG_DISCIPLINE_ID,
payload: value
};
}
// 新增测试用例
export const addTestCase = (obj) => {
return {
@ -622,7 +651,6 @@ export const testCaseOutputChange = (value, index) => {
// // 调试代码时,更改对应的状态值
// export const changeTestCodeStatus = () => {
// 更新测试用命及验证
export const updateTestAndValidate = (obj) => {
return (dispatch) => {
@ -644,3 +672,25 @@ export const updateOpenTestCaseIndex = (value) => {
payload: value
}
}
// 获取课程题库
export const getQuestion = (params) => {
return (dispatch) => {
fetchQuestion(params).then(res => {
const { data = {} } = res;
const { disciplines = [] } = data;
dispatch({
type: types.GET_COURSE_QUESTION,
payload: disciplines
})
})
}
}
// 保存所选择的知识点
export const saveKnowledge = (values) => {
return {
type: types.CHANGE_KNOWLEDGES,
payload: values
}
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 13:41:48
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 21:28:28
* @LastEditTime : 2020-01-02 14:24:09
*/
import types from "../actions/actionTypes";
import { Base64 } from 'js-base64';
@ -94,10 +94,11 @@ const ojForUserReducer = (state = initialState, action) => {
pages: Object.assign({}, state.pages, { total: records_count })
}
case types.SAVE_USER_CODE:
let curCode = Base64.encode(action.payload);
// console.log('save_user_code: ', action.payload);
// let curCode = Base64.encode(action.payload);
return {
...state,
userCode: curCode,
userCode: action.payload,
isUpdateCode: true,
}
case types.IS_UPDATE_CODE:
@ -136,7 +137,6 @@ const ojForUserReducer = (state = initialState, action) => {
} else {
curHack['code'] = '';
}
console.log(curHack);
return {
...state,
hack: Object.assign({}, state.hack, curHack),

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-20 16:40:32
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 20:00:26
* @LastEditTime : 2020-01-02 17:36:40
*/
import { Base64 } from 'js-base64';
import types from '../actions/actionTypes';
@ -15,10 +15,12 @@ const init = {
language: '',
description: '',
difficult: '',
category: '',
sub_discipline_id: '', // 方向
// category: '',
// openOrNot: 1,
timeLimit: 3
},
tag_discipline_id: [], // 知识点
ojFormValidate: {
name: {
validateStatus: '',
@ -36,14 +38,18 @@ const init = {
validateStatus: '',
errMsg: ''
},
category: {
validateStatus: '',
errMsg: ''
},
// category: {
// validateStatus: '',
// errMsg: ''
// },
// openOrNot: {
// validateStatus: '',
// errMsg: ''
// },
sub_discipline_id: {
validateStatus: '',
errMsg: ''
},
timeLimit: {
validateStatus: '',
errMsg: ''
@ -67,6 +73,8 @@ const init = {
testCodeStatus: 'default', // 调试代码状态 default(默认值) | loading(加载中) | loaded(加载完成) | userCase(用户自定义测试用例) | finish(测试完成)
openTestCodeIndex: [0], // 展开的测试用例: 数组, 当出错时,展开所有出错的测试用例, 默认展开第一个
isPublish: 0, // 是否是发布状态: 0 未发布 1 已发布
courseQuestions: [], // 课程题库
knowledges: [], // 知识点下拉值
}
const tcValidateObj = {
@ -127,10 +135,17 @@ const ojFormReducer = (state = initialState, action) => {
return returnState(state, ojForm, ojFormValidate);
case types.VALIDATE_OJ_CATEGORY:
return returnState(state, ojForm, ojFormValidate);
case types.VALIDATE_OJ_SUB_DISCIPLINE_ID:
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.SAVE_TAG_DISCIPLINE_ID:
return {
...state,
tag_discipline_id: action.payload
}
case types.ADD_TEST_CASE:
const { testCase, tcValidate } = action.payload;
const tcArrs = state.testCases.concat([testCase]);
@ -174,7 +189,8 @@ const ojFormReducer = (state = initialState, action) => {
* 6. 更改测试用例状态
* 7. 添加测试用例验证
*/
const { code = '', description, language, name, hack_sets = [], time_limit, difficult, category, status } = action.payload;
const { code = '', description, language, name, hack_sets = [], time_limit, difficult, category, status, sub_discipline_id, tag_discipline_id } = action.payload;
const { courseQuestions } = state;
let desc = null;
try {
desc = JSON.parse(description)
@ -188,7 +204,8 @@ const ojFormReducer = (state = initialState, action) => {
difficult,
category,
openOrNot: 1,
timeLimit: time_limit
timeLimit: time_limit,
sub_discipline_id
};
// state.code = code; // 保存代码块值
let curPosition = 0;
@ -208,6 +225,18 @@ const ojFormReducer = (state = initialState, action) => {
} else if (Array.isArray(code)) {
cbcode = Base64.decode(code[code.length - 1]);
}
// console.log('++++>>>>>>>>>>>>>', courseQuestions);
let temp_knowledges = [];
courseQuestions.forEach(c => {
if (sub_discipline_id && c.sub_disciplines) {
c.sub_disciplines.forEach(sub => {
if (+sub.id === sub_discipline_id) {
temp_knowledges = sub.tag_disciplines || [];
}
});
}
});
// state.position = curPosition; // 计算下一个测试用例的位置值
return {
...state,
@ -218,7 +247,9 @@ const ojFormReducer = (state = initialState, action) => {
testCasesValidate: curTcValidates,
testCodeStatus: hack_sets.length > 0 ? 'userCase' : 'default',
isPublish: status,
showCode: cbcode
showCode: cbcode,
tag_discipline_id,
knowledges: temp_knowledges
}
case types.CHANGE_PUBLISH_VALUE:
return {
@ -301,11 +332,22 @@ const ojFormReducer = (state = initialState, action) => {
if (tIndex === -1) {
tempArr.push(action.payload);
}
console.log(tempArr);
// console.log(tempArr);
return {
...state,
openTestCodeIndex: tempArr
}
case types.GET_COURSE_QUESTION:
return {
...state,
courseQuestions: action.payload
}
case types.CHANGE_KNOWLEDGES: {
return {
...state,
knowledges: action.payload
}
}
default:
return state;
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-20 10:55:38
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 11:06:27
* @LastEditTime : 2019-12-30 09:44:56
*/
import axios from 'axios';
@ -143,3 +143,9 @@ export async function fetchAddNotes (identifier, params) {
const url = `/myproblems/${identifier}/add_notes.json`;
return axios.post(url, params);
}
// 获取课程体系
export async function fetchQuestion (params) {
const url = `/disciplines.json`;
return axios.get(url, { params });
}
Loading…
Cancel
Save