master
jialong.yu 3 years ago
parent 499d332ae7
commit 1b42461663
  1. 160
      package-lock.json
  2. 105
      src/api/http.js
  3. 9
      src/api/index.js
  4. 757
      src/components/TestPanel.vue
  5. 418
      src/components/codemirror.vue
  6. 27
      src/config/index.js
  7. 4
      src/main.js
  8. 60
      src/util/index.js
  9. 25
      src/utils/api.js
  10. 358
      src/utils/http.js
  11. 239
      src/views/Home.vue

160
package-lock.json generated

@ -1715,6 +1715,16 @@
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"cacache": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
@ -1741,6 +1751,34 @@
"unique-filename": "^1.1.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"find-cache-dir": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
@ -1762,6 +1800,25 @@
"path-exists": "^4.0.0"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@ -1843,6 +1900,16 @@
"minipass": "^3.1.1"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"terser-webpack-plugin": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz",
@ -1859,6 +1926,18 @@
"terser": "^4.6.12",
"webpack-sources": "^1.4.3"
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.8.3",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
}
}
}
},
@ -11466,87 +11545,6 @@
}
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.0.0-beta.8",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.8.tgz",
"integrity": "sha512-oouKUQWWHbSihqSD7mhymGPX1OQ4hedzAHyvm8RdyHh6m3oIvoRF+NM45i/bhNOlo8jCnuJhaSUf/6oDjv978g==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"vue-router": {
"version": "3.4.7",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.7.tgz",

@ -0,0 +1,105 @@
import axios from 'axios';
import {
Message
} from 'element-ui'
import router from '../router/index'
import util from '@/util'
import config from '@/config'
const service = axios.create({
baseURL: config.host,
timeout: 10000000
})
// post请求头
service.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
// 请求拦截器
service.interceptors.request.use(config => {
const token = util.getCookie('admin-token')
if (token) {
config.headers.token = token
}
return config;
}, err => {
Message.error({
message: '退出登陆',
onClose: function () {
router.push({name: 'login'});
}
})
return Promise.reject(err);
})
// 响应拦截器
service.interceptors.response.use(
response => {
const res = response.data;
if (res.status == 200 || res.status == 10000 || res.status == 30001) {
return Promise.resolve(res).catch(e => {});
} else if (!res.status) {
return Promise.resolve(res).catch(e => {});
} else {
Message.error(res.message)
return Promise.reject(res)
}
},
// 服务器状态码不是200的情况
error => {
if (error.response.status) {
switch (error.response.status) {
// 401: 未登录
case 401:
history.back()
break;
default:
Message.error(error.response.data.message)
Promise.reject(res);
}
return Promise.reject(error.response);
}
}
);
function get(url, params) {
return new Promise((resolve, reject) => {
service.get(url, { params: params }).then(res => {
resolve(res);
}).catch(err => {
reject(err);
});
});
}
function post(url, params) {
return new Promise((resolve, reject) => {
service.post(url, params).then(res => {
resolve(res);
}).catch(err => {
reject(err.data);
});
});
}
function del(url, params) {
return new Promise((resolve, reject) => {
service.delete(url, {
params
}).then(res => {
resolve(res);
}).catch(err => {
reject(err.data);
});
});
}
function put(url, params) {
return new Promise((resolve, reject) => {
service.put(url, params).then(res => {
resolve(res);
}).catch(err => {
reject(err.data);
});
});
}
export { get, post, del, put }

@ -0,0 +1,9 @@
export default {
QueryProject: 'occupationlab/projectManage/getProjectDetail',
submit: 'python/python/submit',
runPythonCode: 'python/python/runPythonCode',
queryBcJudgmentByBcId: 'judgment/bcJudgmentPoint/queryBcJudgmentByBcId',
queryTestProject: 'occupationlab/projectManage/getProjectBySystemId',
saveCache: 'python/python/saveCache',
getLastCache: 'python/python/getLastCache',
}

@ -1,12 +1,12 @@
<template>
<div>
<el-container class="scrollbar" v-if="ishow">
<el-container class="scrollbar" v-if="pannelVisible">
<el-header>
<div class="flex between">
<div class="flex" style="width: 28%">
<p>实训项目</p>
<el-select
v-model="value1"
v-model="projectId"
placeholder="请选择"
class="select"
:disabled="projectPermissions != 0"
@ -14,7 +14,7 @@
style="flex: 1"
>
<el-option
v-for="item in value"
v-for="item in projectList"
:key="item.projectId"
:label="item.projectName"
:value="item.projectId"
@ -23,7 +23,7 @@
</div>
<div class="countDownBox">
<div style="margin-left: -40px;">
<div :sendSync="sendSync" :autoStart="autoStart" :defaultVal="defaultVal">
<div>
实训{{text}}时间
<span class="timeSpan">{{day}}</span>
<span class="timeSpan">{{hour}}</span>小时
@ -44,7 +44,7 @@
v-show="projectPermissions == 0"
@click="reload"
>重新开始</el-button>
<el-button class="submit-btn" style="margin-right:7px" @click="Submit()" :disabled="isSubmit">提交</el-button>
<el-button style="margin-right:7px" @click="submit" :disabled="isSubmit">提交</el-button>
</div>
</div>
</el-header>
@ -56,8 +56,8 @@
<p>实验目标</p>
</div>
<div class="font_css">
<div class="experimentalGoal">
<div class="break-all" v-html="experimentalGoal"></div>
<div class="experimentTarget">
<div class="break-all" v-html="experimentTarget"></div>
</div>
</div>
</div>
@ -70,24 +70,28 @@
<el-row>
<el-col :span="24">
<el-card shadow="hover">
<el-table :data="tableData" :stripe="true" height="405">
<el-table :data="taskList" :stripe="true" height="405">
<el-table-column type="index"></el-table-column>
<el-table-column prop="judgmentPointsName" label="判分标准" align="center"></el-table-column>
<el-table-column prop="right" label="完成结果" align="center">
<el-table-column prop="name" label="判分标准" align="center"></el-table-column>
<el-table-column label="完成结果" align="center">
<template slot-scope="scope">
<i
v-if="scope.row.right=='0'"
class="el-icon-check"
style="color:green;font-size:20px"
></i>
<i
v-else-if="scope.row.right=='-1'"
class="el-icon-close"
style="color:red;font-size:20px"
></i>
<template v-if="isSubmit">
<i
v-if="scope.row.finishedResult"
class="el-icon-check right"
></i>
<i
v-else
class="el-icon-close wrong"
></i>
</template>
</template>
</el-table-column>
<el-table-column prop="score" label="得分" align="center">
<template slot-scope="scope">
<template v-if="isSubmit">{{ scope.row.score }}</template>
</template>
</el-table-column>
<el-table-column prop="score" label="得分" align="center"></el-table-column>
</el-table>
</el-card>
</el-col>
@ -96,23 +100,23 @@
</div>
</el-aside>
<el-main>
<el-tabs v-model="activeName" type="card">
<el-tabs v-model="pannelTab" type="card">
<el-tab-pane label="案例" name="first">
<div class="break-all" v-html="caseDescription"></div>
<div class="break-all" v-html="experimentDescription"></div>
</el-tab-pane>
<el-tab-pane label="实验要求" name="second">
<el-collapse v-model="activeNames">
<el-collapse v-model="curReq">
<el-collapse-item v-for="(loop, index) in points" :key="index">
<template slot="title">
<i class="el-icon-s-ticket"></i>
<span style="font-size:16px">{{loop.judgmentPointsName}}</span>
<div class="break-all" v-html="loop.experimentalRequirements"></div>
</template>
<div class="break-all" v-html="loop.experimentalRequirements"></div>
<div class="break-all" v-html="loop.expserimentalRequirements"></div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<el-tab-pane label="实验提示" name="fifth" v-if="isstartexperimentSuggests">
<div class="break-all" v-html="experimentSuggests"></div>
<el-tab-pane label="实验提示" name="fifth" v-if="hintOpen">
<div class="break-all" v-html="experimentHint"></div>
</el-tab-pane>
</el-tabs>
</el-main>
@ -121,11 +125,11 @@
<!-- </div> -->
<div
:style="ishow ? {position: 'fixed', left: '85%',top:'50%'} : {position: 'fixed',top:'50%'}"
:style="pannelVisible ? {position: 'fixed', left: '85%',top:'50%'} : {position: 'fixed',top:'50%'}"
>
<div @click="step()">
<img src="../assets/img/left.png" alt class="m_step" v-if="ishow" />
<img src="../assets/img/right.png" alt class="n_step" v-if="!ishow" />
<div @click="togglePannel">
<img src="../assets/img/left.png" alt class="left-btn" v-if="pannelVisible" />
<img src="../assets/img/right.png" alt class="right-btn" v-if="!pannelVisible" />
</div>
</div>
</div>
@ -133,484 +137,291 @@
<script>
import newmain from "../util/newMain";
import axios from "axios";
import * as $ from "jquery";
import { get } from "http";
//"yyyy-MM-dd hh:mm:ss"
function formatDate(fmt,date) {
var date = date ? date : new Date()
var o = {
"M+" : date.getMonth()+1, //
"d+" : date.getDate(), //
"h+" : date.getHours(), //
"m+" : date.getMinutes(), //
"s+" : date.getSeconds(), //
"q+" : Math.floor((date.getMonth()+3)/3), //
"S" : date.getMilliseconds() //
};
if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o) {
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt;
}
import util from '@/util'
export default {
data() {
return {
systemId: this.$config.systemId,
test: [],
ishow: true,
grade: "00",
exampleData: "",
codeid: "",
codeIds: [],
judgmentPointsIds: [],
text: "",
isStart: false,
globalTimer: null, //setInterval
millisecond: 0,
countVal: this.defaultVal, //
pauseTime: 0,
day: 0,
seconds: 0,
minutes: 0,
hour: 0,
createTime: "", //
actEndTime: "", //
value1: "", //
value: [],
experimentalGoal: "", //
caseDescription: "", //
experimentSuggests: "", //
judgmentPointsName: "", //
points: [],
activeNames: [],
tableData: [],
activeName: "first",
schoolId: '',
studentId: "",
courseId: "",
projectId: "",
assessmentId: "",
projectPermissions: 0, //(0 1 2)
isSubmit: false,
entryTime: formatDate('yyyy-MM-dd hh:mm:ss'),
startTime: '',
stopTime: '',
isSelected: false,
userId: '',
workbenchCus: this.workbench,
isRecovery: false,
isstartexperimentSuggests: 1
systemId: util.getCookie('systemId'),
classId: util.getCookie('classId'),
className: util.getCookie('className') ? decodeURI(util.getCookie('className')) : '',
courseId: util.getCookie('courseId'),
projectId: util.getCookie('projectId') ? Number(util.getCookie('projectId')) : '',
assessmentId: util.getCookie('assessmentId'),
projectPermissions: 0, // (0 1 2)
isSubmit: false, //
entryTime: new Date(),
startTime: util.getCookie('startTime'),
endTime: util.getCookie('stopTime'),
pannelVisible: true, //
grade: '00', //
text: '', //
counterTimer: null, // setInterval
day: 0, //
seconds: 0, //
minutes: 0, //
hour: 0, //
projectList: [], //
experimentTarget: '', //
experimentDescription: '', //
experimentHint: '', //
hintOpen: 1, //
points: [], //
judgmentId: '', // id
curReq: [], //
taskList: [], //
pannelTab: 'first', //
isSelected: false // true
};
},
watch: {
countVal: {
deep: true,
handler: function(val, oldVal) {
let vm = this;
if (vm.needSendSunc) {
vm.passToParent(val);
}
}
},
needSendSunc: {
deep: true,
handler: function(val) {
let vm = this;
if (val) {
vm.passToParent(vm.countString);
mounted() {
this.projectPermissions = this.projectId ? 1 : 0 // /
if(this.projectId){ // projectId)
this.getList()
}else{ //
//
this.getList().then(() => {
let cache = localStorage.getItem('codeCache') //
//
if (cache) {
cache = JSON.parse(cache)
this.getCache(cache.projectId, cache.judgmentId)
} else {
this.getCache()
}
}
}).catch(res => {})
}
},
props: {
sendSync: {
type: Boolean,
default: false
},
autoStart: {
type: Boolean,
default: false
},
defaultVal: {
type: Number,
default: null
},
codeId: {
type: Number,
default: 0
},
workbench: {
type: Array,
default: []
}
},
computed: {
needSendSunc: function() {
return this.sendSync;
methods: {
//
getList(){
let data = {
systemId: this.systemId,
cId: this.courseId, // id
permissions: this.projectPermissions // /
}
return new Promise((resolve, reject) => {
this.$get(`${this.api.queryTestProject}`,data).then(res => {
const list = res.projects
this.projectList = list
if (!this.projectPermissions) this.projectId = list ? list[0].projectId : 0 //
this.getProDetail().then(() => {
resolve()
}).catch(res => {
reject()
})
}).catch(res => {
reject()
})
})
},
//
second: function() {
return this.num(this.seconds);
//
getProDetail() {
const projectId = this.projectId
return new Promise((resolve, reject) => {
this.$get(this.api.QueryProject, {
projectId
}).then(res => {
const points = res.projectJudgmentVos
const project = res.projectManage
points.map(e => {
e.code = '' // code
e.codeId = '' // codeIdcodeId
e.answer = '' //
})
this.points = points
this.taskList = points //
this.judgmentId = points[0].judgmentId //
this.experimentTarget = project.experimentTarget
this.experimentDescription = project.experimentDescription
this.experimentHint = project.experimentHint
this.hintOpen = !res.projectManage.hintOpen // 01
this.$emit('tell', projectId, this.points)
const isAss = this.projectPermissions == 1 //
this.text = isAss ? '剩余' : '已用'
this.countVal = isAss ? (new Date(this.endTime).getTime() - Date.now()) / 1000 : 0 // 0
this.startCount()
resolve()
}).catch(err => {
reject()
})
})
},
minute: function() {
return this.num(this.minutes);
}
},
mounted() {
this.schoolId = this.getCookie("schoolId");
this.assessmentId = this.getCookie("assessmentId");
this.userId = this.getCookie("userId");
this.studentId = this.getCookie("studentId");
this.projectId = this.getCookie("projectId");
// this.courseId = this.getCookie("courseId");
this.startTime = this.getCookie("startTime") ? new Date(this.getCookie("startTime")).getTime() : ''
this.stopTime = this.getCookie("stopTime") ? new Date(this.getCookie("stopTime")).getTime() : ''
this.projectPermissions = this.projectId ? 1 : 0
if(this.projectId){
this.getQueryProject();
}else{
this.getProjects();
let codeCache = localStorage.getItem('codeCache')
if(codeCache){
codeCache = JSON.parse(codeCache)
if(codeCache.systemId && codeCache.systemId == this.$config.systemId){
//
getCache(pId, jId) {
const projectId = pId || this.projectId
const judgmentId = jId || this.judgmentId
this.$post(this.api.getLastCache, {
bcId: judgmentId, // ididid
projectId, // id
cid: this.courseId // id
}).then(res => {
const code = res.getLastCache
//
if (code) {
this.$confirm('是否要继续上次的实验?', '提示', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'success'
}).then(() => {
this.value1 = codeCache.projectId
this.workbenchCus = codeCache.workbench
this.isRecovery = true
this.selectProject()
let codeIds = []
codeCache.workbench.map(n => codeIds.push(n.code.codeId))
codeIds = codeIds.filter(n => n)
this.codeIds = codeIds
this.$emit('recoveryCode',codeCache.workbench1)
localStorage.removeItem('codeCache') //
this.projectId = projectId
this.judgmentId = judgmentId
// idid
if (pId) {
this.getProDetail().then(() => {
const points = this.points
const item = points.find(e => e.judgmentId === judgmentId)
if (item) item.code = code
this.$emit('tell', projectId, points)
this.$emit('recoveryCode', points.findIndex(e => e.judgmentId === judgmentId) + '') // tab
}).catch(res => {})
} else {
const item = this.points.find(e => e.judgmentId === judgmentId)
if (item) item.code = code
this.$emit('tell', projectId, this.points)
this.$emit('recoveryCode')
}
}).catch(() => {
localStorage.removeItem('codeCache')
})
}
}
}
this.assessmentId && this.projectId && this.checkVer()
this.codeId && this.codeIds.push(this.codeId)
//
newmain.$on("codeid", val => {
this.codeid = val;
let codeId = this.codeid;
this.codeIds.push(codeId);
});
// tableData
newmain.$on("updateJud", item => {
let list = this.tableData
list.map(n => {
if(n.judgmentPointsId == item.id) n.isError = item.isError
})
this.tableData = list
});
},
methods: {
checkVer() {
let data = {
userId: this.userId,
id: this.assessmentId
}
this.$get(this.api.qualifications,data).then(res => {
if(res.message == 'false'){
this.isSubmit = true;
newmain.$emit("isSubmit", this.isSubmit);
}
});
}).catch(res => {})
},
//
selectProject(){
this.isSelected = true
this.getProDetail().then(() => {
this.getCache()
}).catch(res => {})
this.isSubmit = false
this.countVal = 0
this.grade = '00'
this.$emit('recoveryCode') //
newmain.$emit('isSubmit', this.isSubmit) //
},
//
reload() {
this.$post(this.api.DeleteCodes, this.codeIds).then(res => {
this.getClearTime()
this.grade = '00'
localStorage.removeItem('codeCache')
this.codeIds = []
this.isSubmit = false
newmain.$emit("isSubmit", this.isSubmit)
let workbench = this.workbench
workbench.map(n => {
n.code = {
code: '',
codeId: ''
}
})
this.$emit('recoveryCode',workbench)
let tableData = this.tableData
tableData.map(n => {
delete n.score
delete n.right
})
this.tableData = JSON.parse(JSON.stringify(tableData))
this.startCountFn()
});
this.reloadCount()
this.grade = '00'
localStorage.removeItem('codeCache')
this.isSubmit = false
newmain.$emit('isSubmit', this.isSubmit)
const points = this.points
points.map(e => {
e.code = ''
e.codeId = ''
e.answer = ''
})
this.$emit('tell', this.projectId, points)
this.$emit('recoveryCode')
this.startCount()
},
Submit() {
if(!this.codeIds.length) return this.$message.error('请先完成实验')
//
submit() {
const pointList = this.$parent.workbench
if(!pointList.find(e => e.codeId)) return this.$message.error('请先完成实验')
this.$confirm("此操作将视为结束考试, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
center: true
})
.then(() => {
this.actEndTime = new Date().getTime();
this.getClearTime();
//
this.$post(this.api.Submit, {
// projectPermissions: 0,
createTime: this.startTime,
endTime: this.stopTime,
projectId: this.projectId,
projectPermissions: this.projectPermissions,
// assessmentId: 1,
assessmentId: this.assessmentId ? this.assessmentId : '',
codeIds: this.codeIds,
judgmentPointsIds: this.judgmentPointsIds,
// studentId: 54,
studentId: this.studentId,
record: {
courseId: 1,
// courseId: this.courseId,
projectId: this.projectId,
createTime: this.startTime,
endTime: this.stopTime,
startTime: this.entryTime
}
}).then(() => {
const date = new Date()
const entryTime = this.entryTime
const timeSum = Math.ceil((date.getTime() - entryTime.getTime()) / 60000) //
const submitTime = util.formatDate('yyyy-MM-dd hh:mm:ss', date)
const projectId = this.projectId
const projectName = this.projectList.find(e => e.projectId == projectId).projectName //
this.reloadCount()
//
const attributesReqList = []
pointList.map(e => {
attributesReqList.push({
codeId: e.codeId,
bcId: e.judgmentId,
isSubmit: e.codeId ? 1 : 0,
answer: e.answer
})
.then(res => {
localStorage.removeItem('codeCache')
this.isSubmit = true
newmain.$emit("isSubmit", this.isSubmit);
let list = res.message
let workbench = this.workbenchCus.length ? this.workbenchCus : this.workbench
let result = []
workbench.map(n => {
result.push(list.find(e => e.judgmentPointsId == n.judgmentPointsId))
})
let tableData = this.tableData
result.map(n => {
if(tableData.find(e => e.judgmentPointsId == n.judgmentPointsId).isError){
n.score = 0
n.right = -1
}
})
this.tableData = result
//
var s = 0;
this.tableData.forEach(element => {
this.test = element.score;
s += this.test;
this.grade = s;
});
})
.catch(err => {});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消提交"
});
});
},
//
timeFormat(param) {
return param < 10 ? "0" + param : param;
},
//
step() {
$(".m_step").toggleClass("n_step");
this.ishow = !this.ishow;
},
//
getClearTime() {
// clearInterval(this.globalTimer);
clearInterval(this.countVal);
this.globalTimer = "";
// if(this.projectPermissions != 0){
this.countVal = "";
this.day = "00";
this.seconds = "00";
this.minutes = "00";
this.hour = "00";
// }else{
// this.text = ''
// }
},
handleData(project,type){
if(!this.isSelected){
this.value = project;
this.value1 = project[0].projectId;
}
this.projectId = type == 2 ? project[0].projectId : this.projectId
if(type == 2) this.getQueryProject(0,1)
this.projectPermissions = type == 1 ? project[0].projectPermissions : this.projectPermissions
this.$emit("tell", this.value1, this.projectPermissions,this.isRecovery ? this.workbenchCus : []);
this.experimentalGoal = project[0].experimentalGoal;
this.caseDescription = project[0].caseDescription;
this.experimentSuggests = project[0].experimentSuggests;
this.actEndTime = project[0].endTime;
this.isRecovery = false
},
getQueryProject(projectId,type) {
//++++
this.$get(this.api.QueryProject, {
// studentId: 54,
// projectId: 305,
// assessmentId: 1,
studentId: this.studentId,
projectId: projectId ? projectId : this.projectId,
assessmentId: this.assessmentId
})
.then(res => {
if(!type){
this.handleData(res.message.project,1)
this.projectId = res.message.project[0].projectId
}
this.points = res.message.points;
// -
if (this.points.length) {
this.$parent.workbench1 = '0';
}
this.tableData = res.message.points;
let arr1 = this.tableData;
let result1 = arr1.map(e => e.judgmentPointsId);
this.judgmentPointsIds = this.judgmentPointsIds.concat(result1);
this.isstartexperimentSuggests = !res.message.project[0].isstartexperimentSuggests //01
if (this.projectPermissions == "1") {
this.text = "剩余";
var interval = setInterval(() => {
//
let newTime = new Date().getTime();
//
let endTime = new Date(this.actEndTime).getTime();
let obj = null; //
if (endTime - newTime > 0) {
let time = (endTime - newTime) / 1000; //
let day = parseInt(time / (60 * 60 * 24));
let hou = parseInt((time % (60 * 60 * 24)) / 3600);
let min = parseInt(((time % (60 * 60 * 24)) % 3600) / 60);
let sec = parseInt(((time % (60 * 60 * 24)) % 3600) % 60);
obj = {
day: this.timeFormat(day),
hou: this.timeFormat(hou),
min: this.timeFormat(min),
sec: this.timeFormat(sec)
};
const data = {
classId: this.classId ? this.classId : '',
className: this.className ? this.className : '',
curriculumId: this.courseId,
startTime: this.projectPermissions ? this.startTime : util.formatDate('yyyy-MM-dd hh:mm:ss', entryTime), //
endTime: this.projectPermissions ? this.endTime : submitTime, //
submitTime, // 3
timeSum,
projectId,
projectName,
assessmentId: this.assessmentId ? this.assessmentId : '',
totalScore: 100, // 100
systemId: 1,
purpose: this.experimentTarget, //
attributesReqList
}
this.$post(this.api.submit, data).then(res => {
localStorage.removeItem('codeCache')
this.isSubmit = true
newmain.$emit('isSubmit', this.isSubmit)
let list = res.retInfo
let taskList = this.taskList
var score = 0
taskList.map(e => {
let item = list.find(n => n.judgmentPointsId === e.judgmentId)
if (item) {
e.score = item.score
e.finishedResult = item.finishedResult
} else {
// '00'
obj = {
day: "00",
hou: "00",
min: "00",
sec: "00"
};
clearInterval(interval);
e.score = 0
}
this.day = obj.day;
this.hour = obj.hou;
this.minutes = obj.min;
this.seconds = obj.sec;
}, 1000);
} else if (this.projectPermissions == "0") {
this.text = "已用";
//
this.createTime = new Date().getTime();
//
if (this.autoStart) {
this.startCountFn();
}
}
})
.catch(err => {});
},
getProjects(){
let data = {
systemId: this.systemId,
// schoolId: this.schoolId
schoolId: ''
}
this.$get(`${this.api.queryTestProject}`,data).then(res => {
this.handleData(res.message,2)
}).catch(res => {});
score += e.score
})
this.grade = util.handleZero(score)
})
.catch(err => {})
}).catch(() => {})
},
selectProject(){
this.isSelected = true
this.assessmentId = ''
this.judgmentPointsIds = []
this.codeIds = []
this.getQueryProject(this.value1)
this.isSubmit = false
this.countVal = 0
this.grade = 0
newmain.$emit("isSubmit", this.isSubmit)
//
togglePannel() {
this.pannelVisible = !this.pannelVisible
},
counterFn(counterTime) {
let leave1 = counterTime % (24 * 3600 * 1); //
let leave2 = leave1 % (3600 * 1); //
let leave3 = leave2 % (60 * 1); //
let day = Math.floor(counterTime / (24 * 3600 * 1)); //
let hour = Math.floor(leave1 / (3600 * 1)); //
let minutes = Math.floor(leave2 / (60 * 1)); //
let seconds = Math.round(leave3 / 1); //
day = day >= 10 ? day : "0" + day;
hour = hour >= 10 ? hour : "0" + hour;
minutes = minutes >= 10 ? minutes : "0" + minutes;
seconds = seconds >= 10 ? seconds : "0" + seconds;
this.day = day;
this.hour = hour;
this.minutes = minutes;
this.seconds = seconds;
//
timeFormat(param) {
return param < 10 ? '0' + param : param
},
startCountFn() {
if (!this.isStart) {
this.countVal = this.countVal ? this.countVal : 0;
let timer = setInterval(() => {
this.counterFn(this.countVal++);
}, 1000);
this.globalTimer = timer;
this.isStart = true;
}
//
reloadCount() {
clearInterval(this.counterTimer)
this.countVal = ''
this.day = '00'
this.seconds = '00'
this.minutes = '00'
this.hour = '00'
},
passToParent(data) {
this.$emit("getDataFromChild", data);
//
counter(counterTime) {
let leave1 = counterTime % (24 * 3600) //
let leave2 = leave1 % 3600 //
let leave3 = leave2 % 60 //
let day = Math.floor(counterTime / (24 * 3600 * 1)) //
let hour = Math.floor(leave1 / (3600 * 1)) //
let minutes = Math.floor(leave2 / (60 * 1)) //
let seconds = Math.round(leave3 / 1) //
day = day >= 10 ? day : "0" + day
hour = hour >= 10 ? hour : "0" + hour
minutes = minutes >= 10 ? minutes : "0" + minutes
seconds = seconds >= 10 ? seconds : "0" + seconds
this.day = day
this.hour = hour
this.minutes = minutes
this.seconds = seconds
},
getCookie(cookie_name) {
//cookiekeyvalue
var allcookies = document.cookie; //
var cookie_pos = allcookies.indexOf(cookie_name); // cookie,
if (cookie_pos != -1) {
// cookie_pos1
//cookie1=
cookie_pos = cookie_pos + cookie_name.length + 1; //cookie
var cookie_end = allcookies.indexOf(";", cookie_pos);
if (cookie_end == -1) {
cookie_end = allcookies.length;
} //cookie
var value = unescape(allcookies.substring(cookie_pos, cookie_end));
}
return value;
//
startCount() {
clearInterval(this.counterTimer)
this.counterTimer = setInterval(() => {
this.counter(this.projectPermissions ? this.countVal-- : this.countVal++)
}, 1000)
}
}
};

@ -2,26 +2,22 @@
<div style="display:flex;">
<div class="left">
<codemirror
v-model="exampleData"
:value="codeid"
v-model="codeVal"
:options="cmOption"
class="code-mirror"
@ready="onCmReady3"
@focus="onCmFocus"
@input="onCmCodeChange"
@ready="ready"
ref="myCmGenerate"
></codemirror>
<div v-if="isSubmit" class="code-mask"></div>
<el-button
class="func-btn"
type="warning"
@click="AnswerTips()"
:disabled="isAnswerTips"
@click="runCode"
:disabled="runEnable"
style="width:100px;position:absolute;z-index:99;background:#FDCA17;color:black;right: 50px;bottom:15px;"
>运行</el-button>
</div>
<div class="code-right answer">
<p class="text-wrapper">{{modifys}}</p>
<p class="text-wrapper" v-html="runResult"></p>
<div class="pic-wrap" v-if="picSrc">
<div style="margin-bottom: 5px;text-align: center">
<img class="pic" :src="picSrc" alt="">
@ -29,17 +25,14 @@
<el-button class="download-btn" type="primary" size="mini" @click="$refs.picLink.click()">下载图片</el-button>
<a ref="picLink" style="display: none;" download="运行结果.png" :href="picSrc">下载图片</a>
</div>
<div class="code_yes" v-show="this.isError == 0">
<div class="code_yes" v-show="this.isError">
<img src="../assets/img/yes.png" alt />运行成功
</div>
<div class="code_error" v-show="this.isError == 1">
<div class="code_error" v-show="this.isError === 0">
<img src="../assets/img/error.png" alt />
{{num}}行出现错误
<!-- <el-button
style="color:rgba(255,49,49,1);background:rgba(255,255,255,1);margin-left:80px"
>求助</el-button>-->
<el-button class="tips-btn" @click="getQueryAnswer()" v-show="ShowAssessmentId">提示</el-button>
<el-dialog title="答案提示" center :visible.sync="error">
{{errLine}}行出现错误
<el-button class="tips-btn" @click="getTips" v-show="showTips">提示</el-button>
<el-dialog title="答案提示" center :visible.sync="tipsVisible">
<el-tabs>
<el-tab-pane label="参考答案">
<div class="answer-wrap" v-html="answer"></div>
@ -92,32 +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 // input
export default {
props: ["workbench1", "code", "codeid", "projectId"],
props: ['workbench1', 'code', 'codeId', 'projectId'],
data() {
return {
datas: [],
ShowAssessmentId: false,
answer: "",
exampleData: this.code,
codeId: this.codeid,
codes: [],
submit: "",
modifys: "", //
isError: 2,
timer: "",
after: "",
num: "",
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
@ -145,222 +133,212 @@ export default {
showCursorWhenSelecting: true,
theme: "monokai", //
extraKeys: { Ctrl: "autocomplete" } // keyMap
}
},
inputTextReg: /^((?!#).*?(,|\(|\[|\{|\s)+)?input(?!\w)\(['|"]([\s\S]+?)['|"]\)/m, // input()
requestList: [], // inputaxios
sourceCode: '', // inputexit
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() {
this.assessmentId = this.getCookie("assessmentId");
if (!this.assessmentId) {
this.ShowAssessmentId = true;
}
if (!this.assessmentId) this.showTips = true
//
newmain.$on("isSubmit", isSubmit => {
this.isSubmit = isSubmit;
});
this.isSubmit = isSubmit
})
},
methods: {
onCmReady3() {
this.$refs.myCmGenerate.codemirror.setSize("auto", "calc(100vh - 167px)");
},
onCmFocus(instance, event) {},
getCookie(cookie_name) {
//cookiekeyvalue
var allcookies = document.cookie; //
var cookie_pos = allcookies.indexOf(cookie_name); // cookie,
if (cookie_pos != -1) {
// cookie_pos1
//cookie1=
cookie_pos = cookie_pos + cookie_name.length + 1; //cookie
var cookie_end = allcookies.indexOf(";", cookie_pos);
if (cookie_end == -1) {
cookie_end = allcookies.length;
} //cookie
var value = unescape(allcookies.substring(cookie_pos, cookie_end));
}
return value;
//
ready() {
this.$refs.myCmGenerate.codemirror.setSize("auto", "calc(100vh - 149px)");
},
/**
* python代码里如果有input函数的话是做了单独的处理的原理是先把所有input函数都替换成exit函数再在exit函数里加上特定标识再通过接口传给后端去执行
* 因为exit函数是跟input有类似的效果就是都会产生阻塞所以python引擎一旦遇到exit进程就会被停止然后返回exit函数里面的值而这个值就是上面说的特定标识加上原本这个input函数里的值
* 然后就可以通过这个返回的值来提示给用户让用户继续输入
* 下面这个函数就是递归执行这个input输入过程的函数
*/
confirmInput(msg){
let receiveResult = msg.replace('validing:','')
this.runResult += receiveResult
this.$prompt(receiveResult, "提示", {
confirmButtonText: "确定"
}).then(({ value }) => {
this.runResult += `${value}<br>`
// exit
this.sourceCode = this.sourceCode.replace(`exit('validing:${receiveResult.replace(/[\r\n]*/g,'')}')`,val => {
return `'${value}'`
})
this.sourceCode = this.sourceCode.replace(`exit("validing:${receiveResult.replace(/[\r\n]*/g,'')}")`,val => {
return `'${value}'`
})
clearTimeout(this.requestTimer)
// AnswerTips
this.requestTimer = setTimeout(() => {
this.requestList.map(n => n('interrupt'))
},1000)
onCmCodeChange(instance, obj) {
if(!this.submiting){
this.submiting = true
this.submit = 0;
this.projectId = this.projectId;
this.userId = this.getCookie("userId");
this.studentId = this.getCookie("studentId");
//
if (this.codeId == "") {
this.$post(this.api.AddCode, {
code: this.exampleData,
projectId: this.projectId,
// projectId: 305,
judgmentPointsId: this.workbench1,
userId: parseInt(this.userId),
studentId: this.studentId,
// studentId: 54,
submit: this.submit
axios.post(this.api.runPythonCode,{
code: this.codeVal,
bcId: this.workbench1,
cid: this.courseId,
projectId: this.projectId
},{
cancelToken: new CANCEL_TOKEN(c => { //
this.requestList.push(c)
})
.then(res => {
this.codeId = res.message;
this.submiting = false
newmain.$emit("codeid", this.codeId);
})
.catch(err => {});
} else {
//
// this.timer = setTimeout(this.UpdateCode, 300000);
this.submit = 0;
}
}
},
downloadFile(fileName,url) {
var x = new XMLHttpRequest()
x.open("GET", url, true)
x.responseType = 'blob'
x.onload=function(e) {
var url = window.URL.createObjectURL(x.response)
var a = document.createElement('a')
a.href = url
a.download = fileName
a.click()
}
x.send()
},
AnswerTips() {
// this.$post(this.api.AddCode, {
// // headers: {code: "#-*-coding:utf-8-*-"},
// code: "#-*-coding:utf-8-*-",
// codeId: this.codeId,
// submit: this.submit //(0,1)
// })
// .then(res => {
// })
// .catch(err => {});
}).then(response => {
let res = response.data
let result = res.message.result
if(result.includes('File ')){
let modify = res.message.result
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.runResult += result
}
}).catch(e => {
if(e && e.message == 'interrupt'){
this.runCode(true)
this.requestList = []
}
})
// return false
if (this.isSubmit == "") {
this.submit = 1;
if (this.codeid == "") {
}).catch(err => {})
},
//
runCode(isWhile) { // isWhiletruewhile
if (!this.isSubmit) {
let code = this.codeVal
if (!code) {
this.$message({
message: "警告哦,内容为空不可运行",
type: "warning"
});
})
} else {
// if (/^((?!#).*?(,|\(|\[|\{|\s)+)?input(?!\w)(,|\(|\)|\[|\]|\{|\}|\s)?/m.test(this.exampleData)) {
if (false) {
this.$prompt("请输入...", "提示", {
confirmButtonText: "确定"
}).then(({ value }) => {
this.datas = [];
this.datas.push(value);
this.$post(this.api.ChangeCode, {
datas: this.datas,
code: this.exampleData
})
.then(res => {
this.exampleData = res.message;
})
.catch(err => {
console.log(err);
});
let inputTextReg = this.inputTextReg
let inputFuncReg = /input\(['|"]/g
// input
if (inputTextReg.test(code)) {
let sourceCode = this.codeVal
sourceCode = sourceCode.replace(inputTextReg,val => {
return val.replace(/\\n/g,"")
})
this.codeVal = sourceCode
// inputexit"validing:"便
sourceCode = sourceCode.replace(inputFuncReg,val => {
return `exit(${val[val.length - 1]}validing:`
})
this.sourceCode = sourceCode
if(!isWhile) this.runResult = ''
this.$post(this.api.runPythonCode, {
code: this.codeVal,
bcId: this.workbench1,
cid: this.courseId,
projectId: this.projectId
}).then(res => {
let result = res.message.result
if(result.includes('File ')){
let modify = res.message.result
if(isWhile){
this.runResult += modify
}else{
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)
}
}).catch(err => {})
} else {
this.loadIns = Loading.service({
background: 'transparent'
})
//()
this.$post(this.api.UpdateCode, {
code: this.exampleData,
codeId: this.codeId,
submit: this.submit //(0,1)
// savefig(python),savefig
code = code.replace(/\.savefig\(([\u4e00-\u9fa5\w]*?['"])/mg, str => {
return str + Date.now()
})
// Python
this.$post(this.api.runPythonCode, {
code,
bcId: this.workbench1,
cid: this.courseId,
projectId: this.projectId
}).then(res => {
const data = res.code
const photo = data.photoUrl
const result = data.runResult
this.$emit('cache') //
this.loadIns.close()
this.picSrc = ''
this.$emit('update:codeId', res.codeId) // coddeId
this.$emit('update:answer', result) //
let imgList = ''
try {
imgList = eval(result)
} catch (error) {}
//
if (photo) {
this.isError = '' //
const text = result.replace(photo, '') //
this.runResult = text
this.picSrc = photo
} else if (imgList instanceof Array && imgList.length && (imgList[0].includes('.jpg') || imgList[0].includes('.png') || imgList[0].includes('img'))) {
/**
* 这段是为要下载图片的项目案例写的后端会返回图片名称的数组前端负责循环这个数组然后下载下来
* 只有该系统有这段代码因为其他7个系统没有下载图片的项目后续如果加了直接把这段代码复制过去即可
*/
imgList.map((n,i) => {
util.downloadFile(`${i+1}.jpg`,n)
})
this.isError = 0
this.runResult = '下载完成'
} 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()
})
.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{
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);
if(this.projectId == 593){
let str = /\d+\.\d+/.exec(modify)
if(str.length){
this.modifys = str[0]
}
}
}
})
.catch(res => {
res.status == 500 && this.$message.error('检测到代码里有非法代码,请检查是否有调用系统命令。')
this.loadIns.close()
});
clearTimeout(this.timer);
}
}
} else {
this.isAnswerTips = true;
this.runEnable = true
this.$message({
message: "警告哦,已提交不可再运行",
type: "warning"
});
})
}
},
UpdateCode() {
//()
this.$post(this.api.UpdateCode, {
code: this.exampleData,
codeId: this.codeId,
submit: this.submit //(0,1)
})
.then(res => {})
.catch(err => {});
clearTimeout(this.timer);
},
getQueryAnswer() {
this.error = true;
//
this.$get(this.api.QueryAnswer, {
judgmentPointsId: this.workbench1
})
.then(res => {
this.answer = res.message;
})
.catch(err => {});
//
getTips() {
this.tipsVisible = true
this.$get(this.api.queryBcJudgmentByBcId, {
bcId: this.workbench1
}).then(res => {
this.answer = res.experimentCode
}).catch(err => {})
}
}
};

@ -1,4 +1,29 @@
const isHh = location.host.includes('10.196.131.73') //是否是河海版本
const isBeta = process.env.NODE_ENV === 'development' || location.host.includes('39.108.250.202:9000') //是否是职站测试
const isPro = location.host.includes('occupationlab.com') //是否是职站生产
let host = ''
if(isHh) {
host = "http://10.196.131.73/"
} else if(isBeta) {
host = "http://39.108.250.202:9000/"
} else if(isPro) {
host = "http://www.occupationlab.com/"
}
export default {
/**
* @description 域名切换
*/
host,
/**
* @description 是否是河海版本
*/
isHh,
/**
* @description 是否是开发/测试版本
*/
isBeta,
/**
* @description 配置显示在浏览器标签的title
*/
@ -17,4 +42,4 @@ export default {
* @description 长时间未操作自动退出登录时间
*/
autoLogoutTime: 3600000
}
}

@ -4,13 +4,13 @@ import router from "./router";
import store from "./store";
import ElementUI from 'element-ui'
import './assets/element-variables.scss'
import api from './utils/api';
import api from './api';
import {
post,
get,
del,
put
} from './utils/http';
} from './api/http';
import VueCodeMirror from "vue-codemirror";
import "codemirror/lib/codemirror.css";
import vuescroll from "vuescroll"; //引入vuescroll

@ -0,0 +1,60 @@
export default {
getCookie(cookie_name) {
//获取cookie中指定key的value
var allcookies = document.cookie; //索引长度,开始索引的位置
var cookie_pos = allcookies.indexOf(cookie_name); // 如果找到了索引,就代表cookie存在,否则不存在
if (cookie_pos != -1) {
// 把cookie_pos放在值的开始,只要给值加1即可
//计算取cookie值得开始索引,加的1为“=”
cookie_pos = cookie_pos + cookie_name.length + 1; //计算取cookie值得结束索引
var cookie_end = allcookies.indexOf(";", cookie_pos);
if (cookie_end == -1) {
cookie_end = allcookies.length;
} //得到想要的cookie的值
var value = unescape(allcookies.substring(cookie_pos, cookie_end));
}
return value;
},
// 返回格式化时间,传参例如:"yyyy-MM-dd hh:mm:ss"
formatDate(fmt,date) {
var date = date ? date : new Date()
var o = {
"M+" : date.getMonth()+1, //月份
"d+" : date.getDate(), //日
"h+" : date.getHours(), //小时
"m+" : date.getMinutes(), //分
"s+" : date.getSeconds(), //秒
"q+" : Math.floor((date.getMonth()+3)/3), //季度
"S" : date.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o) {
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt
},
// 下载文件
downloadFile(fileName,url) {
var x = new XMLHttpRequest()
x.open("GET", url, true)
x.responseType = 'blob'
x.onload=function(e) {
var url = window.URL.createObjectURL(x.response)
var a = document.createElement('a')
a.href = url
a.download = fileName
a.click()
}
x.send()
},
// 小于0前面加上0
handleZero (num) {
return num < 10 ? '0' + num : num
}
}

@ -1,25 +0,0 @@
// let host = 'http://192.168.31.125:8081/python'//林
// let host = 'http://192.168.31.152:8081/python'//榕
let host = ''
if(location.host.includes('120.78.198.231') || process.env.NODE_ENV === 'development'){
host = 'http://120.78.198.231:8081/python'
}else{
host = 'http://www.occupationlab.com/python'
}
export default {
QueryProject: `${host}/python/queryProject`, //项目选择下拉框+项目信息+判分点信息展示
ProjectId: `${host}/python/projectId`, //判分点下拉框信息展示
Submit: `${host}/python/submit`, //提交代码与判分点进行判断
AddCode: `${host}/python/addCode`, //新增代码编译器
// AddCode: `${host}/python/updateCode`, //新增代码编译器
UpdateCode: `${host}/python/updateCode`, //实时更新编辑器代码(修改代码)
// UpdateCode: `${host}/python/updateCode`, //实时更新编辑器代码(修改代码)
QueryAnswer: `${host}/python/queryAnswer`, //提示答案
DeleteCodes: `${host}/python/deleteCodes`, //重新开始
QueryAllProject: `${host}/python/queryAllProject`, //项目选择下拉框
ChangeCode: `${host}/python/changeCode`, //input交互
queryTestProject: `${host}/python/queryTestProject`, //input交互
qualifications: `${host}/python/qualifications`, //input交互
saveEvaluation: `${host}/python/saveEvaluation` //中途退出实验并保存实验数据(虚拟仿真实验)
}

@ -1,358 +0,0 @@
import axios from 'axios';
import QS from 'qs';
// import store from '../store/index'
import {
Message
} from 'element-ui'
import router from '../router/index'
// 环境的切换
// if (process.env.NODE_ENV == 'development') {
// axios.defaults.baseURL = '/api';
// } else if (process.env.NODE_ENV == 'debug') {
// axios.defaults.baseURL = '';
// } else if (process.env.NODE_ENV == 'production') {
// axios.defaults.baseURL = 'http://api.123dailu.com/';
// }
// 请求超时时间
axios.defaults.timeout = 30000;
// post请求头
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
// 请求拦截器
// axios.interceptors.request.use(config => {
// if (sessionStorage.getItem('token')) {
// // 存在将token写入 request header
// config.headers.Authorization = `${sessionStorage.getItem('token')}`;
// }
// return config;
// }, err => {
// Message.error({
// message: '退出登陆',
// onClose: function () {
// router.push({name: 'login'});
// }
// })
// return Promise.reject(err);
// })
// 响应拦截器
// axios.interceptors.response.use(
// response => {
// consol.log(response.status)
// if (response.status === 200) {
// return Promise.resolve(response);
// } else {
// return Promise.reject(response);
// }
// },
// // 服务器状态码不是200的情况
// error => {
// if (error.response.status) {
// switch (error.response.status) {
// // 401: 未登录
// // 未登录则跳转登录页面,并携带当前页面的路径
// // 在登录成功后返回当前页面,这一步需要在登录页操作。
// case 500:
// router.replace({
// path: '/login',
// // query: { redirect: router.currentRoute.fullPath }
// });
// break;
// // 403 token过期
// // 登录过期对用户进行提示
// // 清除本地token和清空vuex中token对象
// // 跳转登录页面
// case 403:
// // Toast({
// // message: '登录过期,请重新登录',
// // duration: 1000,
// // forbidClick: true
// // });
// // 清除token
// sessionStorage.removeItem('token');
// store.commit('loginSuccess', null);
// // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
// setTimeout(() => {
// router.replace({
// path: '/login',
// query: {
// redirect: router.currentRoute.fullPath
// }
// });
// }, 1000);
// break;
// // 404请求不存在
// case 404:
// router.replace({
// path: '/404',
// });
// break;
// // 其他错误,直接抛出错误提示
// default:
// router.replace({
// path: '/500',
// });
// }
// return Promise.reject(error.response);
// }
// }
// );
/**
* get方法对应get请求
*/
export function get(url, params) {
return new Promise((resolve, reject) => {
axios.get(url, {
params: params
})
.then(res => {
if (res.data.status) {
switch (res.data.status) {
case 200:
resolve(res.data);
break;
case 10000:
resolve(res.data);
break;
case 300:
this.$message.error(
res.data.errmessage
);
break;
case 500:
this.$message.error(
res.data.errmessage
);
break;
case 404:
this.$message.error(
res.data.errmessage
);
break;
case 403:
this.$message.error(
res.data.errmessage
);
break;
case 401:
Message.error("token失效,请重新登录");
sessionStorage.removeItem('token');
router.replace('/login')
break;
case 405:
this.$message.error(
res.data.errmessage
);
break;
case 406:
this.$message.error(
res.data.errmessage
);
break;
}
}
})
.catch(err => {
reject(err.data)
this.$message({
showClose: true,
message: '请求失败,请刷新页面重新进行请求',
type: 'error'
});
})
});
}
/**
* post方法对应post请求
*/
export function post(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params,{headers: {code: "fsfsdff"}})
.then(res => {
if (res.data.status) {
switch (res.data.status) {
case 200:
resolve(res.data);
break;
case 300:
this.$message.error(
res.data.errmessage
);
break;
case 500:
reject(res.data)
break;
case 404:
this.$message.error(
res.data.errmessage
);
break;
case 403:
this.$message.error(
res.data.errmessage
);
break;
case 401:
Message.error("token失效,请重新登录");
sessionStorage.removeItem('token');
router.replace('/login')
break;
case 405:
this.$message.error(
res.data.errmessage
);
break;
case 406:
this.$message.error(
res.data.errmessage
);
break;
}
}
})
.catch(err => {
reject(err.data)
this.$message({
showClose: true,
message: '请求失败,请刷新页面重新进行请求',
type: 'error'
});
})
});
}
/**
* delete方法对应delete请求
*/
export function del(url, params) {
return new Promise((resolve, reject) => {
axios.delete(url, {
params: params
})
.then(res => {
if (res.data.status) {
switch (res.data.status) {
case 200:
resolve(res.data);
break;
case 300:
this.$message.error(
res.data.errmessage
);
break;
case 500:
this.$message.error(
res.data.errmessage
);
break;
case 404:
this.$message.error(
res.data.errmessage
);
router.replace({
path: '/404',
});
break;
case 403:
this.$message.error(
res.data.errmessage
);
break;
case 401:
Message.error("token失效,请重新登录");
sessionStorage.removeItem('token');
router.replace('/login')
break;
case 405:
this.$message.error(
res.data.errmessage
);
break;
case 406:
this.$message.error(
res.data.errmessage
);
break;
}
}
})
.catch(err => {
reject(err.data)
this.$message({
showClose: true,
message: '请求失败,请刷新页面重新进行请求',
type: 'error'
});
})
});
}
/**
* put修改
* @param {} url
* @param {*} params
*/
export function put(url, params) {
return new Promise((resolve, reject) => {
axios.put(url, params)
.then(res => {
if (res.data.status) {
switch (res.data.status) {
case 200:
resolve(res.data);
break;
case 300:
this.$message.error(
res.data.errmessage
);
break;
case 500:
this.$message.error(
res.data.errmessage
);
break;
case 404:
this.$message.error(
res.data.errmessage
);
break;
case 403:
this.$message.error(
res.data.errmessage
);
break;
case 401:
Message.error("token失效,请重新登录");
sessionStorage.removeItem('token');
router.replace('/login')
break;
case 405:
this.$message.error(
res.data.errmessage
);
break;
case 406:
this.$message.error(
res.data.errmessage
);
break;
}
}
})
.catch(err => {
reject(err.data)
this.$message({
showClose: true,
message: '请求失败,请刷新页面重新进行请求',
type: 'error'
});
})
});
}

@ -1,31 +1,34 @@
<template>
<template>
<div>
<div class="flex header">
<p>{{$config.title}}</p>
<div class="bt">
<el-button type="primary" @click="back()">退出实验</el-button>
<el-button type="primary" @click="back">退出实验</el-button>
</div>
</div>
<div class="flex center">
<p v-if="$config.isHh" style="font-size: 18px">{{$config.title}}</p>
<p>编程语言</p>
<el-input placeholder="请输入内容" v-model="value" :disabled="true"></el-input>
<el-input placeholder="请输入内容" v-model="language" :disabled="true"></el-input>
</div>
<div class="tab">
<el-tabs v-model="workbench1" type="card">
<el-tabs v-model="curTab" type="card">
<el-tab-pane
v-for="item in workbench"
:key="item.judgmentPointsId"
:label="item.judgmentPointsName"
:value="item.judgmentPointsId"
:key="item.judgmentId"
:label="item.name"
:value="item.judgmentId"
>
<codemirror
:key="codeKey"
:projectId.sync="projectId"
:code.sync="item.code.code"
:workbench1="item.judgmentPointsId"
:codeid.sync="item.code.codeId"
:code.sync="item.code"
:workbench1="item.judgmentId"
:codeId.sync="item.codeId"
:answer.sync="item.answer"
@cache="leavePage"
></codemirror>
</el-tab-pane>
</el-tabs>
@ -36,13 +39,7 @@
@tell="getQueryIndex"
@recoveryCode="recoveryCode"
ref="mainindex"
:autoStart="autoStart"
:sendSync="sendSync"
:defaultVal="defaultVal"
@getDataFromChild="getDataFromChild"
:codeId="codeId"
:workbench="workbench"
:key="codeId"
:workbench.sync="workbench"
></testPanel>
</div>
</div>
@ -51,115 +48,62 @@
<script>
import testPanel from "../components/TestPanel";
import codemirror from "../components/codemirror";
import { log } from "util";
//"yyyy-MM-dd hh:mm:ss"
function formatDate(fmt,date) {
var date = date ? date : new Date()
var o = {
"M+" : date.getMonth()+1, //
"d+" : date.getDate(), //
"h+" : date.getHours(), //
"m+" : date.getMinutes(), //
"s+" : date.getSeconds(), //
"q+" : Math.floor((date.getMonth()+3)/3), //
"S" : date.getMilliseconds() //
};
if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o) {
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt;
}
import util from '@/util'
export default {
data() {
return {
//
isShow: false,
projectPermissions: 0, //(0 1 2)
ops: {
vuescroll: {},
scrollPanel: {},
rail: {
keepShow: true
},
bar: {
hoverStyle: true,
onlyShowBarOnScroll: false, //
background: "red", //
opacity: 0.5, //
"overflow-x": "hidden"
}
},
judgmentPointsId: "",
codeId: 0,
value: "Python",
workbench1: "", //
workbench: [],
editableTabs: [],
tabIndex: 2,
name: "",
judgmentPointsIds: [],
autoStart: true,
sendSync: true,
entryTime: formatDate('yyyy-MM-dd hh:mm:ss'),
assessmentId: '',
defaultVal: sessionStorage.getItem("timer")
? parseInt(sessionStorage.getItem("timer"))
: 0,
codeKey: 1,
courseId: util.getCookie("courseId"), // id
assessmentId: util.getCookie("assessmentId"), // id
projectPermissions: 0, // (0 1 2)
language: 'Python', //
curTab: '', //
workbench: [], //
codeKey: 1 //
};
},
components: {
codemirror,
testPanel
},
beforeDestroy(){
let data = {
studentId: this.studentId,
startTime: this.entryTime,
endTime: formatDate('yyyy-MM-dd hh:mm:ss'),
projectId: this.projectId
}
this.$post(this.api.saveEvaluation,data).then(res => {})
this.leavePage()
},
mounted() {
this.autoLogout()
this.assessmentId = this.getCookie("assessmentId");
if (window.history && window.history.pushState) {
//
history.pushState(null, null, document.URL);
window.addEventListener("popstate", this.goBack, false);
//
window.onbeforeunload = () => {
this.leavePage()
}
},
destroyed() {
window.removeEventListener("popstate", this.goBack, false);
},
methods: {
//
leavePage(){
if(!this.$refs.mainindex.isSubmit && !this.assessmentId && this.workbench.length){
let workbench = this.workbench
if(workbench.some(n => n.code.code)){
let codeCache = {
systemId: this.$config.systemId,
projectId: this.projectId,
workbench1: this.workbench1,
workbench
}
localStorage.setItem('codeCache',JSON.stringify(codeCache))
const list = this.workbench
if(!this.$refs.mainindex.isSubmit && list.length && list.some(e => e.code)){
const cache = {
projectId: this.projectId,
judgmentId: list[Number(this.curTab)].judgmentId
}
localStorage.setItem('codeCache', JSON.stringify(cache)) // ididid
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 => {})
}
})
}
},
// 退
autoLogout(){
let lastTime = new Date().getTime()
let logout = false
//
document.onmousedown = () => {
lastTime = new Date().getTime()
}
// 退
setInterval(() => {
if((new Date().getTime() - lastTime) > this.$config.autoLogoutTime){
logout || this.$message.error('用户登录过期,请重新登录')
@ -168,93 +112,20 @@ export default {
}
},1000)
},
goBack() {
this.leavePage()
history.back()
},
getDataFromChild(data) {
sessionStorage.setItem("timer", parseInt(data));
},
recoveryCode(workbench){
this.workbench = workbench
//
recoveryCode(curTab = '0'){
this.curTab = curTab
this.codeKey++
this.workbench1 = '0'
},
reload(){
this.$refs.mainindex.reload()
},
// 退
back() {
this.leavePage()
if(this.projectPermissions){
//
if(location.host.includes('120.78.198.231')){
//
location.href = `http://120.78.198.231/#/ass/list`
}else{
//
location.href = `http://www.occupationlab.com/#/dashboard#2`
}
}else{
//
if(location.host.includes('120.78.198.231')){
location.href = `http://120.78.198.231/#/station/list`
}else{
location.href = `http://www.occupationlab.com/#/dashboard#1`
}
}
this.$refs.mainindex.getClearTime();
history.back()
},
//
getQueryIndex(value1, projectPermissions,workBench) {
//
this.projectId = value1;
this.projectPermissions = projectPermissions;
this.studentId = this.getCookie("studentId");
this.$get(this.api.ProjectId, {
projectId: this.projectId,
// studentId: this.studentId
studentId: 54
})
.then(res => {
if(workBench.length){
this.workbench = workBench
}else{
this.workbench = res.message;
this.workbench.map(item => {
if (item.code.codeId == 0) {
item.code.codeId = "";
}
if (this.projectPermissions == "0") {
item.code.codeId = "";
item.code.code = "";
}
});
}
this.assessmentId && (this.codeId = this.workbench[0].code.codeId)
})
.catch(err => {
console.log(err);
});
// id
getQueryIndex(projectId, workbench) {
this.projectId = projectId
this.workbench = workbench
},
getCookie(cookie_name) {
//cookiekeyvalue
var allcookies = document.cookie; //
var cookie_pos = allcookies.indexOf(cookie_name); // cookie,
if (cookie_pos != -1) {
// cookie_pos1
//cookie1=
cookie_pos = cookie_pos + cookie_name.length + 1; //cookie
var cookie_end = allcookies.indexOf(";", cookie_pos);
if (cookie_end == -1) {
cookie_end = allcookies.length;
} //cookie
var value = unescape(allcookies.substring(cookie_pos, cookie_end));
}
return value;
}
}
};
</script>

Loading…
Cancel
Save