Selaa lähdekoodia

富文本编辑器支持fileSize和type

RuoYi 1 vuosi sitten
vanhempi
commit
8e7754c5d7
1 muutettua tiedostoa jossa 114 lisäystä ja 25 poistoa
  1. 114 25
      src/components/Editor/index.vue

+ 114 - 25
src/components/Editor/index.vue

@@ -1,18 +1,43 @@
 <template>
+  <div>
+    <el-upload
+      :action="uploadUrl"
+      :before-upload="handleBeforeUpload"
+      :on-success="handleUploadSuccess"
+      :on-error="handleUploadError"
+      name="file"
+      :show-file-list="false"
+      :headers="headers"
+      class="editor-img-uploader"
+      v-if="type == 'url'"
+    >
+      <i ref="uploadRef" class="editor-img-uploader"></i>
+    </el-upload>
+  </div>
   <div class="editor">
-      <quill-editor
-        v-model:content="content"
-        contentType="html"
-        @textChange="(e) => $emit('update:modelValue', content)"
-        :options="options"
-        :style="styles"
-      />
+    <quill-editor
+      ref="quillEditorRef"
+      v-model:content="content"
+      contentType="html"
+      @textChange="(e) => $emit('update:modelValue', content)"
+      :options="options"
+      :style="styles"
+    />
   </div>
 </template>
 
 <script setup>
-import { QuillEditor } from '@vueup/vue-quill';
-import '@vueup/vue-quill/dist/vue-quill.snow.css';
+import { QuillEditor } from "@vueup/vue-quill";
+import "@vueup/vue-quill/dist/vue-quill.snow.css";
+import { getToken } from "@/utils/auth";
+
+const { proxy } = getCurrentInstance();
+
+const quillEditorRef = ref();
+const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传的图片服务器地址
+const headers = ref({
+  Authorization: "Bearer " + getToken()
+});
 
 const props = defineProps({
   /* 编辑器的内容 */
@@ -34,6 +59,16 @@ const props = defineProps({
     type: Boolean,
     default: false,
   },
+  /* 上传文件大小限制(MB) */
+  fileSize: {
+    type: Number,
+    default: 5,
+  },
+  /* 类型(base64格式、url格式) */
+  type: {
+    type: String,
+    default: "url",
+  }
 });
 
 const options = ref({
@@ -43,19 +78,19 @@ const options = ref({
   modules: {
     // 工具栏配置
     toolbar: [
-      ["bold", "italic", "underline", "strike"],       // 加粗 斜体 下划线 删除线
-      ["blockquote", "code-block"],                    // 引用  代码块
-      [{ list: "ordered" }, { list: "bullet" }],       // 有序、无序列表
-      [{ indent: "-1" }, { indent: "+1" }],            // 缩进
-      [{ size: ["small", false, "large", "huge"] }],   // 字体大小
-      [{ header: [1, 2, 3, 4, 5, 6, false] }],         // 标题
-      [{ color: [] }, { background: [] }],             // 字体颜色、字体背景颜色
-      [{ align: [] }],                                 // 对齐方式
-      ["clean"],                                       // 清除文本格式
-      ["link", "image", "video"]                       // 链接、图片、视频
+      ["bold", "italic", "underline", "strike"],      // 加粗 斜体 下划线 删除线
+      ["blockquote", "code-block"],                   // 引用  代码块
+      [{ list: "ordered" }, { list: "bullet" }],      // 有序、无序列表
+      [{ indent: "-1" }, { indent: "+1" }],           // 缩进
+      [{ size: ["small", false, "large", "huge"] }],  // 字体大小
+      [{ header: [1, 2, 3, 4, 5, 6, false] }],        // 标题
+      [{ color: [] }, { background: [] }],            // 字体颜色、字体背景颜色
+      [{ align: [] }],                                // 对齐方式
+      ["clean"],                                      // 清除文本格式
+      ["link", "image", "video"]                      // 链接、图片、视频
     ],
   },
-  placeholder: '请输入内容',
+  placeholder: "请输入内容",
   readOnly: props.readOnly
 });
 
@@ -68,7 +103,7 @@ const styles = computed(() => {
     style.height = `${props.height}px`;
   }
   return style;
-})
+});
 
 const content = ref("");
 watch(() => props.modelValue, (v) => {
@@ -77,10 +112,68 @@ watch(() => props.modelValue, (v) => {
   }
 }, { immediate: true });
 
+// 如果设置了上传地址则自定义图片上传事件
+onMounted(() => {
+  if (props.type == 'url') {
+    let quill = quillEditorRef.value.getQuill();
+    let toolbar = quill.getModule("toolbar");
+    toolbar.addHandler("image", (value) => {
+      if (value) {
+        proxy.$refs.uploadRef.click();
+      } else {
+        quill.format("image", false);
+      }
+    });
+  }
+});
 
+// 上传前校检格式和大小
+function handleBeforeUpload(file) {
+  const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];
+  const isJPG = type.includes(file.type);
+  //检验文件格式
+  if (!isJPG) {
+    proxy.$modal.msgError(`图片格式错误!`);
+    return false;
+  }
+  // 校检文件大小
+  if (props.fileSize) {
+    const isLt = file.size / 1024 / 1024 < props.fileSize;
+    if (!isLt) {
+      proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
+      return false;
+    }
+  }
+  return true;
+}
+
+// 上传成功处理
+function handleUploadSuccess(res, file) {
+  // 如果上传成功
+  if (res.code == 200) {
+    // 获取富文本实例
+    let quill = toRaw(quillEditorRef.value).getQuill();
+    // 获取光标位置
+    let length = quill.selection.savedRange.index;
+    // 插入图片,res.url为服务器返回的图片链接地址
+    quill.insertEmbed(length, "image", import.meta.env.VITE_APP_BASE_API + res.fileName);
+    // 调整光标到最后
+    quill.setSelection(length + 1);
+  } else {
+    proxy.$modal.msgError("图片插入失败");
+  }
+}
+
+// 上传失败处理
+function handleUploadError() {
+  proxy.$modal.msgError("图片插入失败");
+}
 </script>
 
 <style>
+.editor-img-uploader {
+  display: none;
+}
 .editor, .ql-toolbar {
   white-space: pre-wrap !important;
   line-height: normal !important;
@@ -96,11 +189,9 @@ watch(() => props.modelValue, (v) => {
   content: "保存";
   padding-right: 0px;
 }
-
 .ql-snow .ql-tooltip[data-mode="video"]::before {
   content: "请输入视频地址:";
 }
-
 .ql-snow .ql-picker.ql-size .ql-picker-label::before,
 .ql-snow .ql-picker.ql-size .ql-picker-item::before {
   content: "14px";
@@ -117,7 +208,6 @@ watch(() => props.modelValue, (v) => {
 .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
   content: "32px";
 }
-
 .ql-snow .ql-picker.ql-header .ql-picker-label::before,
 .ql-snow .ql-picker.ql-header .ql-picker-item::before {
   content: "文本";
@@ -146,7 +236,6 @@ watch(() => props.modelValue, (v) => {
 .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
   content: "标题6";
 }
-
 .ql-snow .ql-picker.ql-font .ql-picker-label::before,
 .ql-snow .ql-picker.ql-font .ql-picker-item::before {
   content: "标准字体";