You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
educoder/public/react/src/redux/actions/ojForm.js

392 lines
10 KiB

/*
* @Description: 开发者社区编辑模块
* @Author: tangjiang
* @Github:
* @Date: 2019-11-20 16:35:46
* @LastEditors: tangjiang
* @LastEditTime: 2019-11-29 18:55:43
*/
import types from './actionTypes';
import CONST from '../../constants';
import { fetchPostOjForm, fetchGetOjById, publishTask } from '../../services/ojService';
import { Base64 } from 'js-base64';
import { message, notification } from 'antd';
const { jcLabel } = CONST;
// 表单字段映射
const maps = {
name: {
label: jcLabel['name'],
type: types.VALIDATE_OJ_NAME
},
language: {
label: jcLabel['language'],
type: types.VALIDATE_OJ_LANGUAGE
},
description: {
label: jcLabel['description'],
type: types.VALIDATE_OJ_DESCRIPTION
},
difficult: {
label: jcLabel['difficult'],
type: types.VALIDATE_OJ_DIFFICULT
},
timeLimit: {
label: jcLabel['timeLimit'],
type: types.VALIDATE_OJ_TIMELIMIT
},
category: {
label: jcLabel['category'],
type: types.VALIDATE_OJ_CATEGORY
},
openOrNot: {
label: jcLabel['openOrNot'],
type: types.VALIDATE_OJ_OPENORNOT
},
input: {
label: '输入'
},
output: {
label: '输出'
}
};
// 非空校验
const emptyValidate = (key, value) => {
if ([undefined, '', null].includes(value)) {
return {
[key]: {
validateStatus: 'error',
errMsg: `${maps[key].label}不能为空`
}
}
} else {
return {
[key]: {
validateStatus: '',
errMsg: ''
}
}
}
};
// 组装字段值及校验信息
const payloadInfo = (key, value, errMsg, validateInfo) => ({
ojForm: {
[key]: errMsg ? '' : value
},
ojFormValidate: {
[key]: validateInfo
}
});
// 表单提交验证
export const validateOjForm = (props, type) => {
return (dispatch, getState) => {
const {ojForm, testCases, identifier, code } = getState().ojFormReducer;
let keys = Object.keys(ojForm);
// 循环判断每个字段是否为空
let hasSuccess = true;
keys.forEach(key => {
const value = ojForm[key];
const validateResult = emptyValidate(key, value);
const errMsg = validateResult[key].errMsg;
if (errMsg) {
hasSuccess = false;
dispatch(
{
type: maps[key].type,
payload: payloadInfo(key, value, errMsg, validateResult[key])
}
)
}
});
// 验证测试用例中的数组是否都有对应的值
const tcValidResult = [];
testCases.forEach(obj => {
// const tcKeys = Object.keys(obj); // 获取 obj 属性: input 与 output
let tempObj = {};
['input', 'output'].forEach(key => {
const value = obj[key];
const validateResult = emptyValidate(key, value);
const errMsg = validateResult[key].errMsg;
// const errMsg = validateResult[key].errMsg;
if (errMsg) {
hasSuccess = false;
}
Object.assign(tempObj, validateResult);
});
tcValidResult.push(tempObj);
});
if (testCases.length === 0) {
notification['error']({
message: '必填',
description: '测试用例必须输入!'
});
return false;
}
if (!code) {
notification['error']({
message: '必填',
description: '代码块内容必须输入!'
});
return;
}
// 更改测试用例验证结果
dispatch({
type: types.VALIDATE_TEST_CODE_ARRS,
payload: tcValidResult
});
// 验证成功后,调用提交接口
if (hasSuccess) {
// console.log('表单保存的数据为: ', getState());
const {ojFormReducer} = getState();
const {code, score, ojForm, testCases = []} = ojFormReducer;
const {category, description, difficult, language, name, openOrNot, timeLimit} = ojForm;
let paramsObj = {};
const hack = { // 编程题干
name,
description,
difficult,
category,
'open_or_not': openOrNot,
'time_limit': timeLimit,
score
};
const hack_codes = { // 代码区域参数
code: Base64.encode(code),
language
};
// const tempTc = testCases.map(tc => {
// delete tc.isAdd
// return tc;
// });
// console.log(tempTc);
if (!identifier) { // 新增
const tempTc = testCases.map(tc => {
delete tc.isAdd
return tc;
});
paramsObj['params'] = {
hack,
hack_sets: tempTc,
hack_codes
}
paramsObj['submitType'] = 'add';
} else { // 存在时调用更新接口
const update_hack_sets = []; // 编辑的测试集
const hack_sets = []; // 新增的测试集
testCases.forEach(tc => {
if (tc.isAdd) { // 新增
delete tc.isAdd;
hack_sets.push(tc);
} else {
delete tc.isAdd;
update_hack_sets.push(tc);
}
});
paramsObj['params'] = {
hack,
hack_sets,
hack_codes,
update_hack_sets
}
paramsObj['submitType'] = 'update';
paramsObj['identifier'] = identifier;
}
function linkToDev () {
dispatch({
type: types.IS_MY_SOURCE,
payload: true
});
setTimeout(() => {
props.history.push('/problems');
}, 1000);
}
fetchPostOjForm(paramsObj).then(res => {
// TODO
if (res.status === 200) { // 保存成功后,重新跳转至列表页
const {identifier} = res.data
if (type === 'publish') { // 存在发布时,直接调用发布接口
identifier && publishTask(identifier).then(res => {
if (res.status === 200) {
message.success('发布成功!');
linkToDev();
}
dispatch({
type: types.PUBLISH_LOADING_STATUS,
payload: false
});
}).catch(() => {
dispatch({
type: types.PUBLISH_LOADING_STATUS,
payload: false
});
});
} else {
message.success('保存成功!');
linkToDev();
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
}
}
}).catch(err => {
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
});
}
}
};
// 保存提交的代码
export const saveOjFormCode = (value) => {
return {
type: types.SAVE_OJ_FORM_CODE,
payload: value
};
}
// 验证任务名称
export const validateOJName = (value) => {
const validate = emptyValidate('name', value)['name'];
const errMsg = validate.errMsg;
return {
type: types.VALIDATE_OJ_NAME,
payload: payloadInfo('name', value, errMsg, validate)
}
};
// 验证编程语言
export const validateOjLanguage = (value) => {
const validate = emptyValidate('language', value)['language'];
const errMsg = validate.errMsg;
return {
type: types.VALIDATE_OJ_LANGUAGE,
payload: payloadInfo('language', value, errMsg, validate)
}
};
// 验证描述
export const validateOjDescription = (value) => {
// createAction('description', value, types.VALIDATE_OJ_DESCRIPTION);
const validate = emptyValidate('description', value)['description'];
const errMsg = validate.errMsg;
return {
type: types.VALIDATE_OJ_DESCRIPTION,
payload: payloadInfo('description', value, errMsg, validate)
}
};
// 验证难易度
export const validateOjDifficult = (value) => {
// createAction('difficult', value, types.VALIDATE_OJ_DIFFICULT);
const validate = emptyValidate('difficult', value)['difficult'];
const errMsg = validate.errMsg;
return {
type: types.VALIDATE_OJ_DIFFICULT,
payload: payloadInfo('difficult', value, errMsg, validate)
}
};
// 验证时间限制
export const validateOjTimeLimit = (value) => {
// createAction('timeLimit', value, types.VALIDATE_OJ_TIMELIMIT);
const validate = emptyValidate('timeLimit', value)['timeLimit'];
const errMsg = validate.errMsg;
return {
type: types.VALIDATE_OJ_TIMELIMIT,
payload: payloadInfo('timeLimit', value, errMsg, validate)
}
};
// 验证分类
export const validateOjCategory = (value) => {
// createAction('category', value, types.VALIDATE_OJ_CATEGORY);
const validate = emptyValidate('category', value)['category'];
const errMsg = validate.errMsg;
return {
type: types.VALIDATE_OJ_CATEGORY,
payload: payloadInfo('category', value, errMsg, validate)
}
};
// 验证公开程序
export const validateOpenOrNot = (value) => {
const validate = emptyValidate('openOrNot', value)['openOrNot'];
const errMsg = validate.errMsg;
return {
type: types.VALIDATE_OJ_OPENORNOT,
payload: payloadInfo('openOrNot', value, errMsg, validate)
}
};
// 新增测试用例
export const addTestCase = (obj) => {
return {
type: types.ADD_TEST_CASE,
payload: obj
}
}
// 删除测试用例
export const deleteTestCase = (obj) => {
return {
type: types.DELETE_TEST_CASE,
payload: obj
}
}
// 根据id号编辑OJ
export const getOJFormById = (id) => {
return (dispatch) => {
fetchGetOjById(id).then(res => {
console.log('获取OJ表单信息成功: ', res);
dispatch({
type: types.SAVE_EDIT_OJ_FORM_AND_TEST_CASE,
payload: res.data
});
});
}
}
// 保存表单 id 信息
export const saveOJFormId = (id) => {
return {
type: types.SAVE_OJ_FORM_ID,
payload: id
}
}
// 清空测试用例集合
export const clearOJFormStore = () => {
return {
type: types.CLEAR_JSFORM_STORE
}
}
// 测试用例输入值改变时
export const testCaseInputChange = (value, index) => {
const validate = emptyValidate('input', value)['input'];
return {
type: types.TEST_CASE_INPUT_CHANGE,
payload: {
input: validate,
value,
index
}
}
}
// 测试用例输出值改变时
export const testCaseOutputChange = (value, index) => {
const validate = emptyValidate('output', value)['output'];
return {
type: types.TEST_CASE_OUTPUT_CHANGE,
payload: {
output: validate,
value,
index
}
}
}
// // 调试代码时,更改对应的状态值
// export const changeTestCodeStatus = () => {