Files
sdk4.0/src/Obj/Element/richText.js
2025-08-22 10:14:12 +08:00

257 lines
7.8 KiB
JavaScript

import { getHost, getToken } from "../../on";
class richText {
#customUploadVideo
#customUploadContent
#primaryCallBack
constructor() {
this.richTextBox = document.createElement('div');
this.richTextBox.className = 'richText-box'
this.richTextBox.style.position = 'absolute'
this.richTextBox.style.width = '60%'
this.richTextBox.style.height = '70%'
this.richTextBox.style.backgroundColor = '#ffffff'
this.richTextBox.style.zIndex = '999999'
this.richTextBox.style.left = '20%'
this.richTextBox.style.top = '15%'
this.richTextBox.style.display = 'flex'
this.richTextBox.style.flexDirection = 'column'
this.uploadImageServer
this.uploadVideoServer
}
// 打开
open(id, title = '', content = '') {
let _this = this;
this.title = title
this.objectId = id
if (document.body.getElementsByClassName('richText-box')[0]) {
document.body.removeChild(this.richTextBox)
}
this.editor = null
let html = `
<div class="richText-box-mask"></div>
<div class="richText-content">
<div class="richText-header">
<p>${title}</P>
<i class="close">&#10005</i>
</div>
<div id="toolbar-container"></div>
<div id="editor-container"></div>
<div class="richText-footer">
<button class="primary">确认</button>
<button class="cancel">取消</button>
</div>
</div>
`
// let elm = document.createRange().createContextualFragment(html)
this.richTextBox.innerHTML = html
document.body.appendChild(this.richTextBox)
const { createEditor, createToolbar } = window.wangEditor
const editorConfig = {
placeholder: '请输入正文...',
MENU_CONF: {
uploadImage: {
fieldName: 'file',
// maxFileSize: 50 * 1024 * 1024,
// base64LimitSize: 50 * 1024 * 1024, // 50M 以下插入 base64
server: this.uploadImageServer,
// // 上传之前触发
// onBeforeUpload(file) { // TS 语法
// // onBeforeUpload(file) { // JS 语法
// // file 选中的文件,格式如 { key: file }
// return file
// // 可以 return
// // 1. return file 或者 new 一个 file ,接下来将上传
// // 2. return false ,不上传这个 file
// },
// // 上传进度的回调函数
// onProgress(progress) { // TS 语法
// // onProgress(progress) { // JS 语法
// // progress 是 0-100 的数字
// console.log('progress', progress)
// },
// // 单个文件上传成功之后
// onSuccess(file, res) { // TS 语法
// // onSuccess(file, res) { // JS 语法
// console.log(`${file.name} 上传成功`, res)
// },
// // 单个文件上传失败
// onFailed(file, res) { // TS 语法
// // onFailed(file, res) { // JS 语法
// console.log(`${file.name} 上传失败`, res)
// },
// // 上传错误,或者触发 timeout 超时
// onError(file, err, res) { // TS 语法
// // onError(file, err, res) { // JS 语法
// console.log(`${file.name} 上传出错`, err, res)
// },
// 自定义上传
async customUpload(file, insertFn) { // TS 语法
// async customUpload(file, insertFn) { // JS 语法
// file 即选中的文件
// 自己实现上传,并得到图片 url alt href
// 最后插入图片
let url = await _this.upload(file)
insertFn((_this.host = _this.host || getHost()) + '/' + url)
}
},
uploadVideo: {
// maxFileSize: 500 * 1024 * 1024,
server: this.uploadVideoServer,
allowedFileTypes: ['video/mp4', 'video/mp3', 'video/ogg', 'video/webm', 'video/avi'],
// 自定义上传
async customUpload(file, insertFn) {
// async customUpload(file, insertFn) {
// file 即选中的文件
// 自己实现上传,并得到图片 url alt href
// 最后插入图片
let url = await _this.upload(file)
insertFn((_this.host = _this.host || getHost()) + '/' + url)
// if(_this.#customUploadVideo) {
// let url = await _this.#customUploadVideo(file)
// insertFn(url, file.name)
// }
}
}
},
onChange(editor) {
const html = editor.getHtml()
// 也可以同步到 <textarea>
}
}
this.editor = createEditor({
selector: '#editor-container',
html: '<p><br></p>',
config: editorConfig,
mode: 'default', // or 'simple'
})
const toolbarConfig = {
// 隐藏菜单
excludeKeys: [
'emotion', // 表情
'insertImage', // 网络图片
'insertVideo' // 网络视频
]
}
const toolbar = createToolbar({
editor: this.editor,
selector: '#toolbar-container',
config: toolbarConfig,
mode: 'default', // or 'simple'
})
this.editor.on('fullScreen', () => { console.log('fullScreen') })
this.editor.setHtml(content)
let closeElm = this.richTextBox.getElementsByClassName('close')[0]
let primaryBtnElm = this.richTextBox.getElementsByClassName('primary')[0]
let cancelBtnElm = this.richTextBox.getElementsByClassName('cancel')[0]
closeElm.addEventListener('click', () => {
this.close()
})
primaryBtnElm.addEventListener('click', () => {
const html = this.editor.getHtml()
this.primaryCallBack(html)
this.close()
// if(this.customUploadContent) {
// this.customUploadContent(this.objectId, html).then((url)=>{
// if(this.primaryCallBack) {
// this.primaryCallBack(url)
// }
// this.close()
// })
// }
})
cancelBtnElm.addEventListener('click', () => {
this.close()
})
}
// 关闭
close() {
if (document.body.getElementsByClassName('richText-box')[0]) {
document.body.removeChild(this.richTextBox)
}
this.editor = null
}
async upload(file) {
let url = ""
this.host = this.host || getHost()
if (this.host.endsWith("yjearth4.0")) {
url = this.host + '/api/v1/richText/upload'
}
else {
url = this.host + '/yjearth4.0/api/v1/richText/upload'
}
const formData = new FormData();
formData.append('file', file);
let response = await fetch(url, {
method: 'post',
body: formData,
headers: {
"token": getToken(),
"Authorization": "Bearer " + getToken(),
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
return data.data.url
}
}
}
// // 设置上传图片服务地址
// setUploadImageServer(server) {
// this.uploadImageServer = server
// if(this.editor) {
// this.open(this.title)
// }
// }
// // 设置上传视频服务地址
// setUploadVideoServer(server) {
// this.uploadVideoServer = server
// if(this.editor) {
// this.open(this.title)
// }
// }
// 自定义上传视频
get customUploadVideo() {
return this.#customUploadVideo
}
set customUploadVideo(event) {
this.#customUploadVideo = event
}
// 自定义上传文本内容
get customUploadContent() {
return this.#customUploadContent
}
set customUploadContent(event) {
this.#customUploadContent = event
}
// 确认回调
get primaryCallBack() {
return this.#primaryCallBack
}
set primaryCallBack(event) {
this.#primaryCallBack = event
}
}
const _rich_text = new richText();
export default _rich_text;