|
@@ -6,29 +6,117 @@
|
|
|
:defaultConfig="toolbarConfig"
|
|
|
mode="default"
|
|
|
/>
|
|
|
- <el-row :gutter="20" class="main">
|
|
|
- <el-col :span="20">
|
|
|
- <div class="bgEditor">
|
|
|
- <div class="editor">
|
|
|
- <h1 contenteditable style="padding: 100px 100px 0; outline: none">
|
|
|
- 无标题
|
|
|
- </h1>
|
|
|
- <Editor
|
|
|
- v-model="valueHtml"
|
|
|
- :defaultConfig="editorConfig"
|
|
|
- style="padding: 0 90px; height: calc(100% - 150px)"
|
|
|
- mode="default"
|
|
|
- @onCreated="handleCreated"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="tool">
|
|
|
- <el-icon ><MoreFilled style="transform: rotate(180deg);" /></el-icon>
|
|
|
- 123
|
|
|
+ <div class="main">
|
|
|
+ <div class="bgeditor">
|
|
|
+ <div class="editor">
|
|
|
+ <h1 contenteditable style="padding: 100px 100px 0; outline: none">
|
|
|
+ 无标题
|
|
|
+ </h1>
|
|
|
+ <Editor
|
|
|
+ v-model="valueHtml"
|
|
|
+ :defaultConfig="editorConfig"
|
|
|
+ style="padding: 0 90px; height: calc(100% - 150px)"
|
|
|
+ mode="default"
|
|
|
+ @onCreated="handleCreated"
|
|
|
+ />
|
|
|
+ <Transition name="toolCol">
|
|
|
+ <div class="tool" v-if="toolShow">
|
|
|
+ <el-icon color="#cacaca" :size="25">
|
|
|
+ <MoreFilled style="transform: rotate(90deg)" />
|
|
|
+ </el-icon>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ style="
|
|
|
+ border-top-right-radius: 0;
|
|
|
+ border-bottom-right-radius: 0;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ 写内容
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ style="
|
|
|
+ border-top-left-radius: 0;
|
|
|
+ border-bottom-left-radius: 0;
|
|
|
+ margin-left: 0;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ 写大纲
|
|
|
+ </el-button>
|
|
|
+ <div>
|
|
|
+ <el-button v-if="load" :loading="load">
|
|
|
+ <svg class="circular" viewBox="-10, -10, 50, 50">
|
|
|
+ <path
|
|
|
+ class="path"
|
|
|
+ d="
|
|
|
+ M 30 15
|
|
|
+ L 28 17
|
|
|
+ M 25.61 25.61
|
|
|
+ A 15 15, 0, 0, 1, 15 30
|
|
|
+ A 15 15, 0, 1, 1, 27.99 7.5
|
|
|
+ L 15 15
|
|
|
+ "
|
|
|
+ style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="btnType"
|
|
|
+ :class="{ btnTypeAct: btnType === 0 }"
|
|
|
+ @click="btnType = 0"
|
|
|
+ >
|
|
|
+ 短
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="btnType"
|
|
|
+ :class="{ btnTypeAct: btnType === 1 }"
|
|
|
+ @click="btnType = 1"
|
|
|
+ >
|
|
|
+ 中
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="btnType"
|
|
|
+ :class="{ btnTypeAct: btnType === 2 }"
|
|
|
+ @click="btnType = 2"
|
|
|
+ >
|
|
|
+ 长
|
|
|
+ </div>
|
|
|
+ <div style="amrgin-right: 10px" @click="toolShow = false">
|
|
|
+ <el-icon color="#cacaca" :size="25"><ArrowRight /></el-icon>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Transition>
|
|
|
+ <Transition name="toolBtn">
|
|
|
+ <el-icon
|
|
|
+ v-if="!toolShow"
|
|
|
+ @click="toolShow = true"
|
|
|
+ class="toolBtnClass"
|
|
|
+ :size="22"
|
|
|
+ color="#3b82f6"
|
|
|
+ ><ArrowLeft
|
|
|
+ /></el-icon>
|
|
|
+ </Transition>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="operate" v-if="statusPage[1]">
|
|
|
+ <div class="toolHead">
|
|
|
+ <div
|
|
|
+ class="toolHeadItem"
|
|
|
+ v-for="(v, i) in select_right_btn_list"
|
|
|
+ :key="'ttt' + i"
|
|
|
+ :style="{ left: v.left + 'px' }"
|
|
|
+ @click="() => change_select_right_btn_type(i)"
|
|
|
+ :class="{ toolAct: v.index === 0 }"
|
|
|
+ >
|
|
|
+ {{ v.text }}
|
|
|
+ <div class="line"></div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </el-col>
|
|
|
- <el-col :span="4">1</el-col>
|
|
|
- </el-row>
|
|
|
+ <component :is="componment_list[select_right_btn_type]"></component>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -36,14 +124,61 @@
|
|
|
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
|
|
|
import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue';
|
|
|
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
|
|
|
+
|
|
|
+import pen_ink from './components/pen_ink.vue';
|
|
|
+import review from './components/review.vue';
|
|
|
+import image from './components/image.vue';
|
|
|
+import dictionary from './components/dictionary.vue';
|
|
|
+import comment from './components/comment.vue';
|
|
|
+
|
|
|
+const componment_list = [pen_ink, review, image, dictionary, comment];
|
|
|
+
|
|
|
// 编辑器实例,必须用 shallowRef
|
|
|
const editorRef = shallowRef();
|
|
|
|
|
|
// 内容 HTML
|
|
|
const valueHtml = ref('<p>hello</p>');
|
|
|
+const select_right_btn_type = ref(0);
|
|
|
+const select_right_btn_list = ref([
|
|
|
+ {
|
|
|
+ text: 'AI写作',
|
|
|
+ width: 56,
|
|
|
+ left: 0,
|
|
|
+ index: 0,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '校阅',
|
|
|
+ width: 42,
|
|
|
+ left: 75,
|
|
|
+ index: 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '图片',
|
|
|
+ width: 42,
|
|
|
+ left: 136,
|
|
|
+ index: 2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '词典',
|
|
|
+ width: 42,
|
|
|
+ left: 197,
|
|
|
+ index: 3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '评论',
|
|
|
+ width: 42,
|
|
|
+ left: 258,
|
|
|
+ index: 4,
|
|
|
+ },
|
|
|
+]);
|
|
|
|
|
|
onMounted(() => {});
|
|
|
|
|
|
+const statusPage = ref([false, true]); // 0 --> 目录 1 --> operate
|
|
|
+const load = ref(true);
|
|
|
+const toolShow = ref(true);
|
|
|
+const btnType = ref(0);
|
|
|
+
|
|
|
const toolbarConfig = {
|
|
|
toolbarKeys: [
|
|
|
'redo',
|
|
@@ -77,9 +212,9 @@ const editorConfig = {
|
|
|
hoverbarKeys: {
|
|
|
text: {
|
|
|
// 如有 match 函数,则优先根据 match 判断,而忽略 element type
|
|
|
- match: editor => {
|
|
|
+ match: () => {
|
|
|
// 可参考下文的源码
|
|
|
- console.log(editor.getConfig());
|
|
|
+ // console.log(editor.getConfig());
|
|
|
},
|
|
|
menuKeys: [], // 定义你想要的 menu keys
|
|
|
},
|
|
@@ -94,35 +229,96 @@ onBeforeUnmount(() => {
|
|
|
const handleCreated = editor => {
|
|
|
editorRef.value = editor; // 记录 editor 实例,重要!
|
|
|
};
|
|
|
+
|
|
|
+const change_select_right_btn_type = index => {
|
|
|
+ const oldList = JSON.parse(JSON.stringify(select_right_btn_list.value));
|
|
|
+ const zIndex = oldList[index].index;
|
|
|
+ const zLeft = oldList[index].left;
|
|
|
+ select_right_btn_type.value = index;
|
|
|
+ for (let i = 0; i < oldList.length; i++) {
|
|
|
+ const v = oldList[i];
|
|
|
+ if (v.index === 0) {
|
|
|
+ v.index = zIndex;
|
|
|
+ v.left = zLeft;
|
|
|
+ }
|
|
|
+ if (i === index) {
|
|
|
+ v.index = 0;
|
|
|
+ v.left = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (let i = 0; i < oldList.length; i++) {
|
|
|
+ const v = oldList[i];
|
|
|
+ if (v.left === 0) continue;
|
|
|
+ v.left = getLast(v.index, oldList);
|
|
|
+ }
|
|
|
+ select_right_btn_list.value = oldList;
|
|
|
+};
|
|
|
+
|
|
|
+const getLast = (index, li) => {
|
|
|
+ let oldleft = 0;
|
|
|
+ for (let i = 0; i < li.length; i++) {
|
|
|
+ if (li[i].index >= index) continue;
|
|
|
+ oldleft += li[i].width + 19;
|
|
|
+ }
|
|
|
+ return oldleft;
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
-</style>
|
|
|
+.toolCol-enter-active,
|
|
|
+.toolCol-leave-active {
|
|
|
+ opacity: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.toolCol-enter-from,
|
|
|
+.toolCol-leave-to {
|
|
|
+ transform: translateX(0%) !important;
|
|
|
+ opacity: 0;
|
|
|
+}
|
|
|
|
|
|
+.toolBtn-enter-active,
|
|
|
+.toolBtn-leave-active {
|
|
|
+ opacity: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.toolBtn-enter-from,
|
|
|
+.toolBtn-leave-to {
|
|
|
+ opacity: 0;
|
|
|
+ transform: translateX(100%);
|
|
|
+}
|
|
|
+</style>
|
|
|
|
|
|
<style scoped>
|
|
|
.AIeditor {
|
|
|
height: 100%;
|
|
|
}
|
|
|
|
|
|
-.AIeditor .main,
|
|
|
-.bgEditor {
|
|
|
- position: relative;
|
|
|
- height: calc(100% - 40px);
|
|
|
-}
|
|
|
-
|
|
|
.AIeditor .main {
|
|
|
+ height: calc(100% - 40px);
|
|
|
overflow-y: auto;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
}
|
|
|
|
|
|
.editor {
|
|
|
- width: 80%;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+ position: relative;
|
|
|
+ width: 100%;
|
|
|
+ max-width: 816px;
|
|
|
box-shadow: 0 0 25px #eeeeee;
|
|
|
height: 100vh;
|
|
|
margin: 1em auto;
|
|
|
}
|
|
|
|
|
|
+.bgeditor {
|
|
|
+ padding: 0 73px 0 73px;
|
|
|
+ flex: 1;
|
|
|
+ height: 100vh;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
.tool {
|
|
|
+ transition: all 0.2s ease;
|
|
|
bottom: 35px;
|
|
|
align-items: center;
|
|
|
display: flex;
|
|
@@ -135,12 +331,108 @@ const handleCreated = editor => {
|
|
|
width: 500px;
|
|
|
-webkit-box-sizing: border-box;
|
|
|
box-sizing: border-box;
|
|
|
- border-radius: 3px;
|
|
|
- border: 1px solid #eee;
|
|
|
padding: 8px 0 8px 9px;
|
|
|
background-color: #fff;
|
|
|
-webkit-box-pack: justify;
|
|
|
-ms-flex-pack: justify;
|
|
|
justify-content: space-between;
|
|
|
}
|
|
|
+
|
|
|
+.btnType {
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 12px;
|
|
|
+ border-radius: 3px;
|
|
|
+ line-height: 32px;
|
|
|
+ text-align: center;
|
|
|
+ border: 1px solid transparent;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.btnTypeAct {
|
|
|
+ background-color: #e4f2ff;
|
|
|
+ border: 1px solid #3b82f6;
|
|
|
+ color: #3b82f6;
|
|
|
+}
|
|
|
+
|
|
|
+.toolBtnClass {
|
|
|
+ transition: all 0.2s ease;
|
|
|
+ position: absolute;
|
|
|
+ right: 5px;
|
|
|
+ bottom: 55px;
|
|
|
+}
|
|
|
+
|
|
|
+.operate {
|
|
|
+ flex: 1;
|
|
|
+ height: 100vh;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+
|
|
|
+@media screen and (max-width: 1500px) {
|
|
|
+ .bgeditor {
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .operate {
|
|
|
+ margin-left: 8px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.toolHead {
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ -webkit-box-flex: 0;
|
|
|
+ -ms-flex: none;
|
|
|
+ flex: none;
|
|
|
+ z-index: 1;
|
|
|
+ position: relative;
|
|
|
+ width: 100%;
|
|
|
+ height: 50px;
|
|
|
+ /* display: flex;
|
|
|
+ flex-wrap: wrap; */
|
|
|
+}
|
|
|
+
|
|
|
+.toolHeadItem {
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ padding: 0.3em 0.5em;
|
|
|
+ color: #8e8e9c;
|
|
|
+ /* margin-right: 19px; */
|
|
|
+ /* transform: scale(0); */
|
|
|
+ font-size: 16px;
|
|
|
+ text-align: center;
|
|
|
+ /* display: inline-block; */
|
|
|
+ position: absolute;
|
|
|
+ line-height: 2;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 700;
|
|
|
+ opacity: 0;
|
|
|
+ cursor: pointer;
|
|
|
+ order: 1;
|
|
|
+}
|
|
|
+.toolHead:hover .toolHeadItem {
|
|
|
+ opacity: 1;
|
|
|
+}
|
|
|
+.toolHeadItem .line {
|
|
|
+ height: 6px;
|
|
|
+ border-radius: 5px;
|
|
|
+ width: 115%;
|
|
|
+ margin-left: -8%;
|
|
|
+ background-color: #e1e1e1;
|
|
|
+}
|
|
|
+.toolAct {
|
|
|
+ color: #1f1f1f;
|
|
|
+ opacity: 1;
|
|
|
+ /* order: 0; */
|
|
|
+}
|
|
|
+.toolAct .line {
|
|
|
+ background-color: #8e8e8e;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|
|
|
+<style>
|
|
|
+.w-e-bar-show {
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
</style>
|