feat: 题目新增选项编辑
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
This commit is contained in:
parent
2137559c62
commit
6724e83beb
@ -123,6 +123,12 @@ const optionsHorizontal = computed(() => {
|
||||
return willSimpleOptionsHorizontal(normalizedOptions.value)
|
||||
})
|
||||
|
||||
// 是否可在编辑弹窗中编辑选项(普通选择题)
|
||||
const hasEditableOptions = computed(() => {
|
||||
if (isWanXing.value || isYueDu.value) return false
|
||||
return !!normalizedOptions.value?.length
|
||||
})
|
||||
|
||||
// 显示答案那些
|
||||
const answerVisible = ref(false)
|
||||
const toggleAnswerVisible = () => {
|
||||
@ -146,9 +152,31 @@ const stemUploading = ref(false)
|
||||
const stemEditorRef = ref<HTMLElement>()
|
||||
const answerEditorRef = ref<HTMLElement>()
|
||||
const explanationEditorRef = ref<HTMLElement>()
|
||||
const optionEditorRefs = ref<HTMLElement[]>([])
|
||||
const editOptions = ref<{ label: string; value: string }[]>([])
|
||||
const stemUploadInputRef = ref<HTMLInputElement>()
|
||||
const stemSelectionRange = ref<null | Range>(null)
|
||||
|
||||
const setOptionEditorRef = (el: any, idx: number) => {
|
||||
if (el) optionEditorRefs.value[idx] = el
|
||||
}
|
||||
|
||||
function getEditableOptionsFromQuestion() {
|
||||
const opts = normalizedOptions.value
|
||||
if (!opts?.length || isWanXing.value || isYueDu.value) return []
|
||||
return opts.map((o: any) => ({
|
||||
label: o.label ?? '',
|
||||
value: o.value ?? '',
|
||||
}))
|
||||
}
|
||||
|
||||
function buildOptionHtmlFromEditors() {
|
||||
return editOptions.value.map((opt, idx) => ({
|
||||
index: opt.label,
|
||||
html: optionEditorRefs.value[idx]?.innerHTML ?? opt.value ?? '',
|
||||
}))
|
||||
}
|
||||
|
||||
const saveStemSelection = () => {
|
||||
const selection = window.getSelection()
|
||||
if (!selection || selection.rangeCount === 0) return
|
||||
@ -234,11 +262,17 @@ const handleEdit = () => {
|
||||
const q = props.question as any
|
||||
editDialogVisible.value = true
|
||||
stemSelectionRange.value = null
|
||||
editOptions.value = getEditableOptionsFromQuestion()
|
||||
optionEditorRefs.value = []
|
||||
nextTick(() => {
|
||||
if (stemEditorRef.value) stemEditorRef.value.innerHTML = q.stem || ''
|
||||
if (answerEditorRef.value) answerEditorRef.value.innerHTML = q.answer || ''
|
||||
if (explanationEditorRef.value)
|
||||
explanationEditorRef.value.innerHTML = q.explanation || ''
|
||||
editOptions.value.forEach((opt, idx) => {
|
||||
const el = optionEditorRefs.value[idx]
|
||||
if (el) el.innerHTML = opt.value || ''
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -249,17 +283,27 @@ const handleEditSave = async () => {
|
||||
const stem = stemEditorRef.value?.innerHTML || ''
|
||||
const answer = answerEditorRef.value?.innerHTML || ''
|
||||
const explanation = explanationEditorRef.value?.innerHTML || ''
|
||||
await saveOrUpdateXkwQuestionTitle({
|
||||
const payload: Record<string, any> = {
|
||||
id: q.id,
|
||||
stem,
|
||||
stemHtml: stem,
|
||||
answer,
|
||||
answerHtml: answer,
|
||||
explanation,
|
||||
})
|
||||
}
|
||||
if (hasEditableOptions.value && editOptions.value.length) {
|
||||
const optionData = buildOptionHtmlFromEditors()
|
||||
const optionHtml = JSON.stringify(optionData)
|
||||
payload.optionHtml = optionHtml
|
||||
}
|
||||
await saveOrUpdateXkwQuestionTitle(payload)
|
||||
q.stem = stem
|
||||
q.answer = answer
|
||||
q.explanation = explanation
|
||||
if (payload.optionHtml) {
|
||||
q.optionHtml = payload.optionHtml
|
||||
q.optionList = JSON.parse(payload.optionHtml)
|
||||
}
|
||||
editDialogVisible.value = false
|
||||
ElMessage.success('保存成功')
|
||||
} finally {
|
||||
@ -504,6 +548,21 @@ const handleEditSave = async () => {
|
||||
@blur="saveStemSelection"
|
||||
></div>
|
||||
</div>
|
||||
<div v-if="hasEditableOptions" class="edit-field">
|
||||
<div class="edit-field-label">选项</div>
|
||||
<div
|
||||
v-for="(opt, idx) in editOptions"
|
||||
:key="opt.label"
|
||||
class="edit-option-item"
|
||||
>
|
||||
<span class="edit-option-label">{{ opt.label }}.</span>
|
||||
<div
|
||||
:ref="(el) => setOptionEditorRef(el, idx)"
|
||||
class="edit-field-editor paper-question-item edit-option-editor"
|
||||
contenteditable="true"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit-field">
|
||||
<div class="edit-field-label">答案</div>
|
||||
<div
|
||||
@ -1143,6 +1202,25 @@ $padding: 16px;
|
||||
content: '请输入内容';
|
||||
}
|
||||
}
|
||||
|
||||
.edit-option-item {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: flex-start;
|
||||
|
||||
.edit-option-label {
|
||||
flex-shrink: 0;
|
||||
min-width: 24px;
|
||||
padding-top: 12px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.edit-option-editor {
|
||||
flex: 1;
|
||||
min-height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user