This commit is contained in:
zyy 2019-08-14 15:03:47 +08:00
commit c304af4811
20 changed files with 1559 additions and 1525 deletions

View File

@ -1,5 +1,5 @@
module.exports = {
presets: [
'@vue/app',["@babel/preset-env", { "modules": false }]
'@vue/app'
]
}

View File

@ -38,4 +38,4 @@ new Vue({
i18n,
render: h => h(App)
});

View File

@ -455,124 +455,145 @@ export const asyncRouter = [
},
{
path: '/teach',
redirect: '/teach/home',
component: Teach,
component: Layout,
meta: {
roles: [admin, userLesson, user]
},
children: [
{
path: 'home',
component: TeachHome,
path: '',
redirect: '/teach/home',
component: Teach,
meta: {
i18n: 'router.teachSystem'
}
},
{
// 课程详情
path: 'detail/:lessonId',
component: TeachDetail,
meta: {
},
hidden: true
},
{
// 实训详情
path: 'practical/:trainingId/:lessonId',
component: TeachPractical,
meta: {
},
hidden: true
},
{
path: 'pay/:lessonId',
component: Pay,
meta: {
},
hidden: true
children: [
{
path: 'home',
component: TeachHome
},
{
// 课程详情
path: 'detail/:lessonId',
component: TeachDetail,
meta: {
},
hidden: true
},
{
// 实训详情
path: 'practical/:trainingId/:lessonId',
component: TeachPractical,
meta: {
},
hidden: true
},
{
path: 'pay/:lessonId',
component: Pay,
meta: {
},
hidden: true
}
]
}
]
},
{
path: '/exam',
redirect: '/exam/home',
component: Exam,
component: Layout,
meta: {
roles: [admin, userExam, user]
},
children: [
{
path: 'home',
component: ExamHome,
path: '',
redirect: '/exam/home',
component: Exam,
meta: {
i18n: 'router.examSystem'
}
},
{
// 试卷详情
path: 'detail/:examId',
component: ExamDetail,
hidden: true
},
{
path: 'course/:lessonId',
component: ExamCourseDetail,
hidden: true
},
{
// 规则管理
path: 'examRule/manage',
component: PublishExamRule,
hidden: true
},
{
path: 'examRule/draft/:mode/:ruleId/:lessonId',
hidden: true,
component: PublishExamRuleDraft
},
{
path: 'pay/:lessonId',
component: Pay,
hidden: true
},
{
// 开始考试
path: 'questionDetail/:examQuestionId',
component: ExamQuestionDetail,
hidden: true
},
{
// 考试结果
path: 'result/:userExamId',
component: ExamResult,
hidden: true
},
children: [
{
path: 'home',
component: ExamHome
},
{
// 试卷详情
path: 'detail/:examId',
component: ExamDetail,
hidden: true
},
{
path: 'course/:lessonId',
component: ExamCourseDetail,
hidden: true
},
{
// 规则管理
path: 'examRule/manage',
component: PublishExamRule,
hidden: true
},
{
path: 'examRule/draft/:mode/:ruleId/:lessonId',
hidden: true,
component: PublishExamRuleDraft
},
{
path: 'pay/:lessonId',
component: Pay,
hidden: true
},
{
// 开始考试
path: 'questionDetail/:examQuestionId',
component: ExamQuestionDetail,
hidden: true
},
{
// 考试结果
path: 'result/:userExamId',
component: ExamResult,
hidden: true
}
]
}
]
},
{
path: '/demonstration',
redirect: '/demonstration/home',
component: Demonstration,
component: Layout,
meta: {
roles: [admin, userSimulation, user]
},
children: [
{
path: 'home',
component: DemonstrationHome,
path: '',
redirect: '/demonstration/home',
component: Demonstration,
meta: {
i18n: 'router.demonstrationSystem'
}
},
{
path: 'detail/:mapId',
component: DemonstrationDetail,
hidden: true
},
{
path: 'pay/:lessonId',
component: Pay,
hidden: true
},
children: [
{
path: 'home',
component: DemonstrationHome,
meta: {
i18n: 'router.demonstrationSystem'
}
},
{
path: 'detail/:mapId',
component: DemonstrationDetail,
hidden: true
},
{
path: 'pay/:lessonId',
component: Pay,
hidden: true
}
]
}
]
},

View File

@ -4,18 +4,33 @@
<b>收银台</b>
</div>
<div :style=" { height: height - 60 +'px' }">
<el-scrollbar wrapClass="scrollbar-wrapper">
<el-steps :active="active" finish-status="success"
style="margin-top: 20px; margin-left: auto; margin-right: auto; width: 80%" center>
<el-step title="提交订单"></el-step>
<el-step title="完成支付"></el-step>
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-steps
:active="active"
finish-status="success"
style="margin-top: 20px; margin-left: auto; margin-right: auto; width: 80%"
center
>
<el-step title="提交订单" />
<el-step title="完成支付" />
</el-steps>
<div style="margin-top: 20px; margin-left: auto; margin-right: auto; width: 80%;">
<commit-draft ref="commit" @commit="commit" :orderData="orderData" :systemName="systemName"
v-show="active===0"></commit-draft>
<confirm-draft ref="confirm" @confirm="confirm" :orderData="orderData" :systemName="systemName" :order="order"
v-show="active===1"></confirm-draft>
<finish-draft ref="finish" @finish="finish" :finishStatus="finishStatus" v-show="active===2"></finish-draft>
<commit-draft
v-show="active===0"
ref="commit"
:order-data="orderData"
:system-name="systemName"
@commit="commit"
/>
<confirm-draft
v-show="active===1"
ref="confirm"
:order-data="orderData"
:system-name="systemName"
:order="order"
@confirm="confirm"
/>
<finish-draft v-show="active===2" ref="finish" :finish-status="finishStatus" @finish="finish" />
</div>
</el-scrollbar>
</div>
@ -23,103 +38,103 @@
</template>
<script>
import { mapGetters } from "vuex";
import { getCommodityDetailByParams } from '@/api/management/goods';
import { PermissionType } from "@/scripts/ConstDic";
import { UrlConfig } from '@/router/index';
import CommitDraft from "./commit";
import ConfirmDraft from "./confirm";
import FinishDraft from "./finish";
import WindowResizeHandler from "@/mixin/WindowResizeHandler";
import { getCommodityDetailByParams } from '@/api/management/goods';
import { PermissionType } from '@/scripts/ConstDic';
import { UrlConfig } from '@/router/index';
import CommitDraft from './commit';
import ConfirmDraft from './confirm';
import FinishDraft from './finish';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
export default {
name: "LessonDetail",
components: {
CommitDraft,
ConfirmDraft,
FinishDraft
},
mixins: [WindowResizeHandler],
data() {
return {
height: "",
active: -1,
order: {},
title: "",
finishStatus: "02",
orderData: {},
routeDict: {
0: "commit",
1: "confirm",
2: "finish"
}
};
},
computed: {
systemName() {
switch (this.$route.query.permissionType) {
case PermissionType.LESSON: return '教学系统';
case PermissionType.EXAM: return '考试系统';
case PermissionType.SIMULATION: return '仿真系统';
case PermissionType.SCREEN: return '大屏系统';
}
}
},
watch: {
$route(newVal) {
this.initLoadPage();
}
},
mounted() {
this.initLoadPage();
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight;
},
//
initLoadPage() {
let data = {
mapId: this.$route.query.mapId,
lessonId: this.$route.params.lessonId,
productType: this.$route.query.permissionType,
mapProductCode: this.$route.query.prdCode,
};
export default {
name: 'LessonDetail',
components: {
CommitDraft,
ConfirmDraft,
FinishDraft
},
mixins: [WindowResizeHandler],
data() {
return {
height: '',
active: -1,
order: {},
title: '',
finishStatus: '02',
orderData: {},
routeDict: {
0: 'commit',
1: 'confirm',
2: 'finish'
}
};
},
computed: {
systemName() {
switch (this.$route.query.permissionType) {
case PermissionType.LESSON: return '教学系统';
case PermissionType.EXAM: return '考试系统';
case PermissionType.SIMULATION: return '仿真系统';
case PermissionType.SCREEN: return '大屏系统';
}
return '';
}
},
watch: {
$route(newVal) {
this.initLoadPage();
}
},
mounted() {
this.initLoadPage();
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight - 61;
},
//
initLoadPage() {
const data = {
mapId: this.$route.query.mapId,
lessonId: this.$route.params.lessonId,
productType: this.$route.query.permissionType,
mapProductCode: this.$route.query.prdCode
};
getCommodityDetailByParams(data).then(response => {
this.active = 0;
this.orderData = response.data;
}).catch(error => {
this.$messageBox('获取课程信息失败');
});
},
//
commit(data) {
this.active = 1;
this.order = data;
},
//
confirm(data) {
this.active = 2;
this.finishStatus = data;
this.$refs.finish.createCountTimer();
},
//
finish(data) {
this.active = 0;
let type = this.$route.query.permissionType;
if (type === PermissionType.LESSON) {
this.$router.replace({ path: `${UrlConfig.teach.detail}/${this.$route.params.lessonId}` });
} else if (type === PermissionType.EXAM) {
this.$router.replace({ path: `${UrlConfig.exam.course}/${this.orderData.lessonId}` });
} else if (type === PermissionType.SCREEN) {
this.$router.replace({ path: `${UrlConfig.dp.detail}/${this.$route.params.lessonId}` });
} else if (type === PermissionType.SIMULATION) {
this.$router.replace({ path: `${UrlConfig.demonstration.detail}/${this.$route.params.lessonId}` });
} else {
this.$router.replace({ path: `/` });
}
}
}
};
</script>
getCommodityDetailByParams(data).then(response => {
this.active = 0;
this.orderData = response.data;
}).catch(() => {
this.$messageBox('获取课程信息失败');
});
},
//
commit(data) {
this.active = 1;
this.order = data;
},
//
confirm(data) {
this.active = 2;
this.finishStatus = data;
this.$refs.finish.createCountTimer();
},
//
finish(data) {
this.active = 0;
const type = this.$route.query.permissionType;
if (type === PermissionType.LESSON) {
this.$router.replace({ path: `${UrlConfig.teach.detail}/${this.$route.params.lessonId}` });
} else if (type === PermissionType.EXAM) {
this.$router.replace({ path: `${UrlConfig.exam.course}/${this.orderData.lessonId}` });
} else if (type === PermissionType.SCREEN) {
this.$router.replace({ path: `${UrlConfig.dp.detail}/${this.$route.params.lessonId}` });
} else if (type === PermissionType.SIMULATION) {
this.$router.replace({ path: `${UrlConfig.demonstration.detail}/${this.$route.params.lessonId}` });
} else {
this.$router.replace({ path: `/` });
}
}
}
};
</script>

View File

@ -1,313 +1,320 @@
<template>
<el-card v-loading="loading">
<div slot="header" style="text-align: center;">
<span v-if="hasProduct"><b>仿真名称 {{ courseModel.name }}</b></span>
<span v-else>无仿真产品</span>
</div>
<el-tabs type="border-card" @tab-click="handleLeave" :value="currentPrdCode"
:style="{ height: height-50 +'px' }">
<el-tab-pane v-for="item in productList" :key="item.code" :name="item.code" :label="item.name"
style="padding: 5px" :style="{ height: height-160 +'px' }">
<el-scrollbar wrapClass="scrollbar-wrapper" :style="{ height: height-170 +'px' }">
<p class="list-item">
<span class="list-label">产品说明</span>
<span class="list-elem">{{ courseModel.remarks }}</span>
</p>
<p class="list-item">
<span class="list-label">权限列表</span>
</p>
<limit-list :ref="`limit_${item.code}`" :courseModel="courseModel" @initLoadPage="initLoadPage">
</limit-list>
</el-scrollbar>
</el-tab-pane>
<div class="btn-buy" v-if="hasProduct">
<el-button type="success" @click="buy">购买</el-button>
<el-button type="primary" @click="distribute" v-if="hasPermssion">权限分发</el-button>
<el-button type="primary" @click="transfer" v-if="hasPermssion">权限转赠</el-button>
<el-button type="primary" @click="start" v-show="isStartDemon">开始仿真</el-button>
<el-button type="primary" @click="start" v-show="isCreateRoom">创建房间</el-button>
<el-button type="primary" @click="joinRoom" v-show="isInRoom">进入房间</el-button>
</div>
</el-tabs>
</el-card>
<el-card v-loading="loading">
<div slot="header" style="text-align: center;">
<span v-if="hasProduct"><b>仿真名称 {{ courseModel.name }}</b></span>
<span v-else>无仿真产品</span>
</div>
<el-tabs
type="border-card"
:value="currentPrdCode"
:style="{ height: height-50 +'px' }"
@tab-click="handleLeave"
>
<el-tab-pane
v-for="item in productList"
:key="item.code"
:name="item.code"
:label="item.name"
style="padding: 5px"
:style="{ height: height-160 +'px' }"
>
<el-scrollbar wrap-class="scrollbar-wrapper" :style="{ height: height-170 +'px' }">
<p class="list-item">
<span class="list-label">产品说明</span>
<span class="list-elem">{{ courseModel.remarks }}</span>
</p>
<p class="list-item">
<span class="list-label">权限列表</span>
</p>
<limit-list :ref="`limit_${item.code}`" :course-model="courseModel" @initLoadPage="initLoadPage" />
</el-scrollbar>
</el-tab-pane>
<div v-if="hasProduct" class="btn-buy">
<el-button type="success" @click="buy">购买</el-button>
<el-button v-if="hasPermssion" type="primary" @click="distribute">权限分发</el-button>
<el-button v-if="hasPermssion" type="primary" @click="transfer">权限转赠</el-button>
<el-button v-show="isStartDemon" type="primary" @click="start">开始仿真</el-button>
<el-button v-show="isCreateRoom" type="primary" @click="start">创建房间</el-button>
<el-button v-show="isInRoom" type="primary" @click="joinRoom">进入房间</el-button>
</div>
</el-tabs>
</el-card>
</template>
<script>
import { getCourseLessonTree } from '@/api/management/exam';
import { getProductList, getPublishMapInfo } from '@/api/jmap/map';
import { getGoodsTryUse } from '@/api/management/goods';
import { getCommodityMapProduct, getMapProductDetail } from '@/api/management/mapprd';
import { mapGetters } from 'vuex';
import { PermissionType } from '@/scripts/ConstDic';
import { launchFullscreen } from '@/utils/screen';
import { queryPermissionSimulation } from '@/api/management/author';
import { postCreateRoom, getjointTraining, checkRoomExist } from '@/api/chat';
import { UrlConfig } from '@/router/index';
import { simulationNotify } from '@/api/simulation';
import localStore from 'storejs';
import LimitList from "@/views/components/limits/index";
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import { getPublishMapInfo } from '@/api/jmap/map';
import { getGoodsTryUse } from '@/api/management/goods';
import { getCommodityMapProduct, getMapProductDetail } from '@/api/management/mapprd';
import { PermissionType } from '@/scripts/ConstDic';
import { launchFullscreen } from '@/utils/screen';
import { queryPermissionSimulation } from '@/api/management/author';
import { postCreateRoom, getjointTraining, checkRoomExist } from '@/api/chat';
import { UrlConfig } from '@/router/index';
import { simulationNotify } from '@/api/simulation';
import localStore from 'storejs';
import LimitList from '@/views/components/limits/index';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
export default {
name: 'ExamDetailList',
mixins: [
WindowResizeHandler
],
components: {
LimitList
},
data() {
return {
height: '',
tryTime: 0,
goodsId: '',
tryUser: 0,
loading: true,
currentLessonId: '',
currentPrdCode: '',
productList: [],
courseModel: {
id: '',
name: '',
mapId: '',
skinStyle: '',
remarks: '',
prdType: '',
prdCode: '',
pmsList: [],
},
EffectiveTypeList: [],
jointShow: false,
jointGroup: '',
}
},
filters: {
setTime(val) {
if (val <= 1) {
return `0分钟`;
} else if (1 < val && val <= 60) {
return '1分钟';
} else if (val > 60) {
let time = parseInt(val / 60);
return `${time}分钟`;
}
}
},
computed: {
hasProduct() {
return this.productList.length;
},
hasPermssion() {
let isShow = false;
if (this.courseModel.pmsList.length) {
isShow = true;
}
return isShow;
},
isStartDemon() {
return this.courseModel.prdType !== '03' && (this.hasPermssion || this.tryTime > 0);
},
isCreateRoom() {
return this.courseModel.prdType === '03' && this.hasPermssion && !this.jointShow
},
isInRoom() {
return this.courseModel.prdType == '03' && this.hasPermssion && this.jointShow
},
mapId() {
return this.$route.params.mapId;
}
},
watch: {
'$route': function (val) {
this.loadInitData();
},
'currentPrdCode': function (code) {
this.initLoadPage({ id: this.mapId, code: code });
}
},
async mounted() {
this.loadInitData();
},
methods: {
async loadInitData() {
this.$Dictionary.effectiveType().then(list => {
this.EffectiveTypeList = list;
});
export default {
name: 'ExamDetailList',
components: {
LimitList
},
filters: {
setTime(val) {
if (val <= 1) {
return `0分钟`;
} else if (val > 1 && val <= 60) {
return '1分钟';
} else if (val > 60) {
const time = parseInt(val / 60);
return `${time}分钟`;
}
}
},
mixins: [
WindowResizeHandler
],
data() {
return {
height: '',
tryTime: 0,
goodsId: '',
tryUser: 0,
loading: true,
currentLessonId: '',
currentPrdCode: '',
productList: [],
courseModel: {
id: '',
name: '',
mapId: '',
skinStyle: '',
remarks: '',
prdType: '',
prdCode: '',
pmsList: []
},
EffectiveTypeList: [],
jointShow: false,
jointGroup: ''
};
},
computed: {
hasProduct() {
return this.productList.length;
},
hasPermssion() {
let isShow = false;
if (this.courseModel.pmsList.length) {
isShow = true;
}
return isShow;
},
isStartDemon() {
return this.courseModel.prdType !== '03' && (this.hasPermssion || this.tryTime > 0);
},
isCreateRoom() {
return this.courseModel.prdType === '03' && this.hasPermssion && !this.jointShow;
},
isInRoom() {
return this.courseModel.prdType == '03' && this.hasPermssion && this.jointShow;
},
mapId() {
return this.$route.params.mapId;
}
},
watch: {
'$route': function (val) {
this.loadInitData();
},
'currentPrdCode': function (code) {
this.initLoadPage({ id: this.mapId, code: code });
}
},
async mounted() {
this.loadInitData();
},
methods: {
async loadInitData() {
this.$Dictionary.effectiveType().then(list => {
this.EffectiveTypeList = list;
});
this.currentPrdCode = '';
this.productList = [];
try {
if (parseInt(this.mapId)) {
this.getJointTrainingList();
let rest = await getPublishMapInfo(this.mapId);
if (rest && rest.code == 200) {
let resp = await getCommodityMapProduct(rest.data.skinStyle);
if (resp.data && resp.data.length) {
this.productList = resp.data.sort((a, b) => {
return Number(b.prdType) - Number(a.prdType);
})
this.currentPrdCode = '';
this.productList = [];
try {
if (parseInt(this.mapId)) {
this.getJointTrainingList();
const rest = await getPublishMapInfo(this.mapId);
if (rest && rest.code == 200) {
const resp = await getCommodityMapProduct(rest.data.skinStyle);
if (resp.data && resp.data.length) {
this.productList = resp.data.sort((a, b) => {
return Number(b.prdType) - Number(a.prdType);
});
this.currentPrdCode = localStore.get(this.$route.path) || this.productList[0].code;
}
}
}
this.loading = false;
} catch (e) {
this.$messageBox('获取产品列表失败');
}
},
resizeHandler: function () {
this.height = this._clientHeight;
},
async getJointTrainingList() {
try {
if (this.mapId) {
let res = await checkRoomExist({ mapId: this.mapId });
this.jointGroup = res.data;
this.jointShow = false;
if (res.data) {
this.jointShow = true;
}
}
} catch (error) {
console.error(error, '获取是否拥有综合演练房间');
}
},
async handleLeave(tab) {
this.currentPrdCode = tab.name;
localStore.set(this.$route.path, this.currentPrdCode);
},
async initLoadPage(data) {
this.loading = true
if (data && parseInt(data.id) && data.code) {
try {
let resp = await getMapProductDetail(data.code);
this.tryUser = 0;
this.loading = false;
this.courseModel = {
id: resp.data.id,
name: resp.data.name,
mapId: data.id,
skinStyle: resp.data.skinStyle,
remarks: resp.data.remarks,
prdType: resp.data.prdType,
prdCode: resp.data.code,
pmsList: resp.data.pmsList || [],
PermissionType: PermissionType.SIMULATION
};
this.currentPrdCode = localStore.get(this.$route.path) || this.productList[0].code;
}
}
}
this.loading = false;
} catch (e) {
this.$messageBox('获取产品列表失败');
}
},
resizeHandler: function () {
this.height = this._clientHeight - 50;
},
async getJointTrainingList() {
try {
if (this.mapId) {
const res = await checkRoomExist({ mapId: this.mapId });
this.jointGroup = res.data;
this.jointShow = false;
if (res.data) {
this.jointShow = true;
}
}
} catch (error) {
console.error(error, '获取是否拥有综合演练房间');
}
},
async handleLeave(tab) {
this.currentPrdCode = tab.name;
localStore.set(this.$route.path, this.currentPrdCode);
},
async initLoadPage(data) {
this.loading = true;
if (data && parseInt(data.id) && data.code) {
try {
const resp = await getMapProductDetail(data.code);
this.tryUser = 0;
this.loading = false;
this.courseModel = {
id: resp.data.id,
name: resp.data.name,
mapId: data.id,
skinStyle: resp.data.skinStyle,
remarks: resp.data.remarks,
prdType: resp.data.prdType,
prdCode: resp.data.code,
pmsList: resp.data.pmsList || [],
PermissionType: PermissionType.SIMULATION
};
let rest = await queryPermissionSimulation({ mapId: this.courseModel.mapId, prdCode: this.courseModel.prdCode });
this.courseModel.pmsList = rest.data;
if (!this.courseModel.pmsList.length) {
this.tryUser = 1;
let paras = {
mapId: data.id,
mapProductCode: data.code,
productType: PermissionType.SIMULATION
};
const rest = await queryPermissionSimulation({ mapId: this.courseModel.mapId, prdCode: this.courseModel.prdCode });
this.courseModel.pmsList = rest.data;
if (!this.courseModel.pmsList.length) {
this.tryUser = 1;
const paras = {
mapId: data.id,
mapProductCode: data.code,
productType: PermissionType.SIMULATION
};
try {
let resr = await getGoodsTryUse(paras);
if (resr.data.tryTime <= 0) {
this.tryTime = 0;
} else {
this.tryTime = resr.data.tryTime;
this.goodsId = resr.data.goodsId;
}
} catch (error) {
this.tryTime = 0;
}
}
} catch (error) {
this.loading = false;
this.$messageBox('刷新失败');
}
} else {
this.loading = false;
}
},
async joinRoom() {
await getjointTraining(this.jointGroup);
let query = { skinStyle: this.courseModel.skinStyle, group: this.jointGroup };
this.$router.push({ path: `/trainroom`, query: query });
},
async start() {
if (this.courseModel.prdType == '03') {
try {
let param = {
mapId: Number(this.mapId),
prdCode: this.courseModel.prdCode,
}
let res = await postCreateRoom(param);
if (res && res.code == 200) {
let query = { skinStyle: this.courseModel.skinStyle, group: res.data };
this.$router.push({ path: `/trainroom`, query: query });
}
} catch (error) {
if (error.code == 20001) {
this.$confirm(`每个用户只能创建一个综合演练房间, 是否进入房间`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => { }).catch(() => { })
}
if (error.code == 500009) {
this.$messageBox(error.message);
}
};
} else {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
if (this.courseModel.pmsList.length) {
this.jump();
} else {
if (this.tryTime <= 1) {
this.loading.close();
this.$confirm('您没有权限,请前往购买产品', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.buy();
}).catch(() => { })
} else {
this.jump();
}
}
}
},
jump() {
let data = { mapId: this.courseModel.mapId, code: this.currentPrdCode }
simulationNotify(data).then(resp => {
// try 0
let query = { skinStyle: this.courseModel.skinStyle, group: resp.data, prdType: this.courseModel.prdType, mapId: this.courseModel.mapId, code: this.currentPrdCode, goodsId: this.goodsId, try: this.tryUser };
this.$router.push({ path: `${UrlConfig.display}/demon`, query: query });
launchFullscreen();
}).catch(error => {
this.$messageBox(`创建仿真失败: ${error.message}`);
})
},
buy() {
this.$router.push({
path: `${UrlConfig.demonstration.pay}/${this.courseModel.id}`,
query: { permissionType: PermissionType.SIMULATION, prdCode: this.courseModel.prdCode, mapId: this.courseModel.mapId }
});
},
transfer() {
if (this.$refs) {
this.$refs[`limit_${this.currentPrdCode}`][0].transfer(this.courseModel);
}
},
distribute() {
if (this.$refs) {
this.$refs[`limit_${this.currentPrdCode}`][0].distribute(this.courseModel);
}
}
}
}
try {
const resr = await getGoodsTryUse(paras);
if (resr.data.tryTime <= 0) {
this.tryTime = 0;
} else {
this.tryTime = resr.data.tryTime;
this.goodsId = resr.data.goodsId;
}
} catch (error) {
this.tryTime = 0;
}
}
} catch (error) {
this.loading = false;
this.$messageBox('刷新失败');
}
} else {
this.loading = false;
}
},
async joinRoom() {
await getjointTraining(this.jointGroup);
const query = { skinStyle: this.courseModel.skinStyle, group: this.jointGroup };
this.$router.push({ path: `/trainroom`, query: query });
},
async start() {
if (this.courseModel.prdType == '03') {
try {
const param = {
mapId: Number(this.mapId),
prdCode: this.courseModel.prdCode
};
const res = await postCreateRoom(param);
if (res && res.code == 200) {
const query = { skinStyle: this.courseModel.skinStyle, group: res.data };
this.$router.push({ path: `/trainroom`, query: query });
}
} catch (error) {
if (error.code == 20001) {
this.$confirm(`每个用户只能创建一个综合演练房间, 是否进入房间`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => { }).catch(() => { });
}
if (error.code == 500009) {
this.$messageBox(error.message);
}
}
} else {
this.loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
if (this.courseModel.pmsList.length) {
this.jump();
} else {
if (this.tryTime <= 1) {
this.loading.close();
this.$confirm('您没有权限,请前往购买产品', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.buy();
}).catch(() => { });
} else {
this.jump();
}
}
}
},
jump() {
const data = { mapId: this.courseModel.mapId, code: this.currentPrdCode };
simulationNotify(data).then(resp => {
// try 0
const query = { skinStyle: this.courseModel.skinStyle, group: resp.data, prdType: this.courseModel.prdType, mapId: this.courseModel.mapId, code: this.currentPrdCode, goodsId: this.goodsId, try: this.tryUser };
this.$router.push({ path: `${UrlConfig.display}/demon`, query: query });
launchFullscreen();
}).catch(error => {
this.$messageBox(`创建仿真失败: ${error.message}`);
});
},
buy() {
this.$router.push({
path: `${UrlConfig.demonstration.pay}/${this.courseModel.id}`,
query: { permissionType: PermissionType.SIMULATION, prdCode: this.courseModel.prdCode, mapId: this.courseModel.mapId }
});
},
transfer() {
if (this.$refs) {
this.$refs[`limit_${this.currentPrdCode}`][0].transfer(this.courseModel);
}
},
distribute() {
if (this.$refs) {
this.$refs[`limit_${this.currentPrdCode}`][0].distribute(this.courseModel);
}
}
}
};
</script>
<style scoped>
::-webkit-scrollbar {

View File

@ -52,7 +52,7 @@ export default {
},
methods: {
resizeHandler() {
this.height = this._clientHeight;
this.height = this._clientHeight - 50;
}
}
};

View File

@ -50,7 +50,7 @@ export default {
},
methods: {
resizeHandler() {
this.height = this._clientHeight;
this.height = this._clientHeight - 50;
},
refresh() {
this.$refs && this.$refs.demonList && this.$refs.demonList.refresh();

View File

@ -18,11 +18,11 @@
@node-click="clickEvent"
@node-contextmenu="showContextMenu"
>
<span slot-scope="{ node, data }">
<span slot-scope="{ node:tnode, data }">
<span
class="el-icon-tickets"
:style="{color: data.valid ? 'green':''}"
>&nbsp;{{ node.label }}</span>
>&nbsp;{{ tnode.label }}</span>
</span>
</el-tree>
</el-scrollbar>

View File

@ -11,23 +11,23 @@
</p>
<el-tabs v-model="activeName">
<el-tab-pane label="试题列表" name="first">
<div :style="{ height: height - 230 +'px' }" v-if="courseModel.detail.length != 0">
<el-scrollbar wrapClass="scrollbar-wrapper">
<div v-if="courseModel.detail.length != 0" :style="{ height: height - 230 +'px' }">
<el-scrollbar wrap-class="scrollbar-wrapper">
<template v-for="item in courseModel.detail">
<ul type="circle" :key="item.code">
<ul :key="item.code" type="circle">
<li>{{ item.name }}</li>
</ul>
</template>
</el-scrollbar>
</div>
<div class="noList" v-else>
<div v-else class="noList">
暂无数据
</div>
</el-tab-pane>
<el-tab-pane label="权限详情" name="second">
<div :style="{ height: height - 230 +'px' }">
<el-scrollbar wrapClass="scrollbar-wrapper">
<limit-list ref="limitList" :courseModel="courseModel" @initLoadPage="loadInitPage"></limit-list>
<el-scrollbar wrap-class="scrollbar-wrapper">
<limit-list ref="limitList" :course-model="courseModel" @initLoadPage="loadInitPage" />
</el-scrollbar>
</div>
</el-tab-pane>
@ -35,114 +35,113 @@
</div>
<div class="btn-buy">
<el-button type="success" @click="buy">购买</el-button>
<el-button type="primary" @click="distribute" v-if="hasPermssion">权限分发(考试)</el-button>
<el-button type="primary" @click="transfer" v-if="hasPermssion">权限转赠</el-button>
<el-button type="primary" @click="checkCourse" v-if="isAddRule">查看课程试卷</el-button>
<el-button v-if="hasPermssion" type="primary" @click="distribute">权限分发(考试)</el-button>
<el-button v-if="hasPermssion" type="primary" @click="transfer">权限转赠</el-button>
<el-button v-if="isAddRule" type="primary" @click="checkCourse">查看课程试卷</el-button>
</div>
</el-card>
</template>
<script>
import { getCourseLessonDetail } from "@/api/management/exam";
import { PermissionType } from "@/scripts/ConstDic";
import { UrlConfig } from '@/router/index';
import WindowResizeHandler from "@/mixin/WindowResizeHandler";
import LimitList from "@/views/components/limits/index";
import { getCourseLessonDetail } from '@/api/management/exam';
import { PermissionType } from '@/scripts/ConstDic';
import { UrlConfig } from '@/router/index';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import LimitList from '@/views/components/limits/index';
export default {
name: "ExamDetailView",
mixins: [WindowResizeHandler],
components: {
LimitList
},
data() {
return {
height: "",
courseModel: {
id: "",
name: "请选择课程",
price: 0,
remarks: "",
detail: [],
pmsList: []
},
EffectiveTypeList: [],
activeName: 'first'
};
},
computed: {
hasPermssion() {
return this.courseModel.pmsList.length > 0;
},
isAddRule() {
let sumRemains = 0;
if (this.courseModel.pmsList) {
this.courseModel.pmsList.forEach(elem => {
sumRemains += elem.remains;
});
}
return sumRemains >= 10 ? true : false;
}
},
watch: {
"$route.params.lessonId": function (val) {
this.loadInitPage(val);
}
},
mounted() {
this.$Dictionary.effectiveType().then(list => {
this.EffectiveTypeList = list;
});
this.loadInitPage(this.$route.params.lessonId);
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight - 40;
},
loadInitPage(lessonId = this.$route.params.lessonId) {
if (lessonId) {
getCourseLessonDetail({ lessonId: lessonId }).then(res => {
this.courseModel = {
id: res.data.id,
name: res.data.name,
skinStyle: res.data.skinStyle,
price: res.data.price,
remarks: res.data.remarks,
detail: res.data.examDefinitionVOList || [],
pmsList: res.data.permissionVOList,
prdCode: res.data.prdCode,
mapId: res.data.mapId,
PermissionType: PermissionType.EXAM
};
});
}
},
buy() {
this.$router.push({
path: `${UrlConfig.exam.pay}/${this.$route.params.lessonId}`,
query: { permissionType: PermissionType.EXAM, prdCode: this.courseModel.prdCode, mapId: this.courseModel.mapId }
});
},
checkCourse() {
this.$router.push({
path: `${UrlConfig.exam.examRuleManage}`,
query: { lessonId: this.courseModel.id }
});
},
transfer() {
if (this.$refs) {
this.activeName = 'second';
this.$refs.limitList.transfer(this.courseModel);
}
},
distribute() {
if (this.$refs) {
this.activeName = 'second';
this.$refs.limitList.distribute(this.courseModel);
}
}
}
};
export default {
name: 'ExamDetailView',
components: {
LimitList
},
mixins: [WindowResizeHandler],
data() {
return {
height: '',
courseModel: {
id: '',
name: '请选择课程',
price: 0,
remarks: '',
detail: [],
pmsList: []
},
EffectiveTypeList: [],
activeName: 'first'
};
},
computed: {
hasPermssion() {
return this.courseModel.pmsList.length > 0;
},
isAddRule() {
let sumRemains = 0;
if (this.courseModel.pmsList) {
this.courseModel.pmsList.forEach(elem => {
sumRemains += elem.remains;
});
}
return sumRemains >= 10;
}
},
watch: {
'$route.params.lessonId': function (val) {
this.loadInitPage(val);
}
},
mounted() {
this.$Dictionary.effectiveType().then(list => {
this.EffectiveTypeList = list;
});
this.loadInitPage(this.$route.params.lessonId);
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight - 90;
},
loadInitPage(lessonId = this.$route.params.lessonId) {
if (lessonId) {
getCourseLessonDetail({ lessonId: lessonId }).then(res => {
this.courseModel = {
id: res.data.id,
name: res.data.name,
skinStyle: res.data.skinStyle,
price: res.data.price,
remarks: res.data.remarks,
detail: res.data.examDefinitionVOList || [],
pmsList: res.data.permissionVOList,
prdCode: res.data.prdCode,
mapId: res.data.mapId,
PermissionType: PermissionType.EXAM
};
});
}
},
buy() {
this.$router.push({
path: `${UrlConfig.exam.pay}/${this.$route.params.lessonId}`,
query: { permissionType: PermissionType.EXAM, prdCode: this.courseModel.prdCode, mapId: this.courseModel.mapId }
});
},
checkCourse() {
this.$router.push({
path: `${UrlConfig.exam.examRuleManage}`,
query: { lessonId: this.courseModel.id }
});
},
transfer() {
if (this.$refs) {
this.activeName = 'second';
this.$refs.limitList.transfer(this.courseModel);
}
},
distribute() {
if (this.$refs) {
this.activeName = 'second';
this.$refs.limitList.distribute(this.courseModel);
}
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
@ -168,4 +167,4 @@
justify-content: center;
transform: translateY(-20px);
}
</style>
</style>

View File

@ -1,230 +1,224 @@
<template>
<el-card>
<div slot="header" style="text-align: center;">
<b>试卷名称 {{ examDetails.name }}</b>
</div>
<div style="margin:50px; overflow-y: auto;">
<el-scrollbar wrapClass="scrollbar-wrapper" :style="{ height: height - 190 +'px' }">
<p class="list-item">
<span class="list-label">考试时间</span>
<span class="list-elem" v-if="examDetails.startTime">
{{ examDetails.startTime }} - {{examDetails.endTime }}</span>
<span class="list-elem" v-else>随时都可以考试</span>
</p>
<p class="list-item">
<span class="list-label">考试说明</span>
<span class="list-elem">{{ examDetails.remarks }}</span>
</p>
<p class="list-item">
<span class="list-label">考试时长</span>
<span class="list-elem">{{ parseInt(examDetails.duration) / 60 }}分钟</span>
</p>
<p class="list-item">
<span class="list-label">考试满分</span>
<span class="list-elem">{{ examDetails.fullPoint }}</span>
</p>
<p class="list-item">
<span class="list-label">考试及格分</span>
<span class="list-elem">{{ examDetails.passingPoint }}</span>
</p>
<p class="list-item">
<span class="list-label">考试规则</span>
<span class="list-elem">
<p class="list-table">
<el-table :data="examDetails.examDefinitionRulesVOList" border show-summary>
<el-table-column prop="name" label="实训类型" width="180">
</el-table-column>
<el-table-column prop="num" label="题数">
</el-table-column>
<el-table-column prop="point" label="分值">
</el-table-column>
<el-table-column prop="chapterIdLong" label="总分">
</el-table-column>
</el-table>
</p>
</span>
</p>
</el-scrollbar>
</div>
<div class="btn-start">
<el-button type="primary" @click="exmaStart">开始考试</el-button>
</div>
</el-card>
<el-card>
<div slot="header" style="text-align: center;">
<b>试卷名称 {{ examDetails.name }}</b>
</div>
<div style="margin:50px; overflow-y: auto;">
<el-scrollbar wrap-class="scrollbar-wrapper" :style="{ height: height - 190 +'px' }">
<p class="list-item">
<span class="list-label">考试时间</span>
<span v-if="examDetails.startTime" class="list-elem">
{{ examDetails.startTime }} - {{ examDetails.endTime }}</span>
<span v-else class="list-elem">随时都可以考试</span>
</p>
<p class="list-item">
<span class="list-label">考试说明</span>
<span class="list-elem">{{ examDetails.remarks }}</span>
</p>
<p class="list-item">
<span class="list-label">考试时长</span>
<span class="list-elem">{{ parseInt(examDetails.duration) / 60 }}分钟</span>
</p>
<p class="list-item">
<span class="list-label">考试满分</span>
<span class="list-elem">{{ examDetails.fullPoint }}</span>
</p>
<p class="list-item">
<span class="list-label">考试及格分</span>
<span class="list-elem">{{ examDetails.passingPoint }}</span>
</p>
<p class="list-item">
<span class="list-label">考试规则</span>
<span class="list-elem">
<p class="list-table">
<el-table :data="examDetails.examDefinitionRulesVOList" border show-summary>
<el-table-column prop="name" label="实训类型" width="180" />
<el-table-column prop="num" label="题数" />
<el-table-column prop="point" label="分值" />
<el-table-column prop="chapterIdLong" label="总分" />
</el-table>
</p>
</span>
</p>
</el-scrollbar>
</div>
<div class="btn-start">
<el-button type="primary" @click="exmaStart">开始考试</el-button>
</div>
</el-card>
</template>
<script>
import { examNotify } from '@/api/simulation';
import { getExamLessonDetail } from '@/api/management/exam';
import { generateExamList } from '@/api/management/userexam';
import { getPublishLessonDetail } from "@/api/jmap/lesson";
import { PermissionType } from '@/scripts/ConstDic';
import { getDetailList } from '@/api/management/dictionary';
import { mapGetters } from 'vuex';
import { launchFullscreen } from '@/utils/screen';
import { UrlConfig } from '@/router/index';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import { examNotify } from '@/api/simulation';
import { getExamLessonDetail } from '@/api/management/exam';
import { generateExamList } from '@/api/management/userexam';
import { getPublishLessonDetail } from '@/api/jmap/lesson';
import { PermissionType } from '@/scripts/ConstDic';
import { getDetailList } from '@/api/management/dictionary';
import { mapGetters } from 'vuex';
import { launchFullscreen } from '@/utils/screen';
import { UrlConfig } from '@/router/index';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
export default {
name: 'ExamDetailView',
mixins: [
WindowResizeHandler
],
data() {
return {
height: '',
examDetails: {
lessonId: '',
name: '',
remarks: '',
examDefinitionRulesVOList: [],
startTime: '',
endTime: '',
fullPoint: '',
passingPoint: '',
duration: '',
type: '',
},
typeList: [],
examList: [],
trainingOperateTypeMap: {},
}
},
watch: {
'$route.params.examId': function (val) {
this.loadInitPage(val);
}
},
computed: {
...mapGetters('trainingList', [
'trainingList'
]),
},
async mounted() {
this.trainingOperateTypeMap = {};
this.$Dictionary.stationControl().then(list => {
this.trainingOperateTypeMap['01'] = list; //
});
this.$Dictionary.signalOperation().then(list => {
this.trainingOperateTypeMap['02'] = list; //
});
this.$Dictionary.switchOperation().then(list => {
this.trainingOperateTypeMap['03'] = list; //
});
this.$Dictionary.sectionOperation().then(list => {
this.trainingOperateTypeMap['04'] = list; //
});
this.$Dictionary.stationStandOperation().then(list => {
this.trainingOperateTypeMap['05'] = list; //
});
this.$Dictionary.trainPlanOperation().then(list => {
this.trainingOperateTypeMap['06'] = list; //
});
this.$Dictionary.trainOperation().then(list => {
this.trainingOperateTypeMap['07'] = list; //
});
await this.getList();
this.loadInitPage(this.$route.params.examId);
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight;
},
async getList() {
this.typeList = [];
await getDetailList('training_type').then(res => {
this.typeList = res.data;
}).catch(error => {
reject(error);
});
},
async loadInitPage(examId) {
if (examId) {
let res = await getExamLessonDetail(examId);
this.examDetails = res.data
this.examDetails.examDefinitionRulesVOList.forEach((res, index) => {
res.chapterIdLong = Number(res.num) * Number(res.point)
this.typeList.forEach(v => {
if (res.trainingType == v.code) {
this.examDetails.examDefinitionRulesVOList[index].name = v.name;
if (res.operateType) {
this.trainingOperateTypeMap[res.trainingType].forEach(item => {
if (item.code == res.operateType) {
this.examDetails.examDefinitionRulesVOList[index].name = `${this.examDetails.examDefinitionRulesVOList[index].name}-${item.name}`;
return;
}
})
}
}
});
});
let resp = await generateExamList(this.examDetails.id)
this.examList = resp.data.userExamQuestionsVOs;
this.userExam = resp.data;
}
},
buy() {
getPublishLessonDetail({ id: this.examDetails.lessonId }).then((res) => {
this.$router.push({
path: `${UrlConfig.exam.pay}/${this.examDetails.lessonId}`,
query: { permissionType: PermissionType.EXAM, prdCode: res.data.prdCode, mapId: res.data.mapId }
});
})
export default {
name: 'ExamDetailView',
mixins: [
WindowResizeHandler
],
data() {
return {
height: '',
examDetails: {
lessonId: '',
name: '',
remarks: '',
examDefinitionRulesVOList: [],
startTime: '',
endTime: '',
fullPoint: '',
passingPoint: '',
duration: '',
type: ''
},
typeList: [],
examList: [],
trainingOperateTypeMap: {}
};
},
computed: {
...mapGetters('trainingList', [
'trainingList'
])
},
watch: {
'$route.params.examId': function (val) {
this.loadInitPage(val);
}
},
async mounted() {
this.trainingOperateTypeMap = {};
this.$Dictionary.stationControl().then(list => {
this.trainingOperateTypeMap['01'] = list; //
});
this.$Dictionary.signalOperation().then(list => {
this.trainingOperateTypeMap['02'] = list; //
});
this.$Dictionary.switchOperation().then(list => {
this.trainingOperateTypeMap['03'] = list; //
});
this.$Dictionary.sectionOperation().then(list => {
this.trainingOperateTypeMap['04'] = list; //
});
this.$Dictionary.stationStandOperation().then(list => {
this.trainingOperateTypeMap['05'] = list; //
});
this.$Dictionary.trainPlanOperation().then(list => {
this.trainingOperateTypeMap['06'] = list; //
});
this.$Dictionary.trainOperation().then(list => {
this.trainingOperateTypeMap['07'] = list; //
});
await this.getList();
this.loadInitPage(this.$route.params.examId);
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight - 50;
},
async getList() {
this.typeList = [];
await getDetailList('training_type').then(res => {
this.typeList = res.data;
});
},
async loadInitPage(examId) {
if (examId) {
const res = await getExamLessonDetail(examId);
this.examDetails = res.data;
this.examDetails.examDefinitionRulesVOList.forEach((res, index) => {
res.chapterIdLong = Number(res.num) * Number(res.point);
this.typeList.forEach(v => {
if (res.trainingType == v.code) {
this.examDetails.examDefinitionRulesVOList[index].name = v.name;
if (res.operateType) {
this.trainingOperateTypeMap[res.trainingType].forEach(item => {
if (item.code == res.operateType) {
this.examDetails.examDefinitionRulesVOList[index].name = `${this.examDetails.examDefinitionRulesVOList[index].name}-${item.name}`;
return;
}
});
}
}
});
});
const resp = await generateExamList(this.examDetails.id);
this.examList = resp.data.userExamQuestionsVOs;
this.userExam = resp.data;
}
},
buy() {
getPublishLessonDetail({ id: this.examDetails.lessonId }).then((res) => {
this.$router.push({
path: `${UrlConfig.exam.pay}/${this.examDetails.lessonId}`,
query: { permissionType: PermissionType.EXAM, prdCode: res.data.prdCode, mapId: res.data.mapId }
});
});
},
async examDetail() {
let data = this.examDetails
try {
let response = await generateExamList(data.id)
this.userExam = response.data;
let list = response.data.userExamQuestionsVOs;
await this.$store.dispatch('exam/start')
await this.$store.dispatch('exam/setUsedTime', this.userExam.usedTime);
await this.$store.dispatch('exam/setTotalTime', this.userExam.duration);
await this.$store.dispatch('trainingList/setTrainingList', list);
} catch (error) {
this.loading.close();
//
if (error.code === 500004) {
this.$confirm('无此课程的考试权限,请前往购买!', '提示', {
cancelButtonText: '取消',
confirmButtonText: '确定',
type: 'warning',
center: true
}).then(() => {
this.buy();
}).catch(() => { });
} else if (error.code === 500005) {
this.$messageBox('不在考试范围之内');
} else {
this.$messageBox(`${error.message}`);
}
}
},
exmaStart() {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
this.examDetail();
if (this.examList.length) {
examNotify({ examId: this.$route.params.examId }).then(resp => {
let query = {
group: resp.data,
trainingId: this.examList[0].trainingId,
userExamId: this.userExam.id,
examQuestionId: this.examList[0].id
};
this.$router.push({ path: `${UrlConfig.display}/exam`, query: query });
launchFullscreen();
}).catch(error => {
this.$messageBox(`创建仿真失败: ${error.message}`);
this.loading.close();
})
}
}
}
}
},
async examDetail() {
const data = this.examDetails;
try {
const response = await generateExamList(data.id);
this.userExam = response.data;
const list = response.data.userExamQuestionsVOs;
await this.$store.dispatch('exam/start');
await this.$store.dispatch('exam/setUsedTime', this.userExam.usedTime);
await this.$store.dispatch('exam/setTotalTime', this.userExam.duration);
await this.$store.dispatch('trainingList/setTrainingList', list);
} catch (error) {
this.loading.close();
//
if (error.code === 500004) {
this.$confirm('无此课程的考试权限,请前往购买!', '提示', {
cancelButtonText: '取消',
confirmButtonText: '确定',
type: 'warning',
center: true
}).then(() => {
this.buy();
}).catch(() => { });
} else if (error.code === 500005) {
this.$messageBox('不在考试范围之内');
} else {
this.$messageBox(`${error.message}`);
}
}
},
exmaStart() {
this.loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
this.examDetail();
if (this.examList.length) {
examNotify({ examId: this.$route.params.examId }).then(resp => {
const query = {
group: resp.data,
trainingId: this.examList[0].trainingId,
userExamId: this.userExam.id,
examQuestionId: this.examList[0].id
};
this.$router.push({ path: `${UrlConfig.display}/exam`, query: query });
launchFullscreen();
}).catch(error => {
this.$messageBox(`创建仿真失败: ${error.message}`);
this.loading.close();
});
}
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";

View File

@ -1,126 +1,118 @@
<template>
<el-card>
<div slot="header" style="text-align: center;">
<span class="title">实训名称 {{ courseModel.name }}</span>
</div>
<div style="margin:50px" :style="{ height: height - 150 +'px' }">
<p class="time-item">
<span class="time-label">考试计时</span>
<span class="time-elem">{{formatExamUsedTime}}</span>
</p>
<p class="list-item">
<span class="list-label">完成本题最大用时</span>
<span class="list-elem">{{ courseModel.maxDuration | setTime}} </span>
</p>
<p class="list-item">
<span class="list-label">完成本题最佳用时</span>
<span class="list-elem">{{ courseModel.minDuration | setTime}} </span>
</p>
<p class="list-item">
<span class="list-label"> 实训说明</span>
<span class="list-elem">{{ courseModel.remarks }}</span>
</p>
<p>
<span class="list-label"></span>
<el-button type="primary" @click="start">开始考试</el-button>
<el-button @click="back" type="danger">放弃考试</el-button>
</p>
</div>
</el-card>
<el-card>
<div slot="header" style="text-align: center;">
<span class="title">实训名称 {{ courseModel.name }}</span>
</div>
<div style="margin:50px" :style="{ height: height - 150 +'px' }">
<p class="time-item">
<span class="time-label">考试计时</span>
<span class="time-elem">{{ formatExamUsedTime }}</span>
</p>
<p class="list-item">
<span class="list-label">完成本题最大用时</span>
<span class="list-elem">{{ courseModel.maxDuration | setTime }} </span>
</p>
<p class="list-item">
<span class="list-label">完成本题最佳用时</span>
<span class="list-elem">{{ courseModel.minDuration | setTime }} </span>
</p>
<p class="list-item">
<span class="list-label"> 实训说明</span>
<span class="list-elem">{{ courseModel.remarks }}</span>
</p>
<p>
<span class="list-label" />
<el-button type="primary" @click="start">开始考试</el-button>
<el-button type="danger" @click="back">放弃考试</el-button>
</p>
</div>
</el-card>
</template>
<script>
import { getCourseLessonTree } from '@/api/management/exam';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import { mapGetters } from 'vuex';
import { getPublishLessonDetail } from '@/api/jmap/lessondraft';
import { setExamGive } from '@/api/management/userexam';
import { getTrainingDetail } from '@/api/jmap/training';
import { PermissionType } from '@/scripts/ConstDic';
import { launchFullscreen } from '@/utils/screen';
import { trainingNotify } from '@/api/jmap/training';
import { timeFormat } from '@/utils/date';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import { setExamGive } from '@/api/management/userexam';
import { getTrainingDetail } from '@/api/jmap/training';
import { launchFullscreen } from '@/utils/screen';
import { timeFormat } from '@/utils/date';
export default {
name: 'ExamDetailList',
mixins: [
WindowResizeHandler
],
data() {
return {
height: '',
courseModel: {
id: '',
name: '',
skinStyle: '',
maxDuration: '',
minDuration: '',
remarks: '',
updateTime: ''
}
}
},
mixins: [
WindowResizeHandler
],
filters: {
setTime(val) {
return val;
}
},
computed: {
formatExamUsedTime() {
return timeFormat(this.$store.state.exam.usedTime);
}
},
watch: {
$route(newVal) {
this.initLoadPage();
}
},
mounted() {
this.initLoadPage();
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight;
},
initLoadPage() {
let data = { id: this.$route.query.trainingId };
if (parseInt(data.id)) {
getTrainingDetail(data).then(res => {
this.courseModel = {
id: res.data.id,
name: res.data.name,
skinStyle: res.data.skinStyle,
maxDuration: res.data.maxDuration,
remarks: res.data.remarks,
minDuration: res.data.minDuration,
updateTime: res.data.updateTime,
};
}).catch(error => {
this.$message.error('获取试题息失败:' + error.message)
});
}
},
start() {
let query = { skinStyle: this.$route.query.skinStyle, trainingId: this.$route.query.trainingId, userExamId: this.$route.query.userExamId, examQuestionId: this.$route.params.examQuestionId }
this.$router.push({ path: '/display/exam', query: query });
launchFullscreen();
},
back() {
this.$confirm('此操作将放弃本次考试, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//
setExamGive(this.$route.query.userExamId).then(() => {
this.$router.push({ path: '/exam/home' });
})
}).catch(() => { });
}
}
}
export default {
name: 'ExamDetailList',
filters: {
setTime(val) {
return val;
}
},
mixins: [
WindowResizeHandler
],
data() {
return {
height: '',
courseModel: {
id: '',
name: '',
skinStyle: '',
maxDuration: '',
minDuration: '',
remarks: '',
updateTime: ''
}
};
},
computed: {
formatExamUsedTime() {
return timeFormat(this.$store.state.exam.usedTime);
}
},
watch: {
$route(newVal) {
this.initLoadPage();
}
},
mounted() {
this.initLoadPage();
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight - 50;
},
initLoadPage() {
const data = { id: this.$route.query.trainingId };
if (parseInt(data.id)) {
getTrainingDetail(data).then(res => {
this.courseModel = {
id: res.data.id,
name: res.data.name,
skinStyle: res.data.skinStyle,
maxDuration: res.data.maxDuration,
remarks: res.data.remarks,
minDuration: res.data.minDuration,
updateTime: res.data.updateTime
};
}).catch(error => {
this.$message.error('获取试题息失败:' + error.message);
});
}
},
start() {
const query = { skinStyle: this.$route.query.skinStyle, trainingId: this.$route.query.trainingId, userExamId: this.$route.query.userExamId, examQuestionId: this.$route.params.examQuestionId };
this.$router.push({ path: '/display/exam', query: query });
launchFullscreen();
},
back() {
this.$confirm('此操作将放弃本次考试, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//
setExamGive(this.$route.query.userExamId).then(() => {
this.$router.push({ path: '/exam/home' });
});
}).catch(() => { });
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
@ -160,4 +152,4 @@
.list-elem {
color: #808080 !important;
}
</style>
</style>

View File

@ -1,62 +1,61 @@
<template>
<el-card :style="{height: height+'px'}">
<div class="home-box" :style="{height: height+'px'}">
<el-scrollbar wrapClass="scrollbar-wrapper" style="margin-top:5px;">
<h1 class="title">
城市轨道交通考试系统
<img :src="logo" alt="" class="logo-img">
</h1>
<div class="card-box">
<el-carousel :interval="4000" type="card" height="370px">
<el-carousel-item v-for="(item, index) in listImg" :key="index">
<img :src="item.src" alt="" height="100%" width="100%">
</el-carousel-item>
</el-carousel>
</div>
<div class="brief-box">
该系统具有自定义考试规则自动生成考卷学员成绩统计数据曲线分析及题库管理等功能从实战操作业务流程故障模拟及考试规则等多角度出发力求打造最符合用户需求的城市轨道交通在线交互实操类考试系统
</div>
</el-scrollbar>
<el-card :style="{height: height+'px'}">
<div class="home-box" :style="{height: height+'px'}">
<el-scrollbar wrap-class="scrollbar-wrapper" style="margin-top:5px;">
<h1 class="title">
城市轨道交通考试系统
<img :src="logo" alt="" class="logo-img">
</h1>
<div class="card-box">
<el-carousel :interval="4000" type="card" height="370px">
<el-carousel-item v-for="(item, index) in listImg" :key="index">
<img :src="item.src" alt="" height="100%" width="100%">
</el-carousel-item>
</el-carousel>
</div>
</el-card>
<div class="brief-box">
该系统具有自定义考试规则自动生成考卷学员成绩统计数据曲线分析及题库管理等功能从实战操作业务流程故障模拟及考试规则等多角度出发力求打造最符合用户需求的城市轨道交通在线交互实操类考试系统
</div>
</el-scrollbar>
</div>
</el-card>
</template>
<script>
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import logo from '@/assets/logo.png';
import home1 from '@/assets/home/home1.png';
import home2 from '@/assets/home/home2.png';
import home3 from '@/assets/home/home2.jpg';
import home4 from '@/assets/home/tring1.png';
import home5 from '@/assets/home/tring4.jpg';
import home6 from '@/assets/home/tring3.jpg';
export default {
name: 'Home',
mixins: [WindowResizeHandler],
data() {
return {
listImg: [
{ src: home1 },
{ src: home2 },
{ src: home3 },
{ src: home4 },
{ src: home5 },
{ src: home6 }
],
logo: logo,
height: 0,
}
},
mounted() {
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import logo from '@/assets/logo.png';
import home1 from '@/assets/home/home1.png';
import home2 from '@/assets/home/home2.png';
import home3 from '@/assets/home/home2.jpg';
import home4 from '@/assets/home/tring1.png';
import home5 from '@/assets/home/tring4.jpg';
import home6 from '@/assets/home/tring3.jpg';
export default {
name: 'Home',
mixins: [WindowResizeHandler],
data() {
return {
listImg: [
{ src: home1 },
{ src: home2 },
{ src: home3 },
{ src: home4 },
{ src: home5 },
{ src: home6 }
],
logo: logo,
height: 0
};
},
mounted() {
},
methods: {
resizeHandler() {
this.height = this._clientHeight;
// this.$store.dispatch('config/resize', { width: this._clientWidth - 310, height: this._clientHeight - 125 });
}
}
}
},
methods: {
resizeHandler() {
this.height = this._clientHeight - 50;
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
@ -103,4 +102,4 @@
font-family: unset;
}
}
</style>
</style>

View File

@ -58,17 +58,7 @@ export default {
},
methods: {
resizeHandler() {
this.height = this._clientHeight;
// let width = 0;
// let height = 0;
// if (this.listShow) {
// width = this._clientWidth - 310;
// height = this._clientHeight - 120;
// } else {
// width = this._clientWidth - 10;
// height = this._clientHeight - 120;
// }
// this.$store.dispatch('config/resize', { width: width, height: height });
this.height = this._clientHeight - 50;
},
loadInitData(path) {
if (path.indexOf('questionDetail') >= 0) {

View File

@ -26,23 +26,23 @@
@node-contextmenu="showContextMenu"
@node-click="clickEvent"
>
<span slot-scope="{ node }" class="custom-tree-node">
<span slot-scope="{ node: tnode }" class="custom-tree-node">
<span
v-if="node.data.type === 'lesson'"
:class="node.data.valid? 'el-icon-sold-out':'el-icon-goods'"
v-if="tnode.data.type === 'lesson'"
:class="tnode.data.valid? 'el-icon-sold-out':'el-icon-goods'"
>
<span
v-if="node.data.type === 'lesson'"
:style="{color: node.data.valid ? 'green':''}"
v-if="tnode.data.type === 'lesson'"
:style="{color: tnode.data.valid ? 'green':''}"
class="el-icon-tickets"
>&nbsp;{{ node.label }}</span>
>&nbsp;{{ tnode.label }}</span>
</span>
<span v-if="node.data.type === 'exam'" :class="node.data.valid? 'el-icon-sold-out':'el-icon-goods'">
<span v-if="tnode.data.type === 'exam'" :class="tnode.data.valid? 'el-icon-sold-out':'el-icon-goods'">
<span
v-if="node.data.type === 'exam'"
:style="{color: node.data.valid ? 'green':''}"
v-if="tnode.data.type === 'exam'"
:style="{color: tnode.data.valid ? 'green':''}"
class="el-icon-edit-outline"
>&nbsp;{{ node.label }}</span>
>&nbsp;{{ tnode.label }}</span>
</span>
</span>
</el-tree>

View File

@ -71,7 +71,7 @@ export default {
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight;
this.height = this._clientHeight - 50;
},
getSummaries(param) {
const { columns, data } = param;

View File

@ -1,190 +1,211 @@
<template>
<el-card class="map-list-main" v-loading="loading">
<div slot="header" class="clearfix">
<span>课程列表</span>
<div class="back-home" v-if="role" @click="backHome">返回首页</div>
</div>
<filter-city ref="filerCity" @filterSelectChange="refresh" isCascader filterEmpty
:queryFunction="queryFunction"></filter-city>
<el-input placeholder="输入关键字进行过滤" v-model="filterText" clearable> </el-input>
<el-scrollbar wrapClass="scrollbar-wrapper" :style="{ height: (height-125) +'px', width:'100%' }">
<el-tree ref="tree" :data="treeData" :props="defaultProps" :filter-node-method="filterNode" node-key="id"
:default-expanded-keys="defaultShowKeys" @node-contextmenu="showContextMenu" highlight-current
@node-click="clickEvent" :span=22>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span v-if="node.data.type === 'lesson'"
:class="node.data.valid? 'el-icon-sold-out':'el-icon-goods'">
<span class="el-icon-tickets">
<span :style="{color: node.data.valid ? 'green':''}">&nbsp;{{ node.label }}</span>
</span>
</span>
<span v-else-if="node.data.type === 'chapter'"
:class="node.data.valid? 'el-icon-sold-out':'el-icon-goods'">
<span class="el-icon-document">
<span :style="{color: node.data.valid ? 'green':''}">&nbsp;{{ node.label }}</span>
</span>
</span>
<span v-else-if="node.data.type === 'training'"
:class="node.data.valid? 'el-icon-sold-out':'el-icon-goods'">
<span class="el-icon-mobile-phone">
<span :style="{color: node.data.valid ? 'green':''}">&nbsp;{{ node.label }}</span>
</span>
</span>
</span>
</el-tree>
</el-scrollbar>
</el-card>
<el-card v-loading="loading" class="map-list-main">
<div slot="header" class="clearfix">
<span>课程列表</span>
<div v-if="role" class="back-home" @click="backHome">返回首页</div>
</div>
<filter-city
ref="filerCity"
is-cascader
filter-empty
:query-function="queryFunction"
@filterSelectChange="refresh"
/>
<el-input v-model="filterText" placeholder="输入关键字进行过滤" clearable />
<el-scrollbar wrap-class="scrollbar-wrapper" :style="{ height: (height-125) +'px', width:'100%' }">
<el-tree
ref="tree"
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
node-key="id"
:default-expanded-keys="defaultShowKeys"
highlight-current
:span="22"
@node-contextmenu="showContextMenu"
@node-click="clickEvent"
>
<span slot-scope="{ node: tnode }" class="custom-tree-node">
<span
v-if="tnode.data.type === 'lesson'"
:class="tnode.data.valid? 'el-icon-sold-out':'el-icon-goods'"
>
<span class="el-icon-tickets">
<span :style="{color: tnode.data.valid ? 'green':''}">&nbsp;{{ tnode.label }}</span>
</span>
</span>
<span
v-else-if="tnode.data.type === 'chapter'"
:class="tnode.data.valid? 'el-icon-sold-out':'el-icon-goods'"
>
<span class="el-icon-document">
<span :style="{color: tnode.data.valid ? 'green':''}">&nbsp;{{ tnode.label }}</span>
</span>
</span>
<span
v-else-if="tnode.data.type === 'training'"
:class="tnode.data.valid? 'el-icon-sold-out':'el-icon-goods'"
>
<span class="el-icon-mobile-phone">
<span :style="{color: tnode.data.valid ? 'green':''}">&nbsp;{{ tnode.label }}</span>
</span>
</span>
</span>
</el-tree>
</el-scrollbar>
</el-card>
</template>
<script>
import { getPublishLessonTree, getPublishLessonDetail } from '@/api/jmap/lesson';
import { PermissionType } from '@/scripts/ConstDic';
import { UrlConfig } from '@/router/index';
import FilterCity from '@/views/components/filterCity';
import { getPublishLessonTree, getPublishLessonDetail } from '@/api/jmap/lesson';
import { PermissionType } from '@/scripts/ConstDic';
import { UrlConfig } from '@/router/index';
import FilterCity from '@/views/components/filterCity';
export default {
name: 'TrainingTree',
components: {
FilterCity
},
props: {
height: {
type: Number
}
},
data() {
return {
loading: true,
filterSelect: [],
filterOptions: [],
filterText: '',
queryFunction: getPublishLessonTree,
treeData: [],
selected: {},
defaultProps: {
children: 'children',
label: 'name'
},
defaultShowKeys: [],
lessonId: 0,
point: {
x: 0,
y: 0
},
node: {
}
}
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
}
},
computed: {
role() {
return this.$store.state.user.roles.includes('04') ||
export default {
name: 'TrainingTree',
components: {
FilterCity
},
props: {
height: {
type: Number,
required: true
}
},
data() {
return {
loading: true,
filterSelect: [],
filterOptions: [],
filterText: '',
queryFunction: getPublishLessonTree,
treeData: [],
selected: {},
defaultProps: {
children: 'children',
label: 'name'
},
defaultShowKeys: [],
lessonId: 0,
point: {
x: 0,
y: 0
},
node: {
}
};
},
computed: {
role() {
return this.$store.state.user.roles.includes('04') ||
this.$store.state.user.roles.includes('05') ||
this.$store.state.user.roles.includes('01')
}
},
methods: {
backHome() {
this.$router.push({ path: `/` });
},
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
showContextMenu(e, obj, node, vueElem) {
if (obj) {
switch (obj.type) {
case 'trainType':
case 'training': {
e.preventDefault();
this.point = {
x: e.clientX,
y: e.clientY
}
this.node = node;
this.selected = obj;
} break;
}
}
},
trainingStart(data, node) {
if (node.level == 1) { // 1 id
this.$router.push({ path: `${UrlConfig.teach.practical}/${data.id}/${node.data.id}` })
} else {
this.trainingStart(data, node.parent)
}
},
lessonDetail(data) {
this.$router.push({ path: `${UrlConfig.teach.detail}/${data.id}` })
},
buy(data) {
this.$router.push({
path: `${UrlConfig.teach.pay}/${data.lessonId}`, query:
this.$store.state.user.roles.includes('01');
}
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
}
},
methods: {
backHome() {
this.$router.push({ path: `/` });
},
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
showContextMenu(e, obj, node, vueElem) {
if (obj) {
switch (obj.type) {
case 'trainType':
case 'training':
e.preventDefault();
this.point = {
x: e.clientX,
y: e.clientY
};
this.node = node;
this.selected = obj;
break;
}
}
},
trainingStart(data, node) {
if (node.level == 1) { // 1 id
this.$router.push({ path: `${UrlConfig.teach.practical}/${data.id}/${node.data.id}` });
} else {
this.trainingStart(data, node.parent);
}
},
lessonDetail(data) {
this.$router.push({ path: `${UrlConfig.teach.detail}/${data.id}` });
},
buy(data) {
this.$router.push({
path: `${UrlConfig.teach.pay}/${data.lessonId}`, query:
{ permissionType: PermissionType.LESSON, prdCode: data.prdCode, mapId: data.mapId }
});
},
clickEvent(obj, node, data) {
this.$store.dispatch('menuOperation/setPopMenu', { position: null, menu: null });
if (obj) {
switch (obj.type) {
case 'lesson': {
this.lessonId = obj.id;
this.lessonDetail(obj);
} break;
case 'training': {
if (obj.valid) {
this.trainingStart(obj, node);
} else {
this.$confirm('无此课程权限, 请前往购买!', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
while (node) {
if (node.data.type === 'lesson') {
let lessonId = node.data.id;
if (lessonId) {
getPublishLessonDetail({ id: lessonId }).then(res => {
let query = {
lessonId: lessonId,
prdCode: res.data.prdCode,
mapId: res.data.mapId,
};
this.buy(query);
});
}
break;
}
node = node.parent;
}
}).catch(() => { });
}
} break;
}
}
},
refresh(filterSelect) {
let params = { mapId: filterSelect[1] };
this.loading = true;
getPublishLessonTree(params).then(response => {
this.treeData = response.data;
this.defaultShowKeys = [this.$route.params.trainingId];
this.$nextTick(() => {
this.loading = false;
this.$refs.tree.setCurrentKey(this.$route.params.trainingId); // value node-key
if (this.filterText) {
this.$refs.tree.filter(this.filterText);
}
});
}).catch(error => {
this.loading = false;
this.$messageBox('刷新失败')
});
}
}
}
});
},
clickEvent(obj, node, data) {
this.$store.dispatch('menuOperation/setPopMenu', { position: null, menu: null });
if (obj) {
switch (obj.type) {
case 'lesson':
this.lessonId = obj.id;
this.lessonDetail(obj);
break;
case 'training':
if (obj.valid) {
this.trainingStart(obj, node);
} else {
this.$confirm('无此课程权限, 请前往购买!', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
while (node) {
if (node.data.type === 'lesson') {
const lessonId = node.data.id;
if (lessonId) {
getPublishLessonDetail({ id: lessonId }).then(res => {
const query = {
lessonId: lessonId,
prdCode: res.data.prdCode,
mapId: res.data.mapId
};
this.buy(query);
});
}
break;
}
node = node.parent;
}
}).catch(() => { });
}
break;
}
}
},
refresh(filterSelect) {
const params = { mapId: filterSelect[1] };
this.loading = true;
getPublishLessonTree(params).then(response => {
this.treeData = response.data;
this.defaultShowKeys = [this.$route.params.trainingId];
this.$nextTick(() => {
this.loading = false;
this.$refs.tree.setCurrentKey(this.$route.params.trainingId); // value node-key
if (this.filterText) {
this.$refs.tree.filter(this.filterText);
}
});
}).catch(() => {
this.loading = false;
this.$messageBox('刷新失败');
});
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.back-home {
@ -204,4 +225,4 @@
.el-tree-node.is-current>.el-tree-node__content {
background-color: #e4e3e3 !important;
}
</style>
</style>

View File

@ -12,12 +12,12 @@
<el-tabs v-model="activeName">
<el-tab-pane label="课程详情" name="first">
<div :style="{ height: height - 270 +'px' }">
<el-scrollbar wrapClass="scrollbar-wrapper">
<el-scrollbar wrap-class="scrollbar-wrapper">
<template v-for="item in courseModel.detail">
<ul type="circle" :key="item.code">
<ul :key="item.code" type="circle">
<li>{{ item.name }}
<template v-for="it in item.trainingVos">
<ul style="float:none;" type="circle" :key="it.code">
<ul :key="it.code" style="float:none;" type="circle">
<li :style="{color: it.trial? 'green':'' }">
<span>{{ it.name }}
<span v-if="it.trial">(免费)</span>
@ -33,8 +33,8 @@
</el-tab-pane>
<el-tab-pane label="权限详情" name="second">
<div :style="{ height: height - 270 +'px' }">
<el-scrollbar wrapClass="scrollbar-wrapper">
<limit-list ref="limitList" :courseModel="courseModel" @initLoadPage="initLoadPage"></limit-list>
<el-scrollbar wrap-class="scrollbar-wrapper">
<limit-list ref="limitList" :course-model="courseModel" @initLoadPage="initLoadPage" />
</el-scrollbar>
</div>
</el-tab-pane>
@ -42,105 +42,104 @@
</div>
<div class="btn-buy">
<el-button type="success" @click="buy">购买</el-button>
<el-button type="primary" @click="distribute" v-if="hasPermssion">权限分发(上课)</el-button>
<el-button type="primary" @click="transfer" v-if="hasPermssion">权限转赠</el-button>
<el-button v-if="hasPermssion" type="primary" @click="distribute">权限分发(上课)</el-button>
<el-button v-if="hasPermssion" type="primary" @click="transfer">权限转赠</el-button>
</div>
</el-card>
</template>
<script>
import { mapGetters } from "vuex";
import { getPublishLessonDetail } from "@/api/jmap/lesson";
import { PermissionType } from "@/scripts/ConstDic";
import { UrlConfig } from '@/router/index';
import WindowResizeHandler from "@/mixin/WindowResizeHandler";
import LimitList from "@/views/components/limits/index";
import { getPublishLessonDetail } from '@/api/jmap/lesson';
import { PermissionType } from '@/scripts/ConstDic';
import { UrlConfig } from '@/router/index';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import LimitList from '@/views/components/limits/index';
export default {
name: "LessonDetail",
components: {
LimitList
},
data() {
return {
num: 5,
height: "",
WhetherTypeList: [],
EffectiveTypeList: [],
courseModel: {
id: "",
name: "",
skinStyle: "",
price: 0,
remarks: "",
detail: [],
pmsList: []
},
activeName: 'first'
};
},
mixins: [WindowResizeHandler],
watch: {
$route(newVal) {
this.initLoadPage();
}
},
computed: {
hasPermssion() {
return this.courseModel.pmsList.length > 0;
}
},
mounted() {
this.$Dictionary.effectiveType().then(list => {
this.EffectiveTypeList = list;
});
this.initLoadPage();
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight;
},
initLoadPage() {
let data = { id: this.$route.params.lessonId };
if (parseInt(data.id)) {
getPublishLessonDetail(data).then(response => {
this.courseModel = {
id: response.data.id,
name: response.data.name,
price: response.data.price,
remarks: response.data.remarks,
detail: response.data.chapters,
pmsList: response.data.pmsList,
prdCode: response.data.prdCode,
mapId: response.data.mapId,
skinStyle: response.data.skinStyle,
PermissionType: PermissionType.LESSON
};
}).catch(error => {
this.$message.error("获取课程信息失败:" + error.message);
});
}
},
buy() {
this.$router.push({
path: `${UrlConfig.teach.pay}/${this.$route.params.lessonId}`,
query: { permissionType: PermissionType.LESSON, prdCode: this.courseModel.prdCode, mapId: this.courseModel.mapId }
});
},
transfer() {
if (this.$refs) {
this.activeName = 'second';
this.$refs.limitList.transfer(this.courseModel);
}
},
distribute() {
if (this.$refs) {
this.activeName = 'second';
this.$refs.limitList.distribute(this.courseModel);
}
}
}
};
export default {
name: 'LessonDetail',
components: {
LimitList
},
mixins: [WindowResizeHandler],
data() {
return {
num: 5,
height: '',
WhetherTypeList: [],
EffectiveTypeList: [],
courseModel: {
id: '',
name: '',
skinStyle: '',
price: 0,
remarks: '',
detail: [],
pmsList: []
},
activeName: 'first'
};
},
computed: {
hasPermssion() {
return this.courseModel.pmsList.length > 0;
}
},
watch: {
$route(newVal) {
this.initLoadPage();
}
},
mounted() {
this.$Dictionary.effectiveType().then(list => {
this.EffectiveTypeList = list;
});
this.initLoadPage();
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight - 50;
},
initLoadPage() {
const data = { id: this.$route.params.lessonId };
if (parseInt(data.id)) {
getPublishLessonDetail(data).then(response => {
this.courseModel = {
id: response.data.id,
name: response.data.name,
price: response.data.price,
remarks: response.data.remarks,
detail: response.data.chapters,
pmsList: response.data.pmsList,
prdCode: response.data.prdCode,
mapId: response.data.mapId,
skinStyle: response.data.skinStyle,
PermissionType: PermissionType.LESSON
};
}).catch(error => {
this.$message.error('获取课程信息失败:' + error.message);
});
}
},
buy() {
this.$router.push({
path: `${UrlConfig.teach.pay}/${this.$route.params.lessonId}`,
query: { permissionType: PermissionType.LESSON, prdCode: this.courseModel.prdCode, mapId: this.courseModel.mapId }
});
},
transfer() {
if (this.$refs) {
this.activeName = 'second';
this.$refs.limitList.transfer(this.courseModel);
}
},
distribute() {
if (this.$refs) {
this.activeName = 'second';
this.$refs.limitList.distribute(this.courseModel);
}
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
@ -160,4 +159,4 @@
justify-content: center;
transform: translateY(-20px);
}
</style>
</style>

View File

@ -1,61 +1,60 @@
<template>
<el-card :style="{height: height+'px'}">
<div class="home-box" :style="{height: height+'px'}">
<el-scrollbar wrapClass="scrollbar-wrapper">
<h1 class="title">
城市轨道交通教学系统
<img :src="logo" alt="" class="logo-img">
</h1>
<div class="card-box">
<el-carousel :interval="4000" type="card" height="380px">
<el-carousel-item v-for="(item, index) in listImg" :key="index">
<img :src="item.src" alt="" height="100%" width="100%">
</el-carousel-item>
</el-carousel>
</div>
<div class="brief-box">
该系统具备真实的业务逻辑以地铁员工和培训点为要素的业务和流程驱动方式进行软件架构从业务流程标准作业培训方式及开放原则等角度出发力求打造最符合用户需求及快速响应变化的实训教学系统</div>
</el-scrollbar>
<el-card :style="{height: height+'px'}">
<div class="home-box" :style="{height: height+'px'}">
<el-scrollbar wrap-class="scrollbar-wrapper">
<h1 class="title">
城市轨道交通教学系统
<img :src="logo" alt="" class="logo-img">
</h1>
<div class="card-box">
<el-carousel :interval="4000" type="card" height="380px">
<el-carousel-item v-for="(item, index) in listImg" :key="index">
<img :src="item.src" alt="" height="100%" width="100%">
</el-carousel-item>
</el-carousel>
</div>
</el-card>
<div class="brief-box">
该系统具备真实的业务逻辑以地铁员工和培训点为要素的业务和流程驱动方式进行软件架构从业务流程标准作业培训方式及开放原则等角度出发力求打造最符合用户需求及快速响应变化的实训教学系统</div>
</el-scrollbar>
</div>
</el-card>
</template>
<script>
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import logo from '@/assets/logo.png';
import home1 from '@/assets/home/home3.png';
import home2 from '@/assets/home/home4.png';
import home3 from '@/assets/home/home3.jpg';
import home4 from '@/assets/home/tring2.png';
import home5 from '@/assets/home/tring5.jpg';
import home6 from '@/assets/home/tring6.jpg';
export default {
name: 'Home',
mixins: [WindowResizeHandler],
data() {
return {
listImg: [
{ src: home1 },
{ src: home2 },
{ src: home3 },
{ src: home4 },
{ src: home5 },
{ src: home6 }
],
logo: logo,
height: 0
}
},
mounted() {
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
import logo from '@/assets/logo.png';
import home1 from '@/assets/home/home3.png';
import home2 from '@/assets/home/home4.png';
import home3 from '@/assets/home/home3.jpg';
import home4 from '@/assets/home/tring2.png';
import home5 from '@/assets/home/tring5.jpg';
import home6 from '@/assets/home/tring6.jpg';
export default {
name: 'Home',
mixins: [WindowResizeHandler],
data() {
return {
listImg: [
{ src: home1 },
{ src: home2 },
{ src: home3 },
{ src: home4 },
{ src: home5 },
{ src: home6 }
],
logo: logo,
height: 0
};
},
mounted() {
},
methods: {
resizeHandler() {
this.height = this._clientHeight;
// this.$store.dispatch('config/resize', { width: this._clientWidth - 310, height: this._clientHeight - 125 });
}
}
}
},
methods: {
resizeHandler() {
this.height = this._clientHeight - 50;
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
@ -102,4 +101,4 @@
font-family: unset;
}
}
</style>
</style>

View File

@ -1,70 +1,70 @@
<template>
<div class="app-wrapper">
<el-scrollbar wrapClass="scrollbar-wrapper">
<div class="list" v-show="treeShow" :style="{width: widthLeft+'px'}">
<lesson-tree ref="tree" :height="height"></lesson-tree>
<el-scrollbar wrap-class="scrollbar-wrapper">
<div v-show="treeShow" class="list" :style="{width: widthLeft+'px'}">
<lesson-tree ref="tree" :height="height" />
</div>
<drap-left :widthLeft="widthLeft" @drapWidth="drapWidth"></drap-left>
<drap-left :width-left="widthLeft" @drapWidth="drapWidth" />
<transition>
<router-view></router-view>
<router-view />
</transition>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from "vuex";
import LessonTree from "./category/tree";
import localStore from "storejs";
import drapLeft from "@/views/components/drapLeft/index";
import WindowResizeHandler from "@/mixin/WindowResizeHandler";
import { mapGetters } from 'vuex';
import LessonTree from './category/tree';
import localStore from 'storejs';
import drapLeft from '@/views/components/drapLeft/index';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
export default {
name: "Lesson",
components: {
LessonTree,
drapLeft
},
mixins: [WindowResizeHandler],
data() {
return {
height: 0,
treeShow: true,
widthLeft: 450
};
},
computed: {
...mapGetters(["lessonbar"])
},
watch: {
"lessonbar.opened": function (val) {
this.treeShow = val;
this.resizeHandler();
},
$route(to, from) {
if (/\/lesson\/detail/.test(to.path) && /\/lesson\/pay/.test(from.path)) {
this.$emit("refresh", [
localStore.get("cityCode") || "",
localStore.get("mapId") || ""
]);
}
}
},
mounted() {
this.widthLeft = Number(localStore.get("LeftWidth"));
},
methods: {
resizeHandler() {
this.height = this._clientHeight;
},
drapWidth(width) {
this.widthLeft = Number(width);
},
refresh(filterSelect) {
this.$refs && this.$refs.tree && this.$refs.tree.refresh(filterSelect);
}
}
};
export default {
name: 'Lesson',
components: {
LessonTree,
drapLeft
},
mixins: [WindowResizeHandler],
data() {
return {
height: 0,
treeShow: true,
widthLeft: 450
};
},
computed: {
...mapGetters(['lessonbar'])
},
watch: {
'lessonbar.opened': function (val) {
this.treeShow = val;
this.resizeHandler();
},
$route(to, from) {
if (/\/lesson\/detail/.test(to.path) && /\/lesson\/pay/.test(from.path)) {
this.$emit('refresh', [
localStore.get('cityCode') || '',
localStore.get('mapId') || ''
]);
}
}
},
mounted() {
this.widthLeft = Number(localStore.get('LeftWidth'));
},
methods: {
resizeHandler() {
this.height = this._clientHeight - 50;
},
drapWidth(width) {
this.widthLeft = Number(width);
},
refresh(filterSelect) {
this.$refs && this.$refs.tree && this.$refs.tree.refresh(filterSelect);
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
@ -80,4 +80,4 @@
.list {
float: left;
}
</style>
</style>

View File

@ -1,112 +1,110 @@
<template>
<el-card>
<div slot="header" style="text-align: center;">
<b>实训名称 {{ courseModel.name }}</b>
</div>
<div style="margin:50px">
<el-scrollbar wrapClass="scrollbar-wrapper" :style="{ height: height - 190 +'px' }">
<p class="list-item">
<span class="list-label">完成实训最佳用时</span>
<span class="list-elem"> {{ courseModel.minDuration | setTime}} </span>
</p>
<p class="list-item">
<span class="list-label">完成实训最大用时</span>
<span class="list-elem">{{ courseModel.maxDuration | setTime}} </span>
</p>
<p class="list-item">
<span class="list-label">实训说明</span>
<span class="list-elem">{{ courseModel.remarks }}</span>
</p>
</el-scrollbar>
</div>
<div class="btn-start">
<el-button type="primary" @click="start">开始实训</el-button>
</div>
</el-card>
<el-card>
<div slot="header" style="text-align: center;">
<b>实训名称 {{ courseModel.name }}</b>
</div>
<div style="margin:50px">
<el-scrollbar wrap-class="scrollbar-wrapper" :style="{ height: height - 190 +'px' }">
<p class="list-item">
<span class="list-label">完成实训最佳用时</span>
<span class="list-elem"> {{ courseModel.minDuration | setTime }} </span>
</p>
<p class="list-item">
<span class="list-label">完成实训最大用时</span>
<span class="list-elem">{{ courseModel.maxDuration | setTime }} </span>
</p>
<p class="list-item">
<span class="list-label">实训说明</span>
<span class="list-elem">{{ courseModel.remarks }}</span>
</p>
</el-scrollbar>
</div>
<div class="btn-start">
<el-button type="primary" @click="start">开始实训</el-button>
</div>
</el-card>
</template>
<script>
import { mapGetters } from "vuex";
import { getTrainingDetail, } from "@/api/jmap/training";
import { trainingNotify } from '@/api/simulation';
import { PermissionType } from "@/scripts/ConstDic";
import { UrlConfig } from '@/router/index';
import { launchFullscreen } from '@/utils/screen';
import WindowResizeHandler from "@/mixin/WindowResizeHandler";
import { getTrainingDetail } from '@/api/jmap/training';
import { trainingNotify } from '@/api/simulation';
import { UrlConfig } from '@/router/index';
import { launchFullscreen } from '@/utils/screen';
import WindowResizeHandler from '@/mixin/WindowResizeHandler';
export default {
name: "LessonPracticalDetail",
components: {},
data() {
return {
height: "",
courseModel: {
id: "",
name: "",
maxDuration: "",
minDuration: "",
remarks: "",
updateTime: ""
}
};
},
mixins: [WindowResizeHandler],
filters: {
setTime(val) {
return val;
}
},
watch: {
$route(newVal) {
this.initLoadPage();
}
},
mounted() {
this.initLoadPage();
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight;
},
initLoadPage() {
let data = { id: this.$route.params.trainingId };
if (parseInt(data.id)) {
getTrainingDetail(data)
.then(res => {
this.courseModel = {
id: res.data.id,
name: res.data.name,
maxDuration: res.data.maxDuration,
remarks: res.data.remarks,
minDuration: res.data.minDuration,
updateTime: res.data.updateTime
};
})
.catch(error => {
this.$message.error("获取课程信息失败:" + error.message);
});
}
},
start() {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
trainingNotify({ trainingId: this.$route.params.trainingId }).then(resp => {
let query = {
group: resp.data, trainingId: this.$route.params.trainingId, lessonId: this.$route.params.lessonId
};
this.$router.push({ path: `${UrlConfig.display}/teach`, query: query });
launchFullscreen();
}).catch(error => {
this.$messageBox(`创建仿真失败: ${error.message}`);
loading.close();
});
}
}
}
export default {
name: 'LessonPracticalDetail',
components: {},
filters: {
setTime(val) {
return val;
}
},
mixins: [WindowResizeHandler],
data() {
return {
height: '',
courseModel: {
id: '',
name: '',
maxDuration: '',
minDuration: '',
remarks: '',
updateTime: ''
}
};
},
watch: {
$route(newVal) {
this.initLoadPage();
}
},
mounted() {
this.initLoadPage();
},
methods: {
resizeHandler: function () {
this.height = this._clientHeight - 50;
},
initLoadPage() {
const data = { id: this.$route.params.trainingId };
if (parseInt(data.id)) {
getTrainingDetail(data)
.then(res => {
this.courseModel = {
id: res.data.id,
name: res.data.name,
maxDuration: res.data.maxDuration,
remarks: res.data.remarks,
minDuration: res.data.minDuration,
updateTime: res.data.updateTime
};
})
.catch(error => {
this.$message.error('获取课程信息失败:' + error.message);
});
}
},
start() {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
trainingNotify({ trainingId: this.$route.params.trainingId }).then(resp => {
const query = {
group: resp.data, trainingId: this.$route.params.trainingId, lessonId: this.$route.params.lessonId
};
this.$router.push({ path: `${UrlConfig.display}/teach`, query: query });
launchFullscreen();
}).catch(error => {
this.$messageBox(`创建仿真失败: ${error.message}`);
loading.close();
});
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";