@@ -90,37 +85,27 @@ import "codemirror/addon/fold/xml-fold.js";
// 编辑的主题文件
import "codemirror/theme/monokai.css";
import "codemirror/theme/base16-light.css";
-import * as $ from "jquery";
import { Loading } from 'element-ui';
import axios from 'axios';
import util from '@/util'
-const CANCEL_TOKEN = axios.CancelToken
+const CANCEL_TOKEN = axios.CancelToken // 用于input中中断请求
export default {
- props: ["workbench1", "code", "codeid", "projectId"],
+ props: ["workbench1", "code", "projectId"],
data() {
return {
- courseId: util.getCookie("courseId"),
- datas: [],
- ShowAssessmentId: false,
- answer: "",
- exampleData: this.code,
- codeId: this.codeid,
- codes: [],
- submit: "",
- modifys: "", //运行后返回的
- isError: 2,
- timer: "",
- after: "",
- num: "",
- userId: '',
- studentId: "",
- isSubmit: "", //提交按钮
- isAnswerTips: false,
- error: false,
- picVisible: false,
- picSrc: '',
- loadIns: null,
- submiting: false,
+ assessmentId: util.getCookie("assessmentId"), // 考核id
+ courseId: util.getCookie("courseId"), // 课程id
+ showTips: false, // 显示隐藏提示按钮
+ answer: '', // 正确答案
+ codeVal: this.code,
+ runResult: '', // 运行结果
+ isError: false, // 运行正确与否
+ errLine: '', // 错误代码的位置
+ isSubmit: false, // 是否提交了
+ runEnable: false, // 是否禁用运行按钮
+ tipsVisible: false, // 答案提示弹框显示标识
+ picSrc: '', // 代码运行出来的图片url
+ loadIns: null, // loading实例
cmOption: {
scrollbarStyle: "native",
tabSize: 2, // tab
@@ -149,41 +134,34 @@ export default {
theme: "monokai", // 主题
extraKeys: { Ctrl: "autocomplete" } // 可以用于为编辑器指定额外的键绑定,以及keyMap定义的键绑定
},
- inputTextReg: /^((?!#).*?(,|\(|\[|\{|\s)+)?input(?!\w)\(['|"]([\s\S]+?)['|"]\)/m,// 匹配input()
- requestList: [],
- sourceCode: '',
- requestTimer: null,
- assessmentId: util.getCookie("assessmentId"),
+ inputTextReg: /^((?!#).*?(,|\(|\[|\{|\s)+)?input(?!\w)\(['|"]([\s\S]+?)['|"]\)/m, // 匹配input()
+ requestList: [], // 有input的情况下,保存每个axios的对象,用于中断请求
+ sourceCode: '', // 把input替换成exit函数后的代码
+ requestTimer: null // 用于中断请求的定时器
};
},
components: {
codemirror
},
watch: {
- list() {
- this.timer();
- },
- exampleData(val) {
- this.$emit("update:code", val);
- },
- codeId(val) {
- this.$emit("update:codeid", val);
+ codeVal(val) {
+ this.$emit("update:code", val)
}
},
mounted() {
- if (!this.assessmentId) {
- this.ShowAssessmentId = true;
- }
+ if (!this.assessmentId) this.showTips = true
//兄弟组件传值
newmain.$on("isSubmit", isSubmit => {
- this.isSubmit = isSubmit;
- });
+ this.isSubmit = isSubmit
+ })
},
methods: {
- onCmReady3() {
+ // 页面加载完后重置编辑框大小
+ ready() {
this.$refs.myCmGenerate.codemirror.setSize("auto", "calc(100vh - 149px)");
},
+ // 下载文件
downloadFile(fileName,url) {
var x = new XMLHttpRequest()
x.open("GET", url, true)
@@ -203,11 +181,11 @@ export default {
// 下面这个函数就是递归执行这个input输入过程的函数
confirmInput(msg){
let receiveResult = msg.replace('validing:','')
- this.modifys += receiveResult
+ this.runResult += receiveResult
this.$prompt(receiveResult, "提示", {
confirmButtonText: "确定"
}).then(({ value }) => {
- this.modifys += `${value}
`
+ this.runResult += `${value}
`
// 把exit函数替换成用户输入的值
this.sourceCode = this.sourceCode.replace(`exit('validing:${receiveResult.replace(/[\r\n]*/g,'')}')`,val => {
return `'${value}'`
@@ -222,8 +200,8 @@ export default {
this.requestList.map(n => n('interrupt'))
},1000)
- axios.post(this.api.UpdateCode,{
- code: this.exampleData,
+ axios.post(this.api.runPythonCode,{
+ code: this.codeVal,
bcId: this.workbench1,
cid: this.courseId,
projectId: this.projectId
@@ -236,19 +214,15 @@ export default {
let result = res.message.result
if(result.includes('File ')){
let modify = res.message.result
- this.modifys = modify
- this.after = modify.substring(
- modify.indexOf("line") + 4,
- modify.length
- );
- this.num = parseInt(this.after)
+ this.runResult = modify
+ this.errLine = parseInt(modify.substring(modify.indexOf("line") + 4, modify.length))
this.isError = res.message.isError
}else if(result.includes('validing:')){
this.isError = 0
this.confirmInput(result)
}else if(!res.message.isError){
this.isError = 0
- this.modifys += result
+ this.runResult += result
newmain.$emit("updateJud",{
id: res.data.judgmentPointsId,
isError: res.data.isError
@@ -256,31 +230,30 @@ export default {
}
}).catch(e => {
if(e && e.message == 'interrupt'){
- this.AnswerTips(true)
+ this.runCode(true)
this.requestList = []
}
})
}).catch(err => {})
},
- AnswerTips(isWhile) {// isWhile为true表示代码里有while循环,右边的运行结果需要拼接展示,而不是直接覆盖
- if (this.isSubmit == "") {
- this.submit = 1;
- if (this.codeid == "") {
+ runCode(isWhile) { // isWhile为true表示代码里有while循环,右边的运行结果需要拼接展示,而不是直接覆盖
+ if (!this.isSubmit) {
+ if (!this.codeVal) {
this.$message({
message: "警告哦,内容为空不可运行",
type: "warning"
- });
+ })
} else {
let inputTextReg = this.inputTextReg
let inputFuncReg = /input\(['|"]/g
// 该正则是验证代码里是否有input,如果有,就要另外做处理,而不是直接传给后端执行
- if (inputTextReg.test(this.exampleData)) {
- let sourceCode = this.exampleData
+ if (inputTextReg.test(this.codeVal)) {
+ let sourceCode = this.codeVal
sourceCode = sourceCode.replace(inputTextReg,val => {
return val.replace(/\\n/g,"")
})
- this.exampleData = sourceCode
+ this.codeVal = sourceCode
// 把input函数替换成exit函数,加上"validing:"作为特定标识,好方便后面的识别
sourceCode = sourceCode.replace(inputFuncReg,val => {
@@ -288,9 +261,9 @@ export default {
})
this.sourceCode = sourceCode
- if(!isWhile) this.modifys = ''
- this.$post(this.api.UpdateCode, {
- code: this.exampleData,
+ if(!isWhile) this.runResult = ''
+ this.$post(this.api.runPythonCode, {
+ code: this.codeVal,
bcId: this.workbench1,
cid: this.courseId,
projectId: this.projectId
@@ -299,16 +272,12 @@ export default {
if(result.includes('File ')){
let modify = res.message.result
if(isWhile){
- this.modifys += modify
+ this.runResult += modify
}else{
- this.modifys = modify
+ this.runResult = modify
}
- this.after = modify.substring(
- modify.indexOf("line") + 4,
- modify.length
- );
- this.num = parseInt(this.after)
+ this.errLine = parseInt(modify.substring(modify.indexOf("line") + 4, modify.length))
this.isError = res.message.isError
}else if(result.includes('validing:')){
this.isError = 0
@@ -319,93 +288,65 @@ export default {
this.loadIns = Loading.service({
background: 'transparent'
})
- //实时更新编辑器代码(修改代码)
- this.$post(this.api.UpdateCode, {
- code: this.exampleData,
+ // 把代码传给后端,在后端运行Python代码
+ this.$post(this.api.runPythonCode, {
+ code: this.codeVal,
bcId: this.workbench1,
cid: this.courseId,
projectId: this.projectId
- })
- .then(res => {
- this.loadIns.close()
- this.picSrc = ''
- if(typeof res.message == 'string'){
- this.isError = res.message.isError;
- this.modifys = ''
- this.picSrc = `${res.message}?id=${new Date().getTime()}`
- newmain.$emit("updateJud",{
- id: res.data.judgmentPointsId,
- isError: res.data.isError
- })
- }else{
- // 这段是为要下载图片的项目案例写的,后端会返回图片名称的数组,前端负责循环这个数组,然后下载下来
- // 只有该系统有这段代码,因为其他7个系统没有下载图片的项目,后续如果加了,直接把这段代码复制过去即可
- if(!res.message.isError){
- let result = ''
- try {
- result = eval(res.message.result)
- } catch (error) {}
- if(result instanceof Array && result.length && (result[0].includes('.jpg') || result[0].includes('.png') || result[0].includes('.gif'))){
- result.map((n,i) => {
- this.downloadFile(`${i+1}.jpg`,n)
- })
- this.isError = 0
- this.modifys = '下载完成'
- }else{
- this.isError = res.message.isError;
- newmain.$emit("updateJud",{
- id: res.data.judgmentPointsId,
- isError: res.data.isError
- })
- var modify = res.message.result;
- this.modifys = modify;
- this.after = modify.substring(
- modify.indexOf("line") + 4,
- modify.length
- );
- this.num = parseInt(this.after);
- }
- }else{
- this.isError = res.message.isError;
- newmain.$emit("updateJud",{
- id: res.data.judgmentPointsId,
- isError: res.data.isError
+ }).then(res => {
+ const data = res.code
+ const photo = data.photoUrl
+ const result = data.runResult
+ this.loadIns.close()
+ this.picSrc = ''
+ if(photo){
+ this.isError = 0
+ this.runResult = ''
+ this.picSrc = `${photo}?id=${new Date().getTime()}`
+ }else{
+ // 这段是为要下载图片的项目案例写的,后端会返回图片名称的数组,前端负责循环这个数组,然后下载下来
+ // 只有该系统有这段代码,因为其他7个系统没有下载图片的项目,后续如果加了,直接把这段代码复制过去即可
+ if(0){
+ if(result instanceof Array && result.length && (result[0].includes('.jpg') || result[0].includes('.png') || result[0].includes('.gif'))){
+ result.map((n,i) => {
+ this.downloadFile(`${i+1}.jpg`,n)
})
- var modify = res.message.result;
- this.modifys = modify;
- this.after = modify.substring(
- modify.indexOf("line") + 4,
- modify.length
- );
- this.num = parseInt(this.after);
+ this.isError = 0
+ this.runResult = '下载完成'
+ }else{
+ this.isError = 0
+ this.runResult = data.runResult
+ this.errLine = parseInt(result.substring(modify.indexOf("line") + 4, modify.length))
}
+ } else {
+ this.isError = data.retResult
+ this.runResult = result
+ this.errLine = parseInt(result.substring(result.indexOf("line") + 4, result.length))
}
- })
- .catch(res => {
- res.status == 500 && this.$message.error('检测到代码里有非法代码,请检查是否有调用系统命令。')
- this.loadIns.close()
- });
- clearTimeout(this.timer);
+ }
+ }).catch(res => {
+ res.status == 500 && this.$message.error('检测到代码里有非法代码,请检查是否有调用系统命令。')
+ this.loadIns.close()
+ })
}
}
} else {
- this.isAnswerTips = true;
+ this.runEnable = true
this.$message({
message: "警告哦,已提交不可再运行",
type: "warning"
- });
+ })
}
},
- getQueryAnswer() {
- this.error = true;
+ getTips() {
+ this.tipsVisible = true
//提示答案
this.$get(this.api.QueryAnswer, {
judgmentPointsId: this.workbench1
- })
- .then(res => {
- this.answer = res.message;
- })
- .catch(err => {});
+ }).then(res => {
+ this.answer = res.message
+ }).catch(err => {})
}
}
};
diff --git a/src/utils/api.js b/src/utils/api.js
index 6095ba7..27acd03 100644
--- a/src/utils/api.js
+++ b/src/utils/api.js
@@ -2,15 +2,12 @@ import config from '@/config'
let host = `${config.host}`
export default {
- QueryProject: `${host}occupationlab/projectManage/getProjectDetail`, //项目选择下拉框+项目信息+判分点信息展示
- ProjectId: `${host}/python/projectId`, //判分点下拉框信息展示
- Submit: `${host}/python/submit`, //提交代码与判分点进行判断
- UpdateCode: `${host}python/python/runPythonCode`, //实时更新编辑器代码(修改代码)
- QueryAnswer: `${host}/python/queryAnswer`, //提示答案
- DeleteCodes: `${host}/python/deleteCodes`, //重新开始
- QueryAllProject: `${host}/python/queryAllProject`, //项目选择下拉框
- ChangeCode: `${host}/python/changeCode`, //input交互
- queryTestProject: `${host}occupationlab/projectManage/getProjectBySystemId`, //input交互
- qualifications: `${host}/python/qualifications`, //input交互
- saveCache: `${host}python/python/saveCache` //中途退出实验并保存实验数据(虚拟仿真实验)
+ QueryProject: `${host}occupationlab/projectManage/getProjectDetail`,
+ Submit: `${host}/python/submit`,
+ runPythonCode: `${host}python/python/runPythonCode`,
+ QueryAnswer: `${host}/python/queryAnswer`,
+ DeleteCodes: `${host}/python/deleteCodes`,
+ queryTestProject: `${host}occupationlab/projectManage/getProjectBySystemId`,
+ saveCache: `${host}python/python/saveCache`,
+ getLastCache: `${host}python/python/getLastCache`
}
\ No newline at end of file
diff --git a/src/views/Home.vue b/src/views/Home.vue
index 85d6cdb..03dd055 100644
--- a/src/views/Home.vue
+++ b/src/views/Home.vue
@@ -11,11 +11,11 @@
{{$config.title}}
编程语言
-
+
-
+
{
+ this.leavePage()
}
},
- destroyed() {
- window.removeEventListener("popstate", this.goBack, false);
- },
methods: {
+ // 页面离开的时候保存未提交的代码(只有练习和未提交状态下才会调用该接口)
leavePage(){
- if(!this.$refs.mainindex.isSubmit && !this.assessmentId && this.workbench.length){
- let data = {
- code: '',
- bcId: this.workbench1,
- cid: this.courseId,
- projectId: this.projectId
+ const list = this.workbench
+ if(!this.$refs.mainindex.isSubmit && !this.assessmentId && list.length){
+ if(list.some(e => e.code)){
+ const cache = {
+ projectId: this.projectId,
+ judgmentId: list[this.curTab].judgmentId
+ }
+ localStorage.setItem('codeCache', JSON.stringify(cache))
+ list.map(e => {
+ if (e.code) {
+ let data = {
+ code: e.code,
+ bcId: e.judgmentId,
+ cid: this.courseId,
+ projectId: this.projectId
+ }
+ this.$post(this.api.saveCache,data).then(res => {}).catch(e => {})
+ }
+ })
}
- this.$post(this.api.saveCache,data).then(res => {}).catch(e => {})
}
},
+ // 自动退出
autoLogout(){
let lastTime = new Date().getTime()
let logout = false
+ // 页面点击后赋值当前时间
document.onmousedown = () => {
lastTime = new Date().getTime()
}
@@ -138,23 +128,19 @@ export default {
}
},1000)
},
- goBack() {
- this.leavePage()
- history.back()
- },
getDataFromChild(data) {
sessionStorage.setItem("timer", parseInt(data));
},
recoveryCode(workbench){
this.workbench = workbench
this.codeKey++
- this.workbench1 = '0'
+ this.curTab = '0'
},
reload(){
this.$refs.mainindex.reload()
},
+ // 退出实验
back() {
- this.leavePage()
if(this.projectPermissions){
// 返回到考核列表
if (this.$config.isBeta) { // 判断是否是职站测试服
@@ -173,9 +159,11 @@ export default {
//工作台展示
getQueryIndex(value1, projectPermissions,workBench) {
//父子组件传值
- this.projectId = value1;
- this.projectPermissions = projectPermissions;
+ console.log(5555,workBench)
+ this.projectId = value1
+ this.projectPermissions = projectPermissions
this.workbench = workBench
+ this.codeKey++
},
}
};