UNPKG

yanzhen-design-vue

Version:

244 lines (243 loc) 8.07 kB
import { shallowRef, computed, unref, ref, onBeforeUnmount } from "vue"; import { bytes, isEmptyArray } from "@yanzhen-libs/utils"; import { createReusableTemplate, useVModel } from "@vueuse/core"; import { provideApiConfig } from "@yanzhen-lowcode/core"; import { uniq, isString, isFunction } from "lodash-es"; import { createWatcher } from "@yanzhen-libs/utils-vue"; import "../../../utils/index.mjs"; import { richTextName, richTextApis } from "./rich-text-props.mjs"; import { richTextToolbarBaseKeys } from "./constants.mjs"; import { throwError, message, logs } from "../../../utils/log.mjs"; function useRichText(props, emit) { const [DefineRichText, ReusableRichText] = createReusableTemplate(); const _toolbarRef = shallowRef(); const _editorRef = shallowRef(); const _ref = computed(() => { return { toolbar: unref(_toolbarRef), editor: unref(_editorRef) }; }); const open = ref(false); const _api = provideApiConfig(props); const _props = computed(() => { return { style: { zIndex: props.zIndex } }; }); const _uploadConfig = computed(() => { var _a; const editor = unref(_editorRef); const config2 = unref(_api); const accept = props.accept ? (_a = props.accept) == null ? void 0 : _a.split(",") : []; const allowedFileTypes = uniq(((props == null ? void 0 : props.allowedFileTypes) ?? []).concat(accept)); const allowedVideoTypes = allowedFileTypes == null ? void 0 : allowedFileTypes.filter( (value) => typeof value === "string" && value.startsWith("video/") ); const allowedImageTypes = allowedFileTypes == null ? void 0 : allowedFileTypes.filter( (value) => typeof value === "string" && value.startsWith("image/") ); const { fieldName, maxFileSize: _maxFileSize, maxNumberOfFiles, timeout, base64LimitSize: _base64LimitSize } = props; const maxFileSize = isString(_maxFileSize) ? bytes.parse(_maxFileSize) : _maxFileSize; const base64LimitSize = isString(_base64LimitSize) ? bytes.parse(_base64LimitSize) : _base64LimitSize; return { fieldName, maxFileSize, maxNumberOfFiles, timeout, base64LimitSize, server: (_api == null ? void 0 : _api.value.action) ?? "#", allowedFileTypes, allowedVideoTypes, allowedImageTypes, // 自定义增加 http header headers: config2 == null ? void 0 : config2.headers, // 跨域是否传递 cookie ,默认为 false withCredentials: props.withCredentials, // 上传之前触发 async onBeforeUpload(file, config3) { if (typeof props.onBeforeUpload === "function") { return props.onBeforeUpload(file); } if (maxFileSize && maxFileSize < file.size) { throwError(richTextName, `单个文件超出最大限制:${bytes.format(maxFileSize)}`); } if (allowedFileTypes && allowedFileTypes.length > 0) { const allowed = allowedFileTypes.some((type) => { if (type.endsWith("/*")) { const t = type.replace("/*", "/\\w{1,}"); return new RegExp(t, "i").test(file.type); } return file.type === type; }); if (!allowed) { throwError(richTextName, `允许的文件类型:${allowedFileTypes.join("|")}`); } } }, // 上传进度的回调函数 async onProgress(progress) { editor == null ? void 0 : editor.showProgressBar(progress); }, // 单个文件上传成功之后 async onSuccess(file, res) { message.info(`${file.name} 上传成功`); }, // 单个文件上传失败 async onFailed(file, res) { message.info(`${file.name} 上传失败`); }, // 上传错误,或者触发 timeout 超时 async onError(file, err, res) { message.info(`${file.name} 上传出错`); } }; }); const handleCustomUpload = async (file, insertFn, _config) => { const { onBeforeUpload, onError } = unref(_config); if (typeof onBeforeUpload === "function") { await onBeforeUpload(file, unref(_config)); } const result = await (_api == null ? void 0 : _api.value.request( { file, ...unref(_config) }, richTextApis.upload )); if ((result == null ? void 0 : result.code) === 0) { insertFn(result == null ? void 0 : result.data, "alt", "href"); return; } if (typeof onError === "function") { const message2 = (result == null ? void 0 : result.message) ?? "上传失败"; onError(file, throwError(richTextName, message2), result, unref(_config)); } }; const config = computed(() => { const { allowedFileTypes, allowedVideoTypes, allowedImageTypes, ...uploadConfig } = unref(_uploadConfig); const uploadVideoConfig = { allowedFileTypes: allowedVideoTypes, ...uploadConfig, customUpload(file, insertFn) { return handleCustomUpload(file, insertFn, uploadVideoConfig); } }; const uploadImageConfig = { allowedFileTypes: allowedImageTypes, ...uploadConfig, customUpload(file, insertFn) { return handleCustomUpload(file, insertFn, uploadImageConfig); } }; const toolbar = { toolbarKeys: !isEmptyArray(props.toolbarKeys) ? props.toolbarKeys : richTextToolbarBaseKeys // insertKeys: [], // 可以在当前 toolbarKeys 的基础上继续插入新菜单,如自定义扩展的菜单。 // excludeKeys, }; const editor = { placeholder: "请输入内容...", autoFocus: false, readOnly: props.disabled, MENU_CONF: { // 字号 fontSize: { fontSizeList: [ // 元素支持两种形式 // 1. 字符串; // 2. { name: 'xxx', value: 'xxx' } "12px", "16px", { name: "24px", value: "24px" }, "40px" ] }, // image 上传 uploadImage: uploadImageConfig, // Video 上传 uploadVideo: uploadVideoConfig }, customAlert: async (info, type) => { if (typeof props.customAlert === "function") { return props.customAlert(info, type); } if (message[type]) { message[type](info); } if (type === "error") { throwError(richTextName, info); } else { logs[type === "warning" ? "warn" : type](info); } } }; return { mode: props.mode, // or 'simple' toolbar, editor }; }); const watcher = createWatcher(); watcher.set("disabled", { source: () => props.disabled, handler(disabled) { const editor = unref(_editorRef); switch (true) { case (disabled && isFunction(editor == null ? void 0 : editor.disable)): editor == null ? void 0 : editor.blur(); editor == null ? void 0 : editor.disable(); break; case isFunction(editor == null ? void 0 : editor.enable): editor == null ? void 0 : editor.enable(); break; } }, immediate: true, debounce: 300 }); const modelValue = useVModel(props, "value", emit); const _modelValue = computed({ get() { return modelValue.value ?? ""; }, set(value) { const editor = _editorRef.value; if (!editor) return; modelValue.value = editor.isEmpty() ? "" : value; } }); const notSupport = computed(() => { return isString(props.nativeTag) && props.nativeTag.startsWith("edit-table"); }); const handleCreated = (editor) => { _editorRef.value = editor; }; onBeforeUnmount(() => { watcher.stop(); const editor = _editorRef.value; if (editor == null) return; editor.destroy(); }); return { _props, _ref, _toolbarRef, _editorRef, _modelValue, open, notSupport, config, handleCreated, DefineRichText, ReusableRichText }; } export { useRichText };