master
yujialong 4 years ago
commit 373c3644a7
  1. 21
      .gitignore
  2. 5
      babel.config.js
  3. 12417
      package-lock.json
  4. 40
      package.json
  5. BIN
      public/favicon.ico
  6. 17
      public/index.html
  7. 44
      src/App.vue
  8. 8
      src/assets/element-variables.scss
  9. BIN
      src/assets/img/bg1.png
  10. BIN
      src/assets/img/bg2.png
  11. BIN
      src/assets/img/btn.png
  12. BIN
      src/assets/img/error.png
  13. BIN
      src/assets/img/header.png
  14. BIN
      src/assets/img/left.png
  15. BIN
      src/assets/img/right.png
  16. BIN
      src/assets/img/yes.png
  17. BIN
      src/assets/logo.png
  18. 1
      src/assets/styles/var.scss
  19. 893
      src/components/TestPanel.vue
  20. 548
      src/components/codemirror.vue
  21. 16
      src/config/index.js
  22. 51
      src/main.js
  23. 35
      src/router/index.js
  24. 23
      src/store/index.js
  25. 2
      src/util/newMain.js
  26. 16
      src/util/rem.js
  27. 25
      src/utils/api.js
  28. 360
      src/utils/http.js
  29. 399
      src/views/Home.vue
  30. 29
      vue.config.js

21
.gitignore vendored

@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

12417
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,40 @@
{
"name": "python_demo",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "npm run serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"axios": "^0.19.2",
"core-js": "^3.6.5",
"element-ui": "^2.13.2",
"jquery": "^3.5.1",
"lib-flexible": "^0.3.2",
"postcss-px2rem": "^0.3.0",
"postcss-pxtorem": "^5.1.1",
"px2rem-loader": "^0.1.9",
"vue": "^2.6.12",
"vue-codemirror": "^4.0.6",
"vue-draggable-resizable": "^2.2.0",
"vue-draggable-resizable-gorkys": "^2.4.4",
"vue-router": "^3.4.7",
"vuescroll": "^4.16.1",
"vuex": "^3.5.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.8",
"@vue/cli-plugin-router": "^4.5.8",
"@vue/cli-plugin-vuex": "^4.5.8",
"@vue/cli-service": "^4.5.8",
"node-sass": "^4.14.1",
"sass-loader": "^8.0.2",
"vue-template-compiler": "^2.6.12"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

@ -0,0 +1,44 @@
<template>
<div>
<!-- <div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>-->
<router-view />
</div>
</template>
<script>
export default {
name: "App",
created() {
//sessionStorage
if (sessionStorage.getItem("store")) {
this.$store.replaceState(
Object.assign(
{},
this.$store.state,
JSON.parse(sessionStorage.getItem("store"))
)
);
} //vuexsessionStorage
window.addEventListener("beforeunload", () => {
sessionStorage.setItem("store", JSON.stringify(this.$store.state));
});
}
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
body {
margin: 0;
}
</style>

@ -0,0 +1,8 @@
/* 改变主题色变量 */
@import 'styles/var.scss';
$--color-primary: $main-color;
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

@ -0,0 +1 @@
$main-color: #ff8a00;

@ -0,0 +1,893 @@
<template>
<div>
<el-container class="scrollbar" v-if="ishow">
<el-header>
<div class="flex between">
<div class="flex" style="width: 28%">
<p>实训项目</p>
<el-select
v-model="value1"
placeholder="请选择"
class="select"
:disabled="projectPermissions != 0"
@change="selectProject"
style="flex: 1"
>
<el-option
v-for="item in value"
:key="item.projectId"
:label="item.projectName"
:value="item.projectId"
></el-option>
</el-select>
</div>
<div class="countDownBox">
<div style="margin-left: -40px;">
<div :sendSync="sendSync" :autoStart="autoStart" :defaultVal="defaultVal">
实训{{text}}时间
<span class="timeSpan">{{day}}</span>
<span class="timeSpan">{{hour}}</span>小时
<span class="timeSpan">{{minutes}}</span>
<span class="timeSpan">{{seconds}}</span>
</div>
</div>
</div>
<div class="countDownBox">
<div>
总得分
<span class="gradeSpan">{{grade}}</span>
</div>
</div>
<div>
<el-button
style="backgroundColor: #202020;color: #d0d0d0;font-size:14px;"
v-show="projectPermissions == 0"
@click="reload"
>重新开始</el-button>
<el-button class="submit-btn" style="margin-right:7px" @click="Submit()" :disabled="isSubmit">提交</el-button>
</div>
</div>
</el-header>
<el-container>
<el-aside width="30%">
<div class="aside-header">
<div class="header_h flex">
<i class="el-icon-s-order"></i>
<p>实验目标</p>
</div>
<div class="font_css">
<div class="experimentalGoal">
<div class="break-all" v-html="experimentalGoal"></div>
</div>
</div>
</div>
<div class="aside-footer">
<div class="header_h flex">
<i class="el-icon-s-management"></i>
<p>实验任务</p>
</div>
<div>
<el-row>
<el-col :span="24">
<el-card shadow="hover">
<el-table :data="tableData" :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">
<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>
</el-table-column>
<el-table-column prop="score" label="得分" align="center"></el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
</div>
</div>
</el-aside>
<el-main>
<el-tabs v-model="activeName" type="card">
<el-tab-pane label="案例" name="first">
<div class="break-all" v-html="caseDescription"></div>
</el-tab-pane>
<el-tab-pane label="实验要求" name="second">
<el-collapse v-model="activeNames">
<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>
</template>
<div class="break-all" v-html="loop.experimentalRequirements"></div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<el-tab-pane label="实验提示" name="fifth" >
<div class="break-all" v-html="experimentSuggests"></div>
</el-tab-pane>
</el-tabs>
</el-main>
</el-container>
</el-container>
<!-- </div> -->
<div
:style="ishow ? {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>
</div>
</div>
</template>
<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;
}
export default {
data() {
return {
systemId: this.$config.systemId,
test: [],
ishow: false,
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
};
},
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);
}
}
}
},
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;
},
//
second: function() {
return this.num(this.seconds);
},
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){
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)
}).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);
}
});
},
//
reload() {
this.$post(this.api.DeleteCodes, this.codeIds).then(res => {
this.getClearTime()
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()
});
},
Submit() {
if(!this.codeIds.length) 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(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;
this.tableData = res.message.points;
let arr1 = this.tableData;
let result1 = arr1.map(e => e.judgmentPointsId);
this.judgmentPointsIds = this.judgmentPointsIds.concat(result1);
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)
};
} else {
// '00'
obj = {
day: "00",
hou: "00",
min: "00",
sec: "00"
};
clearInterval(interval);
}
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 => {});
},
selectProject(){
this.isSelected = true
this.assessmentId = ''
this.judgmentPointsIds = []
this.codeIds = []
this.getQueryProject(this.value1)
this.isSubmit = false
this.countVal = 0
newmain.$emit("isSubmit", this.isSubmit)
},
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;
},
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;
}
},
passToParent(data) {
this.$emit("getDataFromChild", data);
},
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>
<style lang="scss" scoped>
.break-all{
word-break: break-all;
}
.m_step {
height: 150px;
cursor: pointer;
display: block !important;
}
.n_step {
height: 150px;
cursor: pointer;
display: block !important;
}
//el-main
.el-main {
width: 60%;
background-color: #fff;
color: #333;
padding: 0;
font-size: 16px;
margin: 0px 20px 10px 10px;
white-space: pre-wrap;
background: #fff url(../assets/img/bg1.png) top right no-repeat,url(../assets/img/bg2.png) bottom right no-repeat;
}
::v-deep .el-collapse-item__wrap {
border-bottom: none;
}
::v-deep .el-collapse-item__header {
border-bottom: none;
}
::v-deep .el-tabs__content {
margin: 0 20px;
}
::v-deep .el-icon-s-ticket:before {
font-size: 16px;
padding: 5px;
color: $main-color;
}
::v-deep .el-collapse-item__arrow {
margin: 0 5px 0 0;
}
::v-deep .el-icon-arrow-right:before {
// content: "\e78f";
font-size: 12px;
padding: 1px;
margin-left: 10px;
background-color: $main-color;
border-radius: 50%;
color: #ffffff;
}
::v-deep .el-tabs__item {
font-size: 16px;
}
::v-deep .el-tabs--card > .el-tabs__header .el-tabs__nav {
border: none;
}
::v-deep .el-tabs--card > .el-tabs__header .el-tabs__item {
border-left: none;
}
::v-deep .el-tabs--card > .el-tabs__header {
border-bottom: none;
}
::v-deep .el-collapse {
border-bottom: none;
border-top: none;
height: 500px;
overflow: hidden;
overflow-y: auto;
}
::v-deep .el-tabs__item.is-active {
color: #fff;
background-color: $main-color;
}
::v-deep .el-tabs__header {
padding: 5px 20px;
}
//el-aside
.el-aside {
color: #333;
}
.el-aside ::v-deep [class*=" el-icon-"],
[class^="el-icon-"] {
line-height: 40px;
font-size: 16px;
}
.aside-header {
margin: 0px 10px 10px 10px;
background-color: #fff;
}
.aside-footer {
margin: 0px 10px 10px 10px;
background-color: #fff;
}
.header_h {
height: 50px;
background: url(../assets/img/header.png) 0 0/100% 100% no-repeat;
justify-content: center;
}
.header_h i {
color: #fff;
}
.header_h p {
line-height: 40px;
font-size: 16px;
color: #fff;
padding-left: 10px;
}
/deep/.el-card{
border: 0;
border-radius: 0;
}
//
::v-deep .el-card__body {
padding: 0;
}
::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td {
background: #ffebf9;
}
::v-deep .el-table td,
.el-table th.is-leaf {
border-bottom: 0;
}
::v-deep .el-table th > .cell {
font-weight: 100;
}
::v-deep .el-table thead {
color: #ffffff;
font-size: 10px;
th{
padding: 5px 0;
}
}
::v-deep .el-table th,
.el-table tr {
background-color: #ffc385;
}
::v-deep .el-table {
font-size: 12px;
color: #202020;
}
/deep/.el-collapse-item__content{
padding-left: 10px;
padding-right: 10px;
}
//.el-header
.el-header {
color: #333;
padding: 0 12px 0 20px;
}
.between {
justify-content: space-between;
}
//
.font_css {
margin: 0 10px;
text-indent: 2em;
font-size: 14px;
padding: 10px 0;
}
//placeholder
.select ::v-deep input::-webkit-input-placeholder {
color: #333;
}
.select ::v-deep input::-moz-input-placeholder {
color: #333;
}
.select ::v-deep input::-ms-input-placeholder {
color: #333;
}
//icon
.select ::v-deep .el-input__icon {
line-height: 60px;
}
//
.select ::v-deep .el-select__caret:before {
content: "\e78f";
font-size: 16px;
padding: 3px;
background-color: $main-color;
border-radius: 50%;
color: #ffffff;
}
.select ::v-deep .el-input--suffix .el-input__inner {
color: #333;
font-size: 14px;
border-radius: 30px;
border: none;
background-color: #fff;
margin-left: 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
// white-space: pre-line;
}
.select ::v-deep .el-input {
padding: 10px 0;
}
//
.countDownBox {
font-size: 16px;
margin: 0 10px;
padding: 20px 0;
}
.timeSpan {
color: #333333;
padding: 5px 15px;
font-size: 14px;
background: #ffffff;
border-radius: 18px;
margin: 0 5px;
text-align: center;
}
.gradeSpan {
color: #878787;
padding: 10px;
font-size: 14px;
background: #ffc385;
border-radius: 6px;
text-align: center;
}
//
.el-header ::v-deep .el-button {
background-color: $main-color;
color: #fff;
border: none;
margin: 5px 0px 5px 5px;
font-size: 16px;
}
.el-header .submit-btn{
padding-left: 30px;
padding-right: 30px;
background: $main-color url(../assets/img/btn.png) 0 0/100% 100% no-repeat;
}
.el-header ::v-deep .el-button:hover,
.el-button:focus,
.el-button:active {
background-color: $main-color;
color: #fff;
}
//
::v-deep .el-container {
height: 80%;
}
.el-container.is-vertical {
background-color: #f5f5f5;
width: 85%;
height: 70%;
position: fixed;
top: 200px;
bottom: 20px;
left: 0;
}
.flex {
display: flex;
align-items: center;
}
//
.scrollbar ::-webkit-scrollbar {
width: 2px; //
height: 6px; //
}
//
.scrollbar ::-webkit-scrollbar-thumb {
background-color: $main-color;
border-radius: 3px;
box-shadow: inset 0 0 5px #dddddd;
}
.scrollbar ::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #dddddd;
border-radius: 0;
background: #dddddd;
}
</style>

@ -0,0 +1,548 @@
<template>
<div style="display:flex;">
<div style="position:relative;width: 100%;" class="button">
<codemirror
v-model="exampleData"
:value="codeid"
:options="cmOption"
class="code-mirror"
@ready="onCmReady3"
@focus="onCmFocus"
@input="onCmCodeChange"
ref="myCmGenerate"
></codemirror>
<div v-if="isSubmit" class="code-mask"></div>
<el-button
class="func-btn"
type="warning"
@click="AnswerTips()"
:disabled="isAnswerTips"
>运行</el-button>
</div>
<div class="code-right answer">
<p class="text-wrapper">{{modifys}}</p>
<div class="pic-wrap" v-if="picSrc">
<div style="margin-bottom: 5px;text-align: center">
<img class="pic" :src="picSrc" alt="">
</div>
<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">
<img src="../assets/img/yes.png" alt />运行成功
</div>
<div class="code_error" v-show="this.isError == 1">
<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">
<el-tabs>
<el-tab-pane label="参考答案">
<div class="answer-wrap" v-html="answer"></div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
</div>
</div>
</template>
<script>
import newmain from "../util/newMain";
import { codemirror } from "vue-codemirror";
import "codemirror/theme/ambiance.css"; //
import "codemirror/mode/javascript/javascript.js";
import "codemirror/lib/codemirror.css";
// require active-line.js
import "codemirror/addon/selection/active-line.js";
// styleSelectedText
import "codemirror/addon/selection/mark-selection.js";
// hint
import "codemirror/addon/hint/show-hint.js";
import "codemirror/addon/hint/sql-hint.js";
import "codemirror/addon/hint/show-hint.css";
import "codemirror/addon/hint/javascript-hint.js";
// highlightSelectionMatches
import "codemirror/addon/scroll/annotatescrollbar.js";
import "codemirror/addon/search/matchesonscrollbar.js";
import "codemirror/addon/search/match-highlighter.js";
// keyMap
import "codemirror/mode/clike/clike.js";
import "codemirror/mode/sql/sql.js";
import "codemirror/addon/edit/matchbrackets.js";
import "codemirror/addon/comment/comment.js";
import "codemirror/addon/dialog/dialog.js";
import "codemirror/addon/dialog/dialog.css";
import "codemirror/addon/search/searchcursor.js";
import "codemirror/addon/search/search.js";
import "codemirror/keymap/sublime.js";
// foldGutter
import "codemirror/addon/fold/foldgutter.css";
import "codemirror/addon/fold/brace-fold.js";
import "codemirror/addon/fold/comment-fold.js";
import "codemirror/addon/fold/foldcode.js";
import "codemirror/addon/fold/foldgutter.js";
import "codemirror/addon/fold/indent-fold.js";
import "codemirror/addon/fold/markdown-fold.js";
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';
export default {
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,
cmOption: {
scrollbarStyle: "native",
tabSize: 2, // tab
styleActiveLine: true, //
lineNumbers: true, //
styleSelectedText: true,
line: true,
foldGutter: true, //
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
highlightSelectionMatches: { showToken: /\w/, annotateScrollbar: true }, //
mode: {
// , codemirror/mode
name: "javascript",
json: true
},
lineWrapping: true, //
// hint.js options
hintOptions: {
//
completeSingle: false
},
// sublimeemacsvim
keyMap: "sublime",
matchBrackets: true,
showCursorWhenSelecting: true,
theme: "monokai", //
extraKeys: { Ctrl: "autocomplete" } // keyMap
}
};
},
components: {
codemirror
},
watch: {
list() {
this.timer();
},
exampleData(val) {
this.$emit("update:code", val);
},
codeId(val) {
this.$emit("update:codeid", val);
}
},
mounted() {
this.assessmentId = this.getCookie("assessmentId");
if (!this.assessmentId) {
this.ShowAssessmentId = true;
}
//
newmain.$on("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;
},
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
})
.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 => {});
// return false
if (this.isSubmit == "") {
this.submit = 1;
if (this.codeid == "") {
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);
});
}).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)
})
.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(err => {
this.loadIns.close()
});
clearTimeout(this.timer);
}
}
} else {
this.isAnswerTips = 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 => {});
}
}
};
</script>
<style lang="scss" scoped>
.text-wrapper {
white-space: pre-wrap;
}
//
.answer ::v-deep .el-tab-pane {
padding: 0 10px;
height: 340px;
overflow: hidden;
overflow-y: auto;
white-space: pre-wrap;
}
.answer ::v-deep .el-dialog--center {
width: 500px;
height: 500px;
}
.answer ::v-deep .el-dialog__title {
font-size: 22px;
font-weight: 500;
}
.answer ::v-deep .el-tabs__nav-wrap::after {
background-color: #333;
}
.answer ::v-deep .el-tabs__active-bar {
background-color: #fff;
height: 0;
}
.answer ::v-deep .el-tabs__header {
background-color: #333;
}
.answer ::v-deep .el-dialog--center .el-dialog__body {
padding: 0;
}
.answer ::v-deep .el-tabs__item {
color: #fff;
width: 80px;
}
.answer ::v-deep .el-tabs--top .el-tabs__item.is-top:nth-child(2) {
padding-left: 20px;
}
.answer ::v-deep .el-tabs__item.is-active {
color: #fff !important;
background-color: #333 !important;
}
::v-deep .CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
height: 30px;
line-height: 30px;
}
.cm-s-monokai .CodeMirror-linenumber {
height: 30px;
line-height: 30px;
}
.code-right ::v-deep .tips-btn {
margin-top: 10px;
height: 40px;
width: 90px;
border: none;
position: absolute;
right: 0;
background: rgba(255, 49, 49, 1);
color: rgba(255, 255, 255, 1);
}
.code-right ::v-deep .tips-btn:hover,
.tips-btn:focus,
.tips-btn:active {
background: rgba(255, 49, 49, 1);
color: rgba(255, 255, 255, 1);
}
.code_error img {
width: 40px;
height: 40px;
margin-top: 5px;
margin-right: 10px;
}
.code_yes img {
width: 40px;
height: 40px;
margin-top: 5px;
margin-right: 10px;
}
.code_yes {
color: $main-color;
background-color: rgba(43, 40, 22, 1);
}
.code_error {
background-color: rgba(43, 22, 22, 1);
color: red;
}
.code_error,
.code_yes {
display: flex;
bottom: 10px;
position: absolute;
left: 20px;
right: 20px;
padding: 0 10px;
box-sizing: border-box;
}
.code-right p {
font-size: 18px;
margin: 10px;
position: absolute;
height: calc(100vh - 230px);
overflow: auto;
}
.code-right {
width: 500px;
color: #ffffff;
background: #1b1b1b;
display: inline-block;
position: relative;
}
.button ::v-deep .el-button--warning:hover,
.el-button--warning:focus,
.el-button--warning:active {
background: $main-color;
color: #333;
}
.flex {
display: flex;
}
//
.scrollbar ::-webkit-scrollbar {
width: 2px; //
height: 6px; //
}
//
.scrollbar ::-webkit-scrollbar-thumb {
background-color: $main-color;
border-radius: 3px;
box-shadow: inset 0 0 5px #dddddd;
}
.scrollbar ::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #dddddd;
border-radius: 0;
background: #dddddd;
}
.pic-wrap{
position: absolute;
left: 0;
right: 0;
bottom: 5px;
text-align: center;
.pic{
max-width: 80%;
vertical-align: middle;
}
}
.code-mask{
z-index: 2;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.func-btn{
width:100px;
position:absolute;
z-index:99;
background:$main-color;
color:#fff !important;
right: 50px;
bottom:15px;
border-color: $main-color;
}
.download-btn{
background:$main-color;
color:#fff;
border-color: $main-color
}
/deep/.answer-wrap{
img{
max-width: 100%;
}
}
</style>

@ -0,0 +1,16 @@
export default {
/**
* @description 配置显示在浏览器标签的title
*/
title: 'Python数据清洗教学实验系统',
/**
* @description 是否使用国际化默认为false
* 如果不使用则需要在路由中给需要在菜单中展示的路由设置meta: {title: 'xxx'}
* 用来在菜单中显示文字
*/
locale: 'zh',
/**
* @description 跳转子系统链接
*/
systemId: 9
}

@ -0,0 +1,51 @@
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import ElementUI from 'element-ui'
import './assets/element-variables.scss'
import api from './utils/api';
import {
post,
get,
del,
put
} from './utils/http';
import VueCodeMirror from "vue-codemirror";
import "codemirror/lib/codemirror.css";
import vuescroll from "vuescroll"; //引入vuescroll
import "vuescroll/dist/vuescroll.css"; //引入vuescroll样式
import VueDraggableResizable from 'vue-draggable-resizable'
import config from '@/config'
// optionally import default styles
import 'vue-draggable-resizable/dist/VueDraggableResizable.css'
Vue.component('vue-draggable-resizable', VueDraggableResizable)
Vue.use(ElementUI);
Vue.use(vuescroll); //使用
Vue.use(VueCodeMirror);
Vue.prototype.api = api;
Vue.prototype.$get = get;
Vue.prototype.$post = post;
Vue.prototype.$del = del;
Vue.prototype.$put = put;
Vue.prototype.$config = config
Vue.config.productionTip = false;
router.beforeEach((to, from, next) => {
if (to.meta.title) {
document.title = to.meta.title
}
next()
})
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");

@ -0,0 +1,35 @@
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
const routes = [{
path: '/',
component: resolve => require(['../views/Home.vue'], resolve),
meta: {
title: '首页'
},
},
{
path: '/testPanel',
component: resolve => require(['../components/TestPanel.vue'], resolve),
meta: {
title: '平板'
},
},
{
path: '/codemirror',
component: resolve => require(['../components/codemirror.vue'], resolve),
meta: {
title: '编辑器'
},
}
];
const router = new VueRouter({
mode: 'hash',
base: process.env.BASE_URL,
routes
})
export default router

@ -0,0 +1,23 @@
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
projectId: '',
codeid: '',
code: '',
judgmentPointsId: '',
workbench: []
},
mutations: {
projectData(state, payload){
state.projectId = payload.projectId
state.codeid = payload.codeid
state.code = payload.code
state.judgmentPointsId = payload.judgmentPointsId
state.workbench = payload.workbench
}
}
});
export default store;

@ -0,0 +1,2 @@
import Vue from 'vue'
export default new Vue()

@ -0,0 +1,16 @@
// rem等比适配配置文件
// 基准大小
const baseSize = 16
// 设置 rem 函数
function setRem () {
// 当前页面宽度相对于 1920宽的缩放比例,可根据自己需要修改。
const scale = document.documentElement.clientWidth / 1920
// 设置页面根节点字体大小(“Math.min(scale, 2)” 指最高放大比例为2,可根据实际业务需求调整)
document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px'
}
// 初始化
setRem()
// 改变窗口大小时重新设置 rem
window.onresize = function () {
setRem()
}

@ -0,0 +1,25 @@
// let host = 'http://192.168.31.125:8081/python'//林
// let host = 'http://192.168.31.152:8081/python'//榕
let host = ''
if(location.host.includes('liuwanr.cn')){
host = 'http://www.liuwanr.cn/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` //中途退出实验并保存实验数据(虚拟仿真实验)
}

@ -0,0 +1,360 @@
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:
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'
});
})
});
}
/**
* 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'
});
})
});
}

@ -0,0 +1,399 @@
<template>
<div>
<div class="flex header">
<p>{{$config.title}}</p>
<div class="bt">
<el-button type="primary" @click="back()">退出实验</el-button>
</div>
</div>
<div class="flex center">
<p>编程语言</p>
<el-input placeholder="请输入内容" v-model="value" :disabled="true"></el-input>
</div>
<div class="tab">
<el-tabs v-model="workbench1" type="card">
<el-tab-pane
v-for="item in workbench"
:key="item.judgmentPointsId"
:label="item.judgmentPointsName"
:value="item.judgmentPointsId"
>
<codemirror
:key="codeKey"
:projectId.sync="projectId"
:code.sync="item.code.code"
:workbench1="item.judgmentPointsId"
:codeid.sync="item.code.codeId"
></codemirror>
</el-tab-pane>
</el-tabs>
</div>
<div class="menu">
<testPanel
@tell="getQueryIndex"
@recoveryCode="recoveryCode"
ref="mainindex"
:autoStart="autoStart"
:sendSync="sendSync"
:defaultVal="defaultVal"
@getDataFromChild="getDataFromChild"
:codeId="codeId"
:workbench="workbench"
:key="codeId"
></testPanel>
</div>
</div>
</template>
<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;
}
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,
host: location.host.includes('liuwanr.cn') ? 'http://www.liuwanr.cn/' : 'http://www.occupationlab.com/'
};
},
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.assessmentId = this.getCookie("assessmentId");
if (window.history && window.history.pushState) {
//
history.pushState(null, null, document.URL);
window.addEventListener("popstate", this.goBack, false);
}
},
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))
}
}
},
goBack() {
this.leavePage()
history.back()
},
getDataFromChild(data) {
sessionStorage.setItem("timer", parseInt(data));
},
recoveryCode(workbench){
this.workbench = workbench
this.codeKey++
this.workbench1 = '0'
},
reload(){
this.$refs.mainindex.reload()
},
back() {
this.leavePage()
if(this.projectPermissions){
location.href = `${this.host}hrClient/#/dashboard#2`
}else{
location.href = `${this.host}hrClient/#/dashboard#1`
}
this.$refs.mainindex.getClearTime();
},
//
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);
});
},
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>
<style lang="scss" scoped>
.menu {
position: relative;
z-index: 1000;
}
.code-right {
/* height: 800px; */
width: 230px;
background: #1b1b1b;
display: inline-block;
}
//
::v-deep .el-form-item {
margin-bottom: 0px;
}
::v-deep .el-dialog--center {
width: 400px;
}
::v-deep .el-dialog__headerbtn .el-icon-close:before {
padding: 3px;
background-color: $main-color;
border-radius: 50%;
color: #ffffff;
}
.select1 ::v-deep .el-input__icon {
line-height: 40px;
}
.select1 {
margin: 0;
}
//tabs
.tab ::v-deep .el-tabs__header {
margin-bottom: 0;
}
.tab ::v-deep .el-tabs__item.is-active {
color: #fff;
background-color: $main-color;
}
.tab ::v-deep .el-icon-circle-plus-outline:before {
font-size: 16px;
}
.tab {
height: 50px;
line-height: 50px;
}
// tabs
::v-deep .el-tabs--card > .el-tabs__header {
border-bottom: none;
}
::v-deep .el-tabs--card > .el-tabs__header .el-tabs__nav {
border: none;
}
::v-deep .el-tabs--card > .el-tabs__header .el-tabs__item {
border-left: none;
border-bottom: none;
}
//
.center p {
font-size: 16px;
margin-left: 15px;
margin-right: 15px;
}
.center {
height: 60px;
line-height: 60px;
}
.center ::v-deep .el-input {
width: 10%;
}
.center ::v-deep .el-input.is-disabled .el-input__inner {
// border-color: $main-color;
border-radius: 30px;
}
//
.bt ::v-deep .el-button + .el-button {
margin-left: 0;
}
.bt ::v-deep .el-button--primary,
.el-button--primary:focus,
.el-button--primary:hover,
.el-button--primary:active {
border: none;
background-color: $main-color;
}
.bt ::v-deep .el-button {
padding: 23px 50px;
border-radius: 0;
border: none;
}
.bt .restart{
color: #868686;
background-color: #e0e0e0;
}
.header p {
font-size: 20px;
color: #333;
margin-left: 18px;
}
.header {
background-color: #f8f8f8;
justify-content: space-between;
height: 58px;
line-height: 58px;
}
//
p {
margin: 0;
}
.flex {
display: flex;
}
//
::v-deep ::-webkit-scrollbar {
width: 6px; //
height: 6px; //
}
//
::v-deep ::-webkit-scrollbar-thumb {
background-color: $main-color;
border-radius: 3px;
-webkit-box-shadow: inset 0 0 5px #dddddd;
}
::v-deep ::-webkit-scrollbar-track {
/*滚动条里面轨道*/
-webkit-box-shadow: inset 0 0 5px #dddddd;
border-radius: 0;
background: #dddddd;
}
//placeholder
::v-deep input::-webkit-input-placeholder {
color: #333;
}
::v-deep input::-moz-input-placeholder {
color: #333;
}
::v-deep input::-ms-input-placeholder {
color: #333;
}
//icon
::v-deep .el-input__icon {
line-height: 60px;
}
//
::v-deep .el-select__caret:before {
content: "\e78f";
font-size: 16px;
padding: 3px;
background-color: $main-color;
border-radius: 50%;
color: #ffffff;
}
::v-deep .el-input--suffix .el-input__inner {
color: #333;
font-size: 14px;
border-radius: 30px;
border: none;
background-color: #f5f5f5;
margin-left: 10px;
}
</style>

@ -0,0 +1,29 @@
// 引入等比适配插件
const px2rem = require('postcss-px2rem')
// 配置基本大小
const postcss = px2rem({
// 基准大小 baseSize,需要和rem.js中相同
remUnit: 16
})
// 使用等比适配插件
module.exports = {
lintOnSave: true,
css: {
loaderOptions: {
sass: {
prependData: `@import "@/assets/styles/var.scss";`
},
postcss: {
plugins: [
postcss
]
}
}
},
publicPath: './',
outputDir: 'dist',
assetsDir: 'static'
}
Loading…
Cancel
Save