【修改】换题界面搜索试题关键字改为试题内容

【新增】出题界面排序,修改图标
This commit is contained in:
YOHO\20373
2025-06-24 10:34:24 +08:00
parent 8ffbff635b
commit ac9b210466
9 changed files with 701 additions and 283 deletions

View File

@@ -1,6 +1,19 @@
<template> <template>
<div class="edit-dialog"> <div class="edit-dialog">
<Dialog v-model="dialogVisible" :title="dialogTitle" width="85%" top="10vh" class="custom-dialog"> <Dialog v-model="dialogVisible" :title="dialogTitle" width="85%" top="10vh" class="custom-dialog">
<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-scrollbar> <el-scrollbar>
<div class="main"> <div class="main">
<el-form <el-form
@@ -16,11 +29,14 @@
<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>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
@@ -29,22 +45,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-input v-model="formData.quLevel" placeholder="请输入题型难度" />
</el-form-item> -->
<el-form-item label="题型难度" prop="quLevel">
<el-select
v-model="formData.quLevel"
placeholder="请选择题型难度"
clearable
>
<el-option label="简单" :value="'0'" />
<el-option label="一般" :value="'1'" />
<el-option label="困难" :value="'2'" />
</el-select>
</el-form-item>
<el-form-item label="题型难度" prop="quLevel">
<el-select
v-model="formData.quLevel"
placeholder="请选择题型难度"
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-form-item>
</el-col> </el-col>
</el-row> </el-row>
@@ -57,11 +72,18 @@
</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 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-row> </el-row>
<el-row> <el-row>
@@ -147,50 +169,6 @@
</el-dialog> </el-dialog>
</div> </div>
</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 v-if="formType === 'update'" name="point"> <el-tab-pane v-if="formType === 'update'" name="point">
<template #label> <template #label>
@@ -203,7 +181,6 @@
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="setKao()">考点设置</el-dropdown-item> <el-dropdown-item @click="setKao()">考点设置</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
@@ -217,7 +194,7 @@
> >
<el-table-column type="index" label="序号" width="60" /> <el-table-column type="index" label="序号" width="60" />
<el-table-column prop="scoreRate" label="权值" width="90" /> <el-table-column prop="scoreRate" label="权值" width="90" />
<el-table-column prop="content" label="文件名(不带后缀)" width="260" /> <el-table-column prop="content" label="文件名" width="260" />
<el-table-column prop="contentIn" label="考察类型" width="300" /> <el-table-column prop="contentIn" label="考察类型" width="300" />
</el-table> </el-table>
</div> </div>
@@ -229,11 +206,12 @@
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;">
<el-table <el-table
:data="kaodianList" :data="kaodiaRefList"
style="width: 100%;" style="width: 100%;"
row-key="answerId" row-key="answerId"
:default-expand-all="false" :default-expand-all="false"
@@ -241,9 +219,9 @@
> >
<el-table-column type="index" label="序号" width="60" /> <el-table-column type="index" label="序号" />
<el-table-column label="文件名(不带后缀)" width="260"> <el-table-column label="文件名" >
<template #default="scope"> <template #default="scope">
<el-input <el-input
v-model="scope.row.content" v-model="scope.row.content"
@@ -252,16 +230,17 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="权值" width="100"> <el-table-column label="权值" >
<template #default="scope"> <template #default="scope">
<el-input <el-input
v-model="scope.row.scoreRate" v-model="scope.row.scoreRate"
size="small" size="small"
type="number" type="number"
min="0"
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="考察类型" width="300"> <el-table-column label="考察类型" >
<template #default="scope"> <template #default="scope">
<el-select <el-select
v-model="scope.row.contentIn" v-model="scope.row.contentIn"
@@ -269,22 +248,37 @@
size="small" size="small"
style="width: 100%" style="width: 100%"
> >
<el-option label="添加到收藏夹" value="添加到收藏夹" />
<el-option label="添加到文件夹" value="添加到文件夹" /> <el-option label="添加到文件夹" value="添加到文件夹" />
<el-option label="添加到收藏夹" value="添加到收藏夹" />
</el-select> </el-select>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="100"> <el-table-column label="操作" width="160">
<template #default="scope"> <template #default="{ $index }">
<el-button <el-button
type="danger" :icon="ArrowUp"
size="small" circle
@click="removeKaodian(scope.$index)" size="small"
> @click="moveUp($index)"
删除 title="上移"
</el-button> />
</template> <el-button
</el-table-column> :icon="ArrowDown"
circle
size="small"
@click="moveDown($index)"
title="下移"
/>
<el-button
:icon="Delete"
circle
type="danger"
size="small"
@click="removeKaodian($index)"
title="删除"
/>
</template>
</el-table-column>
</el-table> </el-table>
@@ -302,12 +296,11 @@
<template #footer> <template #footer>
<el-button @click="kaoDialogVisible = false">取消</el-button> <el-button @click="confimKaoFalse">取消</el-button>
<el-button type="primary" @click="confirmKao">确定</el-button> <el-button type="primary" @click="confirmKao">确定</el-button>
</template> </template>
</el-dialog> </el-dialog>
</el-tab-pane> </el-tab-pane>
@@ -425,7 +418,10 @@
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 { ArrowUp, ArrowDown, Delete } from '@element-plus/icons-vue'
import FileForm from './components/FileForm.vue'; import FileForm from './components/FileForm.vue';
import * as SpecialtyApi from '@/api/points'
import { defaultProps, handleTree } from '@/utils/tree'
defineOptions({ name: 'ChoiceForm' }) defineOptions({ name: 'ChoiceForm' })
const { t } = useI18n() // 国际化 const { t } = useI18n() // 国际化
@@ -438,6 +434,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: '',
@@ -445,9 +443,8 @@ const formData = ref({
required: '', required: '',
chapteridDictText: '', chapteridDictText: '',
analysis: '', analysis: '',
quLevel: '', quLevel: 0,
pointNames: '', pointNames: '',
audit: '',
subjectName: '', subjectName: '',
status: ' ', status: ' ',
keywords: '', keywords: '',
@@ -456,16 +453,11 @@ const formData = ref({
quId: '', quId: '',
url: '', url: '',
fileType: '1', fileType: '1',
fileName: '' fileName: '原始'
},
{
quId: '',
url: '',
fileType: '2',
fileName: ''
}] }]
}) })
const kaodianList = ref<any[]>([]) const kaodianList = ref<any[]>([])
const kaodiaRefList = ref<any[]>([])
function fileTypeFormatter(row, column, cellValue) { function fileTypeFormatter(row, column, cellValue) {
if (cellValue === '1') return '考试文件' if (cellValue === '1') return '考试文件'
return '未知类型' return '未知类型'
@@ -478,16 +470,36 @@ const kaodianData = ref({
quId: '', // 你打开编辑弹窗时会赋值 quId: '', // 你打开编辑弹窗时会赋值
}) })
function setKao() { function setKao() {
kaodiaRefList.value = JSON.parse(JSON.stringify(kaodianList.value))
kaoDialogVisible.value = true kaoDialogVisible.value = true
} }
function confirmKao() { async function confirmKao() {
if (!kaodianList.value.length) { const contentSet = new Set<string>();
ElMessage.warning("没有考点数据");
return; for (const [index, item] of kaodiaRefList.value.entries()) {
if (!item.content || item.content.trim() === '') {
ElMessage.warning(`${index + 1} 行「文件名」不能为空`)
return
}
if (contentSet.has(item.content.trim())) {
ElMessage.warning(`${index + 1} 行「文件名」不能重复`)
return
}
contentSet.add(item.content.trim())
if (item.scoreRate === null || item.scoreRate === '' || item.scoreRate < 0) {
ElMessage.warning(`${index + 1} 行「权值」不能为空且不能小于 0`)
return
}
if (!item.contentIn || item.contentIn.trim() === '') {
ElMessage.warning(`${index + 1} 行「考察类型」不能为空`)
return
}
} }
// 构建 questionAnswerList // 构建 questionAnswerList
const questionAnswerList = kaodianList.value.map(item => ({ const questionAnswerList = kaodiaRefList.value.map(item => ({
answerId: item.answerId, answerId: item.answerId,
content: item.content, content: item.content,
quId:kaodianData.value.quId, quId:kaodianData.value.quId,
@@ -502,18 +514,53 @@ function confirmKao() {
console.log('确认后的结果:', payload) console.log('确认后的结果:', payload)
QuestionApi.setBrowserPoint(payload) await QuestionApi.setBrowserPoint(payload)
const res = await QuestionApi.getListByQuId(kaodianData.value.quId);
kaodianList.value = res;
kaoDialogVisible.value= false;
}
function confimKaoFalse() {
kaoDialogVisible.value= false; kaoDialogVisible.value= false;
} }
// 删除行 // 删除行
function removeKaodian(index: number) { function removeKaodian(index: number) {
kaodianList.value.splice(index, 1)
}
kaodiaRefList.value.splice(index, 1)
}
// 上移
function moveUp(index) {
if (index === 0) return;
const temp = this.kaodiaRefList[index];
this.kaodiaRefList.splice(index, 1);
this.kaodiaRefList.splice(index - 1, 0, temp);
this.updateSort();
}
// 下移
function moveDown(index) {
if (index === this.kaodiaRefList.length - 1) return;
const temp = this.kaodiaRefList[index];
this.kaodiaRefList.splice(index, 1);
this.kaodiaRefList.splice(index + 1, 0, temp);
this.updateSort();
}
// 重新赋值 sort 字段(保持顺序)
function updateSort() {
this.kaodiaRefList.forEach((item, index) => {
item.sort = index + 1;
});
}
// 增加行 // 增加行
function addKaodianRow() { function addKaodianRow() {
kaodianList.value.push({
kaodiaRefList.value.push({
answerId: '', // 用你项目里生成 ID 的方法 answerId: '', // 用你项目里生成 ID 的方法
content: '', content: '',
quId:kaodianData.value.quId, quId:kaodianData.value.quId,
@@ -702,7 +749,7 @@ const open = async (queryParams: any ,type: string, id?: number) => {
kaodianData.value.quId=id; kaodianData.value.quId=id;
formLoading.value = true formLoading.value = true
try { try {
const res = await QuestionApi.getQuestionnotId(id); const res = await QuestionApi.getQuestion(id);
// 默认两个类型 // 默认两个类型
const fileTypes = ['1']; const fileTypes = ['1'];
@@ -738,10 +785,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
} }
} }
@@ -774,10 +821,15 @@ const submitForm = async () => {
// 过滤掉 url 为空的文件项 // 过滤掉 url 为空的文件项
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, "提交的数据");
await QuestionApi.editQuestionNoAudit(data);
if (formType.value === 'create') {
await QuestionApi.addQuestion(data);
message.success(t('common.createSuccess'));
} else {
await QuestionApi.editQuestion(data);
message.success(t('common.updateSuccess')); message.success(t('common.updateSuccess'));
}
dialogVisible.value = false; dialogVisible.value = false;
emit('success'); emit('success');
@@ -790,19 +842,15 @@ const submitForm = async () => {
/** 重置表单 */ /** 重置表单 */
const resetForm = () => { const resetForm = () => {
formData.value = { formData.value = {
content: `--------------------------------------------------------------------- content: `<p>---------------------------------------------------------------------</p><p> 请在打开的窗口中,进行下列操作,完成所有操作后,请关闭窗口。</p><p>---------------------------------------------------------------------</p><p>`,
请在打开的窗口中,进行下列操作,完成所有操作后,请关闭窗口。
---------------------------------------------------------------------
`,
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: '',
@@ -812,19 +860,71 @@ const resetForm = () => {
quId: '', quId: '',
url: '', url: '',
fileType: '1', fileType: '1',
fileName: '' fileName: '原始'
},
{
quId: '',
url: '',
fileType: '2',
fileName: ''
}] }]
} }
keywordList.value=[], keywordList.value=[],
formRef.value?.resetFields() formRef.value?.resetFields()
} }
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;
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.edit-dialog { .edit-dialog {

View File

@@ -1,6 +1,18 @@
<template> <template>
<div class="edit-dialog"> <div class="edit-dialog">
<Dialog v-model="dialogVisible" :title="dialogTitle" width="85%" top="10vh" class="custom-dialog"> <Dialog v-model="dialogVisible" :title="dialogTitle" width="85%" top="10vh" class="custom-dialog">
<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-scrollbar> <el-scrollbar>
<div class="main"> <div class="main">
<el-form <el-form
@@ -16,11 +28,13 @@
<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>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
@@ -29,21 +43,22 @@
</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-input v-model="formData.quLevel" placeholder="请输入题型难度" />
</el-form-item> -->
<el-form-item label="题型难度" prop="quLevel">
<el-select <el-form-item label="题型难度" prop="quLevel">
v-model="formData.quLevel" <el-select
placeholder="请选择题型难度" v-model="formData.quLevel"
clearable placeholder="请选择题型难度"
> clearable
<el-option label="简单" :value="'0'" /> >
<el-option label="一般" :value="'1'" /> <el-option
<el-option label="困难" :value="'2'" /> v-for="dict in getIntDictOptions(DICT_TYPE.EXAM_QUE_DIFF)"
</el-select> :key="dict.value"
</el-form-item> :label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col> </el-col>
@@ -58,10 +73,17 @@
</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-row> </el-row>
<el-row> <el-row>
@@ -222,7 +244,7 @@
> >
<el-table-column type="index" label="序号" width="60" /> <el-table-column type="index" label="序号" width="60" />
<el-table-column prop="scoreRate" label="权值" width="90" /> <el-table-column prop="scoreRate" label="权值" width="90" />
<el-table-column prop="content" label="文件/文件夹名(带后缀)" width="260" /> <el-table-column prop="content" label="文件/文件夹名(带后缀)" width="180" />
<el-table-column prop="contentIn" label="考察类型" width="300" /> <el-table-column prop="contentIn" label="考察类型" width="300" />
</el-table> </el-table>
</div> </div>
@@ -234,39 +256,40 @@
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;">
<el-table <el-table
:data="kaodianList" :data="kaodiaRefList"
style="width: 100%;" style="width: 100%;"
row-key="answerId" row-key="answerId"
:default-expand-all="false" :default-expand-all="false"
> >
<el-table-column type="index" label="序号" />
<el-table-column type="index" label="序号" width="60" /> <el-table-column label="文件/文件夹名(带后缀)" >
<el-table-column label="文件/文件夹名(带后缀)" width="260">
<template #default="scope"> <template #default="scope">
<el-input <el-input
v-model="scope.row.content" v-model="scope.row.content"
size="small" size="small"
type="input" type="input"
@click="openFileTree(scope.row)"
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="权值" width="100"> <el-table-column label="权值" >
<template #default="scope"> <template #default="scope">
<el-input <el-input
v-model="scope.row.scoreRate" v-model="scope.row.scoreRate"
size="small" size="small"
type="number" type="number"
min="0"
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="考察类型" width="300"> <el-table-column label="考察类型" >
<template #default="scope"> <template #default="scope">
<el-select <el-select
v-model="scope.row.contentIn" v-model="scope.row.contentIn"
@@ -280,40 +303,50 @@
</el-select> </el-select>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="100"> <el-table-column label="操作" width="160">
<template #default="scope"> <template #default="{ $index }">
<el-button <el-button
:icon="ArrowUp"
circle
size="small"
@click="moveUp($index)"
title="上移"
/>
<el-button
:icon="ArrowDown"
circle
size="small"
@click="moveDown($index)"
title="下移"
/>
<el-button
:icon="Delete"
circle
type="danger" type="danger"
size="small" size="small"
@click="removeKaodian(scope.$index)" @click="removeKaodian($index)"
> title="删除"
删除 />
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 增加按钮 --> <!-- 增加按钮 -->
<div style="margin-top: 12px; text-align: center;"> <div style="margin-top: 12px; text-align: center;">
<el-button type="primary" @click="setKaodianRow"> <el-button type="primary" @click="setKaodianRow">
导入考点 导入考点
</el-button> </el-button>
<el-button type="primary" @click="addKaodianRow"> <el-button type="primary" @click="addKaodianRow">
添加考点 添加考点
</el-button> </el-button>
</div> </div>
</div> </div>
<template #footer> <template #footer>
<el-button @click="kaoDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmKao">确定</el-button>
<el-button @click="kaoDialogVisible = false">取消</el-button> </template>
<el-button type="primary" @click="confirmKao">确定</el-button> </el-dialog>
</template>
</el-dialog>
@@ -322,20 +355,6 @@
<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>
<!-- 提示 --> <!-- 提示 -->
@@ -418,16 +437,47 @@
</div> </div>
<!-- 表单弹窗添加/修改 --> <!-- 表单弹窗添加/修改 -->
<FileForm ref="FileRef" @success="handleUploadSuccess"/> <FileForm ref="FileRef" @success="handleUploadSuccess"/>
<el-dialog
v-model="fileTreeDialogVisible"
title="选择文件"
width="40%"
:close-on-click-modal="false"
draggable
>
<div style="margin-bottom: 10px; font-weight: bold;">答案目录</div>
<el-tree
:data="fileTreeData"
node-key="id"
:props="{ label: 'name', children: 'children' }"
@node-click="handleFileNodeClick"
default-expand-all
/>
<div style="margin: 20px 0 10px; font-weight: bold;">原始目录</div>
<el-tree
:data="fileTreeStu"
node-key="id"
:props="{ label: 'name', children: 'children' }"
@node-click="handleFileNodeStuClick"
default-expand-all
/>
</el-dialog>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
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 { ArrowUp, ArrowDown, Delete } from '@element-plus/icons-vue'
import * as QuestionApi from '@/api/paper/question' import * as QuestionApi from '@/api/paper/question'
import FileForm from './components/FileForm.vue'; import FileForm from './components/FileForm.vue';
import { defaultProps, handleTree } from '@/utils/tree'
import * as SpecialtyApi from '@/api/points'
defineOptions({ name: 'ChoiceForm' }) defineOptions({ name: 'ChoiceForm' })
// 定义一个缓存对象
const nodeListCache: Record<number, any> = {};
const stuListCache: Record<number, any> = {};
const { t } = useI18n() // 国际化 const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗 const message = useMessage() // 消息弹窗
@@ -435,17 +485,26 @@ const dialogVisible = 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 fileTreeDialogVisible = ref(false);
const fileTreeData = ref<Tree[]>([]);
const fileTreeStu = ref<Tree[]>([]);
const currentEditingRow = ref<any>(null); // 当前点击的行
const formData = ref({ const formData = ref({
content: '', pointNamesVo:'',
chapteridDictTextVo:'',
content: '<p>---------------------------------------------------------------------</p><p> 请在打开的窗口中,进行下列操作,完成所有操作后,请关闭窗口。</p><p>---------------------------------------------------------------------</p><p>',
specialtyName: '', specialtyName: '',
courseName: '', courseName: '',
quBankName: '', quBankName: '',
required: '', required: '',
chapteridDictText: '', chapteridDictText: '',
analysis: '', analysis: '',
quLevel: '', quLevel: 0,
pointNames: '', pointNames: '',
audit: '',
subjectName: '', subjectName: '',
status: ' ', status: ' ',
keywords: '', keywords: '',
@@ -472,26 +531,117 @@ function fileTypeFormatter(row, column, cellValue) {
//考点 //考点
const openFileTree = (row: any) => {
console.log("111")
const quId = kaodianData.value.quId;
const cached = nodeListCache[quId];
const cachedstu = stuListCache[quId]
if (!cached) {
ElMessage.warning('暂无缓存的文件结构');
return;
}
fileTreeData.value.push(...handleTree(cached))
fileTreeStu.value.push(...handleTree(cachedstu))
currentEditingRow.value = row;
fileTreeDialogVisible.value = true;
};
const handleFileNodeClick = (data) => {
const pathArray = findFilePathById(fileTreeData.value, data.id)
if (!pathArray) return
const fullPath = pathArray.join('\\')
if (currentEditingRow.value) {
currentEditingRow.value.content = fullPath
currentEditingRow.value.attribute = data.attribute || ''
}
fileTreeDialogVisible.value = false
}
const handleFileNodeStuClick = (data) => {
const pathArray = findFilePathById(fileTreeStu.value, data.id)
if (!pathArray) return
const fullPath = pathArray.join('\\')
if (currentEditingRow.value) {
currentEditingRow.value.content = fullPath
currentEditingRow.value.attribute = data.attribute || ''
}
fileTreeDialogVisible.value = false
}
const findFilePathById = (
tree: any[],
targetId: number,
path: string[] = []
): string[] | null => {
for (const node of tree) {
const currentPath = [...path, node.name]
if (node.id === targetId) {
return currentPath
}
if (node.children && node.children.length > 0) {
const result = findFilePathById(node.children, targetId, currentPath)
if (result) return result
}
}
return null
}
const kaoDialogVisible = ref(false) const kaoDialogVisible = ref(false)
const kaodianData = ref({ const kaodianData = ref({
quId: '', // 你打开编辑弹窗时会赋值 quId: '', // 你打开编辑弹窗时会赋值
}) })
const kaodianList = ref<any[]>([])
const kaodiaRefList = ref<any[]>([])
function setKao() { function setKao() {
kaodiaRefList.value = JSON.parse(JSON.stringify(kaodianList.value))
kaoDialogVisible.value = true kaoDialogVisible.value = true
} }
const kaodianList = ref<any[]>([]) async function confirmKao() {
function confirmKao() {
if (!kaodianList.value.length) { const contentSet = new Set<string>();
ElMessage.warning("没有考点数据");
return; for (const [index, item] of kaodiaRefList.value.entries()) {
if (!item.content || item.content.trim() === '') {
ElMessage.warning(`${index + 1} 行「文件名」不能为空`)
return
}
if (contentSet.has(item.content.trim())) {
ElMessage.warning(`${index + 1} 行「文件名」不能重复`)
return
}
contentSet.add(item.content.trim())
if (item.scoreRate === null || item.scoreRate === '' || item.scoreRate < 0) {
ElMessage.warning(`${index + 1} 行「权值」不能为空且不能小于 0`)
return
}
if (!item.contentIn || item.contentIn.trim() === '') {
ElMessage.warning(`${index + 1} 行「考察类型」不能为空`)
return
}
} }
// 构建 questionAnswerList // 构建 questionAnswerList
const questionAnswerList = kaodianList.value.map(item => ({ const questionAnswerList = kaodiaRefList.value.map(item => ({
answerId: item.answerId, answerId: item.answerId,
content: item.content, content: item.content,
quId:kaodianData.value.quId, quId:kaodianData.value.quId,
contentIn:item.contentIn, contentIn:item.contentIn,
scoreRate:item.scoreRate scoreRate:item.scoreRate,
attribute:item.attribute
})); }));
const payload = { const payload = {
quId:kaodianData.value.quId, quId:kaodianData.value.quId,
@@ -501,13 +651,17 @@ function confirmKao() {
console.log('确认后的结果:', payload) console.log('确认后的结果:', payload)
QuestionApi.setBrowserPoint(payload) await QuestionApi.setBrowserPoint(payload)
const res = await QuestionApi.getListByQuId(kaodianData.value.quId);
kaodianList.value = res;
kaoDialogVisible.value= false; kaoDialogVisible.value= false;
} }
// 增加行 // 增加行
function addKaodianRow() { function addKaodianRow() {
kaodianList.value.push({ kaodiaRefList.value.push({
answerId: '', // 用你项目里生成 ID 的方法 answerId: '', // 用你项目里生成 ID 的方法
content: '', content: '',
quId:kaodianData.value.quId, quId:kaodianData.value.quId,
@@ -517,9 +671,31 @@ function addKaodianRow() {
} }
// 删除行 // 删除行
function removeKaodian(index: number) { function removeKaodian(index: number) {
kaodianList.value.splice(index, 1) kaodiaRefList.value.splice(index, 1)
} }
// 上移
function moveUp(index) {
if (index === 0) return;
const temp = this.kaodiaRefList[index];
this.kaodiaRefList.splice(index, 1);
this.kaodiaRefList.splice(index - 1, 0, temp);
this.updateSort();
}
// 下移
function moveDown(index) {
if (index === this.kaodiaRefList.length - 1) return;
const temp = this.kaodiaRefList[index];
this.kaodiaRefList.splice(index, 1);
this.kaodiaRefList.splice(index + 1, 0, temp);
this.updateSort();
}
// 重新赋值 sort 字段(保持顺序)
function updateSort() {
this.kaodiaRefList.forEach((item, index) => {
item.sort = index + 1;
});
}
const setKaodianRow =async () => { const setKaodianRow =async () => {
const uploads = formData.value.fileUploads; const uploads = formData.value.fileUploads;
@@ -533,15 +709,21 @@ const setKaodianRow =async () => {
console.log('导入考点的文件地址为:', fileUrl1, fileUrl2); console.log('导入考点的文件地址为:', fileUrl1, fileUrl2);
const params = { const params = {
answerPath: fileUrl1, shucaiPath: fileUrl1,
shucaiPath: fileUrl2 // 如果不传可以是空字符串,也可以删除这个字段(根据后端是否必填) answerPath : fileUrl2 // 如果不传可以是空字符串,也可以删除这个字段(根据后端是否必填)
}; };
const res = await QuestionApi.getFilePoint(params); const res = await QuestionApi.getFilePoint(params);
kaodianList.value=res; kaodiaRefList.value=res.examQuestionAnswerList;
// 示例:调用后端接口进行导入
// importKaodianFromFiles(fileUrl1, fileUrl2); // 缓存 nodeList键为当前 quId
const quId = kaodianData.value.quId;
if (quId) {
nodeListCache[quId] = res.nodeList;
stuListCache[quId]=res.stuList;
}
}; };
@@ -724,7 +906,7 @@ const open = async (queryParams: any ,type: string, id?: number) => {
kaodianData.value.quId=id; kaodianData.value.quId=id;
formLoading.value = true formLoading.value = true
try { try {
const res = await QuestionApi.getQuestionnotId(id); const res = await QuestionApi.getQuestion(id);
// 默认两个类型 // 默认两个类型
const fileTypes = ['1', '2']; const fileTypes = ['1', '2'];
@@ -758,13 +940,17 @@ keywordList.value = res.keywords
} }
} else { } else {
resetForm() resetForm()
console.log(queryParams.pointNamesVo+"queryParams")
console.log(queryParams.chapteridDictTextVo+"queryParams")
console.log(queryParams.pointNames+"queryParams")
console.log(queryParams.chapteridDictText+"queryParams")
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
} }
} }
@@ -797,10 +983,15 @@ const submitForm = async () => {
// 过滤掉 url 为空的文件项 // 过滤掉 url 为空的文件项
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, "提交的数据");
await QuestionApi.editQuestionNoAudit(data) if (formType.value === 'create') {
message.success(t('common.updateSuccess')); await QuestionApi.addQuestion(data);
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');
@@ -813,9 +1004,7 @@ const submitForm = async () => {
/** 重置表单 */ /** 重置表单 */
const resetForm = () => { const resetForm = () => {
formData.value = { formData.value = {
content: `--------------------------------------------------------------------- content: `<p>---------------------------------------------------------------------</p><p> 请在打开的窗口中,进行下列操作,完成所有操作后,请关闭窗口。</p><p>---------------------------------------------------------------------</p><p>
请在打开的窗口中,进行下列操作,完成所有操作后,请关闭窗口。
---------------------------------------------------------------------
`, `,
specialtyName: '', specialtyName: '',
courseName: '', courseName: '',
@@ -823,9 +1012,8 @@ const resetForm = () => {
required: '', required: '',
chapteridDictText: '', chapteridDictText: '',
analysis: '', analysis: '',
quLevel: '0', quLevel: 0,
pointNames: '', pointNames: '',
audit: '',
subjectName: '', subjectName: '',
status: '0', status: '0',
keywords: '', keywords: '',
@@ -834,7 +1022,7 @@ const resetForm = () => {
quId: '', quId: '',
url: '', url: '',
fileType: '1', fileType: '1',
fileName: '原始' fileName: '原始'
}, },
{ {
quId: '', quId: '',
@@ -847,6 +1035,63 @@ const resetForm = () => {
formRef.value?.resetFields() formRef.value?.resetFields()
} }
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;
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.edit-dialog { .edit-dialog {

View File

@@ -459,6 +459,7 @@ const kaodianData = ref({
const formRules = reactive<FormRules>({ const formRules = reactive<FormRules>({
// specialtyName: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }] // specialtyName: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }]
tname: [{ required: true, message: '数据库库名称不能为空', trigger: 'blur' }]
}) })
const formRef = ref() // 表单 Ref const formRef = ref() // 表单 Ref
// 左侧试题描述 // 左侧试题描述

View File

@@ -194,7 +194,7 @@
> >
<el-table-column type="index" label="序号" width="60" /> <el-table-column type="index" label="序号" width="60" />
<el-table-column prop="scoreRate" label="权值" width="90" /> <el-table-column prop="scoreRate" label="权值" width="90" />
<el-table-column prop="content" label="文件名(不带后缀)" width="260" /> <el-table-column prop="content" label="文件名" width="260" />
<el-table-column prop="contentIn" label="考察类型" width="300" /> <el-table-column prop="contentIn" label="考察类型" width="300" />
</el-table> </el-table>
</div> </div>
@@ -219,9 +219,9 @@
> >
<el-table-column type="index" label="序号" width="60" /> <el-table-column type="index" label="序号" />
<el-table-column label="文件名(不带后缀)" width="260"> <el-table-column label="文件名" >
<template #default="scope"> <template #default="scope">
<el-input <el-input
v-model="scope.row.content" v-model="scope.row.content"
@@ -230,7 +230,7 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="权值" width="100"> <el-table-column label="权值" >
<template #default="scope"> <template #default="scope">
<el-input <el-input
v-model="scope.row.scoreRate" v-model="scope.row.scoreRate"
@@ -240,7 +240,7 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="考察类型" width="300"> <el-table-column label="考察类型" >
<template #default="scope"> <template #default="scope">
<el-select <el-select
v-model="scope.row.contentIn" v-model="scope.row.contentIn"
@@ -253,17 +253,32 @@
</el-select> </el-select>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="100"> <el-table-column label="操作" width="160">
<template #default="scope"> <template #default="{ $index }">
<el-button <el-button
type="danger" :icon="ArrowUp"
size="small" circle
@click="removeKaodian(scope.$index)" size="small"
> @click="moveUp($index)"
删除 title="上移"
</el-button> />
</template> <el-button
</el-table-column> :icon="ArrowDown"
circle
size="small"
@click="moveDown($index)"
title="下移"
/>
<el-button
:icon="Delete"
circle
type="danger"
size="small"
@click="removeKaodian($index)"
title="删除"
/>
</template>
</el-table-column>
</el-table> </el-table>
@@ -403,6 +418,7 @@
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 { ArrowUp, ArrowDown, Delete } from '@element-plus/icons-vue'
import FileForm from './components/FileForm.vue'; import FileForm from './components/FileForm.vue';
import * as SpecialtyApi from '@/api/points' import * as SpecialtyApi from '@/api/points'
import { defaultProps, handleTree } from '@/utils/tree' import { defaultProps, handleTree } from '@/utils/tree'
@@ -518,7 +534,29 @@ function removeKaodian(index: number) {
kaodiaRefList.value.splice(index, 1) kaodiaRefList.value.splice(index, 1)
} }
// 上移
function moveUp(index) {
if (index === 0) return;
const temp = this.kaodiaRefList[index];
this.kaodiaRefList.splice(index, 1);
this.kaodiaRefList.splice(index - 1, 0, temp);
this.updateSort();
}
// 下移
function moveDown(index) {
if (index === this.kaodiaRefList.length - 1) return;
const temp = this.kaodiaRefList[index];
this.kaodiaRefList.splice(index, 1);
this.kaodiaRefList.splice(index + 1, 0, temp);
this.updateSort();
}
// 重新赋值 sort 字段(保持顺序)
function updateSort() {
this.kaodiaRefList.forEach((item, index) => {
item.sort = index + 1;
});
}
// 增加行 // 增加行
function addKaodianRow() { function addKaodianRow() {

View File

@@ -244,7 +244,7 @@
> >
<el-table-column type="index" label="序号" width="60" /> <el-table-column type="index" label="序号" width="60" />
<el-table-column prop="scoreRate" label="权值" width="90" /> <el-table-column prop="scoreRate" label="权值" width="90" />
<el-table-column prop="content" label="文件/文件夹名(带后缀)" width="260" /> <el-table-column prop="content" label="文件/文件夹名(带后缀)" width="180" />
<el-table-column prop="contentIn" label="考察类型" width="300" /> <el-table-column prop="contentIn" label="考察类型" width="300" />
</el-table> </el-table>
</div> </div>
@@ -266,9 +266,9 @@
row-key="answerId" row-key="answerId"
:default-expand-all="false" :default-expand-all="false"
> >
<el-table-column type="index" label="序号" width="60" /> <el-table-column type="index" label="序号" />
<el-table-column label="文件/文件夹名(带后缀)" width="260"> <el-table-column label="文件/文件夹名(带后缀)" >
<template #default="scope"> <template #default="scope">
<el-input <el-input
v-model="scope.row.content" v-model="scope.row.content"
@@ -279,7 +279,7 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="权值" width="100"> <el-table-column label="权值" >
<template #default="scope"> <template #default="scope">
<el-input <el-input
v-model="scope.row.scoreRate" v-model="scope.row.scoreRate"
@@ -289,7 +289,7 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="考察类型" width="300"> <el-table-column label="考察类型" >
<template #default="scope"> <template #default="scope">
<el-select <el-select
v-model="scope.row.contentIn" v-model="scope.row.contentIn"
@@ -303,40 +303,50 @@
</el-select> </el-select>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="100"> <el-table-column label="操作" width="160">
<template #default="scope"> <template #default="{ $index }">
<el-button <el-button
:icon="ArrowUp"
circle
size="small"
@click="moveUp($index)"
title="上移"
/>
<el-button
:icon="ArrowDown"
circle
size="small"
@click="moveDown($index)"
title="下移"
/>
<el-button
:icon="Delete"
circle
type="danger" type="danger"
size="small" size="small"
@click="removeKaodian(scope.$index)" @click="removeKaodian($index)"
> title="删除"
删除 />
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 增加按钮 --> <!-- 增加按钮 -->
<div style="margin-top: 12px; text-align: center;"> <div style="margin-top: 12px; text-align: center;">
<el-button type="primary" @click="setKaodianRow"> <el-button type="primary" @click="setKaodianRow">
导入考点 导入考点
</el-button> </el-button>
<el-button type="primary" @click="addKaodianRow"> <el-button type="primary" @click="addKaodianRow">
添加考点 添加考点
</el-button> </el-button>
</div> </div>
</div> </div>
<template #footer> <template #footer>
<el-button @click="kaoDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmKao">确定</el-button>
<el-button @click="kaoDialogVisible = false">取消</el-button> </template>
<el-button type="primary" @click="confirmKao">确定</el-button> </el-dialog>
</template>
</el-dialog>
@@ -459,6 +469,7 @@
<script lang="ts" setup> <script lang="ts" setup>
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 { ArrowUp, ArrowDown, Delete } from '@element-plus/icons-vue'
import * as QuestionApi from '@/api/paper/question' import * as QuestionApi from '@/api/paper/question'
import FileForm from './components/FileForm.vue'; import FileForm from './components/FileForm.vue';
import { defaultProps, handleTree } from '@/utils/tree' import { defaultProps, handleTree } from '@/utils/tree'
@@ -662,7 +673,29 @@ function addKaodianRow() {
function removeKaodian(index: number) { function removeKaodian(index: number) {
kaodiaRefList.value.splice(index, 1) kaodiaRefList.value.splice(index, 1)
} }
// 上移
function moveUp(index) {
if (index === 0) return;
const temp = this.kaodiaRefList[index];
this.kaodiaRefList.splice(index, 1);
this.kaodiaRefList.splice(index - 1, 0, temp);
this.updateSort();
}
// 下移
function moveDown(index) {
if (index === this.kaodiaRefList.length - 1) return;
const temp = this.kaodiaRefList[index];
this.kaodiaRefList.splice(index, 1);
this.kaodiaRefList.splice(index + 1, 0, temp);
this.updateSort();
}
// 重新赋值 sort 字段(保持顺序)
function updateSort() {
this.kaodiaRefList.forEach((item, index) => {
item.sort = index + 1;
});
}
const setKaodianRow =async () => { const setKaodianRow =async () => {
const uploads = formData.value.fileUploads; const uploads = formData.value.fileUploads;

View File

@@ -459,6 +459,7 @@ const kaodianData = ref({
const formRules = reactive<FormRules>({ const formRules = reactive<FormRules>({
// specialtyName: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }] // specialtyName: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }]
tname: [{ required: true, message: '数据库库名称不能为空', trigger: 'blur' }]
}) })
const formRef = ref() // 表单 Ref const formRef = ref() // 表单 Ref
// 左侧试题描述 // 左侧试题描述

View File

@@ -203,8 +203,8 @@
style="flex: 1; min-width: 180px;" style="flex: 1; min-width: 180px;"
/> />
<el-input <el-input
v-model="queryParams.keywords" v-model="queryParams.content"
placeholder="试题关键字" placeholder="试题内容"
clearable clearable
style="flex: 1; min-width: 180px;" style="flex: 1; min-width: 180px;"
/> />
@@ -415,6 +415,7 @@ const queryParams = reactive({
pointNames: "", pointNames: "",
subjectName: "", subjectName: "",
quNum:"", quNum:"",
content:"",
chapteridDictText:"", chapteridDictText:"",
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
@@ -422,7 +423,6 @@ const queryParams = reactive({
status:"0", status:"0",
specialtyName:"", specialtyName:"",
courseName:"", courseName:"",
keywords:""
}) })
const emit = defineEmits(['done']); const emit = defineEmits(['done']);
const visible = defineModel({ type: Boolean }); // 对应 v-model const visible = defineModel({ type: Boolean }); // 对应 v-model
@@ -478,7 +478,7 @@ const resetSearch = () => {
queryParams.pointNames = ''; queryParams.pointNames = '';
queryParams.quLevel = ''; queryParams.quLevel = '';
queryParams.quNum = ''; queryParams.quNum = '';
queryParams.keywords= "", queryParams.content= "",
queryParams.pageNo = 1; queryParams.pageNo = 1;
getList(); getList();
}; };

View File

@@ -203,8 +203,8 @@
style="flex: 1; min-width: 180px;" style="flex: 1; min-width: 180px;"
/> />
<el-input <el-input
v-model="queryParams.keywords" v-model="queryParams.content"
placeholder="试题关键字" placeholder="试题内容"
clearable clearable
style="flex: 1; min-width: 180px;" style="flex: 1; min-width: 180px;"
/> />
@@ -415,7 +415,7 @@ const queryParams = reactive({
pointNames: "", pointNames: "",
subjectName: "", subjectName: "",
quNum:"", quNum:"",
keywords:"", content:"",
chapteridDictText:"", chapteridDictText:"",
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
@@ -478,7 +478,7 @@ const resetSearch = () => {
queryParams.pointNames = ''; queryParams.pointNames = '';
queryParams.quLevel = ''; queryParams.quLevel = '';
queryParams.quNum = ''; queryParams.quNum = '';
queryParams.keywords= "", queryParams.content= "",
queryParams.pageNo = 1; queryParams.pageNo = 1;
getList(); getList();
}; };

View File

@@ -202,9 +202,9 @@
clearable clearable
style="flex: 1; min-width: 180px;" style="flex: 1; min-width: 180px;"
/> />
<el-input <el-input
v-model="queryParams.keywords" v-model="queryParams.content"
placeholder="试题关键字" placeholder="试题内容"
clearable clearable
style="flex: 1; min-width: 180px;" style="flex: 1; min-width: 180px;"
/> />
@@ -415,6 +415,7 @@ const queryParams = reactive({
pointNames: "", pointNames: "",
subjectName: "", subjectName: "",
quNum:"", quNum:"",
content:"",
chapteridDictText:"", chapteridDictText:"",
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
@@ -422,7 +423,6 @@ const queryParams = reactive({
status:"0", status:"0",
specialtyName:"", specialtyName:"",
courseName:"", courseName:"",
keywords:""
}) })
const emit = defineEmits(['done']); const emit = defineEmits(['done']);
const visible = defineModel({ type: Boolean }); // 对应 v-model const visible = defineModel({ type: Boolean }); // 对应 v-model
@@ -478,7 +478,7 @@ const resetSearch = () => {
queryParams.pointNames = ''; queryParams.pointNames = '';
queryParams.quLevel = ''; queryParams.quLevel = '';
queryParams.quNum = ''; queryParams.quNum = '';
queryParams.keywords= "", queryParams.content= "",
queryParams.pageNo = 1; queryParams.pageNo = 1;
getList(); getList();
}; };