This commit is contained in:
2025-07-11 09:27:36 +08:00
parent 76966a4f76
commit b0e5ceb44f
2 changed files with 65 additions and 176 deletions

View File

@ -17,10 +17,10 @@
</router-link> </router-link>
</scroll-pane> </scroll-pane>
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu"> <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="refreshSelectedTag(selectedTag)">Refresh</li> <li @click="refreshSelectedTag(selectedTag)">刷新</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">Close</li> <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭</li>
<li @click="closeOthersTags">Close Others</li> <li @click="closeOthersTags">关闭其他</li>
<li @click="closeAllTags(selectedTag)">Close All</li> <li @click="closeAllTags(selectedTag)">关闭所有</li>
</ul> </ul>
</div> </div>
</template> </template>

View File

@ -1,202 +1,113 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<h3>组卷信息</h3> <h3>组卷信息</h3>
<el-card style="margin-top: 20px"> <el-card style="margin-top: 20px">
<div style="float: right; font-weight: bold; color: #ff0000">试卷总分{{ postForm.totalScore }}</div> <div style="float: right; font-weight: bold; color: #ff0000">试卷总分{{ postForm.totalScore }}</div>
<div> <div>
<el-button class="filter-item" size="small" type="primary" icon="el-icon-plus" @click="handleAdd"> <el-button class="filter-item" size="small" type="primary" icon="el-icon-plus" @click="handleAdd">
添加题库 添加题库
</el-button> </el-button>
<el-table :data="repoList" :border="false" empty-text="请点击上面的`添加题库`进行设置" style="width: 100%; margin-top: 15px">
<el-table <el-table-column label="题库" width="200">
:data="repoList"
:border="false"
empty-text="请点击上面的`添加题库`进行设置"
style="width: 100%; margin-top: 15px"
>
<el-table-column
label="题库"
width="200"
>
<template v-slot="scope"> <template v-slot="scope">
<repo-select <repo-select v-model="scope.row.repoId" :multi="false" :excludes="excludes"
v-model="scope.row.repoId"
:multi="false"
:excludes="excludes"
@change="repoChange($event, scope.row)" /> @change="repoChange($event, scope.row)" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column label="单选数量" align="center">
label="单选数量"
align="center"
>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number v-model="scope.row.radioCount" :min="0" :max="scope.row.totalRadio" :controls="false" style="width: 100px" /> / {{ scope.row.totalRadio }} <el-input-number v-model="scope.row.radioCount" :min="0" :max="scope.row.totalRadio" :controls="false"
style="width: 100px" /> / {{ scope.row.totalRadio }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="单选分数" align="center">
<el-table-column
label="单选分数"
align="center"
>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number v-model="scope.row.radioScore" :min="0" :controls="false" style="width: 100%" /> <el-input-number v-model="scope.row.radioScore" :min="0" :controls="false" style="width: 100%" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="多选数量" align="center">
<el-table-column
label="多选数量"
align="center"
>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number v-model="scope.row.multiCount" :min="0" :max="scope.row.totalMulti" :controls="false" style="width: 100px" /> / {{ scope.row.totalMulti }} <el-input-number v-model="scope.row.multiCount" :min="0" :max="scope.row.totalMulti" :controls="false"
style="width: 100px" /> / {{ scope.row.totalMulti }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="多选分数" align="center">
<el-table-column
label="多选分数"
align="center"
>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number v-model="scope.row.multiScore" :min="0" :controls="false" style="width: 100%" /> <el-input-number v-model="scope.row.multiScore" :min="0" :controls="false" style="width: 100%" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="判断题数量" align="center">
<el-table-column
label="判断题数量"
align="center"
>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number v-model="scope.row.judgeCount" :min="0" :max="scope.row.totalJudge" :controls="false" style="width: 100px" /> / {{ scope.row.totalJudge }} <el-input-number v-model="scope.row.judgeCount" :min="0" :max="scope.row.totalJudge" :controls="false"
style="width: 100px" /> / {{ scope.row.totalJudge }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="判断题分数" align="center">
<el-table-column
label="判断题分数"
align="center"
>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number v-model="scope.row.judgeScore" :min="0" :controls="false" style="width: 100%" /> <el-input-number v-model="scope.row.judgeScore" :min="0" :controls="false" style="width: 100%" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="删除" align="center" width="80px">
<el-table-column
label="删除"
align="center"
width="80px"
>
<template v-slot="scope"> <template v-slot="scope">
<el-button type="danger" icon="el-icon-delete" circle @click="removeItem(scope.$index)" /> <el-button type="danger" icon="el-icon-delete" circle @click="removeItem(scope.$index)" />
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
</el-card> </el-card>
<h3>考试配置</h3> <h3>考试配置</h3>
<el-card style="margin-top: 20px"> <el-card style="margin-top: 20px">
<el-form ref="postForm" :model="postForm" :rules="rules" label-position="left" label-width="120px"> <el-form ref="postForm" :model="postForm" :rules="rules" label-position="left" label-width="120px">
<el-form-item label="考试名称" prop="title"> <el-form-item label="考试名称" prop="title">
<el-input v-model="postForm.title" /> <el-input v-model="postForm.title" />
</el-form-item> </el-form-item>
<el-form-item label="考试描述" prop="content"> <el-form-item label="考试描述" prop="content">
<el-input v-model="postForm.content" type="textarea" /> <el-input v-model="postForm.content" type="textarea" />
</el-form-item> </el-form-item>
<el-form-item label="总分数" prop="totalScore"> <el-form-item label="总分数" prop="totalScore">
<el-input-number :value="postForm.totalScore" disabled /> <el-input-number :value="postForm.totalScore" disabled />
</el-form-item> </el-form-item>
<el-form-item label="及格分" prop="qualifyScore"> <el-form-item label="及格分" prop="qualifyScore">
<el-input-number v-model="postForm.qualifyScore" :max="postForm.totalScore" /> <el-input-number v-model="postForm.qualifyScore" :max="postForm.totalScore" />
</el-form-item> </el-form-item>
<el-form-item label="考试费用" prop="examFee">
<el-input-number v-model="postForm.examFee" :min="0"/>
</el-form-item>
<el-form-item label="考试时长(分钟)" prop="totalTime"> <el-form-item label="考试时长(分钟)" prop="totalTime">
<el-input-number v-model="postForm.totalTime" /> <el-input-number v-model="postForm.totalTime" />
</el-form-item> </el-form-item>
<el-form-item label="是否限时"> <el-form-item label="是否限时">
<el-checkbox v-model="postForm.timeLimit" /> <el-checkbox v-model="postForm.timeLimit" />
</el-form-item> </el-form-item>
<el-form-item v-if="postForm.timeLimit" label="考试日期" required>
<el-form-item v-if="postForm.timeLimit" label="考试时间" prop="totalTime"> <el-date-picker v-model="dateValues" format="yyyy-MM-dd" value-format="yyyy-MM-dd" type="daterange"
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" />
<el-date-picker </el-form-item>
v-model="dateValues" <el-form-item v-if="postForm.timeLimit" label="考试时间" required>
format="yyyy-MM-dd" <el-time-picker is-range v-model="timeValues" range-separator="" start-placeholder="开始时间"
value-format="yyyy-MM-dd" end-placeholder="结束时间" value-format="HH:mm" format="HH:mm" placeholder="选择时间范围">
type="daterange" </el-time-picker>
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
<h3>权限配置</h3> <h3>权限配置</h3>
<el-card style="margin-top: 20px;"> <el-card style="margin-top: 20px;">
<el-radio-group v-model="postForm.openType" style="margin-bottom: 20px"> <el-radio-group v-model="postForm.openType" style="margin-bottom: 20px">
<el-radio :label="1" border>完全公开</el-radio> <el-radio :label="1" border>完全公开</el-radio>
<el-radio :label="2" border>部门开放</el-radio> <el-radio :label="2" border>部门开放</el-radio>
</el-radio-group> </el-radio-group>
<el-alert v-if="postForm.openType === 1" title="开放的,任何人都可以进行考试!" type="warning" />
<el-alert
v-if="postForm.openType===1"
title="开放的,任何人都可以进行考试!"
type="warning"
/>
<div v-if="postForm.openType === 2"> <div v-if="postForm.openType === 2">
<el-input <el-input v-model="filterText" placeholder="输入关键字进行过滤" />
v-model="filterText" <el-tree v-loading="treeLoading" ref="tree" :data="treeData" :default-checked-keys="postForm.departIds"
placeholder="输入关键字进行过滤" :props="defaultProps" :filter-node-method="filterNode" empty-text=" " default-expand-all show-checkbox
/> node-key="id" @check-change="handleCheckChange" />
<el-tree
v-loading="treeLoading"
ref="tree"
:data="treeData"
:default-checked-keys="postForm.departIds"
:props="defaultProps"
:filter-node-method="filterNode"
empty-text=" "
default-expand-all
show-checkbox
node-key="id"
@check-change="handleCheckChange"
/>
</div> </div>
</el-card> </el-card>
<div style="margin-top: 20px"> <div style="margin-top: 20px">
<el-button type="primary" @click="handleSave">保存</el-button> <el-button type="primary" @click="handleSave">保存</el-button>
</div> </div>
</div> </div>
</template> </template>
@ -210,7 +121,6 @@ export default {
components: { RepoSelect }, components: { RepoSelect },
data() { data() {
return { return {
treeData: [], treeData: [],
defaultProps: { defaultProps: {
label: 'deptName' label: 'deptName'
@ -218,6 +128,7 @@ export default {
filterText: '', filterText: '',
treeLoading: false, treeLoading: false,
dateValues: [], dateValues: [],
timeValues: undefined,
// //
repoList: [], repoList: [],
// //
@ -230,33 +141,35 @@ export default {
// //
openType: 1, openType: 1,
// //
departIds: [] departIds: [],
startDate: '',
endDate: '',
startTime: '',
endTime: '',
examFee: undefined,
}, },
rules: { rules: {
title: [ title: [
{ required: true, message: '考试名称不能为空!' } { required: true, message: '考试名称不能为空!' }
], ],
examFee: [
{ required: true, message: '考试费用不能为空!' }
],
content: [ content: [
{ required: true, message: '考试名称不能为空!' } { required: true, message: '考试名称不能为空!' }
], ],
open: [ open: [
{ required: true, message: '考试权限不能为空!' } { required: true, message: '考试权限不能为空!' }
], ],
totalScore: [ totalScore: [
{ required: true, message: '考试分数不能为空!' } { required: true, message: '考试分数不能为空!' }
], ],
qualifyScore: [ qualifyScore: [
{ required: true, message: '及格分不能为空!' } { required: true, message: '及格分不能为空!' }
], ],
totalTime: [ totalTime: [
{ required: true, message: '考试时间不能为空!' } { required: true, message: '考试时间不能为空!' }
], ],
ruleId: [ ruleId: [
{ required: true, message: '考试规则不能为空' } { required: true, message: '考试规则不能为空' }
], ],
@ -266,24 +179,24 @@ export default {
} }
} }
}, },
watch: { watch: {
filterText(val) { filterText(val) {
this.$refs.tree.filter(val) this.$refs.tree.filter(val)
}, },
dateValues: { dateValues: {
handler() { handler() {
this.postForm.startTime = this.dateValues[0] this.postForm.startDate = this.dateValues[0]
this.postForm.endTime = this.dateValues[1] this.postForm.endDate = this.dateValues[1]
}
},
timeValues: {
handler() {
this.postForm.startTime = this.timeValues[0]
this.postForm.endTime = this.timeValues[1]
} }
}, },
// //
repoList: { repoList: {
handler(val) { handler(val) {
let totalScore = 0 let totalScore = 0
this.excludes = [] this.excludes = []
@ -292,17 +205,14 @@ export default {
if (item.radioCount > 0 && item.radioScore > 0) { if (item.radioCount > 0 && item.radioScore > 0) {
totalScore += item.radioCount * item.radioScore totalScore += item.radioCount * item.radioScore
} }
if (item.multiCount > 0 && item.multiScore > 0) { if (item.multiCount > 0 && item.multiScore > 0) {
totalScore += item.multiCount * item.multiScore totalScore += item.multiCount * item.multiScore
} }
if (item.judgeCount > 0 && item.judgeScore > 0) { if (item.judgeCount > 0 && item.judgeScore > 0) {
totalScore += item.judgeCount * item.judgeScore totalScore += item.judgeCount * item.judgeScore
} }
this.excludes.push(item.id) this.excludes.push(item.id)
} }
// //
this.postForm.totalScore = totalScore this.postForm.totalScore = totalScore
this.postForm.repoList = val this.postForm.repoList = val
@ -310,26 +220,22 @@ export default {
}, },
deep: true deep: true
} }
}, },
created() { created() {
const id = this.$route.params.id const id = this.$route.params.id
if (typeof id !== undefined) { if (typeof id !== undefined) {
this.fetchData(id) this.fetchData(id)
} }
fetchTree({}).then(response => { fetchTree({}).then(response => {
this.treeData = response.data this.treeData = response.data
}) })
}, },
methods: { methods: {
handleSave() { handleSave() {
this.$refs.postForm.validate((valid) => { this.$refs.postForm.validate((valid) => {
if (!valid) { if (!valid) {
return return
} }
if (this.postForm.totalScore === 0) { if (this.postForm.totalScore === 0) {
this.$notify({ this.$notify({
title: '提示信息', title: '提示信息',
@ -337,10 +243,8 @@ export default {
type: 'warning', type: 'warning',
duration: 2000 duration: 2000
}) })
return return
} }
for (let i = 0; i < this.postForm.repoList.length; i++) { for (let i = 0; i < this.postForm.repoList.length; i++) {
const repo = this.postForm.repoList[i] const repo = this.postForm.repoList[i]
if (!repo.repoId) { if (!repo.repoId) {
@ -352,7 +256,6 @@ export default {
}) })
return return
} }
if ((repo.radioCount > 0 && repo.radioScore === 0) || (repo.radioCount === 0 && repo.radioScore > 0)) { if ((repo.radioCount > 0 && repo.radioScore === 0) || (repo.radioCount === 0 && repo.radioScore > 0)) {
this.$notify({ this.$notify({
title: '提示信息', title: '提示信息',
@ -360,10 +263,8 @@ export default {
type: 'warning', type: 'warning',
duration: 2000 duration: 2000
}) })
return return
} }
if ((repo.multiCount > 0 && repo.multiScore === 0) || (repo.multiCount === 0 && repo.multiScore > 0)) { if ((repo.multiCount > 0 && repo.multiScore === 0) || (repo.multiCount === 0 && repo.multiScore > 0)) {
this.$notify({ this.$notify({
title: '提示信息', title: '提示信息',
@ -371,10 +272,8 @@ export default {
type: 'warning', type: 'warning',
duration: 2000 duration: 2000
}) })
return return
} }
if ((repo.judgeCount > 0 && repo.judgeScore === 0) || (repo.judgeCount === 0 && repo.judgeScore > 0)) { if ((repo.judgeCount > 0 && repo.judgeScore === 0) || (repo.judgeCount === 0 && repo.judgeScore > 0)) {
this.$notify({ this.$notify({
title: '提示信息', title: '提示信息',
@ -385,7 +284,6 @@ export default {
return return
} }
} }
this.$confirm('确实要提交保存吗?', '提示', { this.$confirm('确实要提交保存吗?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
@ -395,7 +293,6 @@ export default {
}) })
}) })
}, },
handleCheckChange() { handleCheckChange() {
const that = this const that = this
// //
@ -405,32 +302,30 @@ export default {
that.postForm.departIds.push(item.id) that.postForm.departIds.push(item.id)
}) })
}, },
// //
handleAdd() { handleAdd() {
this.repoList.push({ id: '', rowId: new Date().getTime(), radioCount: 0, radioScore: 0, multiCount: 0, multiScore: 0, judgeCount: 0, judgeScore: 0, saqCount: 0, saqScore: 0 }) this.repoList.push({ id: '', rowId: new Date().getTime(), radioCount: 0, radioScore: 0, multiCount: 0, multiScore: 0, judgeCount: 0, judgeScore: 0, saqCount: 0, saqScore: 0 })
}, },
removeItem(index) { removeItem(index) {
this.repoList.splice(index, 1) this.repoList.splice(index, 1)
}, },
fetchData(id) { fetchData(id) {
fetchDetail(id).then(response => { fetchDetail(id).then(response => {
this.postForm = response.data this.postForm = response.data
if (this.postForm.startDate && this.postForm.endDate) {
this.dateValues[0] = this.postForm.startDate
this.dateValues[1] = this.postForm.endDate
}
if (this.postForm.startTime && this.postForm.endTime) { if (this.postForm.startTime && this.postForm.endTime) {
this.dateValues[0] = this.postForm.startTime this.timeValues[0] = this.postForm.startTime
this.dateValues[1] = this.postForm.endTime this.timeValues[1] = this.postForm.endTime
} }
this.repoList = this.postForm.repoList this.repoList = this.postForm.repoList
}) })
}, },
submitForm() { submitForm() {
// //
this.postForm.repoList = this.repoList this.postForm.repoList = this.repoList
saveData(this.postForm).then(() => { saveData(this.postForm).then(() => {
this.$notify({ this.$notify({
title: '成功', title: '成功',
@ -438,20 +333,16 @@ export default {
type: 'success', type: 'success',
duration: 2000 duration: 2000
}) })
this.$router.push({ name: 'ListExam' }) this.$router.push({ name: 'ListExam' })
}) })
}, },
filterNode(value, data) { filterNode(value, data) {
if (!value) return true if (!value) return true
return data.deptName.indexOf(value) !== -1 return data.deptName.indexOf(value) !== -1
}, },
repoChange(e, row) { repoChange(e, row) {
// ID // ID
row.id = e.id row.id = e.id
if (e != null) { if (e != null) {
row.totalRadio = e.radioCount row.totalRadio = e.radioCount
row.totalMulti = e.multiCount row.totalMulti = e.multiCount
@ -462,8 +353,6 @@ export default {
row.totalJudge = 0 row.totalJudge = 0
} }
} }
} }
} }
</script> </script>