This commit is contained in:
zyy 2020-09-27 13:41:41 +08:00
commit 18f370f36f
12 changed files with 462 additions and 421 deletions

View File

@ -11,6 +11,7 @@ pipeline {
nodejs 'nodejs-10'
}
steps {
sh 'npm update'
sh 'npm install'
sh 'npm run build'
}

View File

@ -17,7 +17,6 @@
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
},
"dependencies": {
"@vue/component-compiler-utils": "^3.1.2",
"axios": "0.18.0",
"echarts": "^4.7.0",
"element-ui": "^2.12.0",
@ -78,8 +77,7 @@
"serve-static": "^1.13.2",
"svg-sprite-loader": "4.1.3",
"svgo": "1.2.2",
"vue-loader": "^15.9.3",
"vue-template-compiler": "^2.6.12"
"vue-template-compiler": "^2.6.11"
},
"engines": {
"node": ">=8.9",

View File

@ -30,15 +30,6 @@ export function participantCreatTrainingRoom(id, data) {
});
}
/** 分页获取地图下的实操列表 */
export function getQuestionListByMapId(params) {
return request({
url: `/api/v1/competitionPractical`,
method: 'get',
params
});
}
// 加载试卷
export function loadingPaper(competitionId, data) {
return request({
@ -239,6 +230,9 @@ export function getTheroyCompetitionResult(competitionId, raceUserId) {
method: 'get'
});
}
// 以下drts项目使用
/** 项目获取试题列表 */
export function getItemListByProjectCode(projectCode, params) {
return request({
@ -247,14 +241,6 @@ export function getItemListByProjectCode(projectCode, params) {
params
});
}
/** 项目提交试卷 */
export function commitProjectTestPaper(projectCode, data, mode) {
return request({
url: `api/v1/competitionTheory/project/${projectCode}/submit?mode=${mode}`,
method: 'post',
data
});
}
/** 项目更新练习的试题的进度列表 */
export function updatePracticeQuestionProgress(projectCode, params) {
@ -273,7 +259,7 @@ export function getPracticeQuestionProgress(projectCode) {
});
}
/** 项目更新练习的试题的进度列表 */
/** 项目提交试卷 */
export function submitPracticeQuestionData(projectCode, data) {
return request({
url: `/api/v1/competitionTheory/project/${projectCode}/submit`,
@ -282,3 +268,21 @@ export function submitPracticeQuestionData(projectCode, data) {
});
}
/** 获取场景列表 */
export function getCompetitionPracticalScene(params) {
return request({
url: `/api/v1/competitionPractical`,
method: 'get',
params: params
});
}
/** 获取场景列表 */
export function addCompetitionPracticalScene(data) {
return request({
url: `/api/v1/competitionPractical`,
method: 'post',
data
});
}

View File

@ -25,14 +25,14 @@ export function updateRace(id, data) {
});
}
/** 获取实操试题列表(题库)*/
export function getPracticeList(params) {
return request({
url: `/api/v1/competitionPractical`,
method: 'get',
params
});
}
// /** 获取实操试题列表(题库)*/
// export function getPracticeList(params) {
// return request({
// url: `/api/v1/competitionPractical`,
// method: 'get',
// params
// });
// }
/** 导入项目试题库 */
export function importQuestionBand(data, projectCode) {
return request({

View File

@ -80,5 +80,6 @@ export default {
examDetail: 'Exam detail',
raceManage: 'Race manage',
practiceManage:'Practice manage',
bankManage: 'Bank manage'
bankManage: 'Bank manage',
sceneManage:'Scene manage'
};

View File

@ -85,5 +85,6 @@ export default {
raceManage: '竞赛管理',
recaList: '报名列表',
bankManage: '题库列表',
practiceManage:'实操列表'
practiceManage:'实操列表',
sceneManage:'场景列表'
};

View File

@ -17,7 +17,7 @@ const Jlmap3dModel = () => import('@/views/jlmap3d/device/jl3ddevice');
const Jlmap3dTrain = () => import('@/views/jlmap3d/devicetrain/jl3ddevicetrain');
const Jlmap3dMaintainer = () => import('@/views/jlmap3d/maintainer/jl3dmaintainer');
const Jlmap3dMaintainerVr = () => import('@/views/jlmap3d/maintainer/jl3dmaintainervr');
const Jl3dTrainRescueVr = () => import('@/views/jlmap3d/maintainer/jl3dTrainRescueVr')
const Jl3dTrainRescueVr = () => import('@/views/jlmap3d/maintainer/jl3dTrainRescueVr');
const Jlmap3dOtherVR = () => import('@/views/jlmap3d/maintainer/jl3dothervr');
// const Jl3dMaintainer = () => import('@/views/jlmap3d/maintainer/jl3dmaintainer');
@ -127,7 +127,10 @@ const MapSort = () => import('@/views/publish/publishMap/mapSort');
const StudentManage = () => import('@/views/studentManage');
const RaceManage = () => import('@/views/competitionManage/competition/index');
const BankManage = () => import('@/views/competitionManage/bankList/index');
const PracticeManage = () => import('@/views/competitionManage/practiceList/index');
const Scene = () => import('@/views/drts/scene/index');
// const PracticeManage = () => import('@/views/competitionManage/practiceList/index');
const QuestionCreatePage = () => import('@/views/competitionManage/bankList/question-create-page');
const QuestionUpdatePage = () => import('@/views/competitionManage/bankList/question-update-page');
const GeneratePaper = () => import('@/views/competitionManage/generatePaper');
@ -1015,11 +1018,19 @@ export const asyncRouter = [
icon: 'design'
}
},
// {
// path: 'practice',
// component: PracticeManage,
// meta: {
// i18n: 'router.practiceManage',
// icon: 'design'
// }
// },
{
path: 'practice',
component: PracticeManage,
path: 'scene',
component: Scene,
meta: {
i18n: 'router.practiceManage',
i18n: 'router.sceneManage',
icon: 'design'
}
},

View File

@ -83,22 +83,19 @@
<set-exam-time ref="setExamTime" :theory-question-list="theoryQuestionList" :operate-question-list="operateQuestionList" />
<theory-review ref="theoryReview" :theory-question-list="theoryQuestionList" />
<theory-question ref="theoryQuestion" :theory-index-list="theoryIndexList" @addQuestion="addTheoryQuestionList" @removeQuestion="removeTheoryQuestion" />
<operate-question ref="operateQuestion" :operate-index-list="operateIndexList" @addQuestion="addOperateQuestionList" @removeQuestion="removeOperateQuestion" />
</div>
</template>
<script>
import TheoryReview from './theoryReview';
import TheoryQuestion from './theoryQuestion';
import OperateQuestion from './operateQuestion';
import SetExamTime from './setExamTime';
export default {
name: 'GeneratPaper',
components: {
SetExamTime,
TheoryReview,
TheoryQuestion,
OperateQuestion
TheoryQuestion
},
data() {
return {
@ -148,7 +145,6 @@ export default {
this.$refs.theoryQuestion.doShow();
},
addOperateQuestion() {
this.$refs.operateQuestion.doShow();
},
goBack() {
this.$router.go(-1);

View File

@ -1,219 +0,0 @@
<template>
<el-dialog :visible.sync="dialogVisible" :before-close="handleClose" title="实操试题" width="80%">
<query-list-page ref="user" :pager-config="pagerConfig" :query-form="queryForm" :query-list="queryList" />
</el-dialog>
</template>
<script>
import { getPracticeList } from '@/api/race';
export default {
mixins: [
// WindowResizeHandler
],
props: {
operateIndexList: {
type: Array,
default() {
return [];
}
}
},
data() {
return {
index: 0,
height: 0,
loading: false,
dialogVisible: false,
pagerConfig: {
pageSize: 'pageSize',
pageIndex: 'pageNum'
},
queryForm: {
reset: true,
labelWidth: '80px',
queryObject: {}
},
queryList: {
query: getPracticeList,
beforeQuery: this.beforeQuery,
// data:[
// {id:1, raceId:2, name:'', creatorName:''},
// {id:2, raceId:4, name:'', creatorName:'zyy'},
// {id:3, raceId:3, name:'', creatorName:''}
// ],
selectCheckShow: false,
indexShow: true,
columns: [
{
title: '实操名称',
prop: 'name',
width: '400'
},
{
title: '实操描述',
prop: 'description'
},
{
type: 'button',
title: '操 作',
width: '420',
buttons: [
{
name: '添加',
handleClick: this.addQuestion,
showControl: (row) => { return !row.paper; },
type: 'success'
},
{
name: '移出',
handleClick: this.removeQuestion,
showControl: (row) => { return row.paper; },
type: 'warning'
}
]
}
]
}
};
},
computed: {
},
watch: {
},
methods: {
loadInitData() {
this.$nextTick(() => {
this.queryList.reload();
});
},
doShow() {
this.dialogVisible = true;
this.loadInitData();
},
handleClose() {
this.dialogVisible = false;
},
addQuestion(index, row) {
this.$set(row, 'paper', true);
this.$emit('addQuestion', row);
},
beforeQuery(params) {
params.mapId = this.$route.query.mapId;
return params;
},
afterQuery(data) {
if (data && data.list) {
const that = this;
const list = data.list;
if (list) {
list.map(elem => {
this.$set(elem, 'paper', that.operateIndexList.includes(elem.id));
});
}
}
return data;
},
removeQuestion(index, row) {
this.$set(row, 'paper', false);
this.$emit('removeQuestion', row);
},
answerTags(row) {
const answer = [];
row.optionList.forEach((el, i) => {
switch (row.type) {
case 'select':
if (el.correct) {
answer.push(this.$asc2chart(i + 65));
}
break;
case 'judge':
if (el.correct) {
answer.push(el.content);
}
break;
}
});
return answer;
}
}
};
</script>
<style lang="scss" scoped>
.layer-center {
width: 900px;
height: 100%;
margin: auto;
background: #fff;
}
.quiz {
background: #eee;
height: 100%;
&::-webkit-scrollbar {
display:none
}
&__card {
height: 100%;
.dir-item {
padding-left: 25px;
}
.dir-caption {
padding-left: 10px;
line-height: 26px;
background: #f1f1f1;
}
}
&__container {
height: 100%;
&-header {
height: auto !important;
.title {
font-size: 24px;
line-height: 60px;
font-weight: bold;
text-align: center;
}
.notes {
color:#606266;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin: 0 20px;
}
}
&-main {
.section {
padding: 5px 20px;
.caption {
line-height: 26px;
}
.context {
}
}
}
&-footer {
text-align: right;
position: sticky;
bottom: 0px;
padding: 40px ;
.buttons {
position: relative;
bottom: 20px;
}
}
}
}
</style>

View File

@ -0,0 +1,128 @@
<template>
<el-dialog title="创建场景" :visible.sync="dialogVisible" width="500px" :before-close="doClose" center>
<data-form ref="dataform" :form="form" :form-model="formModel" :rules="rules" />
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="doCreate">{{ $t('global.confirm') }}</el-button>
<el-button @click="doClose">{{ $t('global.cancel') }}</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
name:'SceneCreate',
props: {
scriptList:{
type: Array,
default() {
return '';
}
}
},
data() {
return {
dialogVisible:false,
formModel: {
name:'', //
description:'', //
disposalProcesses:'', //
scriptId:'', // id
operationScore:0, //
main:true //
}
};
},
computed: {
form() {
const form = {
labelWidth: '120px',
items: [
{ prop: 'name', label: '场景名称', type: 'text' },
{ prop: 'description', label: '场景描述', type: 'textarea' },
{ prop: 'disposalProcesses', label: '处置流程', type: 'textarea' },
{ prop: 'operationScore', label: '运营部分总分', type: 'number', min: 0, max: 100, step:1, precision:1 },
{ prop:'scriptId', label:'关联剧本', type:'select', options:this.scriptList},
{ prop:'main', label:'是否主场景', type:'switch' }
]
};
return form;
},
rules() {
const crules = {
name: [
{ validator: this.validateSceneName, trigger: 'blur' },
{ validator: this.validateSceneName, trigger: 'change' }
],
description: [
{ validator: this.validateDescription, trigger: 'blur' },
{ validator: this.validateDescription, trigger: 'change' }
],
disposalProcesses: [
{ validator: this.validateDisposalProcesses, trigger: 'blur' },
{ validator: this.validateDisposalProcesses, trigger: 'change' }
],
scriptId:[
{ required: true, message: '请选择剧本', trigger: 'change' }
],
operationScore:[
{ required: true, message: '请输入运营部分总分', trigger: 'blur' }
]
};
return crules;
}
},
methods:{
validateSceneName(rule, value, callback) {
if (value.trim().length === 0) {
this.formModel.name = this.formModel.name.replace(/\s/g, '');
return callback(new Error('请输入场景名称'));
} else {
return callback();
}
},
validateDescription(rule, value, callback) {
if (value.trim().length === 0) {
this.formModel.description = this.formModel.description.replace(/\s/g, '');
return callback(new Error('请输入场景描述'));
} else {
return callback();
}
},
validateDisposalProcesses(rule, value, callback) {
if (value.trim().length === 0) {
this.formModel.disposalProcesses = this.formModel.disposalProcesses.replace(/\s/g, '');
return callback(new Error('请输入处置流程'));
} else {
return callback();
}
},
doShow(questid) {
this.dialogVisible = true;
// if (questid) {
// getScriptByIdBasic(questid).then(resp=>{
// const data = {'name':resp.data.name, 'description':resp.data.description, 'mapId':resp.data.mapId, isRace:resp.data.isRace};
// this.formModel = data;
// this.formModel.id = questid;
// this.dialogVisible = true;
// this.isEdit = true;
// });
// } else {
// this.formModel.isRace = true;
// this.dialogVisible = true;
// this.isEdit = false;
// }
},
doCreate() {
const self = this;
this.$refs.dataform.validateForm(() => {
self.$emit('create', Object.assign({}, this.formModel));
self.doClose();
});
},
doClose() {
this.$refs.dataform.resetForm();
this.dialogVisible = false;
}
}
};
</script>

View File

@ -0,0 +1,120 @@
<template>
<div>
<query-list-page ref="user" :pager-config="pagerConfig" :query-form="queryForm" :query-list="queryList" />
<create-scene ref="createScene" :script-list="scriptList" title="创建场景" @create="handleConfirmCreate" />
<!-- <create-practice ref="modifyPractice" :map-list="mapList" title="修改实操" @reloadTable="reloadTable" @create="handleConfirmModify" /> -->
</div>
</template>
<script>
import { launchFullscreen } from '@/utils/screen';
import { getCompetitionPracticalScene, addCompetitionPracticalScene } from '@/api/competition';
import { getScriptPageListOnlineNew } from '@/api/script';
import CreateScene from './create';
export default {
name:'SceneManage',
components:{
CreateScene
},
data() {
return {
scriptList:[],
pagerConfig: {
pageSize: 'pageSize',
pageIndex: 'pageNum'
},
queryForm: {
reset: false,
labelWidth: '80px',
queryObject: {
name: {
type: 'text',
label: '场景名称'
}
}
},
queryList: {
query: getCompetitionPracticalScene,
selectCheckShow: false,
indexShow: true,
columns: [
{
title: '场景名称',
prop: 'name',
width: '400'
},
{
title: '场景描述',
prop: 'description'
},
{
title: '处置流程',
prop: 'disposalProcesses'
},
{
title: '运营部分总分',
prop: 'operationScore'
},
{
title: '关联剧本',
prop: 'scriptId',
type: 'tag',
width: '320',
columnValue: (row) => { return this.$convertField(row.scriptId, this.scriptList, ['value', 'label']); },
tagType: (row) => { return 'success'; }
},
{
type: 'button',
title: '操 作',
width: '420',
buttons: [
{
name: '更 新',
handleClick: this.doUpdate,
type: 'primary'
},
{
name: '删 除',
handleClick: this.doDelete,
type: 'danger'
}
]
}
],
actions: [
{ text: '添 加', handler: this.doCreate }
]
}
};
},
mounted() {
getScriptPageListOnlineNew().then(response=>{
this.scriptList = response.data.list.map(elem => { return { value: elem.id, label: elem.name }; });
// this.queryForm.queryObject.scriptId.config.data = this.scriptList;
});
},
methods:{
doUpdate() {
},
doDelete() {
},
doCreate() {
this.$refs.createScene.doShow();
},
reloadTable() {
if (this.queryList && this.queryList.reload) {
this.queryList.reload();
}
},
handleConfirmCreate(data) {
addCompetitionPracticalScene(data).then(resp => {
this.reloadTable();
this.$message.success('创建场景成功');
}).catch(error => {
this.$messageBox(`创建场景失败: ${error.message}`);
});
}
}
};
</script>

View File

@ -600,8 +600,8 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss">
$bg:#fff;
$light_gray:#eee;
$bg:#fff;
$light_gray:#eee;
.drts_title{
position: absolute;
top: 10%;
@ -664,49 +664,49 @@ export default {
bottom: 200px;
}
}
.login-container {
background: #E4EAEA;
.el-form-item{
background: #fff !important;
border: 1px solid rgba(0, 0, 0, 0.1) !important;
.el-input {
height: 40px;
width: 85%;
background: #fff;
input {
background: #fff !important;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 8px 9px 7px 5px;
color: #000;
height: 100%;
.login-container {
background: #E4EAEA;
.el-form-item{
background: #fff !important;
border: 1px solid rgba(0, 0, 0, 0.1) !important;
.el-input {
height: 40px;
width: 85%;
background: #fff;
input {
background: #fff !important;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 8px 9px 7px 5px;
color: #000;
height: 100%;
&:-webkit-autofill {
box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-text-fill-color: #000 !important;
&:-webkit-autofill {
box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-text-fill-color: #000 !important;
}
}
}
}
}
.item_form_box {
border: 1px solid #ccc;
border-radius: 5px;
color: #454545;
}
.item_form_box {
border: 1px solid #ccc;
border-radius: 5px;
color: #454545;
}
.item_form_password{
margin-bottom: 10px;
}
.item_form_password{
margin-bottom: 10px;
}
.tip-message {
color: #F56C61;
padding: 5px;
font-size: 12px;
height: 23px;
margin-bottom: 10px;
}
.tip-message {
color: #F56C61;
padding: 5px;
font-size: 12px;
height: 23px;
margin-bottom: 10px;
}
.el-loading-spinner i {
font-size: 100px;
}
@ -721,23 +721,23 @@ export default {
font-size: 14px;
}
}
}
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
$bg:#f0f0f0;
$qrbg:#fff;
$dark_gray:#889aa4;
$light_gray:#eee;
$qrcodeSize: 270px;
.popover_box {
position: absolute;
right: 80px;
bottom: 106px;
cursor: pointer;
color: #225592;
font-size: 14px;
}
$bg:#f0f0f0;
$qrbg:#fff;
$dark_gray:#889aa4;
$light_gray:#eee;
$qrcodeSize: 270px;
.popover_box {
position: absolute;
right: 80px;
bottom: 106px;
cursor: pointer;
color: #225592;
font-size: 14px;
}
.countdown_box {
display: inline-block;
width: 35px;
@ -758,118 +758,118 @@ export default {
.news-box:hover {
color: #3943CB;
}
.login-container {
position: fixed;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
background-repeat: no-repeat;
background-origin: border-box;
background-size: 100% 100%;
.content-box{
width: 740px;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
padding: 30px 30px 30px;
margin-bottom: 20px;
box-sizing: border-box;
position: relative;
}
.text-box{
font-size: 40px;
font-weight: bold;
top: 150px;
width: 1000px;
text-align: center;
position: absolute;
}
.left-logo-box{
position: absolute;
top: 2%;
font-size: 28px;
font-weight: bold;
left: 2%;
.login-container {
position: fixed;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
background-repeat: no-repeat;
background-origin: border-box;
background-size: 100% 100%;
.content-box{
width: 740px;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
padding: 30px 30px 30px;
margin-bottom: 20px;
box-sizing: border-box;
position: relative;
}
.text-box{
font-size: 40px;
font-weight: bold;
top: 150px;
width: 1000px;
text-align: center;
position: absolute;
}
.left-logo-box{
position: absolute;
top: 2%;
font-size: 28px;
font-weight: bold;
left: 2%;
}
.logo{
vertical-align: middle;
}
.language_box{
position: absolute;
top: 20px;
right: 40px;
.language_btn{
/*font-weight: bold;*/
cursor: pointer;
font-size: 18px;
}
}
.login-form {
width: 440px;
padding: 0 50px;
}
.svg-container {
padding-left: 14px;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
&_login {
font-size: 16px;
}
}
.title_box {
font-size: 20px;
color: #000;
margin: 0px auto 30px auto;
text-align: center;
}
.show-pwd {
position: absolute;
right: 10px;
top: 3px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
}
.logo{
vertical-align: middle;
}
.language_box{
position: absolute;
top: 20px;
right: 40px;
.language_btn{
/*font-weight: bold;*/
cursor: pointer;
font-size: 18px;
}
}
.login-form {
width: 440px;
padding: 0 50px;
}
.svg-container {
padding-left: 14px;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
.qrcode-main{
width: 300px;
background-color: $qrbg;
text-align: center;
border-right: 1px solid #ececec;
.tip-info {
text-align: left;
display: inline-block;
color: green;
margin: 0 auto;
}
&_login {
font-size: 16px;
}
}
.login-code-box{
width: 150px;
margin: 0 auto;
cursor: pointer;
}
.title_box {
font-size: 20px;
color: #000;
margin: 0px auto 30px auto;
text-align: center;
}
.show-pwd {
position: absolute;
right: 10px;
top: 3px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
}
.qrcode-main{
width: 300px;
background-color: $qrbg;
text-align: center;
border-right: 1px solid #ececec;
.tip-info {
text-align: left;
display: inline-block;
color: green;
margin: 0 auto;
}
.login-code-box{
width: 150px;
margin: 0 auto;
cursor: pointer;
}
.system-type {
margin: 5px 0;
display: block;
}
.sub-title {
font-size: 16px;
text-align: center;
color: #353535;
line-height: 30px;
}
}
.system-type {
margin: 5px 0;
display: block;
}
.sub-title {
font-size: 16px;
text-align: center;
color: #353535;
line-height: 30px;
}
}
</style>