1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297 |
- <template>
- <div class="chapter-container">
- <div v-if="!state.hasRead" class="chapter-describe">
- <div class="describe-cnt" v-html="state.readHtml"></div>
- <div class="describe-readed">
- <a class="readed-btn" :class="{ reading: state.readingTime > 0 }" @click="hasReadClick">知道了{{ state.readingTime > 0 ? ` (${state.readingTime}s)` : '' }}</a>
- </div>
- </div>
- <div v-if="state.hasRead && state.showCnt" class="chapter-box">
- <NavMenus :back-confirm="state.lastChapterNum != maxChapterNum"></NavMenus>
- <div class="chapter-content">
- <!-- 原本的左侧菜单 -->
- <!-- <div class="menu-box" :class="{ fold: state.menuFold }">
- <div class="menu-title">{{ state.chapterTree[state.currentStep]?.name ?? '' }}</div>
- <div class="menu-list">
- <el-scrollbar :max-height="state.menuListHeight">
- <el-steps direction="vertical" space="3rem" :active="state.currentStep">
- <el-step v-for="(item, idx) in state.chapterTree" :title="item.name" @click="menuClick($event, idx)">
- <template #icon>
- <div class="step-icon">
- <div class="step-icon-inner"></div>
- </div>
- </template>
- <template #description v-if="item.children?.length > 0">
- <el-steps
- direction="vertical"
- space="1.8rem"
- :active="idx < state.currentStep ? item.children.length : idx > state.currentStep ? -1 : state.activeSecondMenu"
- >
- <el-step v-for="item1 in item.children" :title="item1.name" @click="menuClick($event, idx, item1.id)">
- <template #icon><div class="step-icon-second"></div></template>
- </el-step>
- </el-steps>
- </template>
- </el-step>
- </el-steps>
- </el-scrollbar>
- <div class="menu-switch" @click="menuSwitch"></div>
- </div>
- </div> -->
-
- <!-- 新的左侧菜单 -->
- <div :class="'menuLeft ' + (menuLeftLook == true ? 'menuLeftOpenEvent' : 'menuLeftExitEvent')" >
- <div class="menuTitle" >
- <div class="logoLeft"></div>
- <div class="txtRight">知识学习</div>
- </div>
- <div class="menuList" >
- <div class="menuListBorder commonsScrollbarNew" >
-
- <div class="menuListMain" v-for="(item, index) of state.chapterTree" :key="index" >
- <div :class="'menuListpParent ' + ( (index < state.currentStep) ? 'menuListpParentYes' : (index == state.currentStep) ? 'menuListpParentSelect' : '' ) "
- @click="menuClickNew(item, index)" >
- <div class="menuListpParentLeft">
- <div v-if="index == state.currentStep" class="logoTime" ></div>
- <div v-if="index != state.currentStep" :class="'' + ( (index <= state.currentStep) ? 'logoMenu' : 'logoNo' )" ></div>
- </div>
- <div class="menuListpParentCenter">{{ item.name }}</div>
- <!-- <div class="menuListpParentRight" v-if="item.children != null && item.children != undefined && item.children.length > 0" >
- +
- </div> -->
- </div>
- <div :class="'menuListpChildren ' + ( (index < state.currentStep || ( index == state.currentStep && index_1 + 1 < state.currentNode ) ) ? 'menuListpChildrenYes' : (index_1 + 1 == state.currentNode) ? 'menuListpChildrenSelect' : '' ) "
- @click="menuClickNew(item_1, index, item_1.id)"
- v-if="item.children?.length > 0" v-for="(item_1, index_1) of item.children" :key="index_1" >
- <div class="menuListpChildrenKong" ></div>
- <div class="menuListpChildrenLeft" >
- <div v-if="(index_1 + 1 == state.currentNode)" class="logoTime" ></div>
- <div v-if="(index_1 + 1 != state.currentNode)" :class="'' + ( (index < state.currentStep || ( index == state.currentStep && index_1 < state.currentNode ) ) ? 'logoMenu' : 'logoNo' )" ></div>
- </div>
- <div class="menuListpChildrenRight">
- {{ item_1.name }}
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div :class="'menuLook ' + (menuLeftLook == true ? 'menuLookOpenEvent ' : 'menuLookExit menuLookExitEvent')"
- @click="(menuLeftLook = menuLeftLook == true ? false : true)" ></div>
-
- <div v-if="state.currentChapter.type != 30" class="chapter-detail">
- <div class="detail-title">{{ state.currentChapter.name }}</div>
- <div class="detail-cnt" v-html="htmlContent"></div>
- </div>
- <!-- <div v-else class="chapter-3d">
- <CourseChapter3d :config="state.chapterTree[state.currentStep]?.threeDimensionalConfig ?? ''"></CourseChapter3d>
- <CourseChapter3dView></CourseChapter3dView>
- </div> -->
- </div>
- <!-- 后台交互,显示,上一步下一步逻辑UI -->
- <StepTips
- v-if="
- stepTipsLook == true
- && (
- (
- courseChapter3dShow().show.showToastViewBool == false
- && courseChapter3dShow().show.showLinkOkNextBool == false
- )
- || (
- courseChapter3dShow().show.showToastViewBool == true
- && courseChapter3dShow().show.showToastState == ''
- && courseChapter3dShow().show.showLinkOkNextBool == false
- )
- )
- "
- :msg="state.tipsMsg"
- :btns="state.tipsBtns"
- :countdown="tipsCountdown"
- :key="state.tipsKey"
- ></StepTips>
- </div>
- <!-- 3d组件放在这里,让它可以隐藏起来,提前加载好场景。要不然后续切换3d场景每次要重新加载,比较麻烦 -->
- <!-- <div v-show="state.hasRead && state.showCnt && state.currentChapter.type == 30" class="chapter-3d"> -->
- <div v-if="courseChapter3dViewBool == true" class="chapter-3d">
- <div v-show="state.hasRead && state.showCnt && state.currentChapter.type == 30">
- <!-- 老版本的三维逻辑了,用不到了 -->
- <!-- <CourseChapter3d
- :config="state?.currentChapter ?? ''"
- :studentTaskIdList="studentTaskIdList"
- @tipsBtnsUpOpen="tipsBtnsUpOpenEvent"
- @tipsBtnsDownOpen="tipsBtnsDownOpenEvent"
- ></CourseChapter3d>
- <CourseChapter3dView
- @showOperationHelpExitEvent="showOperationHelpExitEvent"
- @carCameraScreenshot="carCameraScreenshotEvent"
- @carShutDown="carShutDownEvent"
- ></CourseChapter3dView> -->
-
- <QingXiCheAndQvMain :initTime="initTimeQingXiCarAndQv" :processUiOpen="(stepTipsLook == true ? false : true)"
- @callbackProgress="callbackProgressQingXiCheAndQv" ></QingXiCheAndQvMain>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { onMounted, reactive, computed, watch, onUnmounted, nextTick, ref } from 'vue';
- import NavMenus from '../components/navMenus.vue';
- import StepTips from '../components/stepTips.vue';
- import { useRoute } from 'vue-router';
- import { getCourseInfo, getCourseChapterTree, studyReport, getCurrentChapter, updateProgress } from '@/api/student/trainChapter';
- import { studentTaskOptionPipDefectListByStudentId } from '@/api/student/studentTaskOptionPipDefect';
- import CourseChapter3d from '@/components/student/CourseChapter3d.vue';
- import CourseChapter3dView from '@/components/student/courseChapter3d/view.vue';
- import QingXiCheAndQvMain from '@/components/ThreeWorldEventQingXiCheAndQv/QingXiCheAndQvMain.vue';
- import { getTrainDetail } from '@/api/student/trainList';
- import router from '@/router/index';
- import { courseChapter3dShow } from '@/stores/courseChapter3dShow.ts';
- import { threeWorld } from '@/stores/threeWorld.ts';
- import { uploadFileOss, getLiteMeta } from '../../../util/fileUtils';
- import { ElMessage, ElMessageBox, ElNotification } from 'element-plus';
- import { studentTaskPhoto } from '@/api/techer/taskStudentScore';
- import { ModelHtml5Audio } from "../../../components/student/event/ModelHtml5Audio.ts";
- const route = useRoute();
- const taskId = route.params.taskId as string;
- const studentTaskId = route.params.studentTaskId as string;
- const state: anyObj = reactive({
- hasRead: true,
- readingTime: 10,
- readHtml: '',
- showCnt: false,
- menuFold: false,
- menuListHeight: ``,
- tipsKey: 0,
- tipsMsg: '',
- tipsBtns: [],
- chapterTree: [],
- currentStep: 0,
- currentNode: 0,
- currentChapter: { type: 10 },
- activeSecondMenu: -1,
- lastChapterNum: -1,
- });
- // 控制左侧菜单是否展示
- let menuLeftLook = ref(true)
- // 播放声音
- let objAudio = new ModelHtml5Audio();
- let chapterQueue: Array<Array<anyObj>> = [];
- let maxChapterNum = 0;
- // 获取当前学生任务ID缺陷列表
- let studentTaskIdList: any = ref([]);
- // 用于控制3d场景什么时候加载显示
- let courseChapter3dViewBool = ref(false);
- /**
- * 因为引入了其他三维场景
- * 三维场景里,自带了上一步,下一步的逻辑UI
- * 所以控制,原先前端UI的 上一步,下一步的UI逻辑是否显示还是隐藏
- */
- let stepTipsLook = ref(true);
- // 控制清洗车回到第一个流程逻辑
- let initTimeQingXiCarAndQv = ref("0");
- const buildChapterQueue = (data: anyObj[], optionChapters: anyObj[], root = true): anyObj[] => {
- let chapters: anyObj[] = [];
- data?.forEach((item, idx) => {
- const children = item.children;
- //delete item.children;
- const opt = optionChapters.find((x) => x.chapterId == item.id);
- if (opt) item.durationStudyMin = opt.durationStudyMin;
- chapters.push(item);
- if (children && children.length > 0) {
- const childs = buildChapterQueue(children, optionChapters, false);
- chapters = chapters.concat(childs);
- }
- if (root) {
- chapterQueue[idx] = [...chapters];
- chapters = [];
- }
- });
- if (root) maxChapterNum = (chapterQueue.length - 1) * 100 + chapterQueue[chapterQueue.length - 1].length - 1;
- return chapters;
- };
- const menuSwitch = () => {
- state.menuFold = !state.menuFold;
- };
- const menuClick = (evt: Event, step: number, nodeId?: string) => {
- if ((evt.target as HTMLElement).classList.contains('el-step__title')) {
- let chapterNum = step * 100,
- node = 0;
- if (nodeId) {
- node = chapterQueue[step].findIndex((x) => x.id == nodeId);
- if (node > -1) chapterNum += node;
- }
- if (chapterNum <= state.lastChapterNum) {
- state.currentStep = step;
- state.currentNode = node;
- state.currentChapter = chapterQueue[step][node];
- } else {
- ElMessage({
- message: '该章节还未完成学习,请先按顺序完成学习!',
- type: 'warning',
- });
- }
- }
- evt.stopPropagation();
- };
- /**
- * 新的左侧菜单点击的逻辑
- * @param item
- * @param step
- * @param nodeId
- */
- const menuClickNew = (item: any, step: number, nodeId?: string) => {
- console.log("menuClickNew ---", item, step, nodeId)
-
- let chapterNum = step * 100,
- node = 0;
- if (nodeId) {
- node = chapterQueue[step].findIndex((x) => x.id == nodeId);
- if (node > -1) chapterNum += node;
- }
- if (chapterNum <= state.lastChapterNum) {
- state.currentStep = step;
- state.currentNode = node;
- state.currentChapter = chapterQueue[step][node];
- console.log(
- 'menuClickNew --- 1111111111 ',
- state.currentStep,
- state.currentNode,
- state.currentChapter
- );
- } else {
- ElMessage({
- message: '该章节还未完成学习,请先按顺序完成学习!',
- type: 'warning',
- });
- }
-
- };
- const hasReadClick = () => {
- state.hasRead = true;
- state.showCnt = true;
- setMenuListHeight();
- };
- const setMenuListHeight = () => {
- nextTick(() => {
- let height = document.querySelector('.menu-box')?.clientHeight ?? 0;
- if (height) state.menuListHeight = `calc(${height}px - 12rem)`;
- });
- };
- const countdown = (name: string, callback?: Function) => {
- if (state[name]) {
- const interval = setInterval(() => {
- state[name]--;
- if (state[name] == 0) {
- clearInterval(interval);
- if (callback) callback();
- }
- }, 1000);
- }
- };
- const tipsCountdown = computed(() => {
- let countdown = state.currentChapter.durationStudyMin ?? 0;
- const chapterNum = state.currentStep * 100 + state.currentNode;
- if (chapterNum <= state.lastChapterNum) countdown = 0;
- return countdown;
- });
- const htmlContent = computed(() => {
- if (state.currentChapter.type == 10) {
- return state.currentChapter.richText;
- } else if (state.currentChapter.type == 20) {
- return `<iframe src='${state.currentChapter.videoUrl}' width='100%' height='99%' scrolling='no' frameborder='0'><iframe>`;
- } else return '';
- });
- const prevStep = () => {
- if (state.currentNode == 0) {
- state.currentStep--;
- state.currentNode = chapterQueue[state.currentStep].length - 1;
- } else state.currentNode--;
- state.currentChapter = chapterQueue[state.currentStep][state.currentNode];
- };
- const nextStep = () => {
- updateStudyProgress();
- state.currentNode++;
- if (state.currentNode >= chapterQueue[state.currentStep].length) {
- state.currentStep++;
- state.currentNode = 0;
- }
- state.currentChapter = chapterQueue[state.currentStep][state.currentNode];
- };
- const completeStudy = () => {
- updateStudyProgress();
- router.push({ path: `/train/main/${taskId}` });
- };
- const updateStudyProgress = () => {
- //更新学习进度
- const num = state.currentStep * 100 + state.currentNode;
- if (num > state.lastChapterNum) {
- state.lastChapterNum = num;
- updateProgress(studentTaskId, state.currentChapter.id);
- }
- };
- const initTips = () => {
- state.tipsKey++;
- state.tipsMsg = state.currentChapter.tips;
-
- // 得到三维的参数
- let threeDimensionalConfig = state.currentChapter.threeDimensionalConfig;
- console.log("获取课程树 ---", state.chapterTree)
- console.log(
- "initTips ===> 每次进入不同流程后,进行处理的逻辑",
- state.tipsMsg, state.currentChapter, threeDimensionalConfig
- );
- // /**
- // * 因为加入了其他三维场景
- // * 他们有自带的上一步,下一步的UI控制
- // * 所以这里进行特殊处理
- // */
- // if (typeof threeDimensionalConfig == "string" && threeDimensionalConfig == "仿真模拟_清洗车") {
- // var thisTime = new Date().getTime();
- // initTimeQingXiCarAndQv.value = "" + thisTime;
- // // 此时进入三维场景,就默认进入到最后一个步骤
- // state.tipsBtns = [
- // {
- // name: '上一步',
- // click: prevStep,
- // attr: { type: 'primary', plain: 'plain' },
- // },
- // {
- // name: '完成并前往编制报告',
- // click: completeStudy,
- // attr: { type: 'primary' },
- // },
- // ];
- // // 同时先隐藏UI
- // stepTipsLook.value = false;
- // return;
- // }
- // 显示UI
- stepTipsLook.value = true;
- if (state.currentStep == 0 && state.currentNode == 0) {
- state.tipsBtns = [
- {
- name: '下一步',
- click: nextStep,
- attr: { type: 'primary' },
- },
- ];
- } else if (state.currentStep == chapterQueue.length - 1 && state.currentNode == chapterQueue[state.currentStep].length - 1) {
- state.tipsBtns = [
- {
- name: '上一步',
- click: prevStep,
- attr: { type: 'primary', plain: 'plain' },
- },
- {
- name: '完成并前往编制报告',
- click: completeStudy,
- attr: { type: 'primary' },
- },
- ];
- } else {
- state.tipsBtns = [
- {
- name: '上一步',
- click: prevStep,
- attr: { type: 'primary', plain: 'plain' },
- },
- {
- name: '下一步',
- click: nextStep,
- attr: { type: 'primary' },
- },
- ];
- }
- /**
- * 因为加入了其他三维场景
- * 他们有自带的上一步,下一步的UI控制
- * 所以这里进行特殊处理
- */
- if (typeof threeDimensionalConfig == "string" && threeDimensionalConfig == "仿真模拟_清洗车") {
- var thisTime = new Date().getTime();
- initTimeQingXiCarAndQv.value = "" + thisTime;
- // 隐藏 上一步,下一步 UI
- stepTipsLook.value = false;
- }
- };
- let studyInterval: NodeJS.Timeout;
- // 开场音乐
- let musicIndex = new URL("./../../../assets/music/index.mp3", import.meta.url).href;
- onMounted(() => {
- // // 第一次进来播放指定的声音基本上
- // objAudio.pause();
- // // 设置播放音乐的文件,或者地址
- // objAudio.setUrl(musicIndex);
- // // 不需要循环播放
- // objAudio.loopClose();
- // // 继续播放音乐
- // objAudio.start();
- threeWorld().loadSuccess = false;
- courseChapter3dViewBool.value = false;
- //学习时间上报
- studyInterval = setInterval(() => {
- const type = state.currentChapter.type != 30 ? 1 : 2;
- studyReport(studentTaskId, type);
- }, 1000 * 100);
- //获取任务信息
- getTrainDetail(taskId).then((res) => {
- //获取课程信息
- getCourseInfo(res.data.data.courseId).then((res1) => {
- if (res1.data.data.description) {
- state.hasRead = false;
- state.readHtml = res1.data.data.description;
- countdown('readingTime');
- } else {
- state.hasRead = true;
- state.showCnt = true;
- setMenuListHeight();
- }
- window.addEventListener('resize', () => {
- setMenuListHeight();
- });
- });
- //获取课程树
- getCourseChapterTree(res.data.data.courseId).then((res2) => {
- state.chapterTree = res2.data.data;
- buildChapterQueue(res2.data.data, res.data.data.optionChapters);
- //需先根据学习进度确定开始章节:currentStep和currentNode,默认第一章第一节
- //获取学习到的章节
- getCurrentChapter(studentTaskId).then((res3) => {
- const chapterId = res3.data.data;
- if (chapterId) {
- for (let i = 0; i < chapterQueue.length; i++) {
- const idx = chapterQueue[i].findIndex((x) => x.id == chapterId);
- if (idx > -1) {
- state.currentStep = i;
- state.currentNode = idx;
- break;
- }
- }
- state.lastChapterNum = state.currentStep * 100 + state.currentNode;
- }
- state.currentChapter = chapterQueue[state.currentStep][state.currentNode];
- initTips();
- });
- });
- // 根据学生id任务获取缺陷数据
- studentTaskOptionPipDefectListByStudentId(studentTaskId)
- .then((studentTaskOptionPipDefectListByStudentIdRes) => {
- studentTaskIdList.value = studentTaskOptionPipDefectListByStudentIdRes?.data?.data;
- courseChapter3dViewBool.value = true;
- // console.log(
- // "根据学生id任务获取缺陷数据",
- // studentTaskIdList.value,
- // studentTaskId
- // );
- })
- .catch((error) => {
- courseChapter3dViewBool.value = true;
- });
- });
- });
- onUnmounted(() => {
- if (studyInterval) clearInterval(studyInterval);
- });
- watch(
- () => state.currentChapter,
- (newVal) => {
- initTips();
- //滚动当前课程菜单至可视区域
- nextTick(() => {
- const target = document.querySelector('.el-step__description .is-process') as HTMLElement;
- target?.scrollIntoView({ behavior: 'smooth', block: 'center' });
- });
- //课程菜单默认显示二级,兼容课程树层级大于二级的情况
- if (state.currentNode == 0) state.activeSecondMenu = -1;
- else {
- const idx = (state.chapterTree[state.currentStep].children as anyObj[])?.findIndex((x) => x.id == newVal.id);
- if (idx > -1) state.activeSecondMenu = idx;
- }
- }
- );
- /**
- * 检测实训注意事项 知道了点击回调
- */
- courseChapter3dShow().show.showMatterGotItCallback = function () {
- // console.log(
- // "检测实训注意事项 知道了点击回调", res
- // );
- // 触发下一步逻辑
- nextStep();
- };
- /**
- * 监听弹出提示隐藏后来触发不同的逻辑
- */
- watch(
- () => courseChapter3dShow().show.showToastViewBool,
- (newVal, oldVal) => {
- if (courseChapter3dShow().show.showToastViewBool == true) {
- return;
- }
- // console.log(
- // " () => courseChapter3dShow().show.showToastState 1111111111 ",
- // courseChapter3dShow().show.showToastState
- // );
- switch (courseChapter3dShow().show.showToastState) {
- case '立即穿戴':
- // // 触发下一步逻辑
- // nextStep();
- break;
- }
- }
- );
- // 记录 tipsBtnsUpOpenEvent 事件是否显示上一步按钮
- let tipsBtnsUpOpenEventBool: Boolean = true;
- /**
- * 上一步是否显示
- * open true - 显示, false - 隐藏
- */
- const tipsBtnsUpOpenEvent = (open: Boolean) => {
- // console.log("上一步是否显示", open);
- tipsBtnsUpOpenEventBool = open;
- tipsBtnsUpAndDownOpenEvent();
- };
- // 记录 tipsBtnsUpOpenEvent 事件是否显示下一步按钮
- let tipsBtnsDownOpenEventBool: Boolean = true;
- /**
- * 下一步是否显示
- * open true - 显示, false - 隐藏
- */
- const tipsBtnsDownOpenEvent = (open: Boolean) => {
- // console.log("下一步是否显示", open);
- tipsBtnsDownOpenEventBool = open;
- tipsBtnsUpAndDownOpenEvent();
- };
- /**
- * 通过3d传来的事件来控制上一步下一步是否显示逻辑
- */
- const tipsBtnsUpAndDownOpenEvent = () => {
- let newArray = [];
- if (tipsBtnsUpOpenEventBool == true) {
- // newArray.push({
- // name: '上一步',
- // click: prevStep,
- // attr: { type: 'primary', plain: 'plain' },
- // });
- }
- if (tipsBtnsDownOpenEventBool == true) {
- newArray.push({
- name: '下一步',
- click: nextStep,
- attr: { type: 'primary' },
- });
- }
- // console.log(
- // " ========= state.tipsBtns ========= ",
- // state.tipsBtns
- // );
- // 如果出现 完成并前往编制报告 则不替换
- try {
- for (let i = 0; i < state.tipsBtns.length; i++) {
- let thisTipsBtns = state.tipsBtns[i];
- if (thisTipsBtns.name.indexOf('完成') >= 0) {
- return;
- }
- }
- } catch (e) {}
- state.tipsBtns = newArray;
- };
- // 操作帮助点击退出
- const showOperationHelpExitEvent = () => {
- // 触发下一步逻辑
- nextStep();
- };
- /**
- * 车的完成下井实验
- */
- const carShutDownEvent = () => {
- // 触发下一步逻辑
- nextStep();
- };
- /**
- * 车的相机截图
- * img base64位图片
- */
- const carCameraScreenshotEvent = (img: any) => {
- // console.log(
- // "车的相机截图", img
- // );
- // 将 base64为转换成,Blob格式
- let objBlob = dataURLtoBlob(img);
- // blob 转换成 file对象
- const file = new File([objBlob], 'example.png', { type: 'text/plain' });
- // 优先上传文件
- // @ts-ignore
- uploadFileOss(file, 'course/cover', null)
- .then(function (e: any) {
- // console.log(
- // "上传文件", e
- // );
- studentTaskPhoto({
- studentTaskId: studentTaskId,
- imageUrl: e,
- remark: '',
- })
- .then(function (studentTaskPhotoRes: any) {
- // console.log(
- // "上传文件成功", studentTaskPhotoRes
- // );
- // ElMessage({
- // message: '截图上传完成',
- // type: 'success',
- // });
- courseChapter3dShow().show.showToastViewBool = false;
- courseChapter3dShow().show.showPromptEvent('截图上传完成', null, function (res: any) {
- // console.log("yes", res);
- });
- })
- .catch(function (studentTaskPhotoResError: any) {
- // ElMessage({
- // message: '上传失败',
- // type: 'warning',
- // });
- courseChapter3dShow().show.showToastViewBool = false;
- courseChapter3dShow().show.showPromptEvent('上传失败', null, function (res: any) {
- // console.log("yes", res);
- });
- });
- })
- .catch(function (e: any) {
- // ElMessage({
- // message: e || '上传失败',
- // type: 'warning',
- // });
- courseChapter3dShow().show.showToastViewBool = false;
- courseChapter3dShow().show.showPromptEvent('上传失败', null, function (res: any) {
- // console.log("yes", res);
- });
- });
- };
- /**
- * 将base64转换为blob
- * @param dataurl base64位图片
- */
- const dataURLtoBlob = (dataurl: any) => {
- let arr = dataurl.split(','),
- mime = arr[0].match(/:(.*?);/)[1],
- bstr = atob(arr[1]),
- n = bstr.length,
- u8arr = new Uint8Array(n);
- while (n--) {
- u8arr[n] = bstr.charCodeAt(n);
- }
- return new Blob([u8arr], { type: mime });
- };
- /**
- * 清洗车自定义回调步骤
- */
- const callbackProgressQingXiCheAndQv = (json : any) => {
- console.log("callbackProgressQingXiCheAndQv ===>", json);
- // 完成所有步骤
- if (json.name == "equipmentRepositioningWork") {
- stepTipsLook.value = true;
- }
- }
- </script>
- <style lang="scss" scoped>
- @use './css/animationEvent.scss';
- @use './css/commonsScrollbarNew.scss';
- .chapter-container {
- position: absolute;
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- z-index: 1;
- .chapter-describe {
- position: relative;
- width: 70%;
- height: 90%;
- background-image: url(/src/assets/student/bg_describe.png);
- background-size: 100% 100%;
- &:before {
- content: '';
- position: absolute;
- top: 3%;
- left: 28%;
- height: 6%;
- width: 70%;
- background-image: url(/src/assets/student/training.png);
- background-size: auto 100%;
- background-repeat: no-repeat;
- }
- .describe-cnt {
- overflow: auto;
- box-sizing: border-box;
- position: absolute;
- inset: 10rem 0 10rem 6rem;
- padding-right: 4rem;
- }
- .describe-readed {
- position: absolute;
- bottom: 3rem;
- width: 100%;
- display: flex;
- justify-content: center;
- .readed-btn {
- width: 20rem;
- height: 5.4rem;
- line-height: 5.4rem;
- text-align: center;
- color: white;
- font-size: 2rem;
- border-radius: 0.8rem;
- background: linear-gradient(90deg, #6cd9e9 0%, #4b90dd 100%);
- cursor: pointer;
- &.reading {
- pointer-events: none;
- }
- }
- }
- }
- .chapter-box {
- width: 100%;
- height: 100%;
- }
- .chapter-content {
- position: absolute;
- width: 100%;
- height: 100%;
- .menu-box {
- position: absolute;
- top: 3.2rem;
- left: 2rem;
- width: 20rem;
- height: calc(100% - 18rem);
- transition-property: left;
- transition-duration: 0.6s;
- z-index: 2;
- &.fold {
- left: -20rem;
- .menu-switch {
- background-image: url(/src/assets/student/training/menu_switch1.png);
- }
- }
- .menu-switch {
- position: absolute;
- width: 2rem;
- height: 5rem;
- background-image: url(/src/assets/student/training/menu_switch.png);
- background-size: 100% 100%;
- right: -2rem;
- top: 50%;
- margin-top: -2.5rem;
- cursor: pointer;
- }
- .menu-title {
- height: 5rem;
- background-image: url(/src/assets/student/training/menu_title.png);
- background-size: 100% 100%;
- color: white;
- // font-size: 2rem;
- font-size: 1.8rem;
- overflow: hidden;
- &:before {
- content: '';
- display: inline-block;
- vertical-align: middle;
- height: 5rem;
- width: 8rem;
- background-image: url(/src/assets/student/training/menu_icon.png);
- background-size: auto 50%;
- background-repeat: no-repeat;
- background-position: center center;
- }
- }
- .menu-list {
- position: relative;
- min-height: 20rem;
- max-height: calc(100% - 6rem);
- margin-top: 1rem;
- padding: 3rem 0 3rem 2rem;
- background-image: url(/src/assets/student/training/menu_list.png);
- // background-image: url(/src/assets/menuLeft/menuBottom.webp);
- background-size: 100% 100%;
- box-sizing: border-box;
- --step-item-size: 2rem;
- --step-icon-size: 1.2rem;
- --step-line-left: 0.9rem;
- --step-border-width: 0.2rem;
- .step-icon {
- width: var(--step-item-size);
- height: var(--step-item-size);
- border-radius: 50%;
- border: var(--step-border-width) solid #5faaf4;
- box-sizing: border-box;
- transition: 0.15s ease-out;
- display: flex;
- justify-content: center;
- align-items: center;
- .step-icon-inner {
- width: var(--step-icon-size);
- height: var(--step-icon-size);
- background-size: 100% 100%;
- }
- }
- :deep(.el-step__head) {
- width: var(--step-item-size);
- .el-step__line {
- width: var(--step-border-width);
- top: var(--step-item-size);
- left: var(--step-line-left);
- background-color: #5faaf4;
- }
- .el-step__icon {
- width: unset;
- height: unset;
- background: transparent;
- display: flex;
- }
- &.is-process .step-icon-inner {
- background-image: url(/src/assets/student/training/step_process.png);
- }
- &.is-finish .step-icon-inner {
- background-image: url(/src/assets/student/training/step_finish.png);
- }
- }
- :deep(.el-step__main) {
- padding-left: 2rem;
- padding-right: 2rem;
- .el-step__title {
- // font-size: var(--step-item-size);
- font-size: 1.5rem;
- color: white;
- font-weight: unset;
- line-height: var(--step-item-size);
- cursor: pointer;
- &.is-process,
- &.is-finish {
- text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2);
- background: linear-gradient(180deg, #82ccdd 0%, #589cf2 100%);
- background-clip: text;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- }
- }
- .el-step__description {
- margin-left: -1.1rem;
- // --step-item-size: 0.9rem;
- --step-item-size: 1.1rem;
- --step-icon-size: 0.6rem;
- .el-steps {
- margin: 0.8rem 0;
- }
- .el-step__head {
- width: var(--step-icon-size);
- &.is-process .step-icon-second {
- background-color: #5ff49b;
- }
- &.is-finish .step-icon-second {
- background-color: #5fa9f4;
- }
- }
- .el-step__icon {
- height: var(--step-item-size);
- line-height: var(--step-item-size);
- }
- .step-icon-second {
- width: var(--step-icon-size);
- height: var(--step-icon-size);
- border-radius: 50%;
- box-sizing: border-box;
- background-color: #ccc;
- }
- .el-step__line {
- width: 0.1rem;
- left: 0.25rem;
- top: 0.6rem;
- bottom: -0.4rem;
- margin-bottom: unset !important;
- &:after {
- display: none;
- }
- }
- .el-step:last-of-type .el-step__line {
- display: none;
- }
- .el-step__main {
- padding-left: 0.6rem;
- }
- .el-step__title {
- font-size: var(--step-item-size);
- &.is-process {
- color: #5ff49b;
- -webkit-text-fill-color: unset;
- }
- &.is-finish {
- color: #5fa9f4;
- -webkit-text-fill-color: unset;
- }
- }
- }
- }
- :deep(.el-step:last-of-type) {
- .el-step__line {
- display: block;
- margin-bottom: 1rem;
- &:after {
- content: '';
- position: absolute;
- border: 0.8rem solid transparent;
- border-top-color: #5faaf4;
- bottom: -1rem;
- left: -0.7rem;
- }
- .el-step__line-inner {
- transition-delay: 150ms;
- border-width: 0px;
- height: 0%;
- }
- }
- }
- }
- }
- .chapter-detail {
- position: absolute;
- top: 3.2rem;
- left: 28rem;
- width: 88rem;
- height: 56rem;
- max-height: calc(100% - 12rem);
- background-image: url(/src/assets/student/training/window_bg.png);
- background-size: 100% 100%;
- .detail-title {
- height: 18%;
- font-size: 3rem;
- text-align: center;
- color: white;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .detail-cnt {
- height: 76%;
- padding: 0 5rem;
- box-sizing: border-box;
- overflow: auto;
- :deep(img) {
- max-width: 100%;
- }
- }
- }
- // 左侧菜单
- .menuLeft {
- position: fixed;
- top: 10.92rem;
- bottom: 18rem;
- left: 2.28rem;
- width: 21.64rem;
- z-index: 2;
- opacity: 0.9;
-
- .menuTitle {
- position: absolute;
- width: 100%;
- top: 0px;
- left: 0px;
- height: 5.71rem;
- background-image: url(/src/assets/menuLeft/title.webp);
- background-size: 100% 100%;
-
- .logoLeft, .txtRight {
- position: absolute;
- }
- .logoLeft {
- width: 2.28rem;
- height: 2.92rem;
- background-image: url(/src/assets/menuLeft/gps.webp);
- background-size: 100% 100%;
- top: 1.6rem;
- left: 2.07rem;
- }
- .txtRight {
- top: 0px;
- height: 5.71rem;
- line-height: 5.71rem;
- left: 5.64rem;
- right: 3rem;
- font-weight: 400;
- font-size: 2.5rem;
- color: #FFFFFF;
- white-space: nowrap; /* 不换行 */
- overflow: hidden; /* 隐藏超出部分 */
- text-overflow: ellipsis; /* 显示省略号 */
- }
- }
- .menuList {
- position: absolute;
- width: 100%;
- top: 7rem;
- bottom: 0px;
- background-image: url(/src/assets/menuLeft/menuBottom.webp);
- background-size: 100% 100%;
- padding: 1rem 0.5rem 1rem 0.5rem;
- .menuListBorder {
- position: absolute;
- top: 1rem;
- left: 1rem;
- bottom: 1rem;
- right: 1rem;
-
- .menuListMain {
- position: relative;
- width: 100%;
- height: auto;
- .menuListpParent, .menuListpChildren {
- position: relative;
- width: 90%;
- left: 5%;
- margin: 0.35rem 0rem 0.35rem 0rem;
- padding: 0.35rem 0rem 0.35rem 0rem;
- // 手势
- cursor:pointer;
- }
- .logoMenu {
- width: 1rem;
- height: 1rem;
- background-image: url(/src/assets/menuLeft/yes.webp);
- background-size: 100% 100%;
- }
- .logoTime {
- width: 1rem;
- height: 1rem;
- background-image: url(/src/assets/menuLeft/time.webp);
- background-size: 100% 100%;
- }
- .logoNo {
- width: 1rem;
- height: 1rem;
- background-image: url(/src/assets/menuLeft/no.webp);
- background-size: 100% 100%;
- }
- .menuListpParent {
- font-weight: 400;
- font-size: 1.28rem;
- color: #C8C8C8;
- background: #386064;
- height: 2.5rem;
-
- .menuListpParentLeft, .menuListpParentCenter, .menuListpParentRight {
- position: absolute;
- height: 100%;
- top: 0px;
- }
- .menuListpParentLeft {
- left: 0px;
- width: 2.5rem;
- /* 水平垂直居中,支持文字自动换行 */
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
- .menuListpParentCenter {
- left: 2.5rem;
- right: 2.5rem;
- line-height: 2.5rem;
- white-space: nowrap; /* 不换行 */
- overflow: hidden; /* 隐藏超出部分 */
- text-overflow: ellipsis; /* 显示省略号 */
- }
- .menuListpParentRight {
- width: 2.5rem;
- right: 0px;
- background: #2BA987;
- color: #FFFFFF;
- font-size: 2rem;
- /* 水平垂直居中,支持文字自动换行 */
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
-
- }
- .menuListpParentYes {
- color: #ffffff;
- }
- .menuListpParentSelect {
- color: #ffffff;
- }
- .menuListpChildren {
- font-weight: 400;
- font-size: 1.14rem;
- color: #C8C8C8;
-
- .menuListpChildrenKong, .menuListpChildrenLeft, .menuListpChildrenRight {
- display: inline-flex;
- }
- .menuListpChildrenKong {
- width: 1%;
- }
- .menuListpChildrenLeft {
- width: 16%;
- /* 水平垂直居中,支持文字自动换行 */
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
- .menuListpChildrenRight {
- width: 83%;
- }
- }
- .menuListpChildrenYes {
- color: #2CD36B;
- }
- .menuListpChildrenSelect {
- color: #FFFFFF;
- background: linear-gradient( 90deg, rgba(39,171,151,0.6) 0%, rgba(39,171,151,0.2) 100%);
- }
-
- }
- }
- }
-
- }
- .menuLook {
- position: fixed;
- width: 2rem;
- height: 5.71rem;
- left: 23.5rem;
- top: 50%;
- margin: -2.855rem 0px 0px 0px;
- z-index: 2;
- background-image: url(/src/assets/menuLeft/menuOpen.webp);
- background-size: 100% 100%;
- // 手势
- cursor:pointer;
- }
- .menuLookExit {
- background-image: url(/src/assets/menuLeft/menuExit.webp);
- background-size: 100% 100%;
- }
- }
- }
- </style>
|