mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-06 18:36:55 +08:00
120 lines
3.2 KiB
Vue
120 lines
3.2 KiB
Vue
<script setup lang="ts">
|
|
import { isDarkMode } from '@/Utils'
|
|
import { APIRoot } from '@/api/api-models'
|
|
import { GetHeaders } from '@/api/query'
|
|
import '@/assets/editorDarkMode.css'
|
|
import { BASE_URL, VTSURU_API_URL } from '@/data/constants'
|
|
import { DomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor'
|
|
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
|
import '@wangeditor/editor/dist/css/style.css' // 引入 css
|
|
import { NotificationReactive, useMessage } from 'naive-ui'
|
|
import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue'
|
|
|
|
type InsertFnType = (url: string, alt: string, href: string) => void
|
|
|
|
const props = defineProps({
|
|
defaultValue: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
mode: {
|
|
type: String,
|
|
default: 'default',
|
|
},
|
|
maxLength: {
|
|
type: Number,
|
|
default: 10000,
|
|
},
|
|
})
|
|
const message = useMessage()
|
|
|
|
const editorRef = shallowRef()
|
|
const toolbar = DomEditor.getToolbar(editorRef.value)
|
|
const toolbarConfig: Partial<IToolbarConfig> = {
|
|
excludeKeys: ['group-video', 'group-lineHeight', 'insertImage', 'fullScreen'],
|
|
}
|
|
const uploadProgressRef = ref<NotificationReactive>()
|
|
const editorConfig: Partial<IEditorConfig> = {
|
|
placeholder: '请输入内容...',
|
|
maxLength: props.maxLength,
|
|
|
|
MENU_CONF: {
|
|
uploadImage: {
|
|
maxFileSize: 10 * 1024 * 1024,
|
|
maxNumberOfFiles: 10,
|
|
async customUpload(file: File, insertFn: InsertFnType) {
|
|
const formData = new FormData() //创建一个FormData实例。
|
|
message.info('图片上传中')
|
|
formData.append('file', file)
|
|
const resp = await fetch(VTSURU_API_URL + 'image/upload', {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: GetHeaders(),
|
|
})
|
|
if (resp.ok) {
|
|
const data = (await resp.json()) as APIRoot<string>
|
|
if (data.code == 200) {
|
|
insertFn(data.data, '', '')
|
|
} else {
|
|
message.error('图片上传失败: ' + data.message)
|
|
}
|
|
} else {
|
|
message.error('图片上传失败: ' + resp.statusText)
|
|
}
|
|
},
|
|
onProgress(progress: number) {
|
|
console.log(progress)
|
|
},
|
|
onSuccess(file: File, res: any) {
|
|
console.log(`${file.name} 上传成功`, res)
|
|
message.success('图片上传成功')
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
const value = defineModel<string>('value')
|
|
|
|
onBeforeUnmount(() => {
|
|
const editor = editorRef.value
|
|
if (editor == null) return
|
|
editor.destroy()
|
|
})
|
|
onMounted(() => {
|
|
//editorRef.value?.setHtml(props.defaultValue)
|
|
})
|
|
function handleCreated(editor: unknown) {
|
|
editorRef.value = editor // 记录 editor 实例,重要!
|
|
}
|
|
function getText() {
|
|
return editorRef.value?.getText()
|
|
}
|
|
function getHtml() {
|
|
return editorRef.value?.getText()
|
|
}
|
|
|
|
defineExpose({
|
|
getText,
|
|
getHtml,
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div :class="{ 'dark-theme': isDarkMode }" style="border: 1px solid #ccc">
|
|
<Toolbar
|
|
ref="toolbarRef"
|
|
style="border-bottom: 1px solid #ccc"
|
|
:editor="editorRef"
|
|
:defaultConfig="toolbarConfig"
|
|
:mode="mode"
|
|
/>
|
|
<Editor
|
|
style="height: 500px; overflow-y: hidden"
|
|
v-model="value"
|
|
:defaultConfig="editorConfig"
|
|
:mode="mode"
|
|
@onCreated="handleCreated"
|
|
/>
|
|
</div>
|
|
</template>
|