Merge branch 'test_dispaly' of https://git.code.tencent.com/lian-cbtc/jl-client into test_dispaly

This commit is contained in:
fan 2022-10-17 15:40:52 +08:00
commit ad5c4b78d4
14 changed files with 1369 additions and 1230 deletions

View File

@ -1,20 +1,20 @@
import request from '@/utils/request'; import request from '@/utils/request'
/** 创建对应课程考题 */ /** 创建对应课程考题 */
export function createExam(data) { export function createExam(data) {
return request({ return request({
url: `/api/exam`, url: `/api/exam`,
method: 'post', method: 'post',
data: data data: data,
}); })
} }
/** 获取试卷详情 */ /** 获取试卷详情 */
export function getExamLessonDetail(examId) { export function getExamLessonDetail(examId) {
return request({ return request({
url: `/api/exam/${examId}`, url: `/api/exam/${examId}`,
method: 'get' method: 'get',
}); })
} }
/** 获取试卷列表 */ /** 获取试卷列表 */
@ -22,32 +22,32 @@ export function getExamList(data) {
return request({ return request({
url: '/api/exam/list', url: '/api/exam/list',
method: 'get', method: 'get',
params: data params: data,
}); })
} }
/** 删除试卷 */ /** 删除试卷 */
export function deleteExam(data) { export function deleteExam(data) {
return request({ return request({
url: `/api/exam/${data.id}`, url: `/api/exam/${data.id}`,
method: 'delete' method: 'delete',
}); })
} }
/** 设置试卷下架 */ /** 设置试卷下架 */
export function setExamEfficacy(data) { export function setExamEfficacy(data) {
return request({ return request({
url: `/api/exam/${data.id}/offLine`, url: `/api/exam/${data.id}/offLine`,
method: 'put' method: 'put',
}); })
} }
/** 设置试卷上架 */ /** 设置试卷上架 */
export function setExamEffectivey(data) { export function setExamEffectivey(data) {
return request({ return request({
url: `/api/exam/${data.id}/onLine`, url: `/api/exam/${data.id}/onLine`,
method: 'put' method: 'put',
}); })
} }
/** 更新考试规则*/ /** 更新考试规则*/
@ -55,60 +55,162 @@ export function updateExamRules(data) {
return request({ return request({
url: `/api/exam/${data.id}`, url: `/api/exam/${data.id}`,
method: 'put', method: 'put',
data: data data: data,
}); })
} }
/** 查询本项目下的考试列表 */ /** 查询本项目下的考试列表 */
export function getExamListProject(params) { export function getExamListProject(params) {
return request({ return request({
url: `/api/exam/paged/loginProject`, url: `/api/exam/paged/loginProject`,
method: 'get', method: 'get',
params params,
}); })
} }
/** 查询本项目下的考试列表不分页 */ /** 查询本项目下的考试列表不分页 */
export function getExamListProjectUnpage(params) { export function getExamListProjectUnpage(params) {
return request({ return request({
url: `/api/exam/list/loginProject`, url: `/api/exam/list/loginProject`,
methods: 'get', methods: 'get',
params params,
}); })
} }
/** 查询班级关联的自己创建的试卷 */ /** 查询班级关联的自己创建的试卷 */
export function getExamListSelfByClassId(params) { export function getExamListSelfByClassId(params) {
return request({ return request({
url: `/api/exam/list/org/self`, url: `/api/exam/list/org/self`,
method: 'get', method: 'get',
params params,
}); })
} }
/** 根据地图ID和prdType查询试卷列表 */ /** 根据地图ID和prdType查询试卷列表 */
export function getExamListByMapIdAndPrdType(mapId, prdType) { export function getExamListByMapIdAndPrdType(mapId, prdType) {
return request({ return request({
url: `/api/exam/list/${mapId}`, url: `/api/exam/list/${mapId}`,
method: 'get', method: 'get',
params: { prdType: prdType } params: { prdType: prdType },
}); })
} }
/** 更新试卷规则 */ /** 更新试卷规则 */
export function updateExamRule(data) { export function updateExamRule(data) {
return request({ return request({
url: `/api/exam/update/rules`, url: `/api/exam/update/rules`,
method: 'put', method: 'put',
data:data data: data,
}); })
} }
/** 检查并更新【规则数据异常】状态 */ /** 检查并更新【规则数据异常】状态 */
export function checkAndUpdateAbnormal(mapId) { export function checkAndUpdateAbnormal(mapId) {
return request({ return request({
url: `/api/exam/checkAndUpdateAbnormal/${mapId}`, url: `/api/exam/checkAndUpdateAbnormal/${mapId}`,
method: 'put' method: 'put',
}); })
} }
/** 重新生成考试规则 */ /** 重新生成考试规则 */
export function regenerateRule (mapId) { export function regenerateRule(mapId) {
return request({ return request({
url: `/api/exam/regenerateRules/${mapId}`, url: `/api/exam/regenerateRules/${mapId}`,
method: 'put' method: 'put',
}); })
}
/**
* ============================================================================
* ============================================================================
* ============================= 以下为新版试卷的接口 ============================
* ============================================================================
* ============================================================================
*/
/**
* LIST -
* 根据试卷蓝图名称简介分页查找某个组织的试卷蓝图
* @param {Number} orgId 组织ID
* @param {String} name 试卷蓝图名称
* @param {String} profile 试卷蓝图简介
* @param {Number} findState 状态: (All(1)-所有,Editing(2)-正在编辑的,CanUse(3)-可以用于生成试卷的,Locked(4)-封存,Used(5)-已经被使用过)
* @param {Number} orderBy 排序依据: (1--创建时间 2--更新时间 3--名称默认值为1)
*/
export function getPapaerListOfOrg({ orgId, ...data }) {
return request({
url: `/api/v2/paper/composition/find/page/for/${orgId}`,
method: 'POST',
data,
})
}
/**
* 创建试卷蓝图
* @param {Number} data.orgId 组织ID
* @param {String} data.name 试卷蓝图名称
* @param {String} data.profile 简介
* @param {String} data.startTime 启用起始时间
* @param {String} data.endTime 启用截止时间
* @param {Number} data.validDuration 考试时长
* @param {String} data.passScore 及格分
* @param {String} data.fullScore 满分
* @param {Object} data.ruleList 规则列表
* @param {Object} data.ruleList.id 规则id
* @param {Object} data.ruleList.pcId 试卷蓝图ID
* @param {Object} data.ruleList.type 试题类型
* @param {Object} data.ruleList.subtype 规则类型
* @param {Object} data.ruleList.tags 标签
* @param {Object} data.ruleList.amount 数量
* @param {Object} data.ruleList.score 每题分值
*/
export function createPaper(data) {
return request({
url: `/api/v2/paper/composition/${data.orgId}`,
method: 'POST',
data,
})
}
/**
* @param {Number} data.id 试卷蓝图ID
* @param {Number} data.orgId 组织ID
* @param {String} data.name 试卷蓝图名称
* @param {String} data.profile 简介
* @param {String} data.startTime 启用起始时间
* @param {String} data.endTime 启用截止时间
* @param {Number} data.validDuration 考试时长
* @param {String} data.passScore 及格分
* @param {String} data.fullScore 满分
* @param {Object} data.ruleList 规则列表
* @param {Object} data.ruleList.id 规则id
* @param {Object} data.ruleList.pcId 试卷蓝图ID
* @param {Object} data.ruleList.type 试题类型
* @param {Object} data.ruleList.subtype 规则类型
* @param {Object} data.ruleList.tags 标签
* @param {Object} data.ruleList.amount 数量
* @param {Object} data.ruleList.score 每题分值
*/
export function editPaper(data) {
return request({
url: `/api/v2/paper/composition`,
method: 'PUT',
data,
})
}
/**
* @param {Number} pcId 试卷蓝图ID
*/
export function getPaperDetail(pcId) {
return request({
url: `/api/v2/paper/composition/${pcId}`,
method: 'GET',
})
}
/**
* @param {Number} data.orgId
* @param {Number} data.subtype
* @param {Array<String>} data.tags
*/
export function getQuestionAmount(data) {
return request({
url: `/api/v2/paper/${data.orgId}/question/count`,
method: 'POST',
data,
})
} }

View File

@ -13,7 +13,7 @@ export function listQuestionPage(params) {
// 标签列表 // 标签列表
export function getLableList() { export function getLableList() {
return request({ return request({
url: `/api/question/org/lable`, url: `/api/question/org/label`,
method: 'get' method: 'get'
}); });
} }
@ -49,11 +49,12 @@ export function updateOption(data) {
} }
// 获取题目信息 // 获取题目信息
export function getQuestionInfo(questionId) { export function getQuestionInfo(questionId, params) {
return request({ return request({
// url: `/api/questionBank/questions/${questionId}`, // url: `/api/questionBank/questions/${questionId}`,
url: `/api/question/org/${questionId}`, url: `/api/question/org/${questionId}`,
method: 'get' method: 'get',
params
}); });
} }
@ -65,3 +66,12 @@ export function importQuestion(data) {
data data
}); });
} }
// 预览答题
export function testAnswer(questionId, data) {
return request({
url: `/api/question/org/test/answer/${questionId}`,
method: 'post',
data
});
}

View File

@ -687,7 +687,7 @@ export const publicAsyncRoute = [
hidden: true hidden: true
}, },
{ {
path: 'examRule/draft/:mode/:ruleId/:lessonId', path: 'examRule/draft/:mode/:paperId',
component: PublishExamRuleDraft, component: PublishExamRuleDraft,
hidden: true hidden: true
}, },
@ -1933,10 +1933,12 @@ export const asyncRouter = [
{ {
path: 'subsystem', path: 'subsystem',
component: SubsystemManage, component: SubsystemManage,
hidden: true, hidden: true
meta: { },
i18n: 'newRouter.subsystemManage' {
} path: 'PublishMapDetail',
component: PublishMapDetail,
hidden: true
} }
] ]
}, },

View File

@ -29,8 +29,8 @@ export function handlerUrl() {
// BASE_API = 'http://114.116.51.125/jlcloud'; // BASE_API = 'http://114.116.51.125/jlcloud';
// BASE_API = 'http://192.168.3.90:9100'; // 周寅 // BASE_API = 'http://192.168.3.90:9100'; // 周寅
// BASE_API = 'http://192.168.3.94:9000'; // 旭强 // BASE_API = 'http://192.168.3.94:9000'; // 旭强
BASE_API = 'http://192.168.3.15:9000'; // 张赛 // BASE_API = 'http://192.168.3.15:9000'; // 张赛
// BASE_API = 'http://192.168.3.5:9000'; // 夏增彬 BASE_API = 'http://192.168.3.5:9000'; // 夏增彬
// BASE_API = 'http://192.168.3.37:9000'; // 卫志宏 // BASE_API = 'http://192.168.3.37:9000'; // 卫志宏
// BASE_API = 'http://b29z135112.zicp.vip'; // BASE_API = 'http://b29z135112.zicp.vip';
// BASE_API = 'http://2925963m2a.zicp.vip'; // 杜康 // BASE_API = 'http://2925963m2a.zicp.vip'; // 杜康

View File

@ -2,6 +2,7 @@
<div> <div>
<query-list-page ref="user" :pager-config="pagerConfig" :query-form="queryForm" :query-list="queryList" /> <query-list-page ref="user" :pager-config="pagerConfig" :query-form="queryForm" :query-list="queryList" />
<dialog-detail ref="detail" /> <dialog-detail ref="detail" />
<preview-answer ref="previewAnswer" :question-id="questionId" />
</div> </div>
</template> </template>
@ -9,17 +10,20 @@
// import { UrlConfig } from '@/scripts/ConstDic'; // import { UrlConfig } from '@/scripts/ConstDic';
import { listQuestionPage, deleteQuestion, getLableList } from '@/api/questionBank.js'; import { listQuestionPage, deleteQuestion, getLableList } from '@/api/questionBank.js';
import DialogDetail from './dialog-detail'; import DialogDetail from './dialog-detail';
import PreviewAnswer from './previewAnswer';
import { convertSheetToList } from '@/jmapNew/theme/parser/util.js'; import { convertSheetToList } from '@/jmapNew/theme/parser/util.js';
// import { getCompanyList } from '@/api/company'; // import { getCompanyList } from '@/api/company';
import XLSX from 'xlsx'; import XLSX from 'xlsx';
export default { export default {
components: { components: {
DialogDetail DialogDetail,
PreviewAnswer
}, },
data() { data() {
return { return {
// companyList: [], // companyList: [],
questionId: '',
companyMap: {}, companyMap: {},
pagerConfig: { pagerConfig: {
pageSize: 'pageSize', pageSize: 'pageSize',
@ -35,7 +39,7 @@ export default {
type: 'select', type: 'select',
label: '类 型', label: '类 型',
config: { config: {
data: this.$ConstSelect.QuestionTypeList data: this.$ConstSelect.QuestionTypeList.filter(item => { return !['fill', 'answer'].includes(item.value); })
} }
}, },
topic: { topic: {
@ -59,7 +63,8 @@ export default {
columns: [ columns: [
{ {
title: '题 目', title: '题 目',
prop: 'topic' prop: 'topic',
type: 'html'
}, },
{ {
title: '标 签', title: '标 签',
@ -114,9 +119,13 @@ export default {
// showControl: (row) => { return row.createUserId == this.userId; }, // showControl: (row) => { return row.createUserId == this.userId; },
type: 'danger' type: 'danger'
}, },
// {
// name: ' ',
// handleClick: this.doDetail
// },
{ {
name: '预 览', name: '预答题',
handleClick: this.doDetail handleClick: this.previewAnswer
} }
] ]
} }
@ -186,6 +195,11 @@ export default {
this.$refs.detail.doShow({index, row}); this.$refs.detail.doShow({index, row});
}, },
previewAnswer(index, row) {
this.questionId = row.id;
this.$refs.previewAnswer.doShow();
},
lableTags(row) { lableTags(row) {
return row.tags ? row.tags.split(',') : ''; return row.tags ? row.tags.split(',') : '';
}, },

View File

@ -0,0 +1,190 @@
<template>
<el-dialog v-dialogDrag :close-on-click-moda="false" :title="title" :visible.sync="show" width="860px" :close-on-click-modal="false" :before-close="doClose">
<div class="ql-editor" v-html="$escapeHTML(`${mapType[type] || ''} : ${form.topic}`)" />
<template v-if="checkType(form, 'judge')">
<div class="answer">
:
<div>
<el-radio-group v-model="active">
<el-radio v-for="(el,i) in options" :key="i" class="option" :label="el.id"> {{ el.content }} </el-radio>
</el-radio-group>
</div>
</div>
</template>
<template v-else-if="checkType(form, 'select')">
<div v-for="(el,i) in options" :key="i" class="option" :label="$str2number(el.id)">
<span>{{ $asc2chart(i+65) }}. </span>
<div class="ql-editor" style="display: inline; padding: 0" v-html="$escapeHTML(el.content)" />
</div>
<div class="answer">
:
<div>
<el-radio-group v-model="active">
<el-radio v-for="(el,i) in options" :key="i" class="option" :label="el.id"> {{ $asc2chart(65+i) }} </el-radio>
</el-radio-group>
</div>
</div>
</template>
<template v-else-if="checkType(form, 'multi')">
<div v-for="(el,i) in options" :key="i" class="option" :label="$str2number(el.id)">
<span>{{ $asc2chart(i+65) }}. </span>
<div class="ql-editor" style="display: inline; padding: 0" v-html="$escapeHTML(el.content)" />
</div>
<div class="answer">
:
<el-checkbox-group v-model="active">
<el-checkbox v-for="(el,i) in options" :key="i" class="option" :label="el.id">{{ $asc2chart(65+i) }} </el-checkbox>
</el-checkbox-group>
</div>
</template>
<template v-else-if="checkType(form, 'fill')">
<div class="answer">
:
<div v-for="(el, i) in options" :key="i" class="fillType">
<div class="fillTypeName">{{ `${i + 1}` }}</div>
<el-input v-model="active[i]" class="fillTypeInput" type="textarea" :autosize="{ minRows: 1, maxRows: 4}" placeholder="请输入答案" />
</div>
</div>
</template>
<template v-else-if="checkType(form, 'answer')">
<div class="answer">
:
<div>
<el-input v-model="active" type="textarea" :autosize="{ minRows: 2, maxRows: 4}" placeholder="请输入答案" />
</div>
</div>
</template>
<div v-if="showAnswer" class="show-answer">
<span :class="isCorrect? 'correct': 'error'">{{ isCorrect ? '答案正确!' : '答案错误!' }}</span>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="submit(true)">提交</el-button>
<el-button @click="show = false">关闭</el-button>
</span>
</el-dialog>
</template>
<script>
import {getQuestionInfo, testAnswer } from '@/api/questionBank.js';
export default {
props: {
questionId: {
type:[Number, String],
required: true
}
},
data() {
return {
active: '',
show: false,
showAnswer: false,
isCorrect: false,
form: {
type: '',
optionList: []
}
};
},
computed: {
title() {
return '详 情';
},
options() {
return this.form.optionList;
},
type() {
return this.form.type;
},
mapType() {
const obj = {};
const list = this.$ConstSelect.QuestionTypeList;
list.forEach(item => {
obj[item.value] = item.label;
});
return obj;
}
},
watch: {
questionId(val) {
this.showAnswer = false;
this.getQuestionInfo();
},
type(val) {
if (val == 'judge' || val == 'judge') {
this.active = 0;
} else if (val == 'multi' || val == 'fill') {
this.active = [];
} else {
this.active = '';
}
}
},
methods: {
checkType(option, type) {
return option.type == type;
},
appendIndex(str, index) {
return `${index + 1}. ${str}`;
},
doShow(node) {
// this.form = node.row || {};
this.show = true;
},
getQuestionInfo() {
if (!this.questionId) { return; }
getQuestionInfo(this.questionId, {random: false}).then(res => {
console.log(res, '---res===');
this.form = res.data;
}).catch(err => {
console.log(err, '---err=====');
this.form.optionList = [];
});
},
submit(val) {
console.log(this.active, this.questionId, this.form, '====');
let data = this.active;
if (!Array.isArray(data)) {
data = [data];
}
testAnswer(this.questionId, data).then(res => {
if (val) {
this.showAnswer = true;
this.isCorrect = res.data;
}
// this.doClose();
}).catch(err => {
console.log(err, '===err====');
});
},
doClose(done) {
this.show = false;
}
}
};
</script>
<style lang="scss" scoped>
.option {
line-height: 22px;
padding-left: 20px;
}
.answer {
line-height: 32px;
color: #000;
padding-left: 15px;
}
.show-answer {
padding: 15px;
span {
font-size: 18px;
}
.correct {
color: green;
}
.error {
color: red;
}
}
</style>

View File

@ -146,6 +146,7 @@ export default {
getLableList().then(res => { getLableList().then(res => {
this.labelList = res.data || []; this.labelList = res.data || [];
}).catch(err => { }).catch(err => {
console.log(err);
}); });
}, },
methods: { methods: {

View File

@ -90,7 +90,10 @@ export default {
this.doBack(); this.doBack();
} else if (valid) { } else if (valid) {
// this.formModel.companyId = parseInt(this.companyId); // this.formModel.companyId = parseInt(this.companyId);
this.formModel.tags = this.tagsArr;
if (Array.isArray(this.tagsArr)) {
this.formModel.tags = this.tagsArr.join(','); this.formModel.tags = this.tagsArr.join(',');
}
updateOption(this.formModel).then(resp => { updateOption(this.formModel).then(resp => {
this.doBack(); this.doBack();
}).catch(error => { }).catch(error => {

View File

@ -11,9 +11,13 @@
</template> </template>
<script> <script>
import { getExamListProject, setExamEffectivey, setExamEfficacy } from '@/api/management/exam'; const paperStateMap = {
import localStore from 'storejs'; '1': '正在编辑',
import { getPublishMapListOnline } from '@/api/jmap/map'; '2': '封存',
'3': '已使用',
}
import { getExamListProject, getPapaerListOfOrg, setExamEffectivey, setExamEfficacy } from '@/api/management/exam'
import { getPublishMapListOnline } from '@/api/jmap/map'
export default { export default {
name: 'ExamManage', name: 'ExamManage',
@ -21,7 +25,7 @@ export default {
return { return {
pagerConfig: { pagerConfig: {
pageSize: 'pageSize', pageSize: 'pageSize',
pageIndex: 'pageNum' pageIndex: 'pageNum',
}, },
mapIdList: [], mapIdList: [],
examQueryForm: { examQueryForm: {
@ -33,101 +37,113 @@ export default {
queryObject: { queryObject: {
name: { name: {
type: 'text', type: 'text',
label: '试卷名称:' label: '试卷名称:',
}, },
creatorName: { // creatorName: {
type: 'text', // type: 'text',
label: '创建人:' // label: ':'
}, // },
status: { state: {
type: 'select', type: 'select',
label: '启用/禁用:', label: '状态:',
config: { config: {
data: [ data: Object.entries(paperStateMap).map(([k, v]) => ({ value: k, label: v })),
{ label: '启用', value: '1' }, },
{ label: '禁用', value: '0' } },
] },
}
}
}
}, },
examQueryList: { examQueryList: {
query: getExamListProject, // query: getExamListProject,
query: obj => getPapaerListOfOrg({ ...obj, orgId: this.orgId }),
selectCheckShow: false, selectCheckShow: false,
indexShow: false, indexShow: false,
columns: [ columns: [
{ {
title: '试卷名称', title: '试卷名称',
prop: 'name' prop: 'name',
}, },
{ {
title: '归属地图', title: '归属地图',
prop: 'mapId', prop: 'mapId',
type: 'tag', type: 'tag',
width: '200', width: '200',
columnValue: (row) => { return this.$convertField(row.mapId, this.mapIdList, ['id', 'name']); }, columnValue: row => {
tagType: (row) => { return ''; } return this.$convertField(row.mapId, this.mapIdList, ['id', 'name'])
},
tagType: row => {
return ''
},
}, },
{ {
title: '产品类型', title: '产品类型',
prop: 'prdType', prop: 'prdType',
type: 'tag', type: 'tag',
width: '110', width: '110',
columnValue: (row) => { if (row.prdType === '01') { return '现地工作站'; } else if (row.prdType === '02') { return '行调工作站'; } }, columnValue: row => {
tagType: (row) => { return ''; } if (row.prdType === '01') {
return '现地工作站'
} else if (row.prdType === '02') {
return '行调工作站'
}
},
tagType: row => {
return ''
},
}, },
{ {
title: '启用/禁用', title: '状态',
prop: 'status', prop: 'state',
type: 'tag', type: 'tag',
width: '80', width: '80',
columnValue: (row) => { columnValue: row => {
return row.status == '1' ? '启用' : '禁用'; return paperStateMap[row.state]
},
tagType: row => {
return ''
}, },
tagType: (row) => { return ''; }
}, },
{ {
title: '试卷规则状态', title: '试卷规则状态',
prop: 'abnormal', prop: 'abnormal',
type: 'tag', type: 'tag',
width: '80', width: '80',
columnValue: (row) => { columnValue: row => {
return row.abnormal ? '异常' : '正常'; return row.abnormal ? '异常' : '正常'
},
tagType: row => {
return row.abnormal ? 'danger' : 'success'
}, },
tagType: (row) => { return row.abnormal ? 'danger' : 'success'; }
}, },
{ {
title: '开始时间', title: '开始时间',
prop: 'startTime' prop: 'startTime',
}, },
{ {
title: '截止时间', title: '截止时间',
prop: 'endTime' prop: 'endTime',
}, },
{ {
title: '满分', title: '满分',
prop: 'fullPoint', prop: 'fullScore',
width: '80' width: '80',
}, },
{ {
title: '及格分', title: '及格分',
prop: 'passingPoint', prop: 'passScore',
width: '80' width: '80',
}, },
{ {
title: '时长', title: '时长',
prop: 'duration', prop: 'validDuration',
type: 'tag', type: 'tag',
width: '80', width: '80',
columnValue: (row) => { columnValue: row => row.validDuration,
return Math.floor(row.duration / 60); tagType: row => {},
},
tagType: (row) => { }
}, },
{ {
title: '创建人', title: '创建人',
prop: 'creatorName', prop: 'creatorName',
width: '150' width: '150',
}, },
{ {
type: 'button', type: 'button',
@ -137,113 +153,120 @@ export default {
{ {
name: '成绩查询', name: '成绩查询',
handleClick: this.handleQueryGrade, handleClick: this.handleQueryGrade,
type: 'primary' type: 'primary',
}, },
{ {
name: '成绩统计', name: '成绩统计',
handleClick: this.handleGradeStatistics, handleClick: this.handleGradeStatistics,
type: 'success' type: 'success',
}, },
{ {
name: '编辑', name: '编辑',
handleClick: this.handleEditExam, handleClick: this.handleEditExam,
type: 'primary', type: 'primary',
showControl: (row) => { showControl: row => {
return row.creatorId == this.userId; return row.creatorId == this.userId
} },
}, },
{ {
name: '启用', name: '启用',
handleClick: this.handleEnableExam, handleClick: this.handleEnableExam,
type: 'warning', type: 'warning',
showControl: (row) => { showControl: row => {
return row.creatorId == this.userId && row.status == '0'; return row.creatorId == this.userId /* && row.status == '0' */
} },
}, },
{ {
name: '禁用', name: '禁用',
handleClick: this.handleDeleteExam, handleClick: this.handleDeleteExam,
type: 'danger', type: 'danger',
showControl: (row) => { showControl: row => {
return row.creatorId == this.userId && row.status == '1'; return row.creatorId == this.userId /* && row.status == '1' */
} },
} },
]
}
], ],
actions: [ },
{ text: '新建试卷', handler: this.examCreate } ],
] actions: [{ text: '新建试卷', handler: this.examCreate }],
},
} }
};
}, },
computed: { computed: {
userId() { userId() {
return this.$store.state.user.id; return this.$store.state.user.id
} },
orgId() {
return this.$store.state.user.companyId
},
}, },
created() { created() {
const params = localStore.get(this.$route.path) || {}; // const params = localStore.get(this.$route.path) || {}
if (!params.status) { params.status = '1'; } // if (!params.status) {
localStore.set(this.$route.path, params); // params.status = '1'
this.mapIdList = []; // }
// localStore.set(this.$route.path, params)
this.mapIdList = []
getPublishMapListOnline().then(response => { getPublishMapListOnline().then(response => {
this.mapIdList = response.data; this.mapIdList = response.data
}); })
}, },
methods: { methods: {
handleQueryGrade(index, row) { handleQueryGrade(index, row) {
this.$router.push({ path: '/info/gradeList', query: { examId: row.id, name: row.name } }); this.$router.push({ path: '/info/gradeList', query: { examId: row.id, name: row.name } })
}, },
handleGradeStatistics(index, row) { handleGradeStatistics(index, row) {
this.$router.push({ path: '/info/gradeStatistics', query: { examId: row.id, name: row.name } }); this.$router.push({ path: '/info/gradeStatistics', query: { examId: row.id, name: row.name } })
}, },
handleEditExam(index, row) { handleEditExam(index, row) {
this.$router.push({ path: `/info/examRule/draft/edit/${row.id}/0`, query: { source: 'org' } }); this.$router.push({ path: `/info/examRule/draft/edit/${row.id}`, query: { source: 'org' } })
}, },
examCreate() { examCreate() {
this.$router.push({ path: `/info/examRule/draft/add/0/0`, query: { source: 'org' } }); this.$router.push({ path: `/info/examRule/draft/add/0`, query: { source: 'org' } })
}, },
handleEnableExam(index, data) { handleEnableExam(index, data) {
setExamEffectivey(data).then(res => { setExamEffectivey(data)
this.examRefresh(); .then(res => {
this.$message.success('启用试卷成功!'); this.examRefresh()
}).catch(error => { this.$message.success('启用试卷成功!')
this.$message.error('启用试卷失败:' + error.message); })
}); .catch(error => {
this.$message.error('启用试卷失败:' + error.message)
})
}, },
handleDeleteExam(index, data) { handleDeleteExam(index, data) {
this.$confirm('该操作将禁用试卷,是否继续?', this.$t('global.tips'), { this.$confirm('该操作将禁用试卷,是否继续?', this.$t('global.tips'), {
confirmButtonText: this.$t('global.confirm'), confirmButtonText: this.$t('global.confirm'),
cancelButtonText: this.$t('global.cancel'), cancelButtonText: this.$t('global.cancel'),
type: 'warning' type: 'warning',
}).then(() => { })
setExamEfficacy(data).then(res => { .then(() => {
this.examRefresh(); setExamEfficacy(data)
.then(res => {
this.examRefresh()
this.$message({ this.$message({
type: 'success', type: 'success',
message: '禁用试卷成功!' message: '禁用试卷成功!',
}); })
}).catch(res => { })
.catch(res => {
if (res.code == '10004') { if (res.code == '10004') {
this.$message({ type: 'error', message: '禁用失败:试卷已被使用,无法禁用!' }); this.$message({ type: 'error', message: '禁用失败:试卷已被使用,无法禁用!' })
} else if (res.code == '10003') { } else if (res.code == '10003') {
this.$message({ type: 'warning', message: '禁用失败:无权限禁用!'}); this.$message({ type: 'warning', message: '禁用失败:无权限禁用!' })
} else { } else {
this.$message({ type: 'error', message: '禁用试卷失败!' }); this.$message({ type: 'error', message: '禁用试卷失败!' })
} }
}); })
}).catch(() => { }); })
.catch(() => {})
}, },
examRefresh() { examRefresh() {
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.examQueryListPage.refresh(true); this.$refs.examQueryListPage.refresh(true)
}); })
} },
} },
}; }
</script> </script>
<style scoped> <style scoped></style>
</style>

View File

@ -1,27 +1,59 @@
<template> <template>
<el-dialog v-dialogDrag :title="title" :visible.sync="dialogShow" :before-close="handleCancel" :close-on-click-modal="false"> <el-dialog
v-dialogDrag
:title="title"
:visible.sync="dialogShow"
:before-close="handleCancel"
:close-on-click-modal="false"
>
<el-form ref="form" :model="form" :rules="rules" label-width="140px"> <el-form ref="form" :model="form" :rules="rules" label-width="140px">
<el-form-item :label="$t('publish.trainingType')" prop="trainingType"> <el-form-item label="试题类型" prop="type">
<el-select v-model="form.trainingType" :placeholder="$t('publish.selectTypeScope')" style="width:240px;" @change="changeCourse"> <el-select
<el-option v-for="nor in trainingTypeList" :key="nor.value" :label="nor.label" :value="nor.value" :disabled="nor.disabled" /> v-model="form.type"
placeholder="请选择试题类型"
style="width:240px;"
@change="getQuestionAmount"
>
<el-option
v-for="item in types"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="$t('publish.operationType')" prop="operateType"> <el-form-item label="规则类型" prop="subtype">
<el-select v-model="form.operateType" clearable :placeholder="$t('publish.selectScope')" @change="changeOperation"> <el-select
<el-option v-for="nor in operationTypeList" :key="nor.value" :label="nor.label" :value="nor.value" :disabled="nor.disabled" /> v-model="form.subtype"
placeholder="请选择规则类型"
style="width:240px;"
@change="getQuestionAmount"
>
<el-option
v-for="item in subtypes"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="$t('publish.questionNumbers')" prop="number"> <el-form-item label="标签" prop="tags">
<el-select v-model="form.tags"></el-select>
</el-form-item>
<el-form-item label="题目数量" prop="amount">
<el-input-number <el-input-number
v-model="form.number" v-model="form.amount"
:precision="0" :precision="0"
:min="0" :min="0"
:max="this.topicNum"
style="width: calc(100% - 280px); float: left; margin-right: 10px;" style="width: calc(100% - 280px); float: left; margin-right: 10px;"
/> />
<span style="width: 190px; float: left;">{{ $t('publish.allNumberTipOne') }} {{ topicNum }} {{ $t('publish.allNumberTipTwo') }}</span> <span v-if="this.form.type === 1" style="width: 190px; float: left;"
>{{ $t('publish.allNumberTipOne') }} {{ topicNum }} {{ $t('publish.allNumberTipTwo') }}</span
>
</el-form-item> </el-form-item>
<el-form-item :label="$t('publish.scorePerQuestion')" prop="mark"> <el-form-item :label="$t('publish.scorePerQuestion')" prop="score">
<el-input-number v-model="form.mark" :precision="0" :min="0" style="width:200px" /> <el-input-number v-model="form.score" :precision="0" :min="0" style="width:200px" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
@ -32,134 +64,121 @@
</template> </template>
<script> <script>
import { getQuestionAmount } from '@/api/management/exam'
export default { export default {
name: 'EditRule', name: 'EditRule',
props: { props: {},
operationTypeMap: { computed: {
type: Object, types() {
required:true return [{ value: 1, label: '理论题' }, { value: 2, label: '实训题' }]
}, },
trainingOperateTypeMap: { subtypes() {
type: Object, const data = {
required:true '1': [{ value: 1, label: '单选题' }, { value: 2, label: '多选题' }, { value: 3, label: '判断题' }],
}, '2': [{ value: 4, label: '单操实训' }, { value: 5, label: '场景实训' }],
trainingTypeNums: {
type: Object,
required: true
},
operationTypeNums: {
type: Object,
required: true
},
trainingTypeList: {
type: Array,
required: true
} }
return data[this.form.type]
},
title() {
return this.isEditMode ? this.$t('publish.modifyRules') : this.$t('publish.addRules')
},
}, },
data() { data() {
var number = (rule, value, callback) => { var number = (rule, value, message) => {
if (!value) { if (!value) {
return callback(new Error(this.$t('publish.inputQuestionNumber'))); return message(new Error(this.$t('publish.inputQuestionNumber')))
} }
setTimeout(() => { setTimeout(() => {
if (Number(value) == 0) { if (Number(value) == 0) {
callback(new Error(this.$t('publish.inputQuestionNumberError'))); message(new Error(this.$t('publish.inputQuestionNumberError')))
} else if (!Number(value)) { } else if (!Number(value)) {
callback(new Error(this.$t('publish.inputValidNumber'))); message(new Error(this.$t('publish.inputValidNumber')))
} else if (Number(value) > this.topicNum) { } else if (Number(value) > this.topicNum && this.form.type === 1) {
callback(new Error(this.$t('publish.inputNumberError'))); message(new Error(this.$t('publish.inputNumberError')))
} else { } else {
callback(); message()
} }
}, 100); }, 100)
}; }
var mark = (rule, value, callback) => { var score = (rule, value, message) => {
if (!value) { if (!value) {
return callback(new Error(this.$t('publish.inputScorePerQuestion'))); return message(new Error(this.$t('publish.inputScorePerQuestion')))
} else { } else {
callback(); message()
}
} }
};
return { return {
title: this.$t('publish.addRules'),
form: { form: {
trainingType: '', id: '',
operateType: '', type: '',
number: '', subtype: '',
mark: 0 tags: [],
amount: 1,
score: 1,
}, },
topicNum: 0, topicNum: 0,
dialogShow: false, dialogShow: false,
editOk: false,
rules: { rules: {
trainingType: [ type: [{ required: true, message: this.$t('publish.selectTestType'), trigger: 'change' }],
{ required: true, message: this.$t('publish.selectTestType'), trigger: 'change' } subtype: [{ required: true, message: '请选择规则类型', trigger: 'change' }],
], amount: [{ required: true, validator: number, trigger: 'blur' }],
number: [ score: [{ required: true, validator: score, trigger: 'blur' }],
{ required: true, validator: number, trigger: 'blur' }
],
mark: [
{ required: true, validator: mark, trigger: 'blur' }
]
}, },
typeList: [], }
operationTypeList: [] },
}; created() {
}, },
mounted() {}, mounted() {},
methods: { methods: {
show(detail) { show(detail) {
this.dialogShow = true; this.dialogShow = true
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.form.resetFields(); this.$refs.form.resetFields()
if (detail) { if (detail) {
this.title = this.$t('publish.modifyRules'); this.isEditMode = true
this.editOk = true;
this.changeCourse(detail.trainingType);
this.form = { this.form = {
trainingType: detail.trainingType, type: detail.type,
operateType: detail.operateType, subtype: detail.subtype,
number: detail.num, amount: detail.amount,
mark: detail.point score: detail.score,
}; id: detail.id || '',
this.changeOperation(detail.operateType);
} else {
this.title = this.$t('publish.addRules');
} }
}); this.topicNum = detail.topicNum
} else {
this.isEditMode = false
}
})
},
getQuestionAmount() {
if (!(this.form.type && this.form.subtype)) return
if (this.form.type === 2) return //
const param = {
orgId: this.$store.state.user.companyId,
groupType: this.form.type,
subType: this.form.subtype,
}
getQuestionAmount(param).then(resp => {
this.topicNum = resp.data
})
}, },
handleOk() { handleOk() {
this.$refs['form'].validate((valid) => { this.$refs['form'].validate(valid => {
if (valid) { if (valid) {
this.$emit( this.editOk ? 'editRuleList' : 'addRuleList', this.form); this.$emit('submit', { ...this.form, topicNum: this.topicNum }, this.isEditMode)
this.handleCancel(); this.handleCancel()
} }
}); })
}, },
handleCancel() { handleCancel() {
this.editOk = false; this.topicNum = 0
this.topicNum = 0; this.dialogShow = false
this.operationTypeList = [];
this.dialogShow = false;
}, },
changeCourse(val) {
this.operationTypeList = this.operationTypeMap[val];
this.topicNum = this.trainingTypeNums[val];
this.form.operateType = '';
}, },
changeOperation(val) { }
if (val) {
this.topicNum = this.operationTypeNums[this.form.trainingType][val];
} else {
this.topicNum = this.trainingTypeNums[this.form.trainingType];
}
}
}
};
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
/deep/ { /deep/ {
.el-dialog { .el-dialog {
width: 600px; width: 600px;
} }
@ -171,5 +190,5 @@ export default {
.el-cascader { .el-cascader {
width: 100%; width: 100%;
} }
} }
</style> </style>

View File

@ -4,28 +4,28 @@
<el-form-item :label="$t('publish.testName')" prop="name"> <el-form-item :label="$t('publish.testName')" prop="name">
<el-input v-model="examData.name" :placeholder="$t('publish.inputTestName')" /> <el-input v-model="examData.name" :placeholder="$t('publish.inputTestName')" />
</el-form-item> </el-form-item>
<el-form-item label="归属地图" prop="mapId"> <el-form-item label="简介" prop="profile">
<el-select v-model="examData.mapId" placeholder="请选择归属地图" :disabled="isEdit"> <el-input v-model="examData.profile" placeholder="请输入简介" />
<el-option v-for="map in mapList" :key="map.id" :label="map.name" :value="map.id" />
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="工作站类型" prop="prdType"> <el-form-item :label="$t('publish.testDuration')" prop="validDuration">
<el-select v-model="examData.prdType" placeholder="请选择工作站类型" :disabled="isEdit"> <el-input-number
<el-option v-for="prd in prdList" :key="prd.value" :label="prd.label" :value="prd.value" /> v-model="examData.validDuration"
</el-select> placeholder="请输入"
</el-form-item> style="float: left; width: calc(100% - 80px);"
<el-form-item :label="$t('publish.testDuration')" prop="duration"> :min="1"
<el-input-number v-model="examData.duration" placeholder="请输入" style="float: left; width: calc(100% - 80px);" :disabled="isEdit" :min="1" /> />
<span style="width:80px; display: block;float: left; text-align: center;">&nbsp;{{ $t('publish.durationMinutes') }}</span> <span style="width:80px; display: block;float: left; text-align: center;"
>&nbsp;{{ $t('publish.durationMinutes') }}</span
>
</el-form-item> </el-form-item>
<el-form-item label="开放时间要求" prop="haveDate"> <el-form-item label="开放时间要求" prop="haveDate">
<el-switch v-model="haveDate" /> <el-switch v-model="haveDate" />
</el-form-item> </el-form-item>
<el-form-item v-if="haveDate" :label="$t('publish.testDate')"> <el-form-item v-if="haveDate" :label="$t('publish.testDate')">
<el-col :span="11"> <el-col :span="11">
<el-form-item prop="startDate"> <el-form-item prop="startTime">
<el-date-picker <el-date-picker
v-model="examData.startDate" v-model="examData.startTime"
type="datetime" type="datetime"
:placeholder="$t('publish.startTestTime')" :placeholder="$t('publish.startTestTime')"
style="width: 100%;" style="width: 100%;"
@ -37,9 +37,9 @@
</el-col> </el-col>
<el-col class="line" :span="2">-</el-col> <el-col class="line" :span="2">-</el-col>
<el-col :span="11"> <el-col :span="11">
<el-form-item prop="endDate"> <el-form-item prop="endTime">
<el-date-picker <el-date-picker
v-model="examData.endDate" v-model="examData.endTime"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
type="datetime" type="datetime"
:placeholder="$t('publish.endTestTime')" :placeholder="$t('publish.endTestTime')"
@ -48,167 +48,99 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-form-item> </el-form-item>
<el-form-item :label="$t('publish.fullScore')" prop="fullMark"> <el-form-item :label="$t('publish.fullScore')" prop="fullScore">
<el-input-number v-model="examData.fullMark" placeholder="" :disabled="isEdit" :min="1" @change="fullMarkChange" /> <el-input-number v-model="examData.fullScore" placeholder="" :min="1" @change="fullScoreChange" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('publish.passingScore')" prop="passMark"> <el-form-item :label="$t('publish.passingScore')" prop="passScore">
<el-input-number v-model="examData.passMark" placeholder="" :disabled="isEdit" :min="1" /> <el-input-number v-model="examData.passScore" placeholder="" :min="1" />
</el-form-item> </el-form-item>
<el-form-item v-if="!$route.path.includes('info')" :label="$t('publish.whetherToTry')" required> <!-- <el-form-item v-if="!$route.path.includes('info')" :label="$t('publish.whetherToTry')" required>
<el-radio-group v-model="trial"> <el-radio-group v-model="trial">
<el-radio label="1">{{ $t('publish.trialNo') }}</el-radio> <el-radio label="1">{{ $t('publish.trialNo') }}</el-radio>
<el-radio label="2">{{ $t('publish.trialYes') }}</el-radio> <el-radio label="2">{{ $t('publish.trialYes') }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item> -->
<el-form-item :label="$t('publish.testDescription')" prop="desc">
<el-input v-model="examData.desc" type="textarea" :placeholder="$t('publish.inputTestDescription')" :disabled="isEdit" />
</el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<script> <script>
import { updateExamRules } from '@/api/management/exam';
import { getMapListByProjectCode } from '@/api/jmap/map';
import { getSessionStorage } from '@/utils/auth';
import { ProjectCode } from '@/scripts/ProjectConfig';
export default { export default {
name: 'ExamFrom', name: 'ExamFrom',
props: { props: {
examData: { examData: {
type: Object, type: Object,
default() { default() {
return {}; return {}
} },
} },
}, },
data() { data() {
var checkEndDate = (rule, value, callback) => { var checkendTime = (rule, value, message) => {
if (this.examData.startDate && value) { if (this.examData.startTime && value) {
const startTime = new Date(this.examData.startDate).getTime(); const startTime = new Date(this.examData.startTime).getTime()
const endTime = new Date(value).getTime(); const endTime = new Date(value).getTime()
if (startTime > endTime) { if (startTime > endTime) {
callback(new Error('开始时间必须小于截止时间')); message(new Error('开始时间必须小于截止时间'))
} else { } else {
callback(); message()
} }
} else { } else {
callback(); message()
} }
}; }
var checkPassMark = (rule, value, callback) => { var checkPassScore = (rule, value, message) => {
if (value > this.examData.fullMark) { if (value > this.examData.fullScore) {
callback(new Error('及格分必须小于等于满分')); message(new Error('及格分必须小于等于满分'))
} else { } else {
callback(); message()
}
} }
};
return { return {
pickerOptions: { pickerOptions: {
disabledDate(time) { disabledDate(time) {
return time.getTime() < new Date(new Date().toLocaleDateString()).getTime(); return time.getTime() < new Date(new Date().toLocaleDateString()).getTime()
} },
}, },
haveDate: false, haveDate: false,
mapList: [],
prdList: [{ label: 'ATS现地工作站', value: '01' }, { label: 'ATS行调工作站', value: '02' }],
trial: '1',
options: [], options: [],
selectDisable: false, selectDisable: false,
rules: { rules: {
name: [ name: [{ required: true, message: this.$t('publish.inputTestName'), trigger: 'blur' }],
{ required: true, message: this.$t('publish.inputTestName'), trigger: 'blur' } validDuration: [{ required: true, message: this.$t('publish.inputTestDuration'), trigger: 'blur' }],
], fullScore: [{ required: true, message: this.$t('publish.inputFullScore'), trigger: 'blur' }],
prdType: [ passScore: [
{ required: true, message: '请选择产品类型', trigger: 'change' }
],
mapId: [
{ required: true, message: '请选择归属地图', trigger: 'change' }
],
duration: [
{ required: true, message: this.$t('publish.inputTestDuration'), trigger: 'blur' }
],
fullMark: [
{ required: true, message: this.$t('publish.inputFullScore'), trigger: 'blur' }
],
trial: [
{ required: true, message: this.$t('publish.selectWetherTrial'), trigger: 'blur' }
],
passMark: [
{ required: true, message: this.$t('publish.inputPassingScore'), trigger: 'blur' }, { required: true, message: this.$t('publish.inputPassingScore'), trigger: 'blur' },
{ validator: checkPassMark, trigger: 'blur' } { validator: checkPassScore, trigger: 'blur' },
], ],
endDate: [ endTime: [{ validator: checkendTime, trigger: 'change' }],
{ validator: checkEndDate, trigger: 'change' } },
]
} }
};
}, },
computed: { computed: {
isEdit() { isEdit() {
return this.$route.params.mode == 'edit'; return this.$route.params.mode === 'edit'
}
}, },
created() {
this.refresh();
},
mounted() {
}, },
created() {},
mounted() {},
methods: { methods: {
checkedForm(type) { checkForm() {
this.$refs['form'].validate((valid) => { return this.$refs['form'].validate()
if (valid) {
this.$emit(type);
}
});
}, },
fullMarkChange() { fullScoreChange() {
this.$refs.form.validateField('passMark'); this.$refs.form.validateField('passScore')
}, },
getDate(date) {
const now = new Date(date);
const y = now.getFullYear();
const m = now.getMonth() + 1;
const d = now.getDate();
return y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d) + ' ' + now.toTimeString().substr(0, 8);
}, },
updateForm() { }
this.$refs['form'].validate(async (valid) => {
if (valid) {
const model = {
id: this.$route.params.ruleId,
name: this.examData.name,
endTime: this.examData.endDate,
startTime: this.examData.startDate,
trial: this.trial == 2
};
try {
await updateExamRules(model);
this.$message.success(this.$t('publish.updateExamRuleSuccess'));
} catch (error) {
this.$messageBox(this.$t('publish.updateExamRuleFailed'));
}
}
});
},
refresh() {
const project = ProjectCode[getSessionStorage('project')];
getMapListByProjectCode(project).then(resp => {
this.mapList = resp.data;
}).catch(e => {
this.$message.error('获取地图列表数据异常:' + e.message);
});
}
}
};
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
.exam-rule { .exam-rule {
height: 100%; height: 100%;
} }
.line { .line {
font-size: 16px; font-size: 16px;
text-align: center; text-align: center;
} }
</style> </style>

View File

@ -6,21 +6,25 @@
<el-step :title="$t('publish.examRuleMaking')" icon="el-icon-setting" /> <el-step :title="$t('publish.examRuleMaking')" icon="el-icon-setting" />
</el-steps> </el-steps>
<div class="joylink-card forms"> <div class="joylink-card forms">
<template v-if="currentStep == 1" class="definition"> <exam-from v-show="currentStep === 1" ref="exam" :exam-data="examData" />
<exam-from ref="exam" :exam-data="examData" @goNextStep="goNextStep" @createQuickly="createQuickly" /> <rule-from
</template> :is-edit-mode="isEditMode"
<template v-else class="rule"> v-show="currentStep === 2"
<rule-from ref="rule" :rule-list="ruleList" :exam-data="examData" @regulation="regulation" /> ref="rule"
</template> :rule-list="ruleList"
:exam-data="examData"
/>
</div> </div>
<div class="draft"> <div class="draft">
<el-button-group> <el-button-group>
<el-button v-if="isPrevStep" type="primary" @click="prevStep">{{ this.$t('global.lastStep') }}</el-button> <el-button v-if="showPrevStep" type="primary" @click="prevStep">{{
<el-button v-if="isNextStep" type="primary" @click="nextStep">{{ this.$t('global.nextStep') }}</el-button> this.$t('global.lastStep')
<el-button v-if="isUpdate" type="warning" @click="update">{{ $t('global.update') }}</el-button> }}</el-button>
<el-button v-if="isCreate" type="primary" @click="create">{{ $t('global.create') }}</el-button> <el-button v-if="showNextStep" type="primary" @click="nextStep">{{
this.$t('global.nextStep')
}}</el-button>
<el-button v-if="currentStep === 2" type="primary" @click="submit">提交</el-button>
<el-button type="primary" @click="turnback">{{ $t('global.back') }}</el-button> <el-button type="primary" @click="turnback">{{ $t('global.back') }}</el-button>
<el-button v-if="isFastCreate" type="primary" @click="goToCheckForm">快速创建</el-button>
</el-button-group> </el-button-group>
</div> </div>
</div> </div>
@ -28,162 +32,137 @@
</template> </template>
<script> <script>
import RuleFrom from './rule'; import RuleFrom from './rule'
import ExamFrom from './examFrom'; import ExamFrom from './examFrom'
import { getExamLessonDetail, createExam } from '@/api/management/exam'; import { getPaperDetail } from '@/api/management/exam'
import { UrlConfig } from '@/scripts/ConstDic'; import { UrlConfig } from '@/scripts/ConstDic'
import { createPaper, editPaper } from '@/api/management/exam'
export default { export default {
name: 'ExamRule', name: 'ExamRule',
components: { components: {
ExamFrom, ExamFrom,
RuleFrom RuleFrom,
}, },
data() { data() {
return { return {
currentStep: 1, currentStep: 1,
examData: { examData: {
name: '', name: '',
mapId: '', profile: '',
prdType: '', startTime: '',
startDate: '', endTime: '',
endDate: '', validDuration: 30,
desc: '', fullScore: 100,
type: '', passScore: 60,
duration: '',
fullMark: '',
passMark: ''
}, },
ruleList: [] ruleList: [],
};
},
computed: {
isPrevStep() {
return this.currentStep == 2;
},
isNextStep() {
return this.currentStep == 1;
},
isUpdate() {
return this.$route.params.mode == 'edit';
},
isCreate() {
return this.currentStep == 2 && this.$route.params.mode !== 'edit';
},
isFastCreate() {
return this.currentStep == 1 && this.$route.params.mode != 'edit' && Number(this.$route.params.ruleId);
} }
}, },
computed: {
orgId() {
return this.$store.state.user.companyId
},
showPrevStep() {
return this.currentStep == 2
},
showNextStep() {
return this.currentStep == 1
},
isEditMode() {
return this.$route.params.mode == 'edit'
},
},
created() { created() {
if (this.$route.params.ruleId != 0) { if (this.isEditMode) {
getExamLessonDetail(this.$route.params.ruleId).then(res => { getPaperDetail(this.$route.params.paperId).then(res => {
this.examData = { this.examData = {
name: res.data.name, name: res.data.name,
mapId: res.data.mapId + '', profile: res.data.profile,
prdType: res.data.prdType, startTime: res.data.startTime,
startDate: res.data.startTime, endTime: res.data.endTime,
endDate: res.data.endTime, validDuration: Number(res.data.validDuration),
desc: res.data.remarks, fullScore: res.data.fullScore,
type: res.data.type, passScore: res.data.passScore,
duration: Number(res.data.duration) / 60, }
fullMark: res.data.fullPoint, this.ruleList = res.data.ruleList
passMark: res.data.passingPoint
};
this.ruleList = res.data.examDefinitionRulesVOList;
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.exam.haveDate = !!this.examData.startDate; this.$refs.exam.haveDate = !!this.examData.startTime
}); })
}); })
} }
}, },
methods: { methods: {
regulation() {
this.currentStep = 1;
this.$nextTick(() => {
this.$refs.exam.haveDate = !!this.examData.startDate;
});
},
async createQuickly() {
const resp = await getExamLessonDetail(this.$route.params.ruleId);
const ruleList = resp.data.examDefinitionRulesVOList;
const result = {
duration: Number(this.examData.duration) * 60, //
examDefinitionRulesVOList: ruleList, //
fullPoint: Number(this.examData.fullMark), //
mapId: this.examData.mapId, // id
prdType: this.examData.prdType,
name: this.examData.name, //
passingPoint: Number(this.examData.passMark), //
remarks: this.examData.desc, //
endTime: this.examData.endDate,
startTime: this.examData.startDate,
type: this.examData.type, //
trial: this.examData.trial == 2 //
};
let res = {};
try {
res = await createExam(result);
this.$message.success({ message: res.message });
this.$store.dispatch('exam/setRuleList', []); //
const path = `${this.$route.path.match(/(\/.*)\/examRule/)[1]}${UrlConfig.examRuleManage}`;
this.$router.replace({ path: `${path}`, query: { mapId: this.$route.query.mapId, noPreLogout: this.$route.query.noPreLogout } });
} catch (error) {
if (error) {
this.$messageBox(`${this.$t('publish.saveRuleFailed')} ${error.message}`);
} else {
this.$messageBox(`${this.$t('publish.saveRuleFailed')}`);
}
}
},
goToCheckForm() {
this.$refs.exam.checkedForm('createQuickly');
},
prevStep() { prevStep() {
this.$refs.rule.regulation(); this.currentStep = 1
},
goNextStep() {
this.currentStep = 2;
}, },
nextStep() { nextStep() {
this.$refs.exam.checkedForm('goNextStep'); this.$refs.exam
.checkForm()
.then(() => {
this.currentStep = 2
})
.catch(() => {})
}, },
update() { submit() {
if(this.currentStep === 1) { const scoreValid = this.$refs.rule.checkTotolScores()
this.$refs.exam.updateForm(); if (!scoreValid) {
} else if (this.currentStep === 2) { this.$message.warning('规则满分与试题定义不匹配')
this.$refs.rule.updateOk(); return
} }
}, const examData = { ...this.examData, ...{ orgId: this.orgId } }
create() { const ruleData = this.ruleList
this.$refs.rule.creatOk(); const uploadData = { ...examData, ruleList: ruleData }
console.log(JSON.stringify(uploadData))
const uploadMethodMap = {
add: createPaper,
edit: editPaper,
}
if (this.isEditMode) {
uploadData.id = this.$route.params.paperId
}
uploadMethodMap[this.$route.params.mode](uploadData).then(resp => {
if (resp.code === 200) {
this.$message.success(`${this.isEditMode ? '修改' : '创建'}成功`)
this.turnback()
} else {
this.$message.error(resp.message)
console.log(uploadData)
console.log(resp)
}
})
}, },
turnback() { turnback() {
const path = `${this.$route.path.match(/(\/.*)\/examRule/)[1]}${UrlConfig.examRuleManage}`; const path = `${this.$route.path.match(/(\/.*)\/examRule/)[1]}${UrlConfig.examRuleManage}`
if (this.$route.query.source === 'org') { if (this.$route.query.source === 'org') {
this.$router.go(-1); this.$router.go(-1)
} else { } else {
this.$router.replace({ path: `${path}`, query: { mapId: this.$route.query.mapId, noPreLogout: this.$route.query.noPreLogout} }); this.$router.replace({
path: `${path}`,
query: { mapId: this.$route.query.mapId, noPreLogout: this.$route.query.noPreLogout },
})
} }
} },
} },
}; }
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
.joylink-card{ .joylink-card {
.card-title{ .card-title {
text-align: center; text-align: center;
height: 47px; height: 47px;
line-height: 47px; line-height: 47px;
border-bottom: 1px solid #e6e6e6; border-bottom: 1px solid #e6e6e6;
font-weight:bold; font-weight: bold;
} }
} }
.card-box{ .card-box {
overflow: hidden; overflow: hidden;
height: 100%; height: 100%;
} }
.exam-box { .exam-box {
padding-top: 10px; padding-top: 10px;
overflow: auto; overflow: auto;
@ -205,16 +184,16 @@ export default {
margin-top: 20px; margin-top: 20px;
padding: 40px; padding: 40px;
} }
} }
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 10px; width: 10px;
height: 10px; height: 10px;
} }
.draft { .draft {
width: 500px; width: 500px;
text-align: center; text-align: center;
margin: 20px auto; margin: 20px auto;
} }
</style> </style>

View File

@ -1,323 +1,186 @@
<template> <template>
<div class="exam-rule"> <div class="exam-rule">
<span>{{ $t('publish.fullScoreTips') }} {{ examData.fullMark }} {{ $t('publish.scorePoints') }}</span> <span>{{ $t('publish.fullScoreTips') }} {{ examData.fullScore }} {{ $t('publish.scorePoints') }}</span>
<el-button class="addList" size="small" @click="handleAdd">{{ $t('publish.addRules') }}</el-button> <el-button class="addList" size="small" @click="handleAdd">{{ $t('publish.addRules') }}</el-button>
<el-table :data="ruleList" border show-summary style="width: 100%; min-height: 300px;" :summary-method="getSummaries"> <el-table
<el-table-column prop="name" :label="$t('publish.trainingType')"> :data="ruleList"
border
style="width: 100%; min-height: 300px;"
show-summary
:summary-method="getSummaries"
>
<el-table-column prop="type" label="试题类型">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ getOperateName(scope.row) }}</span> <span>{{ types[scope.row.type] }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="num" :label="$t('publish.questionsNumber')" width="100"> <el-table-column prop="subtype" label="规则类型">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.num }}</span> <span>{{ subtypes[scope.row.subtype] }}</span>
<el-tooltip v-if="checkNum(scope.row)" effect="dark" content="题库数量不足" placement="top">
<i class="el-icon-warning-outline"></i>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="point" :label="$t('publish.eachScore')" width="100" /> <el-table-column prop="amount" label="题目数量" width="100">
<template slot-scope="scope">
<span>{{ scope.row.amount }}</span>
</template>
</el-table-column>
<el-table-column prop="score" :label="$t('publish.eachScore')" width="100" />
<el-table-column :label="$t('publish.totalScore')" width="100"> <el-table-column :label="$t('publish.totalScore')" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ Number(scope.row.num) * Number(scope.row.point) }}</span> <span>{{ Number(scope.row.amount) * Number(scope.row.score) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="题库题数"> <el-table-column label="题库题数">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ getTopicNum(scope.row) }}</span> <span>{{ scope.row.topicNum }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('global.operate')" width="100"> <el-table-column :label="$t('global.operate')" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" size="small" @click="handleForm(scope)">{{ $t('global.edit') }}</el-button> <el-button type="text" size="small" @click="editRow(scope)">{{ $t('global.edit') }}</el-button>
<el-button type="text" size="small" @click="deleteForm(scope)">{{ $t('global.delete') }}</el-button> <el-button type="text" size="small" @click="deleteRule(scope)">{{ $t('global.delete') }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<edit-rule <edit-rule @submit="handleRuleSubmit" ref="addRule" />
ref="addRule"
:map-id="examData.mapId"
:operation-type-map="operationTypeMap"
:training-operate-type-map="trainingOperateTypeMap"
:training-type-nums="trainingTypeNums"
:operation-type-nums="operationTypeNums"
:training-type-list="trainingTypeList"
:prd-type="examData.prdType"
@addRuleList="addRuleList"
@editRuleList="editRuleList"
/>
</div> </div>
</template> </template>
<script> <script>
import { createExam, updateExamRule } from '@/api/management/exam'; import editRule from './editRule'
import { UrlConfig, getOperateTypeMap } from '@/scripts/ConstDic';
import editRule from './editRule';
import ConstConfig from '@/scripts/ConstConfig';
import { getTrainingTypeAndNumByMapIdAndPrdType } from '@/api/jmap/training';
export default { export default {
name: 'Rule', name: 'Rule',
components: { components: {
editRule editRule,
}, },
props: { props: {
examData: { examData: {
type: Object, type: Object,
default: null default: null,
}, },
ruleList: { ruleList: {
type: Array, type: Array,
default() { default() {
return []; return []
} },
} },
isEditMode: {
type: Boolean,
},
}, },
data() { data() {
return { return {
typeList: [], currentTotalScore: 0,
operationTypeMap: {}, operationTypeMap: {},
trainingOperateTypeMap: {}, trainingOperateTypeMap: {},
trainingTypeNums:{}, // trainingTypeNums: {}, //
operationTypeNums: {}, // operationTypeNums: {}, //
trainingTypeList: [] // trainingTypeList: [], //
}; }
}, },
computed: { computed: {
types() {
return ['', '理论题', '实训题']
}, },
watch: { subtypes() {
return ['', '单选题', '多选题', '判断题', '单操实训', '场景实训']
}, },
async created() {
getTrainingTypeAndNumByMapIdAndPrdType({ mapId: this.examData.mapId, prdType: this.examData.prdType }).then(res => {
const list = [];
this.trainingTypeNums = {};
const operateTypeMap = {};
this.operationTypeNums = res.data;
let val;
for (val in ConstConfig.ConstSelect.trainingDeviceType) {
if (res.data[val]) {
list.push({ value: val, label: ConstConfig.ConstSelect.trainingDeviceType[val].label, disabled: false});
this.trainingTypeNums[val] = 0;
const operateLabelMap = getOperateTypeMap(val);
operateTypeMap[val] = [];
let item;
for (item in res.data[val]) {
this.trainingTypeNums[val] += res.data[val][item];
operateTypeMap[val].push({ value: item, label:operateLabelMap[item], disabled: false });
}
}
}
this.trainingTypeList = list;
this.operationTypeMap = operateTypeMap;
}).catch(() => {
this.$messageBox(this.$t('publish.refreshFailed'));
});
}, },
watch: {},
created() {},
methods: { methods: {
handleAdd() { handleAdd() {
this.changeCourseDisable(); this.changeCourseDisable()
this.$refs.addRule.show(); this.$refs.addRule.show()
}, },
async creatOk() { handleRuleSubmit(formData, isEdit) {
if (this.ruleList.length) { const data = {
let flag = 0; type: formData.type,
this.ruleList.forEach(rule => { subtype: formData.subtype,
flag = flag + (Number(rule.num) * Number(rule.point)); amount: formData.amount,
}); score: formData.score,
if (flag == this.examData.fullMark) { topicNum: formData.topicNum,
const result = { }
duration: Number(this.examData.duration) * 60, // if (isEdit) {
examDefinitionRulesVOList: this.ruleList, // this.$set(this.ruleList, this.editingIndex, data)
fullPoint: Number(this.examData.fullMark), //
mapId: this.examData.mapId,
prdType: this.examData.prdType,
name: this.examData.name, //
passingPoint: Number(this.examData.passMark), //
remarks: this.examData.desc, //
endTime: this.examData.endDate,
startTime: this.examData.startDate,
type: this.examData.type, //
trial: this.examData.trial == 2 //
};
await this.save(result);
} else { } else {
this.$messageBox(this.$t('publish.addExamRluesError')); this.ruleList.push(data)
}
} else {
this.$messageBox(this.$t('publish.addExamRules'));
} }
}, },
async updateOk() { deleteRule(data) {
if (this.ruleList.length) { const index = data.$index
let flag = 0; this.ruleList.splice(index, 1)
this.ruleList.forEach(rule => {
flag = flag + (Number(rule.num) * Number(rule.point));
});
if (flag == this.examData.fullMark) {
const result = {
id: this.$route.params.ruleId,
duration: Number(this.examData.duration) * 60, //
examDefinitionRulesVOList: this.ruleList, //
fullPoint: Number(this.examData.fullMark), //
mapId: this.examData.mapId,
prdType: this.examData.prdType,
name: this.examData.name, //
passingPoint: Number(this.examData.passMark), //
remarks: this.examData.desc, //
endTime: this.examData.endDate,
startTime: this.examData.startDate,
type: this.examData.type, //
trial: this.examData.trial == 2 //
};
await this.update(result);
} else {
this.$messageBox(this.$t('publish.addExamRluesError'));
}
} else {
this.$messageBox(this.$t('publish.addExamRules'));
}
},
async save(data) {
try {
const res = await createExam(data);
this.$message.success({ message: res.message });
this.$store.dispatch('exam/setRuleList', []); //
const path = `${this.$route.path.match(/(\/.*)\/examRule/)[1]}${UrlConfig.examRuleManage}`;
if (this.$route.query.source === 'org') {
this.$router.go(-1);
} else {
this.$router.replace({ path: `${path}`, query: { mapId: this.$route.query.mapId, noPreLogout: this.$route.query.noPreLogout} });
}
} catch (error) {
this.$messageBox(`${this.$t('publish.saveRuleFailed')} ${error.message}`);
}
},
async update(data) {
try {
const res = await updateExamRule(data);
this.$message.success({ message: res.message });
this.$store.dispatch('exam/setRuleList', []); //
const path = `${this.$route.path.match(/(\/.*)\/examRule/)[1]}${UrlConfig.examRuleManage}`;
if (this.$route.query.source === 'org') {
this.$router.go(-1);
} else {
this.$router.replace({ path: `${path}`, query: { mapId: this.$route.query.mapId, noPreLogout: this.$route.query.noPreLogout} });
}
} catch (error) {
this.$messageBox(`${this.$t('publish.saveRuleFailed')} ${error.message}`);
}
},
addRuleList(data) {
const element = {
trainingType: data.trainingType,
operateType: data.operateType,
num: Number(data.number),
point: Number(data.mark)
};
this.ruleList.push(element);
},
deleteForm(data) {
const index = data.$index;
this.ruleList.splice(index, 1);
},
editRuleList(data) {
const element = {
trainingType: data.trainingType,
operateType: data.operateType,
num: Number(data.number),
point: Number(data.mark)
};
this.$set(this.ruleList, this.indexCourse, element);
}, },
// //
changeCourseDisable() { changeCourseDisable() {
this.trainingTypeList.forEach(item => { item.disabled = false; }); this.trainingTypeList.forEach(item => {
item.disabled = false
})
for (const val in this.operationTypeMap) { for (const val in this.operationTypeMap) {
this.operationTypeMap[val].forEach( item => { item.disabled = false; }); this.operationTypeMap[val].forEach(item => {
item.disabled = false
})
} }
this.ruleList.forEach(ele => { this.ruleList.forEach(ele => {
this.trainingTypeList.forEach(item => { this.trainingTypeList.forEach(item => {
if (ele.trainingType == item.value && !ele.operateType) { if (ele.trainingType == item.value && !ele.operateType) {
item.disabled = true; item.disabled = true
} }
}); })
(this.operationTypeMap[ele.trainingType] || []).forEach(item => { ;(this.operationTypeMap[ele.trainingType] || []).forEach(item => {
if (ele.operateType && ele.operateType == item.value) { if (ele.operateType && ele.operateType == item.value) {
item.disabled = true; item.disabled = true
} }
}); })
}); })
}, },
getOperateName(row) { checkTotolScores() {
const trainingName = ConstConfig.ConstSelect.trainingDeviceType[row.trainingType].label; console.log(this.currentTotalScore === this.examData.fullScore)
if (row.operateType) { return this.currentTotalScore === this.examData.fullScore
const operateName = getOperateTypeMap(row.trainingType)[row.operateType];
return `${trainingName}-${operateName}`;
} else {
return trainingName;
}
}, },
getTopicNum(row) { editRow(data) {
//this.operationTypeNums this.changeCourseDisable()
//console.log(row, this.operationTypeNums); this.editingIndex = data.$index
return this.operationTypeNums[row.trainingType] ? (this.operationTypeNums[row.trainingType][row.operateType]||0): 0; const list = JSON.stringify(data.row)
}, const detail = JSON.parse(list)
checkNum(row) { this.$refs.addRule.show(detail)
if(!this.operationTypeNums[row.trainingType]) {
return true;
} else if(!this.operationTypeNums[row.trainingType][row.operateType]){
return true;
} else if(row.num > this.operationTypeNums[row.trainingType][row.operateType]) {
return true;
} else {
return false;
}
},
handleForm(data) {
this.changeCourseDisable();
this.indexCourse = data.$index;
const list = JSON.stringify(data.row);
const detail = JSON.parse(list);
this.$refs.addRule.show(detail);
},
regulation() {
this.$emit('regulation', this.course);
}, },
getSummaries({ columns, data }) { getSummaries({ columns, data }) {
const sums = []; const sums = []
columns.forEach((column, index) => { columns.forEach((column, index) => {
if (index === 0) { if (index === 0) {
sums[index] = '合计'; sums[index] = '合计'
return; return
} else if (index === 1) { } else if (index === 2) {
const values = data.map(item => Number(item.num)); const values = data.map(item => Number(item.amount))
sums[1] = values.reduce((prev, curr) => { sums[2] = values.reduce((prev, curr) => {
const value = Number(curr); const value = Number(curr)
if (!isNaN(value)) { if (!isNaN(value)) {
return prev + curr; return prev + curr
} else { } else {
return prev; return prev
} }
}, 0); }, 0)
} else if ( index === 3) { } else if (index === 4) {
const values = data.map(item => Number(item.num) * Number(item.point)); const values = data.map(item => Number(item.amount) * Number(item.score))
sums[3] = values.reduce((prev, curr) => { this.currentTotalScore = sums[4] = values.reduce((prev, curr) => {
const value = Number(curr); const value = Number(curr)
if (!isNaN(value)) { if (!isNaN(value)) {
return prev + curr; return prev + curr
} else { } else {
return prev; return prev
} }
}, 0) + '分'; }, 0)
} }
}); })
return sums; return sums
} },
} },
}; }
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
.exam-rule { .exam-rule {
.addList { .addList {
float: right; float: right;
font-size: 14px; font-size: 14px;
@ -338,5 +201,5 @@ export default {
font-size: 0; font-size: 0;
} }
} }
} }
</style> </style>

View File

@ -276,7 +276,8 @@ export default {
}, },
publicList(index, row) { publicList(index, row) {
this.$router.push({ path: `/publish/map/detail`, query: { mapId: row.id } }); // this.$router.push({ path: `/publish/map/detail`, query: { mapId: row.id } });
this.$router.push({ path: `/systemManagement/lineDataManage/PublishMapDetail`, query: { mapId: row.id } });
}, },
handlePutaway(index, row) { handlePutaway(index, row) {