拆分通知中心的富文本编辑器

This commit is contained in:
2026-08-11 11:26:09 +08:00 Unverified
parent 43908176ff
commit ebc759a53e
3 changed files with 84 additions and 119 deletions
+1
View File
@@ -54,6 +54,7 @@ declare module 'vue' {
ElTag: typeof import('element-plus/es')['ElTag'] ElTag: typeof import('element-plus/es')['ElTag']
ElTimeSelect: typeof import('element-plus/es')['ElTimeSelect'] ElTimeSelect: typeof import('element-plus/es')['ElTimeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload'] ElUpload: typeof import('element-plus/es')['ElUpload']
NotificationRichTextEditor: typeof import('./components/NotificationRichTextEditor.vue')['default']
PerformanceReportPanel: typeof import('./components/PerformanceReportPanel.vue')['default'] PerformanceReportPanel: typeof import('./components/PerformanceReportPanel.vue')['default']
RichMessageContent: typeof import('./components/RichMessageContent.vue')['default'] RichMessageContent: typeof import('./components/RichMessageContent.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
@@ -0,0 +1,79 @@
<script setup lang="ts">
import { Ckeditor } from '@ckeditor/ckeditor5-vue'
import {
AutoLink,
BlockQuote,
Bold,
ClassicEditor,
Essentials,
Heading,
Image,
ImageCaption,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageToolbar,
Italic,
Link,
LinkImage,
List,
Paragraph,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
type EditorConfig,
} from 'ckeditor5'
import 'ckeditor5/ckeditor5.css'
const model = defineModel<string>({ required: true })
const editorConfig: EditorConfig = {
licenseKey: import.meta.env.VITE_CKEDITOR_LICENSE_KEY || 'GPL',
plugins: [
Essentials, Paragraph, Heading, Bold, Italic, Link, AutoLink, List, BlockQuote,
Image, ImageCaption, ImageInsert, ImageInsertViaUrl, ImageResize, ImageStyle,
ImageToolbar, LinkImage, Table, TableCaption, TableCellProperties,
TableColumnResize, TableProperties, TableToolbar,
],
toolbar: {
items: [
'heading', '|', 'bold', 'italic', 'link', '|', 'insertTable', 'insertImage',
'|', 'bulletedList', 'numberedList', 'blockQuote', '|', 'undo', 'redo',
],
shouldNotGroupWhenFull: false,
},
heading: {
options: [
{ model: 'paragraph', title: '正文', class: 'ck-heading_paragraph' },
{ model: 'heading2', view: 'h2', title: '标题', class: 'ck-heading_heading2' },
{ model: 'heading3', view: 'h3', title: '小标题', class: 'ck-heading_heading3' },
],
},
link: { addTargetToExternalLinks: true, defaultProtocol: 'https://' },
image: {
insert: { integrations: ['insertImageViaUrl'] },
toolbar: [
'toggleImageCaption', 'imageTextAlternative', '|', 'imageStyle:inline',
'imageStyle:wrapText', 'imageStyle:breakText', '|', 'resizeImage', 'linkImage',
],
},
table: {
contentToolbar: [
'tableColumn', 'tableRow', 'mergeTableCells', 'toggleTableCaption',
'tableProperties', 'tableCellProperties',
],
},
}
</script>
<template>
<Ckeditor
v-model="model"
:editor="ClassicEditor"
:config="editorConfig"
/>
</template>
+4 -119
View File
@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue' import { computed, defineAsyncComponent, onMounted, reactive, ref } from 'vue'
import { import {
Bell, Bell,
Check, Check,
@@ -11,35 +11,6 @@ import {
Search, Search,
User, User,
} from '@element-plus/icons-vue' } from '@element-plus/icons-vue'
import { Ckeditor } from '@ckeditor/ckeditor5-vue'
import {
AutoLink,
BlockQuote,
Bold,
ClassicEditor,
Essentials,
Heading,
Image,
ImageCaption,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageToolbar,
Italic,
Link,
LinkImage,
List,
Paragraph,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
type EditorConfig,
} from 'ckeditor5'
import 'ckeditor5/ckeditor5.css'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import http, { apiErrorMessage } from '../api/http' import http, { apiErrorMessage } from '../api/http'
import RichMessageContent from '../components/RichMessageContent.vue' import RichMessageContent from '../components/RichMessageContent.vue'
@@ -47,6 +18,8 @@ import { useAuthStore } from '../stores/auth'
const router = useRouter() const router = useRouter()
const auth = useAuthStore() const auth = useAuthStore()
const NotificationRichTextEditor = defineAsyncComponent(
() => import('../components/NotificationRichTextEditor.vue'))
const senderRoles = ['SuperAdmin', 'AcademicAdmin', 'CollegeAdmin', 'Counselor', 'Teacher'] const senderRoles = ['SuperAdmin', 'AcademicAdmin', 'CollegeAdmin', 'Counselor', 'Teacher']
const canSend = computed(() => const canSend = computed(() =>
auth.user?.roles.some(role => senderRoles.includes(role)) ?? false) auth.user?.roles.some(role => senderRoles.includes(role)) ?? false)
@@ -91,92 +64,6 @@ const recipientFilters = reactive({
keyword: '', keyword: '',
}) })
const editorConfig: EditorConfig = {
licenseKey: import.meta.env.VITE_CKEDITOR_LICENSE_KEY || 'GPL',
plugins: [
Essentials,
Paragraph,
Heading,
Bold,
Italic,
Link,
AutoLink,
List,
BlockQuote,
Image,
ImageCaption,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageToolbar,
LinkImage,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
],
toolbar: {
items: [
'heading',
'|',
'bold',
'italic',
'link',
'|',
'insertTable',
'insertImage',
'|',
'bulletedList',
'numberedList',
'blockQuote',
'|',
'undo',
'redo',
],
shouldNotGroupWhenFull: false,
},
heading: {
options: [
{ model: 'paragraph', title: '正文', class: 'ck-heading_paragraph' },
{ model: 'heading2', view: 'h2', title: '标题', class: 'ck-heading_heading2' },
{ model: 'heading3', view: 'h3', title: '小标题', class: 'ck-heading_heading3' },
],
},
link: {
addTargetToExternalLinks: true,
defaultProtocol: 'https://',
},
image: {
insert: {
integrations: ['insertImageViaUrl'],
},
toolbar: [
'toggleImageCaption',
'imageTextAlternative',
'|',
'imageStyle:inline',
'imageStyle:wrapText',
'imageStyle:breakText',
'|',
'resizeImage',
'linkImage',
],
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells',
'toggleTableCaption',
'tableProperties',
'tableCellProperties',
],
},
}
const categories: Record<string, { label: string; className: string }> = { const categories: Record<string, { label: string; className: string }> = {
General: { label: '一般通知', className: 'general' }, General: { label: '一般通知', className: 'general' },
Approval: { label: '审核待办', className: 'approval' }, Approval: { label: '审核待办', className: 'approval' },
@@ -872,10 +759,8 @@ onMounted(() => load())
</el-form-item> </el-form-item>
<el-form-item label="消息正文" required class="editor-form-item"> <el-form-item label="消息正文" required class="editor-form-item">
<Ckeditor <NotificationRichTextEditor
v-model="messageForm.content" v-model="messageForm.content"
:editor="ClassicEditor"
:config="editorConfig"
/> />
<div class="editor-footnote"> <div class="editor-footnote">
<span>支持表格超链接和外链图片图片请填写 HTTPS 地址不上传本地文件</span> <span>支持表格超链接和外链图片图片请填写 HTTPS 地址不上传本地文件</span>