Merge remote-tracking branch 'origin/test'

This commit is contained in:
fan 2024-03-04 17:05:56 +08:00
commit 8cf496c2ae
15 changed files with 208 additions and 39 deletions

View File

@ -329,3 +329,22 @@ export function getTaskTree(paperId, moduleId) {
method: 'get' method: 'get'
}); });
} }
/**
* @param {String} paperId 试卷id
* @param {String} moduleId 模块id
*/
export function beginContestExercise(paperId, moduleId) {
return request({
url: `/api/race/${paperId}/${moduleId}`,
method: 'POST'
});
}
/** 竞赛完成训练 */
export function finishContestExercise() {
return request({
url: '/api/race/finish',
method: 'PUT'
});
}

View File

@ -15,3 +15,20 @@ export function selectQuestionTypeNum(companyId) {
method: 'get' method: 'get'
}); });
} }
/** 加载场景 */
export function loadRace(simulationId, sceneId) {
return request({
url: `/api/race/${simulationId}/load/${sceneId}`,
method: 'put'
});
}
/** 完成任务 */
export function overTask(taskId, data) {
return request({
url: `/api/race/${taskId}/finish`,
method: 'put',
data
});
}

View File

@ -84,8 +84,9 @@ class ValidateHandler {
valid = ((operate.val).toString() === stepOperation.val.toString()) && valid; valid = ((operate.val).toString() === stepOperation.val.toString()) && valid;
} }
const opParam = operate.param === undefined ? {} : operate.param; const opParam = operate.param === undefined ? {} : operate.param;
const stepParam = stepOperation.params === undefined ? {} : stepOperation.params;
if ((opParam || stepOperation.params) && !opParam.hasOwnProperty('fileBase64Str')) { if ((opParam || stepOperation.params) && !opParam.hasOwnProperty('fileBase64Str')) {
valid = this.checkParamConsistent(opParam, stepOperation.params, operate.operation) && valid; valid = this.checkParamConsistent(opParam, stepParam, operate.operation) && valid;
} }
if (valid && store.state.trainingNew.voiceStepIndex > -1) { if (valid && store.state.trainingNew.voiceStepIndex > -1) {

View File

@ -21,7 +21,8 @@ const training = {
voiceStepIndex: -1, voiceStepIndex: -1,
examSwitch: false, // 考试开始结束标注 examSwitch: false, // 考试开始结束标注
stepRecord: [], // 操作记录 stepRecord: [], // 操作记录
joinTrainingInfo: null joinTrainingInfo: null,
isRecord: false
}, },
getters: { getters: {
teachMode: (state) => { teachMode: (state) => {
@ -131,6 +132,9 @@ const training = {
}, },
setJoinTrainingInfo: (state, joinTrainingInfo) => { setJoinTrainingInfo: (state, joinTrainingInfo) => {
state.joinTrainingInfo = joinTrainingInfo; state.joinTrainingInfo = joinTrainingInfo;
},
setIsRecord: (state, flag) => {
state.isRecord = flag;
} }
}, },
actions: { actions: {
@ -234,6 +238,9 @@ const training = {
}, },
setJoinTrainingInfo: ({ commit }, joinTrainingInfo ) => { setJoinTrainingInfo: ({ commit }, joinTrainingInfo ) => {
commit('setJoinTrainingInfo', joinTrainingInfo); commit('setJoinTrainingInfo', joinTrainingInfo);
},
setIsRecord: ({ commit }, flag) => {
commit('setIsRecord', flag);
} }
} }
}; };

View File

@ -1,13 +1,86 @@
<template> <template>
<div>打分结算</div> <div class="taskContainer">
<el-card class="father">
<div style="margin-bottom:10px;font-size: 22px;font-weight: bolder;height: 34px;text-align: center;line-height: 34px;">打分汇总</div>
<el-tree
:data="taskDta"
node-key="id"
default-expand-all
:props="defaultProps"
:expand-on-click-node="false"
style="margin-bottom:50px"
>
<span slot-scope="{ node, data }" class="custom-tree-node">
<span>{{ node.label }}</span>
<div style="display: flex; justify-content: space-between;">
<div style="width:80px;">得分:{{ data.score }}</div>
</div>
</span>
</el-tree>
<div class="son">
<el-button type="primary" size="medium" @click="confirm">确认</el-button>
</div>
</el-card>
</div>
</template> </template>
<script> <script>
import { finishContestExercise} from '@/api/contest';
export default { export default {
name: 'ScoringSettlement' name:'ScoringSettlement',
data() {
return {
taskDta:[],
defaultProps: {
children: 'child',
label: 'name'
}
};
},
created() {
finishContestExercise().then((res) => {
this.taskDta = res.data.node;
}).catch(error => {
this.$message.error(error.message);
});
},
methods: {
confirm() {
this.$confirm('是否确认?', this.$t('tip.hint'), {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$router.push('/contest/list');
});
}
}
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.taskContainer{
width: 50%;
margin: 10px auto;
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 16px;
padding-right: 20px;
}
.father{
position: relative;
.son{
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
}
}
}
</style> </style>

View File

@ -42,9 +42,9 @@
</el-row> </el-row>
</div> </div>
<div style="text-align: center;margin-top: 15px;"> <div style="text-align: center;margin-top: 15px;">
<el-button v-show="nowData.ruleId" type="primary" @click="showScoreRule">评分表</el-button> <el-button v-show="nowData.ruleId" v-loading="loading" type="primary" @click="showScoreRule">评分表</el-button>
<el-button v-show="nowData.sceneId" v-loading="loading" type="primary" @click="startTask">开始任务</el-button> <el-button v-show="nowData.sceneId" v-loading="loading" type="primary" @click="startTask">开始任务</el-button>
<el-button type="primary" :disabled="nowKey === taskList.length-1" @click="nextTask">下一任务</el-button> <el-button v-loading="loading" type="primary" :disabled="nowKey === taskList.length-1" @click="nextTask">下一任务</el-button>
</div> </div>
</el-card> </el-card>
</el-col> </el-col>
@ -154,6 +154,8 @@ export default {
project: 'dsxl', project: 'dsxl',
paperId: this.$route.query.paperId, paperId: this.$route.query.paperId,
moduleId: this.$route.query.moduleId, moduleId: this.$route.query.moduleId,
sceneId: this.nowData.sceneId,
taskId: this.nowData.id,
nowKey: this.nowKey nowKey: this.nowKey
}; };
this.$router.push({ path: '/display/demon', query: query }); this.$router.push({ path: '/display/demon', query: query });

View File

@ -45,7 +45,7 @@
import paperList from './paperList'; import paperList from './paperList';
import drapLeft from '@/views/components/drapLeft/index'; import drapLeft from '@/views/components/drapLeft/index';
import ScoreRule from './scoreRule'; import ScoreRule from './scoreRule';
import { getPaperDetail, getContextScoreDetail} from '@/api/contest'; import { getPaperDetail, getContextScoreDetail, beginContestExercise} from '@/api/contest';
let id = 1; let id = 1;
export default { export default {
@ -64,7 +64,6 @@ export default {
moduleList:[], moduleList:[],
moduleTreeDatas:[], moduleTreeDatas:[],
taskTreeDatas:[], taskTreeDatas:[],
ruleData:[],
defaultProps: { defaultProps: {
disabled: true disabled: true
} }
@ -100,9 +99,6 @@ export default {
}; };
}); });
this.taskTreeDatas = this.moduleTreeDatas[0].children; this.taskTreeDatas = this.moduleTreeDatas[0].children;
getContextScoreDetail(this.moduleTreeDatas[0].moduleScoreRuleId).then(res => {
this.ruleData = res.data.rule ? res.data.rule.units : [];
}).catch(() => { this.ruleData = []; });
}).catch(error => { }).catch(error => {
this.$message.error(error.message); this.$message.error(error.message);
}); });
@ -111,7 +107,11 @@ export default {
this.$refs.scoreRule.doShow(moduleScoreRuleId); this.$refs.scoreRule.doShow(moduleScoreRuleId);
}, },
beginExercise(moduleId) { beginExercise(moduleId) {
beginContestExercise(this.paperId, moduleId).then(res => {
this.$router.push({path: '/contest/detail', query:{paperId:this.paperId, moduleId }}); this.$router.push({path: '/contest/detail', query:{paperId:this.paperId, moduleId }});
}).catch(error => {
this.$message.error(error.message);
});
}, },
transformTree(data) { transformTree(data) {
const result = {label:data.name, children:[], id:id++, type:'taskCatalog' }; const result = {label:data.name, children:[], id:id++, type:'taskCatalog' };

View File

@ -38,7 +38,7 @@ export default {
getContextScoreDetail(id).then(resp => { getContextScoreDetail(id).then(resp => {
this.tableData = resp.data.rule ? resp.data.rule.units : []; this.tableData = resp.data.rule ? resp.data.rule.units : [];
this.loading = false; this.loading = false;
}).catch(() => { this.$message.error('初始化数据失败!'); this.loading = false; this.tableData = []; }); }).catch(() => { this.loading = false; this.tableData = []; });
}, },
handleClose() { handleClose() {
this.dialogVisible = false; this.dialogVisible = false;

View File

@ -247,7 +247,7 @@ export default {
} }
}, },
isRecord() { isRecord() {
return !!this.$route.query.record; return !!this.$store.state.trainingNew.record;
} }
}, },
watch:{ watch:{

View File

@ -31,7 +31,7 @@
<div class="chat-box-footer"> <div class="chat-box-footer">
<el-input v-model="textContent" size="small" placeholder="请输入会话文字点击T发送" style="flex: 1; margin-left: 5px;" :rows="1" /> <el-input v-model="textContent" size="small" placeholder="请输入会话文字点击T发送" style="flex: 1; margin-left: 5px;" :rows="1" />
<el-button :id="sendTextId" size="mini" class="chat-box-footer-create" :disabled="contentSend" @click="sendText">T</el-button> <el-button :id="sendTextId" size="mini" class="chat-box-footer-create" :disabled="contentSend" @click="sendText">T</el-button>
<el-button v-if="!$route.query.record" class="chat-box-footer-create chat-box-footer-send" :class="{'active': recordSending}" :disabled="audioPlay" size="mini" type="primary" @click="startRecording()"> <el-button v-if="!$store.state.trainingNew.isRecord" class="chat-box-footer-create chat-box-footer-send" :class="{'active': recordSending}" :disabled="audioPlay" size="mini" type="primary" @click="startRecording()">
<el-progress id="voice_progress_bar" type="circle" :show-text="false" :percentage="100/60*seconds" :width="40" :stroke-width="2" status="success" /> <el-progress id="voice_progress_bar" type="circle" :show-text="false" :percentage="100/60*seconds" :width="40" :stroke-width="2" status="success" />
<i v-if="recordSending" class="el-icon-close close_icon" @click.stop="cancleRecording()" /> <i v-if="recordSending" class="el-icon-close close_icon" @click.stop="cancleRecording()" />
<span class="iconfont icon-yuyin">&#xe62b;</span> <span class="iconfont icon-yuyin">&#xe62b;</span>

View File

@ -130,7 +130,6 @@ import EditOperate from './editOperate';
import CreateDraftTraining from './createDraftTraining'; import CreateDraftTraining from './createDraftTraining';
import GradeRules from './gradeRules'; import GradeRules from './gradeRules';
import TrackList from './trackList'; import TrackList from './trackList';
import { EventBus } from '@/scripts/event-bus';
export default { export default {
name: 'DesignIndex', name: 'DesignIndex',
@ -217,15 +216,13 @@ export default {
e.stopPropagation(); e.stopPropagation();
}); });
}, },
beforeDestroy() {
this.$store.dispatch('trainingNew/setIsRecord', false);
},
methods: { methods: {
goBackList() { goBackList() {
const qObj = {...this.$route.query}; this.$store.dispatch('trainingNew/setIsRecord', false);
qObj.record = false;
this.$router.replace({ query:{...qObj}});
this.showMode = 'draftTrainingList'; this.showMode = 'draftTrainingList';
this.$nextTick(() => {
EventBus.$emit('viewLoading', false);
});
}, },
computedRoleDisabled(role) { computedRoleDisabled(role) {
if (!this.editData.client) { if (!this.editData.client) {

View File

@ -203,7 +203,7 @@ export default {
return; return;
} }
const qObj = {...this.$route.query}; const qObj = {...this.$route.query};
qObj.record = true; this.$store.dispatch('trainingNew/setIsRecord', true);
this.$router.replace({ query:{...qObj}}); this.$router.replace({ query:{...qObj}});
this.$store.dispatch('training/changeOperateMode', { mode: OperateMode.NORMAL }); // this.$store.dispatch('training/changeOperateMode', { mode: OperateMode.NORMAL }); //
getTrainingAll(row.id).then(resp => { getTrainingAll(row.id).then(resp => {

View File

@ -126,6 +126,15 @@ export default {
this.stepIndex = data.index; this.stepIndex = data.index;
this.stepDetail = data.data; this.stepDetail = data.data;
this.trainingType = data.type; this.trainingType = data.type;
if (!this.stepDetail.operations) {
this.stepDetail.operations = [];
}
if (!this.stepDetail.simCommands) {
this.stepDetail.simCommands = [];
}
if (!this.stepDetail.tipPosition) {
this.stepDetail.tipPosition = {};
}
}, },
clearOperation() { clearOperation() {
this.$confirm('清除操作将清除所有关联操作', '提示', { this.$confirm('清除操作将清除所有关联操作', '提示', {

View File

@ -65,7 +65,13 @@ export default {
this.dialogVisible = false; this.dialogVisible = false;
}, },
doShow() { doShow() {
const playerList = JSON.parse(this.trainingDetail.playerIdJson); let playerList = [];
if (this.$route.query.paperId) {
playerList = this.trainingDetail.playerIds;
} else {
playerList = JSON.parse(this.trainingDetail.playerIdJson);
}
const memberData = this.$store.state.training.memberData; const memberData = this.$store.state.training.memberData;
const newMemberData = {}; const newMemberData = {};
playerList.forEach(playerId => { playerList.forEach(playerId => {

View File

@ -4,7 +4,7 @@
<div ref="drapBox" class="reminder-box"> <div ref="drapBox" class="reminder-box">
<div class="tip-title"> <div class="tip-title">
<div style="display: flex;justify-content: center;align-items: center;"> <div style="display: flex;justify-content: center;align-items: center;">
<i v-if="!trainingDesign && !examSwitch && simulationCreator" class="icon el-icon-document" @click="trainingListShow" /> <i v-if="!trainingDesign && !examSwitch && simulationCreator && !isRace" class="icon el-icon-document" @click="trainingListShow" />
<i v-show="!isShrink && !trainingSwitch && trainingDetail && simulationCreator" class="icon el-icon-video-play" @click="handlerStart" /> <i v-show="!isShrink && !trainingSwitch && trainingDetail && simulationCreator" class="icon el-icon-video-play" @click="handlerStart" />
<i v-show="!isShrink && trainingSwitch && simulationCreator" class="icon el-icon-switch-button" @click="handlerEnd" /> <i v-show="!isShrink && trainingSwitch && simulationCreator" class="icon el-icon-switch-button" @click="handlerEnd" />
<i v-show="isShrink" class="icon el-icon-minus" @click="shrink" /> <i v-show="isShrink" class="icon el-icon-minus" @click="shrink" />
@ -33,7 +33,7 @@
</el-radio-group> </el-radio-group>
</span> </span>
</p> </p>
<p class="list-item"> <p v-if="!isRace" class="list-item">
<span class="list-label" style="vertical-align: top;"> {{ $t('display.training.trainingInstructions') }}</span> <span class="list-label" style="vertical-align: top;"> {{ $t('display.training.trainingInstructions') }}</span>
<span class="list-elem elem-span">{{ trainingDetail ?trainingDetail.description:'' }}</span> <span class="list-elem elem-span">{{ trainingDetail ?trainingDetail.description:'' }}</span>
</p> </p>
@ -44,11 +44,11 @@
<el-button v-if="trainingSwitch" size="small" type="danger" @click="handlerEnd">结束</el-button> <el-button v-if="trainingSwitch" size="small" type="danger" @click="handlerEnd">结束</el-button>
</span> </span>
</p> </p>
<p v-if="!examSwitch && simulationCreator" class="list-item"> <p v-if="!examSwitch && simulationCreator && !isRace" class="list-item">
<span class="list-label"> </span> <span class="list-label"> </span>
<span class="list-elem elem-span training-box" @click="loadTraining(previousTraining)">{{ previousTraining? previousTraining.name: '' }}</span> <span class="list-elem elem-span training-box" @click="loadTraining(previousTraining)">{{ previousTraining? previousTraining.name: '' }}</span>
</p> </p>
<p v-if="!examSwitch && simulationCreator" class="list-item"> <p v-if="!examSwitch && simulationCreator && !isRace" class="list-item">
<span class="list-label"> </span> <span class="list-label"> </span>
<span class="list-elem elem-span training-box" @click="loadTraining(nextTraining)">{{ nextTraining? nextTraining.name:'' }}</span> <span class="list-elem elem-span training-box" @click="loadTraining(nextTraining)">{{ nextTraining? nextTraining.name:'' }}</span>
</p> </p>
@ -69,6 +69,8 @@
<script> <script>
import { ScriptMode } from '@/scripts/ConstDic'; import { ScriptMode } from '@/scripts/ConstDic';
import { startTraining, endTraining, getPublishTrainingDetail, loadPublishTraining, prepareScene } from '@/api/jmap/training'; import { startTraining, endTraining, getPublishTrainingDetail, loadPublishTraining, prepareScene } from '@/api/jmap/training';
import { loadRace, overTask } from '@/api/race';
import { getContextSenceDetail } from '@/api/contest';
import ScenePlayRole from './scenePlayRole'; import ScenePlayRole from './scenePlayRole';
import TestResult from './testResult'; import TestResult from './testResult';
import { EventBus } from '@/scripts/event-bus'; import { EventBus } from '@/scripts/event-bus';
@ -119,11 +121,16 @@ export default {
}, },
simulationCreator() { simulationCreator() {
return this.$store.state.training.simulationCreator; return this.$store.state.training.simulationCreator;
},
isRace() {
return this.$route.query.paperId;
} }
}, },
watch: { watch: {
'$store.state.map.mapViewLoadedCount': function (val) { '$store.state.map.mapViewLoadedCount': function (val) {
// this.loadTraining({ id: 12483 }); if (this.isRace) {
this.loadRaceScene(this.$route.query.sceneId);
}
}, },
'$store.state.trainingNew.trainingDetail': function(val) { '$store.state.trainingNew.trainingDetail': function(val) {
this.initAdjacentTraining(); this.initAdjacentTraining();
@ -184,7 +191,7 @@ export default {
handlePrepareScene() { handlePrepareScene() {
prepareScene(this.group, {mode: this.demoMode}).then(() => { prepareScene(this.group, {mode: this.demoMode}).then(() => {
this.$refs.scenePlayRole.doShow(); this.$refs.scenePlayRole.doShow();
}).catch(() => { }).catch((e) => {
this.$message.error('预开始场景实训失败!'); this.$message.error('预开始场景实训失败!');
}); });
}, },
@ -204,6 +211,15 @@ export default {
trainDetail: this.$store.state.trainingNew.stepRecord trainDetail: this.$store.state.trainingNew.stepRecord
}; };
EventBus.$emit('trainExamSubmit', data); EventBus.$emit('trainExamSubmit', data);
} else {
if (this.isRace) {
overTask(this.$route.query.taskId, {simulationId: this.group, scoreList: this.$store.state.trainingNew.stepRecord }).then((resp) => {
if (this.demoMode === ScriptMode.TEST) {
this.$refs.testResult.doShow(resp.data);
}
}).catch((e) => {
this.$message.error('结束任务失败!');
});
} else { } else {
endTraining(this.group, this.$store.state.trainingNew.stepRecord).then((resp) => { endTraining(this.group, this.$store.state.trainingNew.stepRecord).then((resp) => {
if (this.demoMode === ScriptMode.TEST) { if (this.demoMode === ScriptMode.TEST) {
@ -214,10 +230,32 @@ export default {
this.$message.error('结束实训失败!'); this.$message.error('结束实训失败!');
}); });
} }
}
}, },
trainingListShow() { trainingListShow() {
EventBus.$emit('handleSliderShow'); EventBus.$emit('handleSliderShow');
}, },
async loadRaceScene(sceneId) {
if (this.trainingSwitch) {
this.$message.error('请先结束当前实训后再加载新的实训!');
return;
}
try {
const detailResp = await getContextSenceDetail(sceneId);
this.training = detailResp.data.scene.storageSimulation;
this.training.type = 'SCENE';
this.training.name = detailResp.data.name;
if (this.training.mapLocationJson) {
const mapLocation = JSON.parse(this.training.mapLocationJson);
this.$jlmap.updateTransform(mapLocation.scale, {x:mapLocation.x, y:mapLocation.y});
}
this.$store.dispatch('trainingNew/setTrainingDetail', this.training);
await loadRace(this.group, sceneId, {mode: ''});
this.$message.success('加载场景成功!');
} catch (e) {
this.$message.error('加载场景失败!');
}
},
async loadTraining(training) { async loadTraining(training) {
if (this.trainingSwitch) { if (this.trainingSwitch) {
this.$message.error('请先结束当前实训后再加载新的实训!'); this.$message.error('请先结束当前实训后再加载新的实训!');