|
|
@@ -196,6 +196,9 @@
|
|
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
|
|
|
v-hasPermi="['learn:questions:edit']">修改
|
|
|
</el-button>
|
|
|
+ <el-button link type="primary" icon="" @click="handleTextUpdate(scope.row)"
|
|
|
+ v-hasPermi="['learn:questions:edit']">文本修改
|
|
|
+ </el-button>
|
|
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
|
|
|
v-hasPermi="['learn:questions:remove']">删除
|
|
|
</el-button>
|
|
|
@@ -207,106 +210,184 @@
|
|
|
v-model:limit="queryParams.pageSize" @pagination="getList"/>
|
|
|
|
|
|
<!-- 添加或修改试题对话框 -->
|
|
|
- <el-dialog :title="title" v-model="open" width="700px" append-to-body>
|
|
|
- <el-form ref="questionsRef" :model="form" :rules="rules" label-width="140px">
|
|
|
- <el-form-item label="题型" prop="qtpye">
|
|
|
- <el-input v-model="form.qtpye" type="text" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="试题-题干" prop="title">
|
|
|
- <el-input v-model="form.title" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="选项A" prop="optionA">
|
|
|
- <el-input v-model="form.optionA" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="选项B" prop="optionB">
|
|
|
- <el-input v-model="form.optionB" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="选项C" prop="optionC">
|
|
|
- <el-input v-model="form.optionC" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="选项D" prop="optionD">
|
|
|
- <el-input v-model="form.optionD" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="选项E" prop="optionE">
|
|
|
- <el-input v-model="form.optionE" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="选项D" prop="optionF">
|
|
|
- <el-input v-model="form.optionF" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="选项E" prop="optionG">
|
|
|
- <el-input v-model="form.optionG" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="标准答案" prop="answer1">
|
|
|
- <el-input v-model="form.answer1" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="非标准答案" prop="answer2">
|
|
|
- <el-input v-model="form.answer2" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="类型" prop="qtpye">
|
|
|
- <!-- <el-input v-model="form.qtpye" placeholder="请输入类型" /> -->
|
|
|
+ <el-dialog :title="title" v-model="open" width="1200px" append-to-body>
|
|
|
+ <div class="form-content-wrapper">
|
|
|
+ <el-form ref="questionsRef" :model="form" :rules="rules" label-width="140px">
|
|
|
+ <!-- 只读显示区域:题目标题和选项(仅在修改时显示) -->
|
|
|
+ <div class="readonly-section" v-if="form.id != null">
|
|
|
+ <el-form-item label="标题">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.title) || '-'"></div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-row :gutter="20" v-if="form.optionA || form.optionB || form.optionC || form.optionD || form.optionE || form.optionF || form.optionG">
|
|
|
+ <el-col :span="12" v-if="form.optionA">
|
|
|
+ <el-form-item label="选项A">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.optionA)"></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" v-if="form.optionB">
|
|
|
+ <el-form-item label="选项B">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.optionB)"></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" v-if="form.optionC">
|
|
|
+ <el-form-item label="选项C">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.optionC)"></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" v-if="form.optionD">
|
|
|
+ <el-form-item label="选项D">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.optionD)"></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" v-if="form.optionE">
|
|
|
+ <el-form-item label="选项E">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.optionE)"></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" v-if="form.optionF">
|
|
|
+ <el-form-item label="选项F">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.optionF)"></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" v-if="form.optionG">
|
|
|
+ <el-form-item label="选项G">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.optionG)"></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20" v-if="form.answer1 || form.answer2">
|
|
|
+ <el-col :span="12" v-if="form.answer1">
|
|
|
+ <el-form-item label="答案1">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.answer1)"></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" v-if="form.answer2">
|
|
|
+ <el-form-item label="答案2">
|
|
|
+ <div class="readonly-content" v-html="formatContentWithImages(form.answer2)"></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 横线分隔(仅在修改时显示) -->
|
|
|
+ <el-divider v-if="form.id != null"></el-divider>
|
|
|
+
|
|
|
+ <!-- 可修改内容区域,两列布局 -->
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="科目" prop="subjectId">
|
|
|
+ <el-select v-model="form.subjectId" placeholder="请选择科目" style="width: 100%">
|
|
|
+ <el-option v-for="s in subjectList" :label="s.subjectName" :value="s.subjectId"/>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="题型" prop="qtpye">
|
|
|
+ <el-input v-model="form.qtpye" type="text" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-form-item label="标题" prop="title">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.title" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.title" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入标题内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="选项A" prop="optionA">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.optionA" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.optionA" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="选项B" prop="optionB">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.optionB" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.optionB" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="选项C" prop="optionC">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.optionC" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.optionC" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="选项D" prop="optionD">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.optionD" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.optionD" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="选项E" prop="optionE">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.optionE" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.optionE" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="选项F" prop="optionF">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.optionF" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.optionF" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="选项G" prop="optionG">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.optionG" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.optionG" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="答案1" prop="answer1">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.answer1" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.answer1" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="答案2" prop="answer2">
|
|
|
+ <Editor v-if="!isTextMode" v-model="form.answer2" :min-height="120" />
|
|
|
+ <el-input v-else v-model="form.answer2" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <!-- <el-form-item label="题型" prop="qtpye">
|
|
|
<el-select v-model="form.typeId" placeholder="请选择类型">
|
|
|
<el-option v-for="q in question_type" :label="q.label" :value="q.value"/>
|
|
|
</el-select>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="学科" prop="subjectId">
|
|
|
- <el-select v-model="form.subjectId" placeholder="请选择学科">
|
|
|
- <el-option v-for="s in subjectList" :label="s.subjectName" :value="s.subjectId"/>
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- <!-- <el-form-item label="${comment}" prop="paperId">
|
|
|
- <el-input v-model="form.paperId" placeholder="请输入${comment}" />
|
|
|
</el-form-item> -->
|
|
|
- <el-form-item label="知识点" prop="knowledgeId">
|
|
|
- <el-tree-select node-key="id" v-model="form.knowledgeId" :data="knowledgeTreeList" check-strictly
|
|
|
- :render-after-expand="false" style=""
|
|
|
- :props="{ label: 'name', children: 'children' }"
|
|
|
- placeholder="请选择知识点"/>
|
|
|
- </el-form-item>
|
|
|
- <!-- <el-form-item label="${comment}" prop="diff">
|
|
|
- <el-input v-model="form.diff" placeholder="请输入${comment}"/>
|
|
|
- </el-form-item> -->
|
|
|
- <el-form-item label="相似度" prop="similarity">
|
|
|
- <el-input v-model="form.similarity" placeholder="请输入相似度"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="试题解析" prop="parse">
|
|
|
- <el-input v-model="form.parse" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
- <!-- <el-form-item label="${comment}" prop="knowId">
|
|
|
- <el-input v-model="form.knowId" placeholder="请输入${comment}" />
|
|
|
- </el-form-item> -->
|
|
|
- <el-form-item label="年级ID" prop="gradeId">
|
|
|
- <el-input v-model="form.gradeId" placeholder="请输入年级ID"/>
|
|
|
- </el-form-item>
|
|
|
- <!-- <el-form-item label="${comment}" prop="knowledges">
|
|
|
- <el-input v-model="form.knowledges" placeholder="请输入${comment}" />
|
|
|
- </el-form-item> -->
|
|
|
- <el-form-item label="试题区域" prop="area">
|
|
|
- <el-input v-model="form.area" placeholder="请输入试题区域"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="试题年份" prop="year">
|
|
|
- <el-input v-model="form.year" placeholder="请输入试题年份"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="试题类型" prop="paperTpye">
|
|
|
- <el-input v-model="form.paperTpye" placeholder="请输入试题"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="来源" prop="source">
|
|
|
- <el-input v-model="form.source" placeholder="请输入来源"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="试题来源" prop="fromSite">
|
|
|
- <el-input v-model="form.fromSite" placeholder="请输入试题来源"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="是否存在图片水印" prop="isSub">
|
|
|
- <el-input v-model="form.isSub" placeholder="请输入是否存在图片水印"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="是否常规题" prop="isNormal">
|
|
|
- <el-input v-model="form.isNormal" placeholder="请输入是否常规题"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="是否匹配章节知识点" prop="isKonw">
|
|
|
- <el-input v-model="form.isKonw" placeholder="请输入是否匹配章节知识点"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="试题的tiid" prop="tiid">
|
|
|
- <el-input v-model="form.tiid" placeholder="请输入试题的tiid"/>
|
|
|
- </el-form-item>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="知识点" prop="knowledgeId">
|
|
|
+ <el-tree-select node-key="id" v-model="form.knowledgeId" :data="knowledgeTreeList" check-strictly
|
|
|
+ :render-after-expand="false" style="width: 100%"
|
|
|
+ :props="{ label: 'name', children: 'children' }"
|
|
|
+ placeholder="请选择知识点"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="来源" prop="source">
|
|
|
+ <el-input v-model="form.source" placeholder="请输入来源"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="源ID" prop="tiid">
|
|
|
+ <el-input v-model="form.tiid" placeholder="请输入试题的源ID"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="试题解析" prop="parse">
|
|
|
+ <el-input v-model="form.parse" type="textarea" :autosize="{ minRows: 3 }" placeholder="请输入内容"/>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
<!-- <el-form-item label="试题题干的md5值" prop="md5">
|
|
|
<el-input v-model="form.md5" placeholder="请输入试题题干的md5值" />
|
|
|
</el-form-item> -->
|
|
|
@@ -316,19 +397,19 @@
|
|
|
<!-- <el-form-item label="${comment}" prop="md52">
|
|
|
<el-input v-model="form.md52" placeholder="请输入${comment}" />
|
|
|
</el-form-item> -->
|
|
|
- <el-form-item label="分值" prop="score">
|
|
|
+ <!-- <el-form-item label="分值" prop="score">
|
|
|
<el-input v-model="form.score" placeholder="请输入分值"/>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="选项" prop="options">
|
|
|
<el-input v-model="form.options" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
+ </el-form-item> -->
|
|
|
<!-- <el-form-item label="${comment}" prop="number">
|
|
|
<el-input v-model="form.number" placeholder="请输入${comment}" />
|
|
|
</el-form-item> -->
|
|
|
<!-- <el-form-item label="${comment}" prop="paperTypeTitle">
|
|
|
<el-input v-model="form.paperTypeTitle" placeholder="请输入${comment}" />
|
|
|
</el-form-item> -->
|
|
|
- <el-form-item label="选项" prop="options0">
|
|
|
+ <!-- <el-form-item label="选项" prop="options0">
|
|
|
<el-input v-model="form.options0" type="textarea" placeholder="请输入内容"/>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="试题-材料题题干" prop="title0">
|
|
|
@@ -339,14 +420,15 @@
|
|
|
</el-form-item>
|
|
|
<el-form-item label="试题解析" prop="parse0">
|
|
|
<el-input v-model="form.parse0" type="textarea" placeholder="请输入内容"/>
|
|
|
- </el-form-item>
|
|
|
+ </el-form-item> -->
|
|
|
<!-- <el-form-item label="${comment}" prop="answer0">
|
|
|
<el-input v-model="form.answer0" type="textarea" placeholder="请输入内容" />
|
|
|
</el-form-item> -->
|
|
|
- <el-form-item label="是否更新" prop="isUpdate">
|
|
|
+ <!-- <el-form-item label="是否更新" prop="isUpdate">
|
|
|
<el-input v-model="form.isUpdate" placeholder="请输入是否更新"/>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
+ </el-form-item> -->
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
<template #footer>
|
|
|
<div class="dialog-footer">
|
|
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
|
|
@@ -422,6 +504,7 @@ import {listKnowledgeTree} from "@/api/learn/knowledgeTree"
|
|
|
import {listAllSubject} from "@/api/dz/subject"
|
|
|
import {ElMessage} from "element-plus";
|
|
|
import DictTag from '@/components/DictTag/index.vue'
|
|
|
+import Editor from '@/components/Editor/index.vue'
|
|
|
import { computed } from 'vue'
|
|
|
|
|
|
const {proxy} = getCurrentInstance()
|
|
|
@@ -445,6 +528,7 @@ const typeForm = ref({
|
|
|
const showTypeDialog = ref(false)
|
|
|
const showOptionsDialog = ref(false)
|
|
|
const currentRow = ref({})
|
|
|
+const isTextMode = ref(false) // 是否为文本模式(false为富文本模式)
|
|
|
|
|
|
const subjectList = ref([])
|
|
|
const knowledgeTreeList = ref([])
|
|
|
@@ -493,6 +577,7 @@ const data = reactive({
|
|
|
answer1: null,
|
|
|
answer2: null,
|
|
|
qtpye: null,
|
|
|
+ typeId: null,
|
|
|
subjectId: null,
|
|
|
paperId: null,
|
|
|
knowledgeId: null,
|
|
|
@@ -568,6 +653,7 @@ function getSubjectName(subjectId) {
|
|
|
// 取消按钮
|
|
|
function cancel() {
|
|
|
open.value = false
|
|
|
+ isTextMode.value = false // 重置模式
|
|
|
reset()
|
|
|
}
|
|
|
|
|
|
@@ -620,7 +706,11 @@ function reset() {
|
|
|
isUpdate: null,
|
|
|
isSubType: null
|
|
|
}
|
|
|
- proxy.resetForm("questionsRef")
|
|
|
+ // 先重置表单验证状态
|
|
|
+ if (proxy.$refs["questionsRef"]) {
|
|
|
+ proxy.$refs["questionsRef"].resetFields()
|
|
|
+ proxy.$refs["questionsRef"].clearValidate()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/** 科目变化处理 */
|
|
|
@@ -639,6 +729,8 @@ function handleQuery() {
|
|
|
/** 重置按钮操作 */
|
|
|
function resetQuery() {
|
|
|
proxy.resetForm("queryRef")
|
|
|
+ // 手动清除 typeId,因为 resetForm 可能无法清除 el-select 的值
|
|
|
+ queryParams.value.typeId = null
|
|
|
handleQuery()
|
|
|
}
|
|
|
|
|
|
@@ -652,13 +744,27 @@ function handleSelectionChange(selection) {
|
|
|
/** 新增按钮操作 */
|
|
|
function handleAdd() {
|
|
|
reset()
|
|
|
+ isTextMode.value = false // 新增使用富文本模式
|
|
|
open.value = true
|
|
|
title.value = "添加试题"
|
|
|
}
|
|
|
|
|
|
+/** 文本修改按钮操作 */
|
|
|
+function handleTextUpdate(row) {
|
|
|
+ reset()
|
|
|
+ isTextMode.value = true // 文本修改使用普通文本模式
|
|
|
+ const _id = row.id || ids.value
|
|
|
+ getQuestions(_id).then(response => {
|
|
|
+ form.value = response.data
|
|
|
+ open.value = true
|
|
|
+ title.value = "文本修改"
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
/** 修改按钮操作 */
|
|
|
function handleUpdate(row) {
|
|
|
reset()
|
|
|
+ isTextMode.value = false // 修改使用富文本模式
|
|
|
const _id = row.id || ids.value
|
|
|
getQuestions(_id).then(response => {
|
|
|
form.value = response.data
|
|
|
@@ -671,16 +777,19 @@ function handleUpdate(row) {
|
|
|
function submitForm() {
|
|
|
proxy.$refs["questionsRef"].validate(valid => {
|
|
|
if (valid) {
|
|
|
+ // 提交所有可编辑字段(包括题干和选项)
|
|
|
if (form.value.id != null) {
|
|
|
updateQuestions(form.value).then(response => {
|
|
|
proxy.$modal.msgSuccess("修改成功")
|
|
|
open.value = false
|
|
|
+ isTextMode.value = false // 重置模式
|
|
|
getList()
|
|
|
})
|
|
|
} else {
|
|
|
addQuestions(form.value).then(response => {
|
|
|
proxy.$modal.msgSuccess("新增成功")
|
|
|
open.value = false
|
|
|
+ isTextMode.value = false // 重置模式
|
|
|
getList()
|
|
|
})
|
|
|
}
|
|
|
@@ -728,6 +837,86 @@ function handleShowOptions(row) {
|
|
|
showOptionsDialog.value = true
|
|
|
}
|
|
|
|
|
|
+/** 获取图片代理URL(如果需要后端代理,可以在这里实现) */
|
|
|
+function getImageProxyUrl(imageUrl) {
|
|
|
+ if (!imageUrl) return ''
|
|
|
+
|
|
|
+ // 如果是相对路径或本地路径,直接返回
|
|
|
+ if (!imageUrl.startsWith('http://') && !imageUrl.startsWith('https://') && !imageUrl.startsWith('//')) {
|
|
|
+ return imageUrl
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果需要通过后端代理访问第三方图片,可以取消下面的注释
|
|
|
+ // 注意:需要后端提供图片代理接口
|
|
|
+ // const encodedUrl = encodeURIComponent(imageUrl)
|
|
|
+ // return `${import.meta.env.VITE_APP_BASE_API}/common/image/proxy?url=${encodedUrl}`
|
|
|
+
|
|
|
+ // 暂时直接返回原URL,通过添加跨域属性来处理
|
|
|
+ return imageUrl
|
|
|
+}
|
|
|
+
|
|
|
+/** 格式化内容,将图片URL转换为img标签 */
|
|
|
+function formatContentWithImages(content) {
|
|
|
+ if (!content) return ''
|
|
|
+
|
|
|
+ // 如果内容已经是HTML格式(包含img标签),需要处理其中的图片URL
|
|
|
+ if (content.includes('<img') || content.includes('<IMG')) {
|
|
|
+ // 提取所有img标签中的src属性
|
|
|
+ const imgSrcRegex = /<img[^>]+src=["']([^"']+)["'][^>]*>/gi
|
|
|
+ let formattedContent = content
|
|
|
+
|
|
|
+ formattedContent = formattedContent.replace(imgSrcRegex, (match, src) => {
|
|
|
+ // 如果是第三方图片URL,转换为代理URL
|
|
|
+ let imageUrl = src
|
|
|
+ if (src.startsWith('http://') || src.startsWith('https://') || src.startsWith('//')) {
|
|
|
+ // 对于第三方图片,尝试使用代理
|
|
|
+ // 如果代理不可用,则使用原URL并添加跨域属性
|
|
|
+ imageUrl = getImageProxyUrl(src)
|
|
|
+ // 如果代理URL和原URL相同(代理不可用),添加跨域属性
|
|
|
+ if (imageUrl === src) {
|
|
|
+ return match.replace(src, src).replace('<img', '<img crossorigin="anonymous" referrerpolicy="no-referrer"')
|
|
|
+ } else {
|
|
|
+ return match.replace(src, imageUrl)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return match
|
|
|
+ })
|
|
|
+
|
|
|
+ return formattedContent
|
|
|
+ }
|
|
|
+
|
|
|
+ // 匹配图片URL的正则表达式
|
|
|
+ // 支持:https://、http://、//开头的完整URL,以及相对路径
|
|
|
+ const imageUrlRegex = /(https?:\/\/[^\s<>"']+\.(jpg|jpeg|png|gif|bmp|webp|svg)(\?[^\s<>"']*)?)|(\/\/[^\s<>"']+\.(jpg|jpeg|png|gif|bmp|webp|svg)(\?[^\s<>"']*)?)|(\/[^\s<>"']+\.(jpg|jpeg|png|gif|bmp|webp|svg)(\?[^\s<>"']*)?)/gi
|
|
|
+
|
|
|
+ // 将纯文本的图片URL转换为img标签
|
|
|
+ let formattedContent = content
|
|
|
+ const matches = content.match(imageUrlRegex)
|
|
|
+
|
|
|
+ if (matches) {
|
|
|
+ matches.forEach(url => {
|
|
|
+ // 确保URL是完整的
|
|
|
+ let imageUrl = url.trim()
|
|
|
+ // 如果是以//开头的,添加https:
|
|
|
+ if (imageUrl.startsWith('//')) {
|
|
|
+ imageUrl = 'https:' + imageUrl
|
|
|
+ }
|
|
|
+
|
|
|
+ // 对于第三方图片,尝试使用代理
|
|
|
+ const proxyUrl = getImageProxyUrl(imageUrl)
|
|
|
+ // 如果代理不可用,使用原URL并添加跨域属性
|
|
|
+ const finalUrl = proxyUrl !== imageUrl ? proxyUrl : imageUrl
|
|
|
+ const crossOriginAttr = proxyUrl === imageUrl ? 'crossorigin="anonymous" referrerpolicy="no-referrer"' : ''
|
|
|
+
|
|
|
+ // 将URL替换为img标签
|
|
|
+ const imgTag = `<img src="${finalUrl}" ${crossOriginAttr} alt="图片" style="max-width: 100%; height: auto; display: block; margin: 10px 0;" onerror="this.onerror=null; this.src='${imageUrl}'; this.style.border='1px solid #ddd'; this.alt='图片加载失败,点击查看原图'; this.style.cursor='pointer'; this.title='点击查看原图'; this.onclick='window.open(this.src)';" />`
|
|
|
+ formattedContent = formattedContent.replace(url, imgTag)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ return formattedContent
|
|
|
+}
|
|
|
+
|
|
|
getKnowledgeTreeList()
|
|
|
getSubjectList()
|
|
|
getList()
|
|
|
@@ -762,4 +951,41 @@ getList()
|
|
|
color: #909399;
|
|
|
padding: 20px 0;
|
|
|
}
|
|
|
+
|
|
|
+.readonly-section {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ padding: 15px;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.readonly-content {
|
|
|
+ color: #606266;
|
|
|
+ word-break: break-word;
|
|
|
+ white-space: pre-wrap;
|
|
|
+ line-height: 1.6;
|
|
|
+ min-height: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.readonly-content :deep(img) {
|
|
|
+ max-width: 100%;
|
|
|
+ height: auto;
|
|
|
+ display: block;
|
|
|
+ margin: 10px 0;
|
|
|
+ border-radius: 4px;
|
|
|
+ object-fit: contain;
|
|
|
+}
|
|
|
+
|
|
|
+.readonly-content :deep(img[src=""]) {
|
|
|
+ display: none;
|
|
|
+}
|
|
|
+
|
|
|
+.readonly-content :deep(img:not([src])) {
|
|
|
+ display: none;
|
|
|
+}
|
|
|
+
|
|
|
+.form-content-wrapper {
|
|
|
+ max-width: 1100px;
|
|
|
+ margin: 0 auto;
|
|
|
+}
|
|
|
</style>
|