From ccfd07feeaa670a3d56548d7fea0936e299df95b Mon Sep 17 00:00:00 2001
From: huangyinfeng <1244041895@qq.com>
Date: 星期三, 18 九月 2024 14:33:31 +0800
Subject: [PATCH] 部分功能

---
 src/components/Tinymce/src/index.vue |  237 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 224 insertions(+), 13 deletions(-)

diff --git a/src/components/Tinymce/src/index.vue b/src/components/Tinymce/src/index.vue
index f8ed625..1053692 100644
--- a/src/components/Tinymce/src/index.vue
+++ b/src/components/Tinymce/src/index.vue
@@ -2,16 +2,72 @@
   <div :class="prefixCls" :style="{ width: containerWidth }">
     <textarea
       :id="tinymceId"
-      ref="elRef"
+      ref="elPwRef"
       :style="{ visibility: 'hidden' }"
       v-if="!initOptions.inline"
     ></textarea>
     <slot v-else></slot>
+    <!-- <div class="p-2 tox-statusbar">
+      <a-upload
+        v-if="isElse"
+        v-model:file-list="fileListTemp"
+        action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
+        list-type="picture"
+        class="upload-list-inline"
+      >
+        <a-button type="text" size="small" style="margin: 0 auto">
+          <upload-outlined></upload-outlined>
+          闄勪欢
+        </a-button>
+        <template #iconRender><PaperClipOutlined /></template>
+        <template #itemRender="{ file, fileList, actions }">
+          <a-space class="ant-upload-list-picture-card">
+            <span style="display: flex; flex-wrap: wrap">
+              <PaperClipOutlined style="margin-right: 4px" />
+              <span v-if="!file.editor" :style="file.status === 'error' ? 'color: red' : ''">{{
+                file.name
+              }}</span>
+              <span v-else>
+                <a-input size="small" v-model:value="file.tempName"></a-input>
+              </span>
+            </span>
+            <span v-if="!file.editor">
+              <a href="javascript:;" @click="actions.preview">棰勮</a>
+              <a href="javascript:;" @click="fnRename(file, fileList)">閲嶅懡鍚�</a>
+              <a href="javascript:;" @click="actions.remove">鍒犻櫎</a>
+            </span>
+            <span v-else>
+              <a href="javascript:;" @click="fnSaveRename(file, fileList)">淇濆瓨</a>
+              <a href="javascript:;" @click="fnOffRename(file, fileList)">鍙栨秷</a>
+            </span>
+          </a-space>
+        </template>
+      </a-upload>
+      <div :class="fileListTemp.length > 0 ? 'my-upload-list' : ''">
+        <div style="display: flex">
+          <ImgUpload
+            :fullscreen="fullscreen"
+            @uploading="handleImageUploading"
+            @done="handleDone"
+            v-if="isImg"
+            v-show="editorRef"
+            :title="'鍥剧墖'"
+            :disabled="disabled"
+            :accept="'.jpg,.jpeg,.gif,.png,.webp'"
+          />
+          <a-button v-if="isText" type="text" size="small">
+            <SnippetsOutlined />
+            蹇�熸枃鏈�</a-button
+          >
+        </div>
+      </div>
+    </div> -->
   </div>
 </template>
 
 <script lang="ts" setup>
   import type { Editor, RawEditorSettings } from 'tinymce';
+  import { PaperClipOutlined, UploadOutlined, SnippetsOutlined } from '@ant-design/icons-vue';
   import tinymce from 'tinymce/tinymce';
   import 'tinymce/themes/silver';
   import 'tinymce/icons/default/icons';
@@ -88,12 +144,14 @@
     PropType,
     useAttrs,
   } from 'vue';
+  import ImgUpload from './ImgUpload.vue';
   import {
     plugins as defaultPlugins,
     toolbar as defaultToolbar,
     toolbar_groups as defaultStyleFormats,
   } from './tinymce';
   import { buildShortUUID } from '@/utils/uuid';
+  import { bindHandlers } from './helper';
   import { onMountedOrActivated } from '@vben/hooks';
   import { useDesign } from '@/hooks/web/useDesign';
   import { isNumber } from '@/utils/is';
@@ -129,7 +187,7 @@
     height: {
       type: [Number, String] as PropType<string | number>,
       required: false,
-      default: 200,
+      default: 400,
     },
     width: {
       type: [Number, String] as PropType<string | number>,
@@ -143,15 +201,27 @@
     fontsize: {
       type: String,
     },
+    isElse: {
+      type: Boolean,
+      default: true,
+    },
+    isText: {
+      type: Boolean,
+      default: true,
+    },
+    isImg: {
+      type: Boolean,
+      default: true,
+    },
   });
-console.log('Editor', props);
 
   const emit = defineEmits(['change', 'update:modelValue', 'inited', 'init-error']);
 
   const attrs = useAttrs();
   const editorRef = ref<Editor | null>(null);
-  const tinymceId = ref<string>(buildShortUUID('tiny-vue'));
-  const elRef = ref<HTMLElement | null>(null);
+  const fullscreen = ref(false);
+  const tinymceId = ref<string>(buildShortUUID('tiny-vue-pw'));
+  const elPwRef = ref<HTMLElement | null>(null);
 
   const { prefixCls } = useDesign('tinymce-container');
 
@@ -187,13 +257,10 @@
       fontsize_formats: '10px 11px 12px 14px 16px 18px 24px 36px 48px 48px 56px 72px',
       image_advtab: true,
       importcss_append: true, // 鍏佽鏍峰紡鐢熸晥
-      toolbar:[],
-      toolbar_sticky: true, // 绮樻�у伐鍏锋爮锛堟垨鍋滈潬宸ュ叿鏍忥級锛屽湪鍚戜笅婊氬姩缃戦〉鐩村埌涓嶅啀鍙缂栬緫鍣ㄦ椂锛屽皢宸ュ叿鏍忓拰鑿滃崟鍋滈潬鍦ㄥ睆骞曢《閮�
-      toolbar_mode: 'floating', //榛樿wrap涓嶆敹缂╁伐鍏锋爮锛屽彇鍊间负floating鎴杝liding鏃讹紝灏嗙涓�琛屾斁涓嶄笅鐨勫伐鍏锋爮鎸夐挳缂╄繘鎶藉眽锛�3涓偣鐨勫浘鏍囷級閲岋紝scrolling鍒欓噰鐢ㄧЩ鍔ㄧ鐨勬í绾挎粴鍔ㄦ柟寮忋��
-      // style_formats_autohide: true,
       menubar: false,
       branding: false,
       elementpath: false,
+      toolbar:[],
       // quickbars_selection_toolbar: 'bold italic | quicklink h2 h3 blockquote quickimage quicktable',
       plugins,
       language_url: publicPath + 'resource/tinymce/langs/' + langName.value + '.js',
@@ -209,12 +276,22 @@
       skin_url: publicPath + 'resource/tinymce/skins/ui/' + skinName.value,
       content_css: publicPath + 'resource/tinymce/skins/ui/' + skinName.value + '/content.min.css',
       ...options,
+      readonly:true,
       setup: (editor: Editor) => {
         editorRef.value = editor;
+        editor.on('init', (e) => initSetup(e));
       },
-      // 鍙妯″紡
-      readonly: true,
     };
+  });
+
+  const disabled = computed(() => {
+    const { options } = props;
+    const getdDisabled = options && Reflect.get(options, 'readonly');
+    const editor = unref(editorRef);
+    if (editor) {
+      editor.setMode(getdDisabled ? 'readonly' : 'design');
+    }
+    return getdDisabled ?? false;
   });
 
   watch(
@@ -254,7 +331,7 @@
   }
 
   function initEditor() {
-    const el = unref(elRef);
+    const el = unref(elPwRef);
     if (el) {
       el.style.visibility = '';
     }
@@ -268,6 +345,18 @@
       });
   }
 
+  function initSetup(e) {
+    const editor = unref(editorRef);
+    if (!editor) {
+      return;
+    }
+    const value = props.modelValue || '';
+
+    editor.setContent(value);
+    bindModelHandlers(editor);
+    bindHandlers(e, attrs, unref(editorRef));
+  }
+
   function setValue(editor: Record<string, any>, val?: string, prevVal?: string) {
     if (
       editor &&
@@ -276,9 +365,123 @@
       val !== editor.getContent({ format: attrs.outputFormat })
     ) {
       editor.setContent(val);
+    }else{
+      editor.setContent('');
+      console.log('-5-5-5555555555');
+      
     }
   }
-  
+
+  function bindModelHandlers(editor: any) {
+    const modelEvents = attrs.modelEvents ? attrs.modelEvents : null;
+    const normalizedEvents = Array.isArray(modelEvents) ? modelEvents.join(' ') : modelEvents;
+
+    watch(
+      () => props.modelValue,
+      (val, prevVal) => {
+        setValue(editor, val, prevVal);
+      },
+    );
+
+    watch(
+      () => props.value,
+      (val, prevVal) => {
+        setValue(editor, val, prevVal);
+      },
+      {
+        immediate: true,
+      },
+    );
+
+    editor.on(normalizedEvents ? normalizedEvents : 'change keyup undo redo', () => {
+      const content = editor.getContent({ format: attrs.outputFormat });
+      emit('update:modelValue', content);
+      const data = {
+        content,
+        fileUNID: fileListTemp.value,
+      };
+      emit('change', data);
+    });
+
+    editor.on('FullscreenStateChanged', (e) => {
+      fullscreen.value = e.state;
+    });
+  }
+
+  function handleImageUploading(name: string) {
+    const editor = unref(editorRef);
+    if (!editor) {
+      return;
+    }
+    editor.execCommand('mceInsertContent', false, getUploadingImgName(name));
+    const content = editor?.getContent() ?? '';
+    setValue(editor, content);
+  }
+
+  function handleDone(name: string, url: string) {
+    const editor = unref(editorRef);
+    if (!editor) {
+      return;
+    }
+    const content = editor?.getContent() ?? '';
+    const val = content?.replace(getUploadingImgName(name), `<img src="${url}"/>`) ?? '';
+    setValue(editor, val);
+  }
+
+  function getUploadingImgName(name: string) {
+    return `[uploading:${name}]`;
+  }
+
+  // 闄勪欢
+  const fileListTemp = ref<UploadProps['fileList']>([
+    // {
+    //   uid: '-1',
+    //   name: 'xxx.png',
+    //   tempName: 'xxx',
+    //   status: 'done',
+    //   url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
+    //   thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
+    //   editor: false,
+    // },
+    // {
+    //   uid: '-2',
+    //   name: 'yyy.png',
+    //   tempName: 'yyy',
+    //   status: 'done',
+    //   url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
+    //   thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
+    //   editor: false,
+    // },
+  ]);
+  function fnRename(file, fileList) {
+    console.log(file, fileList);
+    fileListTemp.value = fileList.map((item) => {
+      // item.tempName = item.name.split('.').slice(0,-1)
+      if (file.uid == item.uid) {
+        item.editor = true;
+      } else {
+        item.editor = false;
+      }
+      return item;
+    });
+  }
+  function fnSaveRename(file, fileList) {
+    fileListTemp.value = fileList.map((item) => {
+      if (file.uid == item.uid) {
+        item.name = item.tempName;
+        item.editor = false;
+      }
+      return item;
+    });
+  }
+  function fnOffRename(file, fileList) {
+    fileListTemp.value = fileList.map((item) => {
+      if (file.uid == item.uid) {
+        item.editor = false;
+      }
+      return item;
+    });
+  }
 </script>
 <style lang="less" scope>
   @prefix-cls: ~'@{namespace}-tinymce-container';
@@ -293,9 +496,17 @@
     }
   }
 
+  .my-upload-list {
+    // 杩囨浮
+    position: absolute;
+    left: 78px;
+    transition: all 0.3s;
+  }
+
   .tox-statusbar {
     display: flex;
     // position: absolute;
+    min-height: 40px;
     border-bottom-right-radius: 8px;
     border-bottom-left-radius: 8px;
     background: #f0f2f5;

--
Gitblit v1.8.0