/* * @Description: * @Author: tangjiang * @Github: * @Date: 2019-11-20 16:40:32 * @LastEditors : tangjiang * @LastEditTime : 2020-01-02 17:36:40 */ import { Base64 } from 'js-base64'; import types from '../actions/actionTypes'; const init = { ojForm: { name: '', // 任务名称 language: '', description: '', difficult: '', sub_discipline_id: '', // 方向 // category: '', // openOrNot: 1, timeLimit: 3 }, tag_discipline_id: [], // 知识点 ojFormValidate: { name: { validateStatus: '', errMsg: '' }, language: { validateStatus: '', errMsg: '' }, description: { validateStatus: '', errMsg: '' }, difficult: { validateStatus: '', errMsg: '' }, // category: { // validateStatus: '', // errMsg: '' // }, // openOrNot: { // validateStatus: '', // errMsg: '' // }, sub_discipline_id: { validateStatus: '', errMsg: '' }, timeLimit: { validateStatus: '', errMsg: '' } }, testCases: [ // { // input: "", // output: "", // position: 1, // 当前测试用例位置 // isAdd: true // 是否是新增 // } ], // 测试用例集合 testCasesValidate: [], // 测试用例验证 position: 1, // TODO 每次加载信息时同步指定positio值 score: 200, // 分值: 选择难易度后自动计算分值 200 | 500 | 1000 code: '', // 提交的代码 showCode: '', // 编辑器显示的代码 identifier: '', // OJ表单id loading: false, // 僵尸loading标志 testCodeStatus: 'default', // 调试代码状态 default(默认值) | loading(加载中) | loaded(加载完成) | userCase(用户自定义测试用例) | finish(测试完成) openTestCodeIndex: [0], // 展开的测试用例: 数组, 当出错时,展开所有出错的测试用例, 默认展开第一个 isPublish: 0, // 是否是发布状态: 0 未发布 1 已发布 courseQuestions: [], // 课程题库 knowledges: [], // 知识点下拉值 } const tcValidateObj = { input: { errMsg: '', validateStatus: '' }, output: { errMsg: '', validateStatus: '' } } const scoreMaps = { 1: 200, 2: 500, 3: 1000 }; const initialState = Object.assign({}, init); const ojFormReducer = (state = initialState, action) => { let ojFormValidate = {}; let ojForm = {}; if (action.payload) { ojFormValidate = action.payload.ojFormValidate; ojForm = action.payload.ojForm; } const returnState = (state, ojForm, ojFormValidate) => { return { ...state, ojFormValidate: Object.assign({}, state.ojFormValidate, ojFormValidate), ojForm: Object.assign({}, state.ojForm, ojForm) }; } switch (action.type) { case types.VALIDATE_OJ_FORM: // 验证成功后,调用后台接口 return returnState(state, ojForm, ojFormValidate); case types.SAVE_OJ_FORM_CODE: return { ...state, code: action.payload } case types.VALIDATE_OJ_NAME: // 验证任务名称 return returnState(state, ojForm, ojFormValidate); case types.VALIDATE_OJ_DESCRIPTION: return returnState(state, ojForm, ojFormValidate); case types.VALIDATE_OJ_LANGUAGE: return returnState(state, ojForm, ojFormValidate); case types.VALIDATE_OJ_DIFFICULT: const curDifficult = action.payload.ojForm.difficult.trim(); if (action.payload.ojForm.difficult) { state.score = scoreMaps[`${curDifficult}`]; } 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]); const tcValidateArrs = state.testCasesValidate.concat([tcValidate]); state.position++; // 位置递增 const len = tcArrs.length - 1; return { ...state, testCases: [...tcArrs], testCasesValidate: [...tcValidateArrs], openTestCodeIndex: [len] // 当前展开的测试用例 }; case types.DELETE_TEST_CASE: const { position } = action.payload; // 根据 position 去查找当前元素在数组中的位置 const index = state.testCases.findIndex((item) => item.position === position); const tempTestCase = state.testCases || []; const tempTestValicate = state.testCasesValidate || []; if (index > -1) { tempTestCase.splice(index, 1); // 删除当前元素 tempTestValicate.splice(index, 1); // 删除测试用例对应的校验 } return { ...state, testCases: [...tempTestCase], testCasesValidate: [...tempTestValicate] }; case types.SAVE_OJ_FORM_ID: // state.identifier = action.payload; return { ...state, identifier: action.payload } case types.SAVE_EDIT_OJ_FORM_AND_TEST_CASE: // 保存编辑的值 /** * 1. 将当前值保存至OJForm中 * 2. 将当前的测试用例保存至 testCases中, 并增加 isAdd: false 属性 * 3. 设置position的值, 即新增下一个测试用例的位置 * 4. 自定义测试用例是否需要返回 * 5. 代码执行的结果 * 6. 更改测试用例状态 * 7. 添加测试用例验证 */ 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) } catch (error) { desc = description; } const currentOjForm = { name, // 任务名称 language, description: desc, difficult, category, openOrNot: 1, timeLimit: time_limit, sub_discipline_id }; // state.code = code; // 保存代码块值 let curPosition = 0; const curTestCases = []; const curTcValidates = []; hack_sets.forEach(hack => { if (hack.position > curPosition) { curPosition = hack.position; } curTcValidates.push(tcValidateObj); // 一个测试用例对应一个校验 curTestCases.push(Object.assign({}, hack, { isAdd: false })); // state.testCases.push(Object.assign({}, hack, { isAdd: false })); }); let cbcode = ''; if (typeof code === 'string') { cbcode = Base64.decode(code); } 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, ojForm: currentOjForm, position: curPosition + 1, code: cbcode, testCases: curTestCases, testCasesValidate: curTcValidates, testCodeStatus: hack_sets.length > 0 ? 'userCase' : 'default', isPublish: status, showCode: cbcode, tag_discipline_id, knowledges: temp_knowledges } case types.CHANGE_PUBLISH_VALUE: return { ...state, isPublish: action.payload }; case types.CLEAR_JSFORM_STORE: state = Object.assign({}, init); return { ...state } // case types.TEST_CODE_STATUS: // return { // ...state, // testCodeStatus: action.payload // 当前状态值 // } case types.VALIDATE_TEST_CODE_ARRS: return { ...state, testCasesValidate: action.payload } case types.TEST_CASE_INPUT_CHANGE: const { input } = action.payload; // 更新验证消息 const curIOjTestValidate = state.testCasesValidate.map((tc, i) => { if (i === action.payload.index) { return Object.assign({}, tc, {input}); } return tc; }); let curITestValues = state.testCases.map((tc, i) => { if (i === action.payload.index) { return Object.assign({}, tc, { input: action.payload.value }) } return tc; }); return { ...state, testCasesValidate: [...curIOjTestValidate], testCases: [...curITestValues] } case types.TEST_CASE_OUTPUT_CHANGE: const { output } = action.payload; // 更新验证消息 const curOOjTestValidate = state.testCasesValidate.map((tc, i) => { if (i === action.payload.index) { return Object.assign({}, tc, {output}); } return tc; }); let curOTestValues = state.testCases.map((tc, i) => { if (i === action.payload.index) { return Object.assign({}, tc, { output: action.payload.value }) } return tc; }); return { ...state, testCasesValidate: [...curOOjTestValidate], testCases: [...curOTestValues] } case types.UPDATE_TEST_AND_VALIDATE: // 保存或更新测试用例值 const tempValitate = action.payload.testCaseValidate; const openColArrs = []; const curOjTestCaseValidate = state.testCasesValidate.map((tc, i) => { if (tempValitate[i].input.errMsg || tempValitate[i].output.errMsg) { openColArrs.push(i); } return Object.assign({}, tc, tempValitate[i]); }); // console.log('+++++++++++', openColArrs); return { ...state, testCasesValidate: [...curOjTestCaseValidate], openTestCodeIndex: openColArrs } case types.UPDATE_OPEN_TESTCASE_INDEX: const tempArr = []; const tIndex = state.openTestCodeIndex.findIndex(i => i === action.payload); if (tIndex === -1) { tempArr.push(action.payload); } // 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; } } export default ojFormReducer;