Accept Merge Request #109: (hyc -> master)
Merge Request: 【修改】试题审核出题页面 Created By: @华允传 Accepted By: @华允传 URL: https://g-iswv8783.coding.net/p/education/d/pengchen-ui-exam-vue3/git/merge/109?initial=true
This commit is contained in:
@@ -16,48 +16,103 @@
|
|||||||
<el-input v-model="formData.specialtyName" placeholder="请输入专业" disabled/>
|
<el-input v-model="formData.specialtyName" placeholder="请输入专业" disabled/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<!-- <el-col :span="12">
|
||||||
|
<el-form-item label="试题名称" prop="quBankName">
|
||||||
|
<el-input v-model="formData.quBankName" placeholder="请试题名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col> -->
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="章节名称" prop="chapteridDictText">
|
||||||
|
<el-input v-model="formData.chapteridDictTextVo" placeholder="请输入章节名称" disabled/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
<!-- <el-col :span="12">
|
||||||
|
<el-form-item label="题库" prop="required">
|
||||||
|
<el-input v-model="formData.required" placeholder="请选择题库" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col> -->
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
<el-form-item label="课程" prop="courseName">
|
<el-form-item label="课程" prop="courseName">
|
||||||
<el-input v-model="formData.courseName" placeholder="请输入课程" disabled/>
|
<el-input v-model="formData.courseName" placeholder="请输入课程" disabled/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="题型难度" prop="quLevel">
|
<el-form-item label="题型难度" prop="quLevel">
|
||||||
<el-input v-model="formData.quLevel" placeholder="请输入题型难度" disabled/>
|
<el-select
|
||||||
</el-form-item>
|
v-model="formData.quLevel"
|
||||||
</el-col>
|
placeholder="请选择题型难度"
|
||||||
<el-col :span="12">
|
clearable
|
||||||
<el-form-item label="章节名称" prop="chapteridDictText">
|
>
|
||||||
<el-input v-model="formData.chapteridDictText" placeholder="请输入章节名称" disabled />
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.EXAM_QUE_DIFF)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="知识点" prop="pointNames">
|
|
||||||
<el-input v-model="formData.pointNames" placeholder="请输入知识点" disabled/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="题型" prop="subjectName">
|
<el-form-item label="题型" prop="subjectName">
|
||||||
<el-input v-model="formData.subjectName" placeholder="请输入题型" disabled/>
|
<el-input v-model="formData.subjectName" placeholder="请输入题型" disabled/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="知识点" prop="pointNames">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.pointNamesVo"
|
||||||
|
placeholder="请选择知识点"
|
||||||
|
readonly
|
||||||
|
@click="openPoints()"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisiblePoints" title="选择知识点" width="30%">
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="deptList"
|
||||||
|
node-key="id"
|
||||||
|
:props="{ label: 'name', children: 'children' }"
|
||||||
|
highlight-current
|
||||||
|
default-expand-all
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- <el-col :span="12">
|
||||||
|
<el-form-item label="审核状态" prop="audit">
|
||||||
|
<el-input v-model="formData.audit" placeholder="请输入审核状态" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col> -->
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="启用状态" prop="status">
|
<el-form-item label="启用状态" prop="status">
|
||||||
<el-radio-group v-model="formData.status">
|
<el-radio-group v-model="formData.status">
|
||||||
<el-radio :label="'0'">启用</el-radio>
|
<el-radio :label="'0'">启用</el-radio>
|
||||||
<el-radio :label="'1'">禁用</el-radio>
|
<el-radio :label="'1'">禁用</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<!-- <el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="来源" prop="resourceValue">
|
||||||
|
<el-input v-model="formData.resourceValue" placeholder="请输入来源" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row> -->
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
<div class="edit-left bottom-common">
|
<div class="edit-left bottom-common">
|
||||||
@@ -256,7 +311,8 @@
|
|||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { FormRules } from 'element-plus'
|
import { FormRules } from 'element-plus'
|
||||||
import * as QuestionApi from '@/api/paper/question'
|
import * as QuestionApi from '@/api/paper/question'
|
||||||
|
import * as SpecialtyApi from '@/api/points'
|
||||||
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
defineOptions({ name: 'ChoiceForm' })
|
defineOptions({ name: 'ChoiceForm' })
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
@@ -267,6 +323,8 @@ const dialogTitle = ref('') // 弹窗的标题
|
|||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
|
pointNamesVo:'',
|
||||||
|
chapteridDictTextVo:'',
|
||||||
content: '',
|
content: '',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
@@ -274,7 +332,7 @@ const formData = ref({
|
|||||||
required: '',
|
required: '',
|
||||||
chapteridDictText: '',
|
chapteridDictText: '',
|
||||||
analysis: '',
|
analysis: '',
|
||||||
quLevel: '',
|
quLevel: 0,
|
||||||
pointNames: '',
|
pointNames: '',
|
||||||
audit: '',
|
audit: '',
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
@@ -349,12 +407,9 @@ const open = async (queryParams: any ,type: string, id?: number) => {
|
|||||||
dialogTitle.value = t('action.' + type)
|
dialogTitle.value = t('action.' + type)
|
||||||
formType.value = type
|
formType.value = type
|
||||||
resetForm()
|
resetForm()
|
||||||
console.log(id+"idid")
|
|
||||||
|
|
||||||
// 修改时,设置数据
|
// 修改时,设置数据
|
||||||
if (id) {
|
if (id) {
|
||||||
|
|
||||||
|
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
formData.value = await QuestionApi.getQuestionnotId(id)
|
formData.value = await QuestionApi.getQuestionnotId(id)
|
||||||
@@ -422,10 +477,8 @@ const submitForm = async () => {
|
|||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value as unknown
|
const data = formData.value as unknown
|
||||||
|
await QuestionApi.editQuestionNoAudit(data)
|
||||||
await QuestionApi.editQuestionNoAudit(data)
|
message.success(t('common.updateSuccess'))
|
||||||
message.success(t('common.updateSuccess'))
|
|
||||||
|
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
// 发送操作成功的事件
|
// 发送操作成功的事件
|
||||||
emit('success')
|
emit('success')
|
||||||
@@ -444,21 +497,66 @@ const resetForm = () => {
|
|||||||
required: '',
|
required: '',
|
||||||
chapteridDictText: '',
|
chapteridDictText: '',
|
||||||
analysis: '',
|
analysis: '',
|
||||||
quLevel: '',
|
quLevel: 0,
|
||||||
pointNames: '',
|
pointNames: '',
|
||||||
audit: '',
|
audit: '',
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
status: '',
|
status: '',
|
||||||
resourceValue: '',
|
resourceValue: ''
|
||||||
|
|
||||||
}
|
}
|
||||||
radio.value = 'A',
|
|
||||||
// 清空 optionsContent 的属性
|
|
||||||
Object.keys(optionsContent).forEach(key => {
|
|
||||||
delete optionsContent[key]
|
|
||||||
})
|
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const dialogVisiblePoints = ref(false)
|
||||||
|
const openPoints = async () => {
|
||||||
|
await getTree();
|
||||||
|
dialogVisiblePoints.value = true;
|
||||||
|
}
|
||||||
|
// 只允许点击第三级节点
|
||||||
|
const treeRef = ref() // 引用 el-tree
|
||||||
|
const handleNodeClick = (data, node) => {
|
||||||
|
if (data.level === 3) {
|
||||||
|
formData.value.pointNames = data.id
|
||||||
|
formData.value.pointNamesVo = data.name
|
||||||
|
|
||||||
|
// 获取父节点(章节名称)
|
||||||
|
const currentNode = treeRef.value.getNode(data)
|
||||||
|
const parentNode = currentNode.parent
|
||||||
|
if (parentNode && parentNode.data) {
|
||||||
|
formData.value.chapteridDictTextVo = parentNode.data.name
|
||||||
|
formData.value.chapteridDictText = parentNode.data.id
|
||||||
|
} else {
|
||||||
|
formData.value.chapteridDictText = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogVisiblePoints.value = false
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const deptList = ref<Tree[]>([]) // 树形结构
|
||||||
|
/** 获得部门树 */
|
||||||
|
const getTree = async () => {
|
||||||
|
const res = await SpecialtyApi.listPoints()
|
||||||
|
const tree = handleTree(res)
|
||||||
|
deptList.value = []
|
||||||
|
deptList.value = handleTreeWithLevel(tree)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 添加层级信息
|
||||||
|
const handleTreeWithLevel = (list, level = 1) => {
|
||||||
|
return list.map(item => {
|
||||||
|
const node = { ...item, level }
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
node.children = handleTreeWithLevel(item.children, level + 1)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.edit-dialog {
|
.edit-dialog {
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
<el-input v-model="formData.specialtyName" placeholder="请输入专业" disabled/>
|
<el-input v-model="formData.specialtyName" placeholder="请输入专业" disabled/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="知识点" prop="pointNames">
|
<el-col :span="12">
|
||||||
<el-input v-model="formData.pointNames" placeholder="请输入知识点" disabled/>
|
<el-form-item label="章节名称" prop="chapteridDictText">
|
||||||
|
<el-input v-model="formData.chapteridDictTextVo" placeholder="请输入章节名称" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -33,19 +34,20 @@
|
|||||||
<el-input v-model="formData.quLevel" placeholder="请输入题型难度" />
|
<el-input v-model="formData.quLevel" placeholder="请输入题型难度" />
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
|
|
||||||
<el-form-item label="题型难度" prop="quLevel">
|
<el-form-item label="题型难度" prop="quLevel">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.quLevel"
|
v-model="formData.quLevel"
|
||||||
placeholder="请选择题型难度"
|
placeholder="请选择题型难度"
|
||||||
clearable
|
clearable
|
||||||
>
|
>
|
||||||
<el-option label="简单" :value="'0'" />
|
<el-option
|
||||||
<el-option label="一般" :value="'1'" />
|
v-for="dict in getIntDictOptions(DICT_TYPE.EXAM_QUE_DIFF)"
|
||||||
<el-option label="困难" :value="'2'" />
|
:key="dict.value"
|
||||||
</el-select>
|
:label="dict.label"
|
||||||
</el-form-item>
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
@@ -58,10 +60,27 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="章节名称" prop="chapteridDictText">
|
<el-form-item label="知识点" prop="pointNames">
|
||||||
<el-input v-model="formData.chapteridDictText" placeholder="请输入章节名称" disabled />
|
<el-input
|
||||||
|
v-model="formData.pointNamesVo"
|
||||||
|
placeholder="请选择知识点"
|
||||||
|
readonly
|
||||||
|
@click="openPoints()"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisiblePoints" title="选择知识点" width="30%">
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="deptList"
|
||||||
|
node-key="id"
|
||||||
|
:props="{ label: 'name', children: 'children' }"
|
||||||
|
highlight-current
|
||||||
|
default-expand-all
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
@@ -173,7 +192,7 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<el-table-column type="index" label="序号" width="60" />
|
<el-table-column type="index" label="序号" width="60" />
|
||||||
<el-table-column prop="score" label="权值" width="60" />
|
<el-table-column prop="scoreRate" label="权值" width="60" />
|
||||||
<el-table-column prop="content" label="考点语句" width="800" />
|
<el-table-column prop="content" label="考点语句" width="800" />
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
@@ -185,21 +204,30 @@
|
|||||||
width="60%"
|
width="60%"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
class="custom-dialog"
|
class="custom-dialog"
|
||||||
|
draggable
|
||||||
>
|
>
|
||||||
<!-- 可滚动容器 -->
|
<!-- 可滚动容器 -->
|
||||||
<div style="height: 400px; overflow-y: auto;">
|
<div style="height: 400px; overflow-y: auto;width:100%;">
|
||||||
<el-table
|
<el-table
|
||||||
:data="kaodianList"
|
:data="kaodianList"
|
||||||
style="width: 100%;"
|
style="width: 100%; "
|
||||||
row-key="answerId"
|
row-key="answerId"
|
||||||
:default-expand-all="false"
|
:default-expand-all="false"
|
||||||
@row-contextmenu="(row, column, event) => handleTextRightClick(event, row)"
|
@row-contextmenu="(row, column, event) => handleTextRightClick(event, row)"
|
||||||
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<el-table-column type="index" label="序号" width="60" />
|
<el-table-column type="index" label="序号" />
|
||||||
<el-table-column prop="score" label="权值" width="60" />
|
<el-table-column label="权值" width="80">
|
||||||
<el-table-column prop="content" label="考点语句" width="600" />
|
<template #default="{ row }">
|
||||||
|
<el-input
|
||||||
|
v-model="row.scoreRate"
|
||||||
|
size="small"
|
||||||
|
placeholder="请输入"
|
||||||
|
style="width: 100%;"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="content" label="考点语句" />
|
||||||
|
|
||||||
<!-- 展开行 -->
|
<!-- 展开行 -->
|
||||||
<el-table-column type="expand">
|
<el-table-column type="expand">
|
||||||
@@ -218,7 +246,8 @@
|
|||||||
v-model="scope.row.scoreRate"
|
v-model="scope.row.scoreRate"
|
||||||
size="small"
|
size="small"
|
||||||
style="width: 70px;"
|
style="width: 70px;"
|
||||||
@input="updateScore(props.row)"
|
min="0"
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -272,67 +301,12 @@
|
|||||||
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<!-- <el-tab-pane name="medium">
|
|
||||||
<template #label>
|
|
||||||
<div class="custom-tabs-label">
|
|
||||||
<p>媒体文件</p>
|
|
||||||
<el-dropdown>
|
|
||||||
<span class="el-dropdown-link" @click.stop="false">
|
|
||||||
<div class="setting_icon"></div>
|
|
||||||
</span>
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu>
|
|
||||||
<el-dropdown-item>
|
|
||||||
<el-upload
|
|
||||||
v-model:file-list="fileList"
|
|
||||||
class="upload-demo"
|
|
||||||
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
|
|
||||||
>
|
|
||||||
<el-button>导入</el-button>
|
|
||||||
</el-upload>
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item>导出</el-dropdown-item>
|
|
||||||
<el-dropdown-item>播放</el-dropdown-item>
|
|
||||||
<el-dropdown-item>编辑</el-dropdown-item>
|
|
||||||
<el-dropdown-item>删除选中</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="block">
|
|
||||||
<el-table
|
|
||||||
:data="mediumList"
|
|
||||||
style="width: 100%"
|
|
||||||
@selection-change="handleMediumSelectionChange"
|
|
||||||
>
|
|
||||||
<el-table-column type="index" width="50" />
|
|
||||||
<el-table-column type="selection" width="55" />
|
|
||||||
<el-table-column prop="type" label="媒体类型" width="80" />
|
|
||||||
<el-table-column prop="title" label="标题" />
|
|
||||||
<el-table-column prop="displayIndex" label="显示序号" />
|
|
||||||
<el-table-column prop="size" label="大小" />
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
</el-tab-pane> -->
|
|
||||||
<el-tab-pane name="annex">
|
<el-tab-pane name="annex">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="custom-tabs-label">
|
<div class="custom-tabs-label">
|
||||||
<p>试题附件</p>
|
<p>试题附件</p>
|
||||||
<!-- <el-dropdown>
|
|
||||||
<span class="el-dropdown-link" @click.stop="false">
|
|
||||||
<div class="setting_icon"></div>
|
|
||||||
</span>
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu>
|
|
||||||
<el-dropdown-item>导入单文件</el-dropdown-item>
|
|
||||||
<el-dropdown-item>导入多文件</el-dropdown-item>
|
|
||||||
<el-dropdown-item>导出</el-dropdown-item>
|
|
||||||
<el-dropdown-item>删除</el-dropdown-item>
|
|
||||||
<el-dropdown-item>帮助</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- 提示 -->
|
<!-- 提示 -->
|
||||||
@@ -422,6 +396,8 @@
|
|||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { FormRules } from 'element-plus'
|
import { FormRules } from 'element-plus'
|
||||||
import * as QuestionApi from '@/api/paper/question'
|
import * as QuestionApi from '@/api/paper/question'
|
||||||
|
import * as SpecialtyApi from '@/api/points'
|
||||||
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
import FileForm from './components/FileForm.vue';
|
import FileForm from './components/FileForm.vue';
|
||||||
defineOptions({ name: 'ChoiceForm' })
|
defineOptions({ name: 'ChoiceForm' })
|
||||||
import type { TabPaneName } from 'element-plus'
|
import type { TabPaneName } from 'element-plus'
|
||||||
@@ -434,6 +410,8 @@ const dialogTitle = ref('') // 弹窗的标题
|
|||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
|
pointNamesVo:'',
|
||||||
|
chapteridDictTextVo:'',
|
||||||
content: '',
|
content: '',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
@@ -441,9 +419,9 @@ const formData = ref({
|
|||||||
required: '',
|
required: '',
|
||||||
chapteridDictText: '',
|
chapteridDictText: '',
|
||||||
analysis: '',
|
analysis: '',
|
||||||
quLevel: '',
|
quLevel: 0,
|
||||||
pointNames: '',
|
pointNames: '',
|
||||||
audit: '',
|
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
status: ' ',
|
status: ' ',
|
||||||
keywords: '',
|
keywords: '',
|
||||||
@@ -452,13 +430,13 @@ const formData = ref({
|
|||||||
quId: '',
|
quId: '',
|
||||||
url: '',
|
url: '',
|
||||||
fileType: '1',
|
fileType: '1',
|
||||||
fileName: ''
|
fileName: '原始'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
quId: '',
|
quId: '',
|
||||||
url: '',
|
url: '',
|
||||||
fileType: '2',
|
fileType: '2',
|
||||||
fileName: ''
|
fileName: '结果'
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -490,24 +468,10 @@ const rightHandleClick = (tab, e) => {
|
|||||||
// 发起考点请求
|
// 发起考点请求
|
||||||
QuestionApi.getListByQuId(kaodianData.value.quId).then(res => {
|
QuestionApi.getListByQuId(kaodianData.value.quId).then(res => {
|
||||||
// res 是接口返回的数据数组
|
// res 是接口返回的数据数组
|
||||||
kaodianList.value = res.map(item => {
|
kaodianList.value = res;
|
||||||
const totalScore = item.examMysqlKeywordList?.reduce((sum, kw) => {
|
|
||||||
return sum + Number(kw.scoreRate || 0);
|
|
||||||
}, 0);
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
score: isNaN(totalScore) ? 0 : totalScore, // 如果是 NaN 则显示为 0
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
function updateScore(parentRow: any) {
|
|
||||||
parentRow.score = (parentRow.examMysqlKeywordList || []).reduce((sum, kw) => {
|
|
||||||
const rate = parseFloat(kw.scoreRate);
|
|
||||||
return sum + (isNaN(rate) ? 0 : rate);
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -577,14 +541,12 @@ function addKaodian(row: any) {
|
|||||||
|
|
||||||
|
|
||||||
function confirmKao() {
|
function confirmKao() {
|
||||||
if (!kaodianList.value.length) {
|
|
||||||
ElMessage.warning("没有考点数据");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 构建 questionAnswerList
|
// 构建 questionAnswerList
|
||||||
const questionAnswerList = kaodianList.value.map(item => ({
|
const questionAnswerList = kaodianList.value.map(item => ({
|
||||||
answerId: item.answerId,
|
answerId: item.answerId,
|
||||||
content: item.content,
|
content: item.content,
|
||||||
|
scoreRate:item.scoreRate,
|
||||||
examMysqlKeywordList: (item.examMysqlKeywordList || []).map(kw => ({
|
examMysqlKeywordList: (item.examMysqlKeywordList || []).map(kw => ({
|
||||||
keywordId: kw.keywordId,
|
keywordId: kw.keywordId,
|
||||||
answerId: kw.answerId,
|
answerId: kw.answerId,
|
||||||
@@ -632,9 +594,10 @@ const fetchKaodianByUrl = async (url: string) => {
|
|||||||
|
|
||||||
// 将 SQL 字符串数组转换为 kaodianList 所需结构
|
// 将 SQL 字符串数组转换为 kaodianList 所需结构
|
||||||
kaodianList.value = sqlList.map((sql, index) => ({
|
kaodianList.value = sqlList.map((sql, index) => ({
|
||||||
answerId: index + 1, // 可自定义唯一ID生成逻辑
|
answerId: index + 1, // 可自定义唯一ID生成逻辑
|
||||||
quId: kaodianData.value.quId, // 如果有题目ID,可以在这里设置
|
quId: kaodianData.value.quId, // 如果有题目ID,可以在这里设置
|
||||||
content: sql,
|
content: sql,
|
||||||
|
scoreRate:1,
|
||||||
examMysqlKeywordList: [] // 默认空关键词列表
|
examMysqlKeywordList: [] // 默认空关键词列表
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -663,7 +626,7 @@ const beforeUpload = (file: File) => {
|
|||||||
|
|
||||||
function removeKeyword(parentRow: any, keywordIndex: number) {
|
function removeKeyword(parentRow: any, keywordIndex: number) {
|
||||||
parentRow.examMysqlKeywordList.splice(keywordIndex, 1);
|
parentRow.examMysqlKeywordList.splice(keywordIndex, 1);
|
||||||
updateScore(parentRow); // 删除后更新score
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -880,8 +843,10 @@ keywordList.value = res.keywords
|
|||||||
formData.value.specialtyName = queryParams.specialtyName
|
formData.value.specialtyName = queryParams.specialtyName
|
||||||
formData.value.courseName = queryParams.courseName
|
formData.value.courseName = queryParams.courseName
|
||||||
formData.value.subjectName = queryParams.subjectName
|
formData.value.subjectName = queryParams.subjectName
|
||||||
formData.value.pointNames=queryParams.pointNames
|
formData.value.pointNames=queryParams.pointNamesVo
|
||||||
formData.value.chapteridDictText=queryParams.chapteridDictText
|
formData.value.pointNamesVo=queryParams.pointNames
|
||||||
|
formData.value.chapteridDictText=queryParams.chapteridDictTextVo
|
||||||
|
formData.value.chapteridDictTextVo=queryParams.chapteridDictText
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -917,12 +882,8 @@ const submitForm = async () => {
|
|||||||
data.fileUploads = data.fileUploads?.filter(file => file.url && file.url.trim() !== '');
|
data.fileUploads = data.fileUploads?.filter(file => file.url && file.url.trim() !== '');
|
||||||
|
|
||||||
console.log(data, "提交的数据");
|
console.log(data, "提交的数据");
|
||||||
|
await QuestionApi.editQuestionNoAudit(data);
|
||||||
|
message.success(t('common.updateSuccess'));
|
||||||
await QuestionApi.editQuestionNoAudit(data);
|
|
||||||
message.success(t('common.updateSuccess'));
|
|
||||||
|
|
||||||
|
|
||||||
dialogVisible.value = false;
|
dialogVisible.value = false;
|
||||||
emit('success');
|
emit('success');
|
||||||
} finally {
|
} finally {
|
||||||
@@ -935,23 +896,15 @@ const submitForm = async () => {
|
|||||||
/** 重置表单 */
|
/** 重置表单 */
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
content: `---------------------------------------------------------------------------
|
content: `<p style="text-align: left;"><span style="font-family: 宋体;">--------------------------------------------------------------------------- </span></p><p style="text-align: left;"><span style="font-family: 宋体;">注意事项:</span></p><p style="text-align: left;"><span style="font-family: 宋体;">请利用图形化管理界面或者MySQL命令行工具,在指定的试题数据库中进行答题。 </span></p><p style="text-align: left;"><span style="font-family: 宋体;">MySQL连接地址为localhost</span></p><p style="text-align: left;"><span style="font-family: 宋体;">MySQL登录用户名为root</span></p><p style="text-align: left;"><span style="font-family: 宋体;">MySQL端口号为3306或者6033</span></p><p style="text-align: left;"><span style="font-family: 宋体;">MySQL密码为空</span></p><p style="text-align: left;"><span style="font-family: 宋体;">---------------------------------------------------------------------------</span>`,
|
||||||
注意事项:
|
|
||||||
请利用图形化管理界面或者MySQL命令行工具,在指定的试题数据库中进行答题。
|
|
||||||
MySQL连接地址为localhost
|
|
||||||
MySQL登录用户名为root
|
|
||||||
MySQL端口号为6033或3306
|
|
||||||
MySQL密码为空
|
|
||||||
---------------------------------------------------------------------------`,
|
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
required: '',
|
required: '',
|
||||||
chapteridDictText: '',
|
chapteridDictText: '',
|
||||||
analysis: '',
|
analysis: '',
|
||||||
quLevel: '0',
|
quLevel: 0,
|
||||||
pointNames: '',
|
pointNames: '',
|
||||||
audit: '',
|
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
status: '0',
|
status: '0',
|
||||||
keywords: '',
|
keywords: '',
|
||||||
@@ -961,13 +914,13 @@ MySQL密码为空
|
|||||||
quId: '',
|
quId: '',
|
||||||
url: '',
|
url: '',
|
||||||
fileType: '1',
|
fileType: '1',
|
||||||
fileName: ''
|
fileName: '原始'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
quId: '',
|
quId: '',
|
||||||
url: '',
|
url: '',
|
||||||
fileType: '2',
|
fileType: '2',
|
||||||
fileName: ''
|
fileName: '结果'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -977,6 +930,62 @@ MySQL密码为空
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectedPointName = ref('')
|
||||||
|
const selectedchapterText = ref('')
|
||||||
|
const dialogVisiblePoints = ref(false)
|
||||||
|
|
||||||
|
// 添加层级信息
|
||||||
|
const handleTreeWithLevel = (list, level = 1) => {
|
||||||
|
return list.map(item => {
|
||||||
|
const node = { ...item, level }
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
node.children = handleTreeWithLevel(item.children, level + 1)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只允许点击第三级节点
|
||||||
|
const treeRef = ref() // 引用 el-tree
|
||||||
|
const handleNodeClick = (data, node) => {
|
||||||
|
if (data.level === 3) {
|
||||||
|
formData.value.pointNames = data.id
|
||||||
|
formData.value.pointNamesVo = data.name
|
||||||
|
|
||||||
|
// 获取父节点(章节名称)
|
||||||
|
const currentNode = treeRef.value.getNode(data)
|
||||||
|
const parentNode = currentNode.parent
|
||||||
|
if (parentNode && parentNode.data) {
|
||||||
|
formData.value.chapteridDictTextVo = parentNode.data.name
|
||||||
|
formData.value.chapteridDictText = parentNode.data.id
|
||||||
|
} else {
|
||||||
|
formData.value.chapteridDictText = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogVisiblePoints.value = false
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const deptList = ref<Tree[]>([]) // 树形结构
|
||||||
|
/** 获得部门树 */
|
||||||
|
const getTree = async () => {
|
||||||
|
const res = await SpecialtyApi.listPoints()
|
||||||
|
const tree = handleTree(res)
|
||||||
|
deptList.value = []
|
||||||
|
deptList.value = handleTreeWithLevel(tree)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
const openPoints = async () => {
|
||||||
|
await getTree();
|
||||||
|
dialogVisiblePoints.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -17,8 +17,12 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="知识点" prop="pointNames">
|
<el-form-item label="章节名称" prop="chapteridDictText">
|
||||||
<el-input v-model="formData.pointNames" placeholder="请输入知识点" disabled />
|
<el-input
|
||||||
|
v-model="formData.chapteridDictTextVo"
|
||||||
|
placeholder="请输入章节名称"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -30,10 +34,17 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="题型难度" prop="quLevel">
|
<el-form-item label="题型难度" prop="quLevel">
|
||||||
<el-select v-model="formData.quLevel" placeholder="请选择题型难度" clearable>
|
<el-select
|
||||||
<el-option label="简单" :value="'0'" />
|
v-model="formData.quLevel"
|
||||||
<el-option label="一般" :value="'1'" />
|
placeholder="请选择题型难度"
|
||||||
<el-option label="困难" :value="'2'" />
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.EXAM_QUE_DIFF)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -45,29 +56,49 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="章节名称" prop="chapteridDictText">
|
<el-form-item label="知识点" prop="pointNames">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.chapteridDictText"
|
v-model="formData.pointNamesVo"
|
||||||
placeholder="请输入章节名称"
|
placeholder="请选择知识点"
|
||||||
disabled
|
readonly
|
||||||
|
@click="openPoints()"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisiblePoints" title="选择知识点" width="30%">
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="deptList"
|
||||||
|
node-key="id"
|
||||||
|
:props="{ label: 'name', children: 'children' }"
|
||||||
|
highlight-current
|
||||||
|
default-expand-all
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="启用状态" prop="status">
|
<el-form-item label="启用状态" prop="status">
|
||||||
<el-radio-group v-model="formData.status">
|
<el-radio-group v-model="formData.status">
|
||||||
<el-radio
|
<el-radio :label="'0'">启用</el-radio>
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.SYS_STATUS)"
|
<el-radio :label="'1'">禁用</el-radio>
|
||||||
:key="dict.value"
|
|
||||||
:value="dict.value"
|
|
||||||
>
|
|
||||||
{{ dict.label }}
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<!-- <el-col :span="12">
|
||||||
|
<el-form-item label="审核状态" prop="audit">
|
||||||
|
<el-select v-model="formData.audit" placeholder="请选择审核状态">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.QUESTION_AUDIT)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col> -->
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
@@ -87,8 +118,24 @@
|
|||||||
<Editor v-model="formData.analysis" height="150px" />
|
<Editor v-model="formData.analysis" height="150px" />
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="试题考点" name="answer">
|
<el-tab-pane name="answer">
|
||||||
<el-button @click="addPptxInfo">新增</el-button>
|
<template #label>
|
||||||
|
<div class="custom-tabs-label">
|
||||||
|
<p>试题考点</p>
|
||||||
|
<el-dropdown>
|
||||||
|
<span class="el-dropdown-link" @click.stop="false">
|
||||||
|
<div class="setting_icon"></div>
|
||||||
|
</span>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item>
|
||||||
|
<el-button @click="addPptxInfo">添加</el-button>
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<!-- <el-button type="danger">删除</el-button> -->
|
<!-- <el-button type="danger">删除</el-button> -->
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<el-table
|
<el-table
|
||||||
@@ -97,8 +144,15 @@
|
|||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
>
|
>
|
||||||
<!-- <el-table-column type="selection" width="55" /> -->
|
<!-- <el-table-column type="selection" width="55" /> -->
|
||||||
<el-table-column label="考点" align="center" prop="contentIn" />
|
<el-table-column label="考点" align="center" prop="contentIn" width="360px"/>
|
||||||
<el-table-column label="权值" align="center" prop="scoreRate" />
|
<el-table-column label="权值" align="center" prop="scoreRate" width="100px"/>
|
||||||
|
<el-table-column label="操作" align="center" width="100px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" link @click="handleDelete(scope.row)">
|
||||||
|
<Icon icon="ep:delete" />删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -186,9 +240,29 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="150">
|
<el-table-column label="操作" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button type="primary" plain @click="openForm(scope.row.fileType)">
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm(scope.row.fileType)"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
<Icon icon="ep:upload" class="mr-5px" /> 上传
|
<Icon icon="ep:upload" class="mr-5px" /> 上传
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="downloadFile(scope.row.url)"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 下载
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
@click="deleteUrl(scope.$index)"
|
||||||
|
size="small"
|
||||||
|
><Icon icon="ep:download" class="mr-5px" />删除
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -232,7 +306,7 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
|
||||||
import { FormRules } from 'element-plus'
|
import { FormRules } from 'element-plus'
|
||||||
import * as QuestionApi from '@/api/paper/question'
|
import * as QuestionApi from '@/api/paper/question'
|
||||||
import * as WordApi from '@/api/wps/word'
|
import * as WordApi from '@/api/wps/word'
|
||||||
@@ -240,7 +314,7 @@ import * as PptxApi from '@/api/wps/pptx'
|
|||||||
import FileForm from './components/FileForm.vue'
|
import FileForm from './components/FileForm.vue'
|
||||||
import { defaultProps, handleTree } from '@/utils/tree'
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
import * as SpecialtyApi from '@/api/points'
|
||||||
defineOptions({ name: 'WpsPptxFrom' })
|
defineOptions({ name: 'WpsPptxFrom' })
|
||||||
const pptxPointsList = ref<Tree[]>([]) // 树形结构
|
const pptxPointsList = ref<Tree[]>([]) // 树形结构
|
||||||
const pptxPointsInfoList = ref<Tree[]>([]) // 树形结构
|
const pptxPointsInfoList = ref<Tree[]>([]) // 树形结构
|
||||||
@@ -254,6 +328,8 @@ const dialogTitle = ref('') // 弹窗的标题
|
|||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
|
pointNamesVo:'',
|
||||||
|
chapteridDictTextVo:'',
|
||||||
content: '',
|
content: '',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
@@ -261,7 +337,7 @@ const formData = ref({
|
|||||||
required: '',
|
required: '',
|
||||||
chapteridDictText: '',
|
chapteridDictText: '',
|
||||||
analysis: '',
|
analysis: '',
|
||||||
quLevel: '',
|
quLevel: 0,
|
||||||
pointNames: '',
|
pointNames: '',
|
||||||
audit: '',
|
audit: '',
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
@@ -311,6 +387,14 @@ const pptxPoints = ref({
|
|||||||
})
|
})
|
||||||
let pptxPointsInfosList: (typeof pptxPoints)[] = []
|
let pptxPointsInfosList: (typeof pptxPoints)[] = []
|
||||||
|
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
for (let i = 0; i < list.value.length; i++) {
|
||||||
|
if (row.content == list.value[i].content) {
|
||||||
|
list.value.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function fileTypeFormatter(row, column, cellValue) {
|
function fileTypeFormatter(row, column, cellValue) {
|
||||||
if (cellValue === '0') return '素材文件(上传ZIP)'
|
if (cellValue === '0') return '素材文件(上传ZIP)'
|
||||||
if (cellValue === '1') return '考试文件'
|
if (cellValue === '1') return '考试文件'
|
||||||
@@ -368,13 +452,21 @@ const handleCheckChange = (data: Tree, checked: boolean, indeterminate: boolean)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const addPptxInfo = async () => {
|
const addPptxInfo = async () => {
|
||||||
|
var filePath = ''
|
||||||
|
for (var i = 0; i < documentList.value.length; i++) {
|
||||||
|
if (documentList.value[i].fileType == '2') {
|
||||||
|
filePath = documentList.value[i].url
|
||||||
|
}
|
||||||
|
}
|
||||||
// http://115.120.213.238:9000/exam/9f7d8f5d7c68cc2bfd03a23c19045efe7ba13a4bebeb833abece146908bcd0c6.docx documentList.value[1].url
|
// http://115.120.213.238:9000/exam/9f7d8f5d7c68cc2bfd03a23c19045efe7ba13a4bebeb833abece146908bcd0c6.docx documentList.value[1].url
|
||||||
if (documentList.value[2].url == '' || documentList.value[2].url == null) {
|
if (filePath == '' || filePath == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const res = await PptxApi.getPptxInfo(documentList.value[2].url)
|
if (pptxPointsList.value.length <= 0) {
|
||||||
pptxPointsList.value = []
|
const res = await PptxApi.getPptxInfo(filePath)
|
||||||
pptxPointsList.value.push(...handleTree(res))
|
pptxPointsList.value = []
|
||||||
|
pptxPointsList.value.push(...handleTree(res))
|
||||||
|
}
|
||||||
dialogFormVisiblePptxInfo.value = true
|
dialogFormVisiblePptxInfo.value = true
|
||||||
}
|
}
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
@@ -405,11 +497,21 @@ const submitPptxPoints = async () => {
|
|||||||
const res = await PptxApi.getPptxListInfos(pptxPointsInfosList)
|
const res = await PptxApi.getPptxListInfos(pptxPointsInfosList)
|
||||||
pptxPointsInfosList = []
|
pptxPointsInfosList = []
|
||||||
console.log(list.value)
|
console.log(list.value)
|
||||||
|
var indexFlag = false
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
||||||
list.value.push(res[i])
|
for (let x = 0; x < list.value.length; x++) {
|
||||||
|
if (res[i].content == list.value[x].content) {
|
||||||
|
// 如果存在相同的数据话 不进入
|
||||||
|
indexFlag = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!indexFlag) {
|
||||||
|
list.value.push(res[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dialogFormVisiblePptxInfo.value = false
|
dialogFormVisiblePptxInfo.value = false
|
||||||
dialogFormVisiblePptxInfos.value = false
|
dialogFormVisiblePptxInfos.value = false
|
||||||
|
pptxPointsList.value = []
|
||||||
}
|
}
|
||||||
const formRules = reactive<FormRules>({
|
const formRules = reactive<FormRules>({
|
||||||
status: [{ required: true, message: '启用状态必填', trigger: 'blur' }]
|
status: [{ required: true, message: '启用状态必填', trigger: 'blur' }]
|
||||||
@@ -462,7 +564,7 @@ const open = async (queryParams: any, type: string, id?: number) => {
|
|||||||
if (id) {
|
if (id) {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await QuestionApi.getQuestion(id)
|
const res = await QuestionApi.getQuestionnotId(id)
|
||||||
formData.value = res
|
formData.value = res
|
||||||
list.value = formData.value.answerList
|
list.value = formData.value.answerList
|
||||||
documentList.value = res.fileUploads
|
documentList.value = res.fileUploads
|
||||||
@@ -492,13 +594,8 @@ const submitForm = async () => {
|
|||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value as unknown
|
const data = formData.value as unknown
|
||||||
if (formType.value === 'create') {
|
await QuestionApi.editQuestionNoAudit(data)
|
||||||
await QuestionApi.addQuestion(data)
|
message.success(t('common.updateSuccess'))
|
||||||
message.success(t('common.createSuccess'))
|
|
||||||
} else {
|
|
||||||
await QuestionApi.editQuestion(data)
|
|
||||||
message.success(t('common.updateSuccess'))
|
|
||||||
}
|
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
// 发送操作成功的事件
|
// 发送操作成功的事件
|
||||||
emit('success')
|
emit('success')
|
||||||
@@ -506,7 +603,42 @@ const submitForm = async () => {
|
|||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const downloadFile = async (url: string) => {
|
||||||
|
if (!url) {
|
||||||
|
ElMessage.warning('暂无可下载的文件地址')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(url)
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('下载失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
const blob = await response.blob()
|
||||||
|
const blobUrl = window.URL.createObjectURL(blob)
|
||||||
|
|
||||||
|
// 提取文件名
|
||||||
|
const filename = url.substring(url.lastIndexOf('/') + 1).split('?')[0]
|
||||||
|
|
||||||
|
// 创建 a 标签并下载
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = blobUrl
|
||||||
|
a.download = filename
|
||||||
|
a.style.display = 'none'
|
||||||
|
document.body.appendChild(a)
|
||||||
|
a.click()
|
||||||
|
a.remove()
|
||||||
|
|
||||||
|
window.URL.revokeObjectURL(blobUrl)
|
||||||
|
} catch (err: any) {
|
||||||
|
ElMessage.error(`下载失败:${err.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const deleteUrl = (index: number) => {
|
||||||
|
formData.value.fileUploads[index].url = ''
|
||||||
|
formData.value.fileUploads[index].fileName = ''
|
||||||
|
}
|
||||||
/** 重置表单 */
|
/** 重置表单 */
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
@@ -517,11 +649,11 @@ const resetForm = () => {
|
|||||||
required: '',
|
required: '',
|
||||||
chapteridDictText: '',
|
chapteridDictText: '',
|
||||||
analysis: '',
|
analysis: '',
|
||||||
quLevel: '',
|
quLevel: 0,
|
||||||
pointNames: '',
|
pointNames: '',
|
||||||
audit: '',
|
audit: '',
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
status: '',
|
status: '0',
|
||||||
resourceValue: '',
|
resourceValue: '',
|
||||||
answerList: [
|
answerList: [
|
||||||
{
|
{
|
||||||
@@ -572,8 +704,59 @@ const resetForm = () => {
|
|||||||
fileName: ''
|
fileName: ''
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
list.value = []
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dialogVisiblePoints = ref(false)
|
||||||
|
const openPoints = async () => {
|
||||||
|
await getTree();
|
||||||
|
dialogVisiblePoints.value = true;
|
||||||
|
}
|
||||||
|
// 只允许点击第三级节点
|
||||||
|
const treeRef = ref() // 引用 el-tree
|
||||||
|
const handleNodeClick = (data, node) => {
|
||||||
|
if (data.level === 3) {
|
||||||
|
formData.value.pointNames = data.id
|
||||||
|
formData.value.pointNamesVo = data.name
|
||||||
|
|
||||||
|
// 获取父节点(章节名称)
|
||||||
|
const currentNode = treeRef.value.getNode(data)
|
||||||
|
const parentNode = currentNode.parent
|
||||||
|
if (parentNode && parentNode.data) {
|
||||||
|
formData.value.chapteridDictTextVo = parentNode.data.name
|
||||||
|
formData.value.chapteridDictText = parentNode.data.id
|
||||||
|
} else {
|
||||||
|
formData.value.chapteridDictText = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogVisiblePoints.value = false
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const deptList = ref<Tree[]>([]) // 树形结构
|
||||||
|
/** 获得部门树 */
|
||||||
|
const getTree = async () => {
|
||||||
|
const res = await SpecialtyApi.listPoints()
|
||||||
|
const tree = handleTree(res)
|
||||||
|
deptList.value = []
|
||||||
|
deptList.value = handleTreeWithLevel(tree)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 添加层级信息
|
||||||
|
const handleTreeWithLevel = (list, level = 1) => {
|
||||||
|
return list.map(item => {
|
||||||
|
const node = { ...item, level }
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
node.children = handleTreeWithLevel(item.children, level + 1)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.edit-dialog {
|
.edit-dialog {
|
||||||
|
|||||||
@@ -16,11 +16,18 @@
|
|||||||
<el-input v-model="formData.specialtyName" placeholder="请输入专业" disabled />
|
<el-input v-model="formData.specialtyName" placeholder="请输入专业" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="知识点" prop="pointNames">
|
<el-form-item label="章节名称" prop="chapteridDictText">
|
||||||
<el-input v-model="formData.pointNames" placeholder="请输入知识点" disabled />
|
<el-input
|
||||||
|
v-model="formData.chapteridDictTextVo"
|
||||||
|
placeholder="请输入章节名称"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@@ -29,13 +36,21 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="题型难度" prop="quLevel">
|
|
||||||
<el-select v-model="formData.quLevel" placeholder="请选择题型难度" clearable>
|
<el-form-item label="题型难度" prop="quLevel">
|
||||||
<el-option label="简单" :value="'0'" />
|
<el-select
|
||||||
<el-option label="一般" :value="'1'" />
|
v-model="formData.quLevel"
|
||||||
<el-option label="困难" :value="'2'" />
|
placeholder="请选择题型难度"
|
||||||
</el-select>
|
clearable
|
||||||
</el-form-item>
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.EXAM_QUE_DIFF)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
@@ -45,29 +60,50 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="章节名称" prop="chapteridDictText">
|
<el-form-item label="知识点" prop="pointNames">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.chapteridDictText"
|
v-model="formData.pointNamesVo"
|
||||||
placeholder="请输入章节名称"
|
placeholder="请选择知识点"
|
||||||
disabled
|
readonly
|
||||||
|
@click="openPoints()"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisiblePoints" title="选择知识点" width="30%">
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="deptList"
|
||||||
|
node-key="id"
|
||||||
|
:props="{ label: 'name', children: 'children' }"
|
||||||
|
highlight-current
|
||||||
|
default-expand-all
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="启用状态" prop="status">
|
<el-form-item label="启用状态" prop="status">
|
||||||
<el-radio-group v-model="formData.status">
|
<el-radio-group v-model="formData.status">
|
||||||
<el-radio
|
<el-radio :label="'0'">启用</el-radio>
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.SYS_STATUS)"
|
<el-radio :label="'1'">禁用</el-radio>
|
||||||
:key="dict.value"
|
|
||||||
:value="dict.value"
|
|
||||||
>
|
|
||||||
{{ dict.label }}
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<!-- <el-col :span="12">
|
||||||
|
<el-form-item label="审核状态" prop="audit">
|
||||||
|
<el-select v-model="formData.audit" placeholder="请选择审核状态">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.QUESTION_AUDIT)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col> -->
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
@@ -87,8 +123,24 @@
|
|||||||
<Editor v-model="formData.analysis" height="150px" />
|
<Editor v-model="formData.analysis" height="150px" />
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="试题考点" name="answer">
|
<el-tab-pane name="answer">
|
||||||
<el-button @click="addWordInfo">新增</el-button>
|
<template #label>
|
||||||
|
<div class="custom-tabs-label">
|
||||||
|
<p>试题考点</p>
|
||||||
|
<el-dropdown>
|
||||||
|
<span class="el-dropdown-link" @click.stop="false">
|
||||||
|
<div class="setting_icon"></div>
|
||||||
|
</span>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item>
|
||||||
|
<el-button @click="addWordInfo">添加</el-button>
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<!-- <el-button type="danger">删除</el-button> -->
|
<!-- <el-button type="danger">删除</el-button> -->
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<el-table
|
<el-table
|
||||||
@@ -97,8 +149,15 @@
|
|||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
>
|
>
|
||||||
<!-- <el-table-column type="selection" width="55" /> -->
|
<!-- <el-table-column type="selection" width="55" /> -->
|
||||||
<el-table-column label="考点" align="center" prop="contentIn" />
|
<el-table-column label="考点" align="center" prop="contentIn" width="360px" />
|
||||||
<el-table-column label="权值" align="center" prop="scoreRate" />
|
<el-table-column label="权值" align="center" prop="scoreRate" width="100px" />
|
||||||
|
<el-table-column label="操作" align="center" width="100px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" link @click="handleDelete(scope.row)">
|
||||||
|
<Icon icon="ep:delete" />删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -186,9 +245,29 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="150">
|
<el-table-column label="操作" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button type="primary" plain @click="openForm(scope.row.fileType)">
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm(scope.row.fileType)"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
<Icon icon="ep:upload" class="mr-5px" /> 上传
|
<Icon icon="ep:upload" class="mr-5px" /> 上传
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="downloadFile(scope.row.url)"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 下载
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
@click="deleteUrl(scope.$index)"
|
||||||
|
size="small"
|
||||||
|
><Icon icon="ep:download" class="mr-5px" />删除
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -208,6 +287,7 @@
|
|||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<FileForm ref="FileRef" @success="handleUploadSuccess" />
|
<FileForm ref="FileRef" @success="handleUploadSuccess" />
|
||||||
<el-dialog v-model="dialogFormVisibleWordInfo" title="考点设置" width="400px">
|
<el-dialog v-model="dialogFormVisibleWordInfo" title="考点设置" width="400px">
|
||||||
|
<el-skeleton :rows="5" animated v-if="wordPointsList.length < 0 && isLoading" />
|
||||||
<el-tree
|
<el-tree
|
||||||
style="max-width: 600px"
|
style="max-width: 600px"
|
||||||
:data="wordPointsList"
|
:data="wordPointsList"
|
||||||
@@ -232,7 +312,7 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
|
||||||
import { FormRules } from 'element-plus'
|
import { FormRules } from 'element-plus'
|
||||||
import * as QuestionApi from '@/api/paper/question'
|
import * as QuestionApi from '@/api/paper/question'
|
||||||
import * as WordApi from '@/api/wps/word'
|
import * as WordApi from '@/api/wps/word'
|
||||||
@@ -241,7 +321,7 @@ import WordInfo from './components/WordInfo.vue'
|
|||||||
import WordInfos from './components/WordInfos.vue'
|
import WordInfos from './components/WordInfos.vue'
|
||||||
import { defaultProps, handleTree } from '@/utils/tree'
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
import * as SpecialtyApi from '@/api/points'
|
||||||
defineOptions({ name: 'WpsWordFrom' })
|
defineOptions({ name: 'WpsWordFrom' })
|
||||||
const wordPointsList = ref<Tree[]>([]) // 树形结构
|
const wordPointsList = ref<Tree[]>([]) // 树形结构
|
||||||
const wordPointsInfoList = ref<Tree[]>([]) // 树形结构
|
const wordPointsInfoList = ref<Tree[]>([]) // 树形结构
|
||||||
@@ -251,10 +331,13 @@ const { t } = useI18n() // 国际化
|
|||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const loading = ref(false) // 列表的加载中
|
const loading = ref(false) // 列表的加载中
|
||||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const isLoading = ref(false)
|
||||||
const dialogTitle = ref('') // 弹窗的标题
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
|
pointNamesVo:'',
|
||||||
|
chapteridDictTextVo:'',
|
||||||
content: '',
|
content: '',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
@@ -262,7 +345,7 @@ const formData = ref({
|
|||||||
required: '',
|
required: '',
|
||||||
chapteridDictText: '',
|
chapteridDictText: '',
|
||||||
analysis: '',
|
analysis: '',
|
||||||
quLevel: '',
|
quLevel: 0,
|
||||||
pointNames: '',
|
pointNames: '',
|
||||||
audit: '',
|
audit: '',
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
@@ -270,10 +353,10 @@ const formData = ref({
|
|||||||
resourceValue: '',
|
resourceValue: '',
|
||||||
answerList: [
|
answerList: [
|
||||||
{
|
{
|
||||||
image: "",
|
image: '',
|
||||||
content: "",
|
content: '',
|
||||||
contentIn: "",
|
contentIn: '',
|
||||||
scoreRate: "",
|
scoreRate: ''
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
fileUploads: [
|
fileUploads: [
|
||||||
@@ -302,17 +385,13 @@ const wordPointsFun = ref({
|
|||||||
function: ''
|
function: ''
|
||||||
})
|
})
|
||||||
const wordPoints = ref({
|
const wordPoints = ref({
|
||||||
id: '',
|
name: '',
|
||||||
chineseName: '',
|
|
||||||
englishName: '',
|
englishName: '',
|
||||||
filePath: '',
|
filePath: '',
|
||||||
type: '',
|
type: '',
|
||||||
belongTo: '',
|
belongTo: '',
|
||||||
parameter: '',
|
isboo: '',
|
||||||
function: [] as {
|
function: ''
|
||||||
chineseName: string
|
|
||||||
function: string
|
|
||||||
}[]
|
|
||||||
})
|
})
|
||||||
let wordPointsInfosList: (typeof wordPoints)[] = []
|
let wordPointsInfosList: (typeof wordPoints)[] = []
|
||||||
|
|
||||||
@@ -359,74 +438,154 @@ const wordData = reactive({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const handleCheckChange = (data: Tree, checked: boolean, indeterminate: boolean) => {
|
const handleCheckChange = (data: Tree, checked: boolean, indeterminate: boolean) => {
|
||||||
if (checked || indeterminate) {
|
// if (checked || indeterminate) {
|
||||||
|
// wordPoints.value.belongTo = data.belongTo
|
||||||
|
// wordPoints.value.parameter = data.isboo
|
||||||
|
// wordPoints.value.type = data.type
|
||||||
|
// wordPointsFun.value = {
|
||||||
|
// chineseName: '',
|
||||||
|
// function: ''
|
||||||
|
// }
|
||||||
|
// wordPointsFun.value.chineseName = data.toChinese
|
||||||
|
// wordPointsFun.value.function = data.nodeFunction
|
||||||
|
// wordPoints.value.function.push(cloneDeep(wordPointsFun.value))
|
||||||
|
// console.log(wordPoints)
|
||||||
|
// }
|
||||||
|
if (data.titleType == '2') {
|
||||||
|
wordPoints.value.name = chineseName.value + data.toChinese
|
||||||
|
wordPoints.value.filePath = filePath.value
|
||||||
|
wordPoints.value.function = englishNames.value + data.nodeFunction
|
||||||
|
wordPoints.value.englishName = englishNames.value
|
||||||
wordPoints.value.belongTo = data.belongTo
|
wordPoints.value.belongTo = data.belongTo
|
||||||
wordPoints.value.parameter = data.isboo
|
wordPoints.value.isboo = data.isboo
|
||||||
wordPoints.value.type = data.type
|
wordPoints.value.type = data.type
|
||||||
wordPointsFun.value = {
|
wordPointsInfosList.push(cloneDeep(wordPoints.value))
|
||||||
chineseName: '',
|
|
||||||
function: ''
|
|
||||||
}
|
|
||||||
wordPointsFun.value.chineseName = data.name
|
|
||||||
wordPointsFun.value.function = data.nodeFunction
|
|
||||||
wordPoints.value.function.push(cloneDeep(wordPointsFun.value))
|
|
||||||
console.log(wordPoints)
|
|
||||||
}
|
}
|
||||||
console.log(data, checked, indeterminate)
|
console.log(data, checked, indeterminate)
|
||||||
}
|
}
|
||||||
|
const dialogVisiblePoints = ref(false)
|
||||||
|
const openPoints = async () => {
|
||||||
|
await getTree();
|
||||||
|
dialogVisiblePoints.value = true;
|
||||||
|
}
|
||||||
|
// 只允许点击第三级节点
|
||||||
|
const treeRef = ref() // 引用 el-tree
|
||||||
|
const handleNodeClick = (data, node) => {
|
||||||
|
if (data.level === 3) {
|
||||||
|
formData.value.pointNames = data.id
|
||||||
|
formData.value.pointNamesVo = data.name
|
||||||
|
|
||||||
|
// 获取父节点(章节名称)
|
||||||
|
const currentNode = treeRef.value.getNode(data)
|
||||||
|
const parentNode = currentNode.parent
|
||||||
|
if (parentNode && parentNode.data) {
|
||||||
|
formData.value.chapteridDictTextVo = parentNode.data.name
|
||||||
|
formData.value.chapteridDictText = parentNode.data.id
|
||||||
|
} else {
|
||||||
|
formData.value.chapteridDictText = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogVisiblePoints.value = false
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const deptList = ref<Tree[]>([]) // 树形结构
|
||||||
|
/** 获得部门树 */
|
||||||
|
const getTree = async () => {
|
||||||
|
const res = await SpecialtyApi.listPoints()
|
||||||
|
const tree = handleTree(res)
|
||||||
|
deptList.value = []
|
||||||
|
deptList.value = handleTreeWithLevel(tree)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 添加层级信息
|
||||||
|
const handleTreeWithLevel = (list, level = 1) => {
|
||||||
|
return list.map(item => {
|
||||||
|
const node = { ...item, level }
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
node.children = handleTreeWithLevel(item.children, level + 1)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const addWordInfo = async () => {
|
const addWordInfo = async () => {
|
||||||
|
var filePath = ''
|
||||||
|
for (var i = 0; i < documentList.value.length; i++) {
|
||||||
|
if (documentList.value[i].fileType == '2') {
|
||||||
|
filePath = documentList.value[i].url
|
||||||
|
}
|
||||||
|
}
|
||||||
// http://115.120.213.238:9000/exam/9f7d8f5d7c68cc2bfd03a23c19045efe7ba13a4bebeb833abece146908bcd0c6.docx documentList.value[1].url
|
// http://115.120.213.238:9000/exam/9f7d8f5d7c68cc2bfd03a23c19045efe7ba13a4bebeb833abece146908bcd0c6.docx documentList.value[1].url
|
||||||
if (documentList.value[2].url == '' || documentList.value[2].url == null) {
|
if (filePath == '' || filePath == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const res = await WordApi.getWordInfo(documentList.value[2].url)
|
|
||||||
wordPointsList.value = []
|
|
||||||
wordPointsList.value.push(...handleTree(res))
|
|
||||||
dialogFormVisibleWordInfo.value = true
|
dialogFormVisibleWordInfo.value = true
|
||||||
|
isLoading.value = true
|
||||||
|
if (wordPointsList.value.length <= 0) {
|
||||||
|
const res = await WordApi.getWordInfo(filePath)
|
||||||
|
isLoading.value = false
|
||||||
|
wordPointsList.value = []
|
||||||
|
wordPointsList.value.push(...handleTree(res))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
nodeFunction: undefined
|
nodeFunction: undefined
|
||||||
})
|
})
|
||||||
const handleSpecialtyNodeClick = async (row: any) => {
|
const chineseName = ref('')
|
||||||
titles.value = row.name
|
const nodeFunctions = ref('')
|
||||||
englishName.value = row.englishName
|
const englishNames = ref('')
|
||||||
filePath.value = row.filePath
|
|
||||||
nodeFunction.value = row.selectName
|
|
||||||
dialogFormVisibleWordInfos.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleNodelClick = async (row: any) => {
|
const handleNodelClick = async (row: any) => {
|
||||||
|
console.log(row)
|
||||||
queryParams.nodeFunction = row.selectName
|
queryParams.nodeFunction = row.selectName
|
||||||
wordPoints.value.chineseName = row.name.split(':')[0]
|
chineseName.value = '【' + row.name + '】'
|
||||||
wordPoints.value.englishName = row.englishName
|
filePath.value = row.filePath
|
||||||
wordPoints.value.filePath = row.filePath
|
nodeFunctions.value = row.selectName
|
||||||
wordPoints.value.id = row.id
|
englishNames.value = row.englishName
|
||||||
const res = await WordApi.getWordInfos(queryParams)
|
const res = await WordApi.getWordInfos(queryParams)
|
||||||
wordPointsInfoList.value = []
|
wordPointsInfoList.value = []
|
||||||
wordPointsInfoList.value.push(...handleTree(res))
|
wordPointsInfoList.value.push(...handleTree(res))
|
||||||
dialogFormVisibleWordInfos.value = true
|
dialogFormVisibleWordInfos.value = true
|
||||||
}
|
}
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
console.log(row)
|
||||||
|
for (let i = 0; i < list.value.length; i++) {
|
||||||
|
if (row.content == list.value[i].content) {
|
||||||
|
list.value.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const submitWordPoints = async () => {
|
const submitWordPoints = async () => {
|
||||||
wordPointsInfosList.push(wordPoints.value)
|
|
||||||
const res = await WordApi.getWordListInfos(wordPointsInfosList)
|
const res = await WordApi.getWordListInfos(wordPointsInfosList)
|
||||||
wordPoints.value = {
|
wordPoints.value = {
|
||||||
id: '',
|
name: '',
|
||||||
chineseName: '',
|
|
||||||
englishName: '',
|
englishName: '',
|
||||||
filePath: '',
|
filePath: '',
|
||||||
type: '',
|
type: '',
|
||||||
belongTo: '',
|
belongTo: '',
|
||||||
parameter: '',
|
isboo: '',
|
||||||
function: []
|
function: ''
|
||||||
}
|
}
|
||||||
wordPointsInfosList = []
|
wordPointsInfosList = []
|
||||||
console.log(list.value)
|
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
||||||
list.value.push(res[i])
|
var indexFlag = false
|
||||||
|
for (let x = 0; x < list.value.length; x++) {
|
||||||
|
if (res[i].content == list.value[x].content) {
|
||||||
|
// 如果存在相同的数据话 不进入
|
||||||
|
indexFlag = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!indexFlag) {
|
||||||
|
list.value.push(res[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dialogFormVisibleWordInfo.value = false
|
dialogFormVisibleWordInfo.value = false
|
||||||
dialogFormVisibleWordInfos.value = false
|
dialogFormVisibleWordInfos.value = false
|
||||||
|
wordPointsList.value = []
|
||||||
}
|
}
|
||||||
const formRules = reactive<FormRules>({
|
const formRules = reactive<FormRules>({
|
||||||
status: [{ required: true, message: '启用状态必填', trigger: 'blur' }]
|
status: [{ required: true, message: '启用状态必填', trigger: 'blur' }]
|
||||||
@@ -455,7 +614,42 @@ const FileRef = ref()
|
|||||||
const openForm = (type: string) => {
|
const openForm = (type: string) => {
|
||||||
FileRef.value.open(type)
|
FileRef.value.open(type)
|
||||||
}
|
}
|
||||||
|
const downloadFile = async (url: string) => {
|
||||||
|
if (!url) {
|
||||||
|
ElMessage.warning('暂无可下载的文件地址')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(url)
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('下载失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
const blob = await response.blob()
|
||||||
|
const blobUrl = window.URL.createObjectURL(blob)
|
||||||
|
|
||||||
|
// 提取文件名
|
||||||
|
const filename = url.substring(url.lastIndexOf('/') + 1).split('?')[0]
|
||||||
|
|
||||||
|
// 创建 a 标签并下载
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = blobUrl
|
||||||
|
a.download = filename
|
||||||
|
a.style.display = 'none'
|
||||||
|
document.body.appendChild(a)
|
||||||
|
a.click()
|
||||||
|
a.remove()
|
||||||
|
|
||||||
|
window.URL.revokeObjectURL(blobUrl)
|
||||||
|
} catch (err: any) {
|
||||||
|
ElMessage.error(`下载失败:${err.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const deleteUrl = (index: number) => {
|
||||||
|
formData.value.fileUploads[index].url = ''
|
||||||
|
formData.value.fileUploads[index].fileName = ''
|
||||||
|
}
|
||||||
// 媒体文件
|
// 媒体文件
|
||||||
const mediumList = ref([] as any)
|
const mediumList = ref([] as any)
|
||||||
const multipleMediumSelection = ref([] as any)
|
const multipleMediumSelection = ref([] as any)
|
||||||
@@ -484,7 +678,7 @@ const open = async (queryParams: any, type: string, id?: number) => {
|
|||||||
if (id) {
|
if (id) {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await QuestionApi.getQuestion(id)
|
const res = await QuestionApi.getQuestionnotId(id)
|
||||||
formData.value = res
|
formData.value = res
|
||||||
console.log(formData.value)
|
console.log(formData.value)
|
||||||
list.value = formData.value.answerList
|
list.value = formData.value.answerList
|
||||||
@@ -497,8 +691,10 @@ const open = async (queryParams: any, type: string, id?: number) => {
|
|||||||
formData.value.specialtyName = queryParams.specialtyName
|
formData.value.specialtyName = queryParams.specialtyName
|
||||||
formData.value.courseName = queryParams.courseName
|
formData.value.courseName = queryParams.courseName
|
||||||
formData.value.subjectName = queryParams.subjectName
|
formData.value.subjectName = queryParams.subjectName
|
||||||
formData.value.pointNames = queryParams.pointNames
|
formData.value.pointNames=queryParams.pointNamesVo
|
||||||
formData.value.chapteridDictText = queryParams.chapteridDictText
|
formData.value.pointNamesVo=queryParams.pointNames
|
||||||
|
formData.value.chapteridDictText=queryParams.chapteridDictTextVo
|
||||||
|
formData.value.chapteridDictTextVo=queryParams.chapteridDictText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
@@ -527,13 +723,8 @@ const submitForm = async () => {
|
|||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value as unknown
|
const data = formData.value as unknown
|
||||||
if (formType.value === 'create') {
|
await QuestionApi.editQuestionNoAudit(data)
|
||||||
await QuestionApi.addQuestion(data)
|
message.success(t('common.updateSuccess'))
|
||||||
message.success(t('common.createSuccess'))
|
|
||||||
} else {
|
|
||||||
await QuestionApi.editQuestion(data)
|
|
||||||
message.success(t('common.updateSuccess'))
|
|
||||||
}
|
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
// 发送操作成功的事件
|
// 发送操作成功的事件
|
||||||
emit('success')
|
emit('success')
|
||||||
@@ -552,40 +743,40 @@ const resetForm = () => {
|
|||||||
required: '',
|
required: '',
|
||||||
chapteridDictText: '',
|
chapteridDictText: '',
|
||||||
analysis: '',
|
analysis: '',
|
||||||
quLevel: '',
|
quLevel: 0,
|
||||||
pointNames: '',
|
pointNames: '',
|
||||||
audit: '',
|
audit: '',
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
status: '',
|
status: '0',
|
||||||
resourceValue: '',
|
resourceValue: '',
|
||||||
answerList: [
|
answerList: [
|
||||||
{
|
{
|
||||||
image: "",
|
image: '',
|
||||||
content: "",
|
content: '',
|
||||||
contentIn: "",
|
contentIn: '',
|
||||||
scoreRate: "",
|
scoreRate: ''
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
fileUploads: [
|
fileUploads: [
|
||||||
{
|
{
|
||||||
quId: '',
|
quId: '',
|
||||||
url: '',
|
url: '',
|
||||||
fileType: '0',
|
fileType: '0',
|
||||||
fileName: ''
|
fileName: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
quId: '',
|
quId: '',
|
||||||
url: '',
|
url: '',
|
||||||
fileType: '1',
|
fileType: '1',
|
||||||
fileName: ''
|
fileName: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
quId: '',
|
quId: '',
|
||||||
url: '',
|
url: '',
|
||||||
fileType: '2',
|
fileType: '2',
|
||||||
fileName: ''
|
fileName: ''
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
documentList.value = [
|
documentList.value = [
|
||||||
{
|
{
|
||||||
@@ -607,6 +798,7 @@ const resetForm = () => {
|
|||||||
fileName: ''
|
fileName: ''
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
list.value = []
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -179,7 +179,7 @@
|
|||||||
<el-table-column
|
<el-table-column
|
||||||
label="知识点"
|
label="知识点"
|
||||||
align="center"
|
align="center"
|
||||||
prop="pointNames"
|
prop="pointNamesVo"
|
||||||
:show-overflow-tooltip="true"
|
:show-overflow-tooltip="true"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|||||||
Reference in New Issue
Block a user