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/ojForUser.js

323 lines
9.3 KiB

/*
* @Description:
* @Author: tangjiang
* @Github:
* @Date: 2019-11-27 13:42:11
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-04 15:50:54
*/
import types from "./actionTypes";
import { Base64 } from 'js-base64';
import {
fetchStartProgram,
fetchUserProgramDetail,
fetchDebuggerCode,
fetchCodeSubmit,
fetchUserCommitRecord,
fetchUserCommitRecordDetail,
fetchUpdateCode,
fetchUserCodeSubmit,
fetchRestoreInitialCode
} from "../../services/ojService";
// 进入编程页面时,首先调用开启编程题接口
export const startProgramQuestion = (id, props) => {
return (dispatch) => {
fetchStartProgram(id).then(res => {
const { status, data } = res;
if (status === 200) {
const {identifier} = data;
dispatch({
type: types.SAVE_USER_PROGRAM_ID,
payload: identifier
});
// 跳转至开启编程
debugger;
props.history.push(`/myproblems/${identifier}`);
// Redirect.to
}
})
}
}
// 保存 identifier, 防止刷新时读取不到
export const saveUserProgramIdentifier = (identifier) => {
return {
type: types.SAVE_USER_PROGRAM_ID,
payload: identifier
}
}
// 获取用户编程题详情
export const getUserProgramDetail = (identifier, type) => {
// 调用用户编程详情接口
return (dispatch) => {
fetchUserProgramDetail(identifier).then(res => {
const { status, data = {} } = res;
if (status === 200) {
if (!type) {
dispatch({
type: types.USER_PROGRAM_DETAIL,
payload: data
});
} else {
dispatch({
type: types.GET_COMMIT_RECORD_DETAIL_BY_ID,
payload: data
})
}
}
});
}
}
/**
* @description 更新代码
* @param {*} identifier
* @param {*} inputValue 输入值: 自定义 | 系统返回的
* @param {*} type 测评类型 debug | submit
*/
export const updateCode = (identifier, inputValue, type) => {
return (dispatch, getState) => {
const { userCode, isUpdateCode } = getState().ojForUserReducer;
if (isUpdateCode) {
fetchUpdateCode(identifier, {
code: userCode
}).then(res => {
// 是否更新了代码, 目的是当代码没有更新时不调用更新代码接口,目录没有实现
// TODO 需要优化
dispatch({
type: types.IS_UPDATE_CODE,
flag: false
});
// debuggerCode(identifier, inputValue);
dispatch(debuggerCode(identifier, inputValue, type));
});
} else {
// 没有更新时,直接调用调试接口
dispatch(debuggerCode(identifier, inputValue, type));
}
}
}
/**
* @description 调试代码
* @param {*} identifier
* @param {*} inputValue 输入值: 自定义 | 系统返回的
* @param {*} type 测评类型 debug | submit
*/
export const debuggerCode = (identifier,value, type) => {
return (dispatch, getState) => {
// 调用之前 先保存 code
// TODO
// console.log(identifier, value);
const {hack: {time_limit = 0}} = getState().ojForUserReducer;
if (!type || type === 'debug') {
dispatch({ // 加载中...
type: types.TEST_CODE_STATUS,
payload: 'loading'
});
}
fetchDebuggerCode(identifier, value).then(res => {
// console.log('调用调试代码成功并返回结果: ', res);
const { status } = res;
if (status === 200) {
// 调试代码成功后,调用轮循接口, 注意: 代码执行的时间要小于设置的时间限制
const intervalTime = 500;
let count = 1;
/**
* @param {*} excuteTime 执行时间
* @param {*} finalTime 总时间
* @param {*} count 执行次数
* @param {*} timer 定时器
*/
function getCodeSubmit (intervalTime, finalTime, count, timer){
const excuteTime = (count++) * intervalTime; // 当前执行时间
fetchCodeSubmit(identifier, { mode: type }).then(res => {
const { status } = res.data; // 评测返回结果
// 清除定时器条件: 评测通过或者评测时间大于指定时间
if (+status === 0 || (excuteTime / 1000) > (finalTime + 1)) {
clearInterval(timer); // 清除定时器
timer = null;
let returnData = null;
if (status === 1) { // 结果没有返回
returnData = {
error_line: -1,
error_msg: '',
execute_memory: '',
execute_time: finalTime,
input: '',
output: '',
status: 2,
expected_output: ''
};
} else { // 成功返回结果
returnData = res.data.data;
}
// 返回评测结果
dispatch({
type: types.COMMIT_RECORD_DETAIL,
payload: returnData
});
if (!type || type === 'debug') {
dispatch({ // 改变 loading 值
type: types.LOADING_STATUS,
payload: false
});
// 保存执行状态
dispatch({
type: types.TEST_CODE_STATUS,
payload: 'finish'
});
} else {
// 回滚提交按钮状态
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
// 改变tab值至提交记录(只在提交时才跳转,测评时,切换到代码执行结果就可以了)
dispatch({
type: types.CHANGE_USER_CODE_TAB,
payload: 'record'
});
// 重新调用一下提交记录接口
dispatch(getUserCommitRecord(identifier));
}
}
}).catch(err => { // 评测异常时
// 清除定时器
clearInterval(timer);
timer = null;
// 回滚按钮状态
if (!type || type === 'debug') {
dispatch({ // 改变 loading 值
type: types.LOADING_STATUS,
payload: false
});
} else { // 回滚提交按钮状态
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
}
});
}
// 开启定时器,调用监听接口
let timer = setInterval(() => {
getCodeSubmit(intervalTime, time_limit, count++, timer);
}, intervalTime);
}
}).catch(() => {
dispatch({
type: types.TEST_CODE_STATUS,
payload: ''
});
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
});
}
}
// 获取提交记录
export const getUserCommitRecord = (identifier) => {
return (dispatch) => {
fetchUserCommitRecord(identifier).then(res => {
const {status, data} = res;
if (status === 200) {
dispatch({
type: types.COMMIT_RECORD,
payload: data
})
}
});
}
}
// 获取提交记录详情
export const getUserCommitRecordDetail = (identifier) => {
return (dispatch) => {
fetchUserCommitRecordDetail(identifier).then(res => {
console.log('提交记录详情======》》》》', res);
});
}
}
// 保存用户时时输入的代码
export const saveUserInputCode = (code) => {
return {
type: types.SAVE_USER_CODE,
payload: code
}
}
// 监听是否更新代码块内容
// export const isUpdateCodeCtx = (flag) => {
// return {
// type: types.IS_UPDATE_CODE,
// payload: flag
// };
// }
// 改变学员测评 tab 值
export const changeUserCodeTab = (key) => {
return {
type: types.CHANGE_USER_CODE_TAB,
payload: key
}
}
/**
* @description 用户提交代码, 先调用保存代码接口,再调提交接口,成功后调用调试接口
* @param {*} identifier
*/
export const submitUserCode = (identifier, inputValue, type) => {
return (dispatch, getState) => {
const { userCode, isUpdateCode } = getState().ojForUserReducer;
function userCodeSubmit () {
fetchUserCodeSubmit(identifier).then(res => {
// console.log('用户提交代码成功======》》》》》', res);
if (res.status === 200) {
dispatch(debuggerCode(identifier, inputValue, type || 'submit'));
}
}).catch(() => {
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
});
});
}
if (isUpdateCode) {
fetchUpdateCode(identifier, {
code: userCode
}).then(res => {
// 是否更新了代码, 目的是当代码没有更新时不调用更新代码接口,目录没有实现
// TODO 需要优化
dispatch({
type: types.IS_UPDATE_CODE,
flag: false
});
userCodeSubmit();
}).catch(() => {
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
})
});
} else {
userCodeSubmit();
}
}
}
export const restoreInitialCode = (identifier) => {
return (dispatch) => {
fetchRestoreInitialCode(identifier).then(res => {
console.log('恢复初始代码====》》》》', res);
});
}
}