|
|
@@ -0,0 +1,61 @@
|
|
|
+<template>
|
|
|
+ <div class="notice-editor">
|
|
|
+ <Toolbar :editor="editorRef" :default-config="toolbarConfig" mode="default" />
|
|
|
+ <Editor v-model="html" :default-config="editorConfig" mode="default" style="height: 500px" @on-created="handleCreated" />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { computed, onBeforeUnmount, shallowRef } from 'vue'
|
|
|
+import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
|
|
+import '@wangeditor/editor/dist/css/style.css'
|
|
|
+import request from '@/utils/request'
|
|
|
+
|
|
|
+const props = defineProps({ modelValue: { type: String, default: '' } })
|
|
|
+const emit = defineEmits(['update:modelValue'])
|
|
|
+const editorRef = shallowRef()
|
|
|
+const html = computed({
|
|
|
+ get: () => props.modelValue || '',
|
|
|
+ set: value => emit('update:modelValue', value)
|
|
|
+})
|
|
|
+const toolbarConfig = { excludeKeys: ['uploadVideo', 'fullScreen'] }
|
|
|
+const editorConfig = {
|
|
|
+ placeholder: '请输入公告内容…',
|
|
|
+ MENU_CONF: {
|
|
|
+ uploadImage: {
|
|
|
+ maxFileSize: 10 * 1024 * 1024,
|
|
|
+ allowedFileTypes: ['image/*'],
|
|
|
+ async customUpload(file, insertFn) {
|
|
|
+ const data = new FormData()
|
|
|
+ data.append('file', file)
|
|
|
+ const response = await request({
|
|
|
+ url: '/common/upload',
|
|
|
+ method: 'post',
|
|
|
+ data
|
|
|
+ })
|
|
|
+ // 与原 Editor 保持一致:存储“前端代理基址 + 相对路径”,
|
|
|
+ // 保证开发/生产环境经代理均可正常加载,避免写入后端绝对地址导致跨域/不可达。
|
|
|
+ const base = import.meta.env.VITE_APP_BASE_API || ''
|
|
|
+ const src = base + response.fileName
|
|
|
+ insertFn(src, file.name, src)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+function handleCreated(editor) {
|
|
|
+ editorRef.value = editor
|
|
|
+}
|
|
|
+onBeforeUnmount(() => editorRef.value?.destroy())
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.notice-editor { width: 100%; border: 1px solid var(--el-border-color); border-radius: 4px; }
|
|
|
+.notice-editor :deep(.w-e-toolbar) { border-bottom: 1px solid var(--el-border-color); }
|
|
|
+.notice-editor :deep(.w-e-text-container [data-slate-editor] p) { margin: 4px 0; line-height: 1.6; }
|
|
|
+.notice-editor :deep(.w-e-text-container [data-slate-editor] h1,
|
|
|
+ .w-e-text-container [data-slate-editor] h2,
|
|
|
+ .w-e-text-container [data-slate-editor] h3,
|
|
|
+ .w-e-text-container [data-slate-editor] h4,
|
|
|
+ .w-e-text-container [data-slate-editor] h5,
|
|
|
+ .w-e-text-container [data-slate-editor] h6) { margin: 6px 0; }
|
|
|
+</style>
|