Files
EasyFlow/easyflow-ui-admin/app/src/views/ai/documentCollection/FaqEditDialog.vue

202 lines
4.6 KiB
Vue

<script setup lang="ts">
import type {IDomEditor} from '@wangeditor/editor';
import {onBeforeUnmount, ref, shallowRef, watch} from 'vue';
import {$t} from '@easyflow/locales';
import {ElButton, ElDialog, ElForm, ElFormItem, ElInput, ElMessage} from 'element-plus';
import DOMPurify from 'dompurify';
import {Editor, Toolbar} from '@wangeditor/editor-for-vue';
import '@wangeditor/editor/dist/css/style.css';
const props = defineProps({
modelValue: {
type: Boolean,
default: false,
},
data: {
type: Object as any,
default: () => ({}),
},
});
const emit = defineEmits(['submit', 'update:modelValue']);
const editorRef = shallowRef<IDomEditor | null>(null);
const form = ref<any>({
id: '',
collectionId: '',
question: '',
answerHtml: '',
orderNo: 0,
});
watch(
() => props.data,
(newData: any) => {
form.value = {
id: newData?.id || '',
collectionId: newData?.collectionId || '',
question: newData?.question || '',
answerHtml: newData?.answerHtml || '',
orderNo: newData?.orderNo ?? 0,
};
},
{ immediate: true, deep: true },
);
const toolbarConfig = {
excludeKeys: [
'uploadImage',
'insertImage',
'group-image',
'insertVideo',
'group-video',
'uploadVideo',
'todo',
'emotion',
],
};
const editorConfig = {
placeholder: $t('documentCollection.faq.answerPlaceholder'),
};
const handleEditorCreated = (editor: IDomEditor) => {
editorRef.value = editor;
};
const closeDialog = () => {
emit('update:modelValue', false);
};
const handleSubmit = () => {
if (!form.value.question?.trim()) {
ElMessage.error($t('documentCollection.faq.questionRequired'));
return;
}
const sanitizedHtml = DOMPurify.sanitize(form.value.answerHtml || '');
const pureText = sanitizedHtml.replace(/<[^>]*>/g, '').trim();
if (!pureText) {
ElMessage.error($t('documentCollection.faq.answerRequired'));
return;
}
emit('submit', {
...form.value,
question: form.value.question.trim(),
answerHtml: sanitizedHtml,
orderNo: Number(form.value.orderNo) || 0,
});
};
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor) {
editor.destroy();
}
});
</script>
<template>
<ElDialog
class="faq-edit-dialog"
:model-value="modelValue"
:title="form.id ? $t('button.edit') : $t('button.add')"
width="min(920px, 92vw)"
:close-on-click-modal="false"
@close="closeDialog"
>
<ElForm class="faq-form" label-position="top">
<ElFormItem :label="$t('documentCollection.faq.question')">
<ElInput
v-model="form.question"
:placeholder="$t('documentCollection.faq.questionPlaceholder')"
/>
</ElFormItem>
<ElFormItem :label="$t('documentCollection.faq.answer')">
<div class="editor-wrapper">
<Toolbar
:editor="editorRef"
:default-config="toolbarConfig"
mode="default"
/>
<Editor
v-model="form.answerHtml"
:default-config="editorConfig"
mode="default"
@on-created="handleEditorCreated"
/>
</div>
</ElFormItem>
</ElForm>
<template #footer>
<div class="dialog-footer">
<ElButton class="footer-btn" @click="closeDialog">{{ $t('button.cancel') }}</ElButton>
<ElButton class="footer-btn" type="primary" @click="handleSubmit">
{{ $t('button.save') }}
</ElButton>
</div>
</template>
</ElDialog>
</template>
<style scoped>
.faq-form :deep(.el-form-item__label) {
padding-bottom: 8px;
font-weight: 600;
}
.editor-wrapper {
width: 100%;
border: 1px solid var(--el-border-color-light);
border-radius: 10px;
background: var(--el-fill-color-blank);
overflow: hidden;
transition: border-color 0.2s ease;
}
.editor-wrapper:focus-within {
border-color: var(--el-color-primary);
}
:deep(.w-e-toolbar) {
border-bottom: 1px solid var(--el-border-color-lighter);
background: var(--el-fill-color-blank);
}
:deep(.w-e-text-container) {
min-height: 320px;
background: var(--el-fill-color-blank);
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 12px;
}
.footer-btn {
min-width: 88px;
}
:deep(.faq-edit-dialog .el-dialog) {
border-radius: 14px;
overflow: hidden;
}
:deep(.faq-edit-dialog .el-dialog__header) {
margin-right: 0;
padding: 18px 22px;
border-bottom: 1px solid var(--el-border-color-lighter);
}
:deep(.faq-edit-dialog .el-dialog__body) {
padding: 18px 22px 16px;
}
:deep(.faq-edit-dialog .el-dialog__footer) {
padding: 12px 22px 18px;
border-top: 1px solid var(--el-border-color-lighter);
}
</style>