فهرست منبع

Merge branch 'dev_220318_test' into test

wenliming 3 سال پیش
والد
کامیت
0cc1a5b136
7فایلهای تغییر یافته به همراه598 افزوده شده و 91 حذف شده
  1. 149 41
      package-lock.json
  2. 7 2
      package.json
  3. 8 0
      src/http/publishApi.js
  4. 46 48
      src/view/components/give-dialog.vue
  5. 348 0
      src/view/components/tinymce.vue
  6. 3 0
      src/view/test.vue
  7. 37 0
      yarn.lock

+ 149 - 41
package-lock.json

@@ -1539,6 +1539,12 @@
         }
       }
     },
+    "@faker-js/faker": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-6.1.1.tgz",
+      "integrity": "sha512-8yq1LJVGn4GY06riLddIU1LbJm15yjt46hjfkpWNpH/mqdciPOBVzicKOJxzQNrGgVHVBxcdm7sgwjI/Y19MYw==",
+      "dev": true
+    },
     "@gar/promisify": {
       "version": "1.1.3",
       "resolved": "https://registry.npmmirror.com/@gar/promisify/-/promisify-1.1.3.tgz",
@@ -1844,6 +1850,21 @@
       "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==",
       "dev": true
     },
+    "@tinymce/tinymce-vue": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/@tinymce/tinymce-vue/-/tinymce-vue-4.0.7.tgz",
+      "integrity": "sha512-1esB8wGWrjPCY+rK8vy3QB1cxwXo7HLJWuNrcyPl6LOVR+QJjub0OiV/C+TUEsLN6OpCtRv+QnIqMC5vXz783Q==",
+      "requires": {
+        "tinymce": "^5.5.0"
+      },
+      "dependencies": {
+        "tinymce": {
+          "version": "5.10.3",
+          "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.10.3.tgz",
+          "integrity": "sha512-O59ssHNnujWvSk5Gt8hIGrdNCMKVWVQv9F8siAgLTRgTh0t3NDHrP1UlLtCxArUi9DPWZvlBeUz8D5fJTu7vnA=="
+        }
+      }
+    },
     "@trysound/sax": {
       "version": "0.2.0",
       "resolved": "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz",
@@ -2356,6 +2377,27 @@
           "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
           "dev": true
         },
+        "@vue/vue-loader-v15": {
+          "version": "npm:vue-loader@15.9.8",
+          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.8.tgz",
+          "integrity": "sha512-GwSkxPrihfLR69/dSV3+5CdMQ0D+jXg8Ma1S4nQXKJAznYFX14vHdc/NetQc34Dw+rBbIJyP7JOuVb9Fhprvog==",
+          "dev": true,
+          "requires": {
+            "@vue/component-compiler-utils": "^3.1.0",
+            "hash-sum": "^1.0.2",
+            "loader-utils": "^1.1.0",
+            "vue-hot-reload-api": "^2.3.0",
+            "vue-style-loader": "^4.1.0"
+          },
+          "dependencies": {
+            "hash-sum": {
+              "version": "1.0.2",
+              "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+              "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
+              "dev": true
+            }
+          }
+        },
         "ansi-regex": {
           "version": "5.0.1",
           "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -2418,6 +2460,26 @@
           "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
           "dev": true
         },
+        "json5": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.0"
+          }
+        },
+        "loader-utils": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^1.0.1"
+          }
+        },
         "minipass": {
           "version": "3.1.6",
           "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.1.6.tgz",
@@ -3017,47 +3079,6 @@
         }
       }
     },
-    "@vue/vue-loader-v15": {
-      "version": "npm:vue-loader@15.9.8",
-      "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.9.8.tgz",
-      "integrity": "sha512-GwSkxPrihfLR69/dSV3+5CdMQ0D+jXg8Ma1S4nQXKJAznYFX14vHdc/NetQc34Dw+rBbIJyP7JOuVb9Fhprvog==",
-      "dev": true,
-      "requires": {
-        "@vue/component-compiler-utils": "^3.1.0",
-        "hash-sum": "^1.0.2",
-        "loader-utils": "^1.1.0",
-        "vue-hot-reload-api": "^2.3.0",
-        "vue-style-loader": "^4.1.0"
-      },
-      "dependencies": {
-        "hash-sum": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz",
-          "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
-          "dev": true
-        },
-        "json5": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz",
-          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
-          "dev": true,
-          "requires": {
-            "minimist": "^1.2.0"
-          }
-        },
-        "loader-utils": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.0.tgz",
-          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
-          "dev": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^1.0.1"
-          }
-        }
-      }
-    },
     "@vue/web-component-wrapper": {
       "version": "1.3.0",
       "resolved": "https://registry.npmmirror.com/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz",
@@ -5993,6 +6014,18 @@
         }
       }
     },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "fast-diff": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
+      "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
+      "dev": true
+    },
     "fast-glob": {
       "version": "3.2.11",
       "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.11.tgz",
@@ -9571,6 +9604,12 @@
         "boolbase": "^1.0.0"
       }
     },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
     "object-is": {
       "version": "1.1.5",
       "resolved": "https://registry.npmmirror.com/object-is/-/object-is-1.1.5.tgz",
@@ -9728,6 +9767,12 @@
         "tslib": "^2.0.3"
       }
     },
+    "parchment": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
+      "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==",
+      "dev": true
+    },
     "parent-module": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
@@ -10512,6 +10557,54 @@
         }
       }
     },
+    "quill": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
+      "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
+      "dev": true,
+      "requires": {
+        "clone": "^2.1.1",
+        "deep-equal": "^1.0.1",
+        "eventemitter3": "^2.0.3",
+        "extend": "^3.0.2",
+        "parchment": "^1.1.4",
+        "quill-delta": "^3.6.2"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+          "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+          "dev": true
+        },
+        "eventemitter3": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
+          "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=",
+          "dev": true
+        }
+      }
+    },
+    "quill-delta": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
+      "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
+      "dev": true,
+      "requires": {
+        "deep-equal": "^1.0.1",
+        "extend": "^3.0.2",
+        "fast-diff": "1.1.2"
+      }
+    },
+    "quill-mention": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/quill-mention/-/quill-mention-3.1.0.tgz",
+      "integrity": "sha512-uyjGK8QPJHEcjvNc3wUJy6a05Oiu+6JJ0N9SFAwjYHYThgMzlKucyD975fq28Mr1it8ZFRNiRMPa0sCiVOAEwA==",
+      "dev": true,
+      "requires": {
+        "quill": "^1.3.7"
+      }
+    },
     "randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
@@ -11656,6 +11749,11 @@
       "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
       "dev": true
     },
+    "tinymce": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.0.1.tgz",
+      "integrity": "sha512-+y3Lhm65GFs87gUfKuSWm2JA6ULHCC29trof4umIk2+TT+ql2poSsqsmRCSPN4elEo4EssIgEPFVRyPvrS/pDg=="
+    },
     "to-fast-properties": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@@ -12514,6 +12612,16 @@
         "loader-utils": "^2.0.0"
       }
     },
+    "vue-quill-editor": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/vue-quill-editor/-/vue-quill-editor-3.0.6.tgz",
+      "integrity": "sha512-g20oSZNWg8Hbu41Kinjd55e235qVWPLfg4NvsLW6d+DhgBTFbEuMpcWlUdrD6qT3+Noim6DRu18VLM9lVShXOQ==",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "quill": "^1.3.4"
+      }
+    },
     "vue-style-loader": {
       "version": "4.1.3",
       "resolved": "https://registry.npmmirror.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz",

+ 7 - 2
package.json

@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "@paypal/paypal-js": "^5.0.2",
+    "@tinymce/tinymce-vue": "^4.0.7",
     "axios": "^0.26.1",
     "core-js": "^3.8.3",
     "element-plus": "^2.1.4",
@@ -17,23 +18,27 @@
     "node-sass": "^7.0.1",
     "postcss-import": "^14.0.2",
     "postcss-url": "^10.1.3",
-    "quill": "^1.3.7",
     "sass-loader": "^12.6.0",
+    "tinymce": "^6.0.1",
     "vue": "^3.2.13"
   },
   "devDependencies": {
     "@babel/core": "^7.12.16",
     "@babel/eslint-parser": "^7.12.16",
+    "@faker-js/faker": "^6.1.1",
     "@vue/cli-plugin-babel": "~5.0.0",
     "@vue/cli-plugin-eslint": "~5.0.0",
     "@vue/cli-service": "~5.0.0",
     "eslint": "^7.32.0",
     "eslint-plugin-vue": "^8.0.3",
     "node-sass": "^7.0.1",
+    "quill": "^1.3.7",
+    "quill-mention": "^3.1.0",
     "sass-loader": "^12.6.0",
     "unplugin-auto-import": "^0.6.6",
     "unplugin-vue-components": "^0.18.3",
-    "vue-cli-plugin-chrome-extension-cli": "~1.1.2"
+    "vue-cli-plugin-chrome-extension-cli": "~1.1.2",
+    "vue-quill-editor": "^3.0.6"
   },
   "eslintConfig": {
     "root": true,

+ 8 - 0
src/http/publishApi.js

@@ -24,4 +24,12 @@ export function srcPublishSuccess(params) {
       method: 'post',
       data: params
     })
+}
+
+export function searchTwitterUser(params) {
+  return service({
+    url: `/openapi/searchTwitterUser`,
+    method: 'post',
+    data: params
+  })
 }

+ 46 - 48
src/view/components/give-dialog.vue

@@ -26,7 +26,6 @@
                 </div>
                 <div class="right">
                     <template v-if="!showPreview">
-                        <div id="editor" class=""></div>
                         <div class="form-wrapper">
                             <div class="form-base">
                                 <div class="item">
@@ -72,7 +71,9 @@
                                         {{ item.label }}
                                     </div>
                                     <div class="control">
-                                        <el-input
+                                        <tinymce v-if="item.nodeType == 'textarea'"
+                                            @changeAccountVal="changeAccountVal"></tinymce>
+                                        <!-- <el-input
                                             :type="item.nodeType"
                                             rows="2"
                                             resize="none"
@@ -83,11 +84,21 @@
                                                 'box-shadow': 'none',
                                                 'padding': '1px',
                                                 'line-height': '1'
-                                            }"/>
+                                            }"/> -->
                                     </div>
                                     <el-switch v-model="item.checked" />
                                 </div>
                             </div>
+                            <!-- <div class="anti-bot-wrapper">
+                                <div class="label">
+                                    <img src="" class="icon-bot">
+                                    Anti Bot
+                                    <img src="" class="icon-beta">
+                                    <img src="" class="icon-question">
+                                </div>
+                                <el-switch v-model="openAntiBot" />
+                            </div> -->
+
                             <div class="submit-btn" @click="confirm">NEXT</div>
                         </div>
                     </template>
@@ -106,21 +117,15 @@
 <script setup>
 import { ref, watch, reactive, defineProps, defineEmits, onMounted } from "vue";
 import {postPublish, verifyPaypalResult} from "../../http/publishApi"
-// import Quill from 'quill';
-// import 'quill/dist/quill.snow.css'
-
-// const quillOptions = {
-//     placeholder: 'Compose an epic...',
-// };
-
 import previewCard from "./preview-card";
 import paypalButton from "./paypal-button";
+import tinymce from "./tinymce.vue"
 
 const paypalClientId = 'ASn7k0zqyS5AWYikVSfmamR-RFpjyU_QFJWSxOHHoWE04-RgHNO6nahn0GyHUaUAEBxj-aKgtSrq4O4G';
 
 let publishRes = reactive({})
 
-let visible = ref(true);
+let visible = ref(false);
 let showPreview = ref(false);
 let dialogHeight = ref(620);
 let previewDialogHeight = ref(880)
@@ -168,9 +173,6 @@ watch(
     (newVal) => {
         console.log("watch", newVal);
         visible.value = newVal;
-        if(newVal) {
-            // initQuill();
-        }
     }
 );
 
@@ -272,30 +274,13 @@ const payPalFinsh = (params) => {
     })
 }
 
-
-// const initQuill = () => {
-//     let container = document.getElementById('editor');
-//     let editor  = new Quill(container, quillOptions);
-
-//     editor.on('text-change', () => {
-//         if(editor.getText()) {
-//             /**
-//              * quill.insertText(5, 'Quill', {
-//                 'color': '#ffff00',
-//                 'italic': true
-//                 });
-//              */
-//             // editor.setContents([
-//             //     { insert: 'World!', attributes: { color: 'blue' } },
-//             // ]);
-//         }
-//         console.log(editor.getText())
-//     });
-// }
+const changeAccountVal = (val) => {
+    formList[0]['text'] = val;
+    console.log('formList',formList);
+}
 
 onMounted(() => {
     setPreviewDialogHeight();
-    // initQuill();
 })
 
 </script>
@@ -310,7 +295,7 @@ onMounted(() => {
     right: 0;
     bottom: 0;
     left: 0;
-    z-index: 2000;
+    z-index: 1000;
     height: 100%;
     background-color: rgba(0, 0, 0, 0.5);
     overflow: auto;
@@ -478,23 +463,36 @@ onMounted(() => {
                                 height: 50px;
                                 line-height: 50px;
                                 cursor: pointer;
-
-                                .inner {
-                                    width: 100%;
-                                    height: 100%;
-                                    box-sizing: border-box;
-                                    display: flex;
-                                    align-items: center;
-                                }
-                            }
-
-                            .icon-remove-button {
-                                cursor: pointer;
                             }
                         }
                     }
                 }
 
+                .anti-bot-wrapper {
+                    width: 100%;
+                    height: 60px;
+                    display: flex;
+                    align-items: center;
+                    justify-content: space-between;
+                    box-sizing: border-box;
+                    border-radius: 15px;
+                    border: 1px solid #ececec;
+                    padding: 0 15px;
+                    margin-top: 14px;
+
+                    .label {
+                        .icon-bot {
+
+                        }
+                        .icon-beta {
+
+                        }
+                        .icon-question {
+
+                        }
+                    }
+
+                }
                 .submit-btn {
                     width: calc(100% - 36px);
                     height: 60px;

+ 348 - 0
src/view/components/tinymce.vue

@@ -0,0 +1,348 @@
+<template>
+    <div class="wrapper">
+        <Editor
+            v-model="content"
+            :init="editorInit"
+            :api-key="apiKey"
+            output-format="text"
+            @change="handlerFunction"/>
+    </div>
+</template>
+
+<script setup>
+/* eslint-disable */
+import { reactive, ref, onMounted, defineEmits } from "vue";
+import Editor from "@tinymce/tinymce-vue";
+import { faker } from "@faker-js/faker";
+import {searchTwitterUser} from "../../http/publishApi"
+
+// import Quill from "quill";
+// import "quill/dist/quill.snow.css";
+
+// import mention from "quill-mention"; // 引入mention 组件
+
+// import "quill-mention/dist/quill.mention.min.css";
+
+// 为quill 注册mention 组件
+
+// Quill.register({
+//     "modules/mention": mention,
+// });
+
+// let editor = reactive({});
+// const editorOptions = {
+//     placeholder: "", // 文本提示信息
+
+//     modules: {
+//         toolbar: [], // 定义菜单栏 (粗体,下划线,颜色,排序)
+//         mention: {
+//             // 重点: 提醒功能配置项
+
+//             allowedChars: /^[A-Za-z\s]*$/, // 正则匹配
+//             mentionDenotationChars: ["@"], // 匹配符号,匹配到@符号弹出提醒框
+//             offsetLeft: 4,
+//             source: (searchTerm, renderList, mentionChar) => {
+//                 // 数据源(遍历成{id, value}形式)
+//                 console.log("111", searchTerm);
+//                 const values = [
+//                     {
+//                         id: 1,
+//                         value: "sdsd",
+//                     },
+//                     {
+//                         id: 2,
+//                         value: "kkkie",
+//                     },
+//                 ];
+//                 renderList(values, searchTerm); // 渲染函数(生成提醒框)
+//             },
+
+//             onSelect: (data, insertItem) => {
+//                 // 注意:选中后的回调函数
+//                 const item = {
+//                     text: `@${data.value}`,
+//                     name: data.value,
+//                     id: data.id,
+//                 };
+//                 insertItem(data); // 注意:这个函数必须加上,有这个才会在文本框显示选中的值
+//                 getText(data);
+//                 // this.onSelectd(item) // 返回给后端的选中提醒的人
+//             },
+//         },
+//     },
+// };
+let content = ref("");
+const emits = defineEmits(["changeAccountVal"])
+
+// const onHandleChange = () => {};
+// const getText = () => {
+//     console.log(editor.getText());
+// };
+
+onMounted(() => {
+    // let container = document.getElementById('quill');
+    // editor  = new Quill(container, editorOptions);
+    // editor.on('text-change', () => {
+    //     console.log(editor.getText())
+    // });
+});
+const handlerFunction = (value) => {
+    emits('changeAccountVal', content.value);
+    console.log("handlerFunction", content.value);
+};
+
+var fakeServer = (function () {
+    /* Use TinyMCE's Promise shim */
+    // var Promise = tinymce.util.Promise;
+
+    /* Some user profile images for our fake server (original source: unsplash) */
+    var images = [
+        "Abdullah_Hadley",
+        "Abriella_Bond",
+        "Addilynn_Dodge",
+        "Adolfo_Hess",
+        "Alejandra_Stallings",
+        "Alfredo_Schafer",
+        "Aliah_Pitts",
+        "Amilia_Luna",
+        "Andi_Lane",
+        "Angelina_Winn",
+        "Arden_Dean",
+        "Ariyanna_Hicks",
+        "Asiya_Wolff",
+        "Brantlee_Adair",
+        "Carys_Metz",
+        "Daniela_Dewitt",
+        "Della_Case",
+        "Dianna_Smiley",
+        "Eliana_Stout",
+        "Elliana_Palacios",
+        "Fischer_Garland",
+        "Glen_Rouse",
+        "Grace_Gross",
+        "Heath_Atwood",
+        "Jakoby_Roman",
+        "Judy_Sewell",
+        "Kaine_Hudson",
+        "Kathryn_Mcgee",
+        "Kayley_Dwyer",
+        "Korbyn_Colon",
+        "Lana_Steiner",
+        "Loren_Spears",
+        "Lourdes_Browning",
+        "Makinley_Oneill",
+        "Mariana_Dickey",
+        "Miyah_Myles",
+        "Moira_Baxter",
+        "Muhammed_Sizemore",
+        "Natali_Craig",
+        "Nevaeh_Cates",
+        "Oscar_Khan",
+        "Rodrigo_Hawkins",
+        "Ryu_Duke",
+        "Tripp_Mckay",
+        "Vivianna_Kiser",
+        "Yamilet_Booker",
+        "Yarely_Barr",
+        "Zachary_Albright",
+        "Zahir_Mays",
+        "Zechariah_Burrell",
+    ];
+
+    /* Create an array of 200 random names using faker.js */
+    var userNames = [];
+    for (var i = 0; i < 200; i++) {
+        userNames.push(faker.name.findName());
+    }
+
+    /* This represents a database of users on the server */
+    var userDb = {};
+    // /docs/images/unsplash/uifaces-unsplash-portrait-' + images[Math.floor(images.length * Math.random())] + '.jpg
+    userNames
+        .map(function (fullName) {
+            var id = fullName.toLowerCase().replace(/ /g, "");
+            return {
+                id: id,
+                name: fullName,
+                fullName: fullName,
+                description: faker.name.jobTitle(),
+                image: "https://img2.baidu.com/it/u=4244073868,573478915&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400",
+            };
+        })
+        .forEach(function (user) {
+            userDb[user.id] = user;
+        });
+
+    /* This represents getting the complete list of users from the server with the details required for the mentions "profile" item */
+    var fetchUsers = function () {
+        return new Promise(function (resolve, _reject) {
+            /* simulate a server delay */
+            setTimeout(function () {
+                var users = Object.keys(userDb).map(function (id) {
+                    return {
+                        id: id,
+                        name: userDb[id].name,
+                        image: userDb[id].image,
+                        description: userDb[id].description,
+                    };
+                });
+                resolve(users);
+            }, 500);
+        });
+    };
+
+    /* This represents requesting all the details of a single user from the server database */
+    var fetchUser = function (id) {
+        return new Promise(function (resolve, reject) {
+            /* simulate a server delay */
+            setTimeout(function () {
+                if (Object.prototype.hasOwnProperty.call(userDb, id)) {
+                    resolve(userDb[id]);
+                }
+                reject('unknown user id "' + id + '"');
+            }, 300);
+        });
+    };
+
+    return {
+        fetchUsers: fetchUsers,
+        fetchUser: fetchUser,
+    };
+})();
+
+/* These are "local" caches of the data returned from the fake server */
+var usersRequest = null;
+var userRequest = {};
+
+var mentions_fetch = function (query, success) {
+    /* Fetch your full user list from somewhere */
+    // if (usersRequest === null) {
+    //     usersRequest = fakeServer.fetchUsers();
+    // }
+    // usersRequest.then(function (users) {
+    //     /* `query.term` is the text the user typed after the '@' */
+    //     users = users.filter(function (user) {
+    //         return user.name.indexOf(query.term.toLowerCase()) !== -1;
+    //     });
+
+    //     users = users.slice(0, 10);
+
+    //     /* Where the user object must contain the properties `id` and `name`
+    //     but you could additionally include anything else you deem useful. */
+    //     console.log('users',users)
+    //     success(users);
+    // });
+    console.log('searchTwitterUser', query)
+    searchTwitterUser({
+        params: {
+            name : query.term
+        }
+    }).then(res => {
+        if(res.code == 0) {
+            let dataList = [];
+            for (let i = 0; i < res.data.length; i++) {
+                let item = res.data[i];
+                dataList.push({
+                    id: i + '',
+                    name: item.screenName,
+                    image: item.avatarlUrl,
+                    description: item.name
+                })
+            }
+            success(dataList);
+        }
+        console.log('searchTwitterUser',res)
+    })
+};
+
+var mentions_menu_hover = function (userInfo, success) {
+    /* Request more information about the user from the server and cache it locally */
+    if (!userRequest[userInfo.id]) {
+        userRequest[userInfo.id] = fakeServer.fetchUser(userInfo.id);
+    }
+    userRequest[userInfo.id].then(function (userDetail) {
+        var div = document.createElement("div");
+
+        div.innerHTML =
+            '<div class="card">' +
+            '<img class="avatar" src="' +
+            userDetail.image +
+            '"/>' +
+            "<h1>" +
+            userDetail.fullName +
+            "</h1>" +
+            "<p>" +
+            userDetail.description +
+            "</p>" +
+            "</div>";
+
+        success(div);
+    });
+};
+
+var mentions_menu_complete = function (editor, userInfo) {
+    var span = editor.getDoc().createElement("span");
+    span.className = "mymention";
+    span.setAttribute("data-mention-id", userInfo.id);
+    span.appendChild(editor.getDoc().createTextNode("@" + userInfo.name));
+    return span;
+};
+
+var mentions_select = function (mention, success) {
+    console.log('mention', mention, success)
+    /* `mention` is the element we previously created with `mentions_menu_complete`
+      in this case we have chosen to store the id as an attribute */
+    // var id = mention.getAttribute("data-mention-id");
+    // /* Request more information about the user from the server and cache it locally */
+    // if (!userRequest[id]) {
+    //     userRequest[id] = fakeServer.fetchUser(id);
+    // }
+    // userRequest[id].then(function (userDetail) {
+        // var div = document.createElement("div");
+        // div.innerHTML =
+        //     '<div class="card">' +
+        //     '<img class="avatar" style="width: 40px" src="' +
+        //     userDetail.image +
+        //     '"/>' +
+        //     "<h1>" +
+        //     userDetail.fullName +
+        //     "</h1>" +
+        //     "<p>" +
+        //     userDetail.description +
+        //     "</p>" +
+        //     "</div>";
+        // success();
+    // });
+};
+
+const apiKey = ref("qagffr3pkuv17a8on1afax661irst1hbr4e6tbv888sz91jc");
+let editorInit = reactive({
+    plugins: ["mentions"],
+    content_style:
+        ".mymention{ color: blue; }" +
+        "body { font-family:Helvetica,Arial,sans-serif; font-size:14px }",
+    mentions_selector: ".mymention",
+    mentions_fetch: mentions_fetch,
+    mentions_menu_complete: mentions_menu_complete,
+    mentions_select: mentions_select,
+    // mentions_menu_hover: mentions_menu_hover,
+    mentions_item_type: "profile",
+    toolbar: false,
+    menubar: false,
+    branding: false,//tiny技术支持信息是否显示
+    statusbar: false,
+    paste_data_images: false,
+    width: 264,
+    height: 50,
+    border: false,
+    resize: false, //编辑器宽高是否可变,false-否,true-高可变,'both'-宽高均可,注意引号
+    placeholder: "Enter account number", //textarea中的提示信息
+    // language: "zh_CN", //语言类型
+});
+</script>
+
+<style lang="scss" scoped>
+/deep/ .tox-tinymce {
+    border: none;
+}
+</style>

+ 3 - 0
src/view/test.vue

@@ -41,6 +41,9 @@ window.addEventListener("message", function (event) {
 </script>
 
 <style>
+.tox-metions__card-common {
+    display: none !important;
+}
 .main_app {
 }
 </style>

+ 37 - 0
yarn.lock

@@ -978,6 +978,11 @@
     minimatch "^3.0.4"
     strip-json-comments "^3.1.1"
 
+"@faker-js/faker@^6.1.1":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-6.1.1.tgz#adf002d986e1751daadfcf65d1cc03944dab3ced"
+  integrity sha512-8yq1LJVGn4GY06riLddIU1LbJm15yjt46hjfkpWNpH/mqdciPOBVzicKOJxzQNrGgVHVBxcdm7sgwjI/Y19MYw==
+
 "@gar/promisify@^1.0.1":
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
@@ -1121,6 +1126,13 @@
   resolved "https://registry.npmmirror.com/@soda/get-current-script/-/get-current-script-1.0.2.tgz#a53515db25d8038374381b73af20bb4f2e508d87"
   integrity sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==
 
+"@tinymce/tinymce-vue@^4.0.7":
+  version "4.0.7"
+  resolved "https://registry.yarnpkg.com/@tinymce/tinymce-vue/-/tinymce-vue-4.0.7.tgz#811dd87a2a9f70e60c43c2d9d932771c0c8b4677"
+  integrity sha512-1esB8wGWrjPCY+rK8vy3QB1cxwXo7HLJWuNrcyPl6LOVR+QJjub0OiV/C+TUEsLN6OpCtRv+QnIqMC5vXz783Q==
+  dependencies:
+    tinymce "^5.5.0"
+
 "@tootallnate/once@1":
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
@@ -5887,6 +5899,13 @@ quill-delta@^3.6.2:
     extend "^3.0.2"
     fast-diff "1.1.2"
 
+quill-mention@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/quill-mention/-/quill-mention-3.1.0.tgz#acf0bf21524b627e9304f63534e6d2b8c59ab4fd"
+  integrity sha512-uyjGK8QPJHEcjvNc3wUJy6a05Oiu+6JJ0N9SFAwjYHYThgMzlKucyD975fq28Mr1it8ZFRNiRMPa0sCiVOAEwA==
+  dependencies:
+    quill "^1.3.7"
+
 quill@^1.3.4, quill@^1.3.7:
   version "1.3.7"
   resolved "https://registry.yarnpkg.com/quill/-/quill-1.3.7.tgz#da5b2f3a2c470e932340cdbf3668c9f21f9286e8"
@@ -6774,6 +6793,16 @@ timsort@^0.3.0:
   resolved "https://registry.npmmirror.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
   integrity sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==
 
+tinymce@^5.5.0:
+  version "5.10.3"
+  resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-5.10.3.tgz#9485cf00159fd70c4948cb5e9dd49bce2a775899"
+  integrity sha512-O59ssHNnujWvSk5Gt8hIGrdNCMKVWVQv9F8siAgLTRgTh0t3NDHrP1UlLtCxArUi9DPWZvlBeUz8D5fJTu7vnA==
+
+tinymce@^6.0.1:
+  version "6.0.1"
+  resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-6.0.1.tgz#ec832632e398661507cc51b2a7574d17655fb9c8"
+  integrity sha512-+y3Lhm65GFs87gUfKuSWm2JA6ULHCC29trof4umIk2+TT+ql2poSsqsmRCSPN4elEo4EssIgEPFVRyPvrS/pDg==
+
 to-fast-properties@^2.0.0:
   version "2.0.0"
   resolved "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -7052,6 +7081,14 @@ vue-loader@^17.0.0:
     hash-sum "^2.0.0"
     loader-utils "^2.0.0"
 
+vue-quill-editor@^3.0.6:
+  version "3.0.6"
+  resolved "https://registry.yarnpkg.com/vue-quill-editor/-/vue-quill-editor-3.0.6.tgz#1f85646211d68a31a80a72cb7f45bb2f119bc8fb"
+  integrity sha512-g20oSZNWg8Hbu41Kinjd55e235qVWPLfg4NvsLW6d+DhgBTFbEuMpcWlUdrD6qT3+Noim6DRu18VLM9lVShXOQ==
+  dependencies:
+    object-assign "^4.1.1"
+    quill "^1.3.4"
+
 vue-style-loader@^4.1.0, vue-style-loader@^4.1.3:
   version "4.1.3"
   resolved "https://registry.npmmirror.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz#6d55863a51fa757ab24e89d9371465072aa7bc35"