Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
jmal 2025-01-18 13:50:21 +08:00
commit 3e7ce17650
14 changed files with 449 additions and 91 deletions

View File

@ -3607,6 +3607,10 @@ export default {
this.newCreateFileDialogTitle = '新建Word文档'
this.createNewFile('docx')
break
case 'createExcalidrawFile':
this.newCreateFileDialogTitle = '新建白板'
this.createNewFile('excalidraw')
break
case 'createExcelFile':
this.newCreateFileDialogTitle = '新建Excel工作表'
this.createNewFile('xlsx')

View File

@ -0,0 +1,408 @@
<template>
<div>
<div class="top-bar">
<div class="top-left"></div>
<div class="top-center" :style="{'color': saved ? (lightTheme ? '':'#ffffff'): '#ff8200'}">{{ title }}</div>
<div class="top-right">
<div class="top-right-option">
<div style="margin-right: 15px">
<el-button v-if="historyVersion.metadata.time" @click="cancelPreview" size="mini"
:class="lightTheme ? '':'dark-button'">取消预览
</el-button>
</div>
<history-popover
ref="historyPopover"
:light-theme.sync="lightTheme"
:has-history-version.sync="hasHistoryVersion"
:history-list-popover-visible.sync="historyListPopoverVisible"
:history-operation-loading="!loading.closed"
:saved.sync="saved"
@viewHistoryFile="viewHistoryFile"
@recoverySuccess="recoverySuccess"
>
</history-popover>
<div style="margin-right: 15px">
<el-button v-if="!saved" @click="saveBtn" size="mini" :loading="saveBtnUpdating"
:class="lightTheme ? '':'dark-button'">保存
</el-button>
</div>
<div>
<el-button title="外部打开" size="medium" type="primary" @click="openUrl"><svg-icon icon-class="wailian"/></el-button>
</div>
</div>
</div>
</div>
<div class="excalidraw-content" :style="{'top': readOnly ? '0': '2.5rem'}">
<iframe ref="excalidrawIframe" class="excalidraw-iframe" :src="excalidrawUrl" :title="file.name"></iframe>
</div>
</div>
</template>
<script>
import api from '@/api/file-api'
import historyApi from '@/api/file-history'
import txtApi from '@/api/markdown-api'
import HistoryPopover from '@/components/HistoryPopover/index.vue'
import _ from 'lodash'
import { mapState } from 'vuex'
export default {
name: 'ExcalidrawEditor',
components: { HistoryPopover },
props: {
file: {
type: Object,
default: function() {
return {}
},
},
shareId: {
type: String,
default: '',
},
readOnly: {
type: Boolean,
default: false,
},
},
data() {
return {
// excalidrawUrl: 'http://localhost:3000/excalidraw/app/',
excalidrawUrl: 'http://localhost:8085/excalidraw/app/',
excalidrawData: {
elements: [],
appState: {},
files: {}
},
saveBtnUpdating: false,
title: this.file.name,
thisEditorClosing: false,
saved: true,
ready: false,
currentContext: undefined,
currentTitle: undefined,
historyVersion: { metadata: {} },
hasHistoryVersion: false,
historyListPopoverVisible: false,
viewHistory: false,
loading: {
closed: true,
},
lightTheme: true,
}
},
computed: {
...mapState(['message']),
},
created() {
},
mounted() {
this.clearExcalidrawCache()
window.addEventListener('message', this.handleMessage)
},
beforeDestroy() {
window.removeEventListener('message', this.handleMessage)
},
destroyed() {
},
watch: {
'file.id': {
handler(id) {
if (!id) {
return
}
let request = 'previewText'
if (!this.$store.state.user.token) {
request = 'sharePreviewText'
}
api[request]({
shareId: this.shareId,
fileId: this.file.id,
id: this.file.id,
fileName: this.file.name,
path: encodeURI(this.file.path),
username: this.$store.state.user.name,
content: true,
}).then(async (res) => {
this.file.path = res.data.path
this.loadData(res.data.contentText)
this.currentContext = res.data.contentText
})
this.$nextTick(() => {
this.$refs.historyPopover.loadHistoryList(this.file.id)
})
},
immediate: true,
deep: true,
},
message(msg) {
if (msg.event === 'previewSaveAndClose') {
this.saveAndClose()
}
},
},
methods: {
loadData(contentText) {
if (contentText) {
const data = JSON.parse(contentText)
if (typeof this.excalidrawData === 'string') {
this.excalidrawData = JSON.parse(data)
} else {
this.excalidrawData = data
}
}
},
viewHistoryFile({ historyInfo, recovery }) {
if (!this.saved) {
this.$message({ type: 'info', message: '请先保存当前修改的内容' })
return
}
let loadingInfo = recovery ? '恢复中...' : '加载中...'
this.loading = this.$message({
iconClass: 'el-icon-loading',
type: 'info',
duration: 0,
dangerouslyUseHTMLString: true,
message: `<span>&nbsp;&nbsp;${loadingInfo}</span>`,
})
historyApi.previewHistoryText({ id: historyInfo.id }).then((res) => {
this.loading.close()
if (this.historyListPopoverVisible) {
this.historyListPopoverVisible = false
}
if (recovery) {
this.cancelPreview(null, res.data.contentText)
this.$message({ message: '恢复成功', type: 'success' })
} else {
this.currentTitle = this.title
this.loadData(res.data.contentText)
this.updateContent()
this.historyVersion = historyInfo
this.title = `历史版本:${historyInfo.metadata.time}`
this.viewHistory = true
}
}).catch(() => {
this.loading.close()
})
},
recoverySuccess({ historyInfo }) {
this.viewHistoryFile({ historyInfo: historyInfo, recovery: true })
},
cancelPreview(event, currentContext) {
if (!currentContext) {
currentContext = this.currentContext
}
this.historyVersion = { metadata: {} }
this.loadData(currentContext)
this.updateContent()
if (this.currentTitle) {
this.title = this.currentTitle
}
this.viewHistory = false
},
saveAndClose() {
this.saveBtn()
this.thisEditorClosing = true
},
updateContent() {
const excalidrawData = {
type: 'INIT_DATA',
data: this.excalidrawData
};
this.$refs.excalidrawIframe.contentWindow.postMessage(excalidrawData, '*');
},
saveBtn() {
this.getDataBase()
},
loadExcalidrawFiles(files) {
const data = {
type: 'REQUEST_SAVE',
data: {
elements: JSON.parse(localStorage.getItem('excalidraw')),
appState: JSON.parse(localStorage.getItem('excalidraw-state')),
files: files
}
}
this.$refs.excalidrawIframe.contentWindow.postMessage(data, '*')
},
update() {
this.saveBtnUpdating = true
this.currentContext = JSON.stringify(this.excalidrawData)
txtApi.editMarkdownByPath({
relativePath: encodeURI(this.file.path + this.file.name),
userId: this.$store.state.user.userId,
username: this.$store.state.user.name,
mountFileId: this.$store.state.user.userId !== this.file.userId ? this.file.id : '',
contentText: this.currentContext,
}).then(() => {
this.saveBtnUpdating = false
this.saved = true
this.title = this.file.name
this.$emit('onEdit', this.saved)
this.$refs.historyPopover.loadHistoryList(this.file.id)
if (this.thisEditorClosing) {
this.thisEditorClosing = false
this.$emit('onClose')
}
}).catch(() => {
this.thisEditorClosing = false
this.saveBtnUpdating = false
})
},
clearExcalidrawCache() {
localStorage.removeItem('excalidraw')
localStorage.removeItem('excalidraw-state')
localStorage.removeItem('version-dataState')
localStorage.removeItem('version-files')
},
getDataBase() {
const request = indexedDB.open("files-db", 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains("files-store")) {
db.createObjectStore("files-store", { keyPath: "id" });
}
};
request.onsuccess = (event) => {
const db = event.target.result;
this.getData(db);
};
},
// 获取所有数据
getData(db) {
const transaction = db.transaction("files-store", "readonly");
const store = transaction.objectStore("files-store");
const getAllRequest = store.getAll();
const files = {}
getAllRequest.onsuccess = (event) => {
const data = event.target.result;
data.forEach((item) => {
files[item.id] = item;
});
this.loadExcalidrawFiles(files);
};
getAllRequest.onerror = (event) => {
console.error("Error getting data:", event.target.error);
};
},
handleMessage(event) {
const editWindow = this.$refs.excalidrawIframe.contentWindow
if (event.source !== editWindow) {
return
}
const payload = event.data
switch (payload.type) {
case 'EXCALIDRAW_READY':
this.updateContent()
break
case 'INIT_DONE':
this.ready = true
this.$emit('onReady')
break
case 'CHANGE_FILE':
if (!this.viewHistory) {
const data = JSON.parse(localStorage.getItem('excalidraw'))
if (_.isEqual(this.excalidrawData.elements, data)) {
this.saved = true
if (this.title === `*${this.file.name}`) {
this.title = this.file.name
}
} else {
this.saved = false
this.title = `*${this.file.name}`
}
this.$emit('onEdit', this.saved)
}
break
case 'SAVE_FILE':
if (typeof payload.data === 'string') {
this.excalidrawData = JSON.parse(payload.data)
} else {
this.excalidrawData = payload.data
}
if (!this.saved) {
this.update()
}
break
}
},
openUrl() {
window.open(this.excalidrawUrl)
}
},
}
</script>
<style lang="scss" scoped>
@import 'src/styles/iframe.scss';
.excalidraw-content {
z-index: 999;
position: absolute;
top: 2.5rem;
left: 0;
width: 100%;
height: calc(100% - 2.5rem);
> > > .dark-button {
background: #3e3e3e;
border: 1px solid #3e3e3e;
color: #ffffff;
}
> > > .dark-button:hover {
color: #409EFF;
background-color: #181818;
}
.excalidraw-title {
z-index: 2001;
position: relative;
.excalidraw-title-name {
line-height: 32px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
z-index: 2001;
position: absolute;
text-align: center;
width: 40%;
top: 16px;
left: 50%;
transform: translate(-50%, -50%);
}
.excalidraw-operation {
display: flex;
float: right;
margin-right: 15px;
line-height: 32px;
}
}
.excalidraw-iframe {
z-index: 1999;
position: absolute;
top: 2px;
left: 0;
width: 100%;
height: 100%;
background: 0 0;
border: 0;
float: none;
margin: -1px 0 0;
max-width: none;
outline: 0;
padding: 0;
}
}
</style>

View File

@ -19,6 +19,7 @@
<CADPreview v-if="fileType === 'cad'" :file="file" :shareId="shareId" :file-url="fileUrl" @onReady="onReady" @loadFileFailed="loadFileFailed"></CADPreview>
<pdf-preview v-else-if="fileType === 'pdf'" :file="file" :shareId="shareId" :file-url="fileUrl" @onReady="onReady"></pdf-preview>
<drawio v-else-if="fileType === 'drawio'" v-show="fileReday" :file="file" :shareId="shareId" :read-only="readOnly" @onEdit="onEdit" @onReady="onReady" @onClose="close"></drawio>
<excalidraw-editor v-else-if="fileType === 'excalidraw'" v-show="fileReday" :file="file" :shareId="shareId" :read-only="readOnly" @onEdit="onEdit" @onReady="onReady" @onClose="close"></excalidraw-editor>
<my-mind-editor v-else-if="fileType === 'mind'" :file="file" :shareId="shareId" :read-only="readOnly" @onEdit="onEdit" @onReady="onReady" @onClose="close"></my-mind-editor>
<model-preview v-else-if="fileType === 'glTF/GLB'" :file="file" :file-url="fileUrl" :shareId="shareId" @onReady="onReady"></model-preview>
<only-office-editor ref="officeEditor" v-else-if="fileType === 'office'" :file="file" :file-url="fileUrl" :shareId="shareId" :sharer="sharer" :read-only="readOnly" @onEdit="onEdit" @manualSave="manualSave" @onClose="close" @onReady="onReady"></only-office-editor>
@ -31,6 +32,7 @@
<script>
import ExcalidrawEditor from '@/components/office/ExcalidrawEditor.vue'
import ModelPreview from '@/components/office/ModelPreview.vue'
import OnlyOfficeEditor from "@/components/office/OnlyOfficeEditor";
import MessageDialog from "@/components/message/MessageDialog";
@ -41,7 +43,8 @@ import Drawio from "@/components/office/Drawio";
export default {
name: 'IframePreview',
components: { IframeContentPreview, ModelPreview, Drawio, PdfPreview, MessageDialog, OnlyOfficeEditor,
components: {
ExcalidrawEditor, IframeContentPreview, ModelPreview, Drawio, PdfPreview, MessageDialog, OnlyOfficeEditor,
MyMindEditor: () => import('@/components/Minder/minder'),
CADPreview: () => import('@/components/preview/CADPreview.vue')
},
@ -145,6 +148,8 @@ export default {
switch (suffix) {
case 'drawio':
return 'drawio'
case 'excalidraw':
return 'excalidraw'
case 'pdf':
return 'pdf'
case 'mind':

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -14,3 +14,15 @@ export const fileArrangements = [
{ label: '上传时间', operation: 'orderUploadDate', orderProp: 'uploadDate'},
{ label: '修改时间', operation: 'orderUpdateDate', orderProp: 'updateDate'},
]
export const createFiles = [
{ label: '文件夹', operation: 'createFolder', iconClass: 'folder'},
{ divider: true, operation: 'divider' },
{ label: '文本', operation: 'createTextFile', iconClass: 'file-txt'},
{ label: '白板', operation: 'createExcalidrawFile', iconClass: 'file-excalidraw'},
{ label: '思维导图', operation: 'createMinderFile', iconClass: 'file-mind'},
{ label: '流程图', operation: 'createDrawioFile', iconClass: 'file-drawio'},
{ label: 'Word', operation: 'createWordFile', iconClass: 'file-word'},
{ label: 'Excel', operation: 'createExcelFile', iconClass: 'file-excel'},
{ label: 'PPT', operation: 'createPPTFile', iconClass: 'file-ppt'},
]

View File

@ -10,7 +10,7 @@ export const suffix = {
compressedFile: [
'zip','tar','7z', 'rar', 'jar','tar.gz','tgz','tar.bz2'
],
iframePreviewFile: ['pdf', 'csv', 'drawio', 'mind', 'glb', 'gltf', 'dwg']
iframePreviewFile: ['pdf', 'csv', 'drawio', 'mind', 'glb', 'gltf', 'dwg', 'excalidraw']
}
monaco.languages.getLanguages().forEach(language => {
@ -68,6 +68,7 @@ iconClass.set('docxf','file-docxf')
iconClass.set('ppt','file-ppt')
iconClass.set('pptx','file-ppt')
iconClass.set('drawio','file-drawio')
iconClass.set('excalidraw','file-excalidraw')
iconClass.set('csv','file-csv')
iconClass.set('pdf','file-pdf')
iconClass.set('mind','file-mind')

View File

@ -17,7 +17,7 @@
<script>
import ShowFile from "@/components/ShowFile/ShowFile";
import { fileArrangements } from '@/utils/file-operations'
import { createFiles, fileArrangements } from '@/utils/file-operations'
export default {
components: {ShowFile},
@ -40,16 +40,7 @@
},
{ label: '刷新', operation: 'refresh'},
{ divider: true, operation: 'divider' },
{ label: '新建', operation: 'create' , homeDisable: true, child: [
{ label: '文件夹', operation: 'createFolder', iconClass: 'folder'},
{ divider: true, operation: 'divider' },
{ label: '文本', operation: 'createTextFile', iconClass: 'file-txt'},
{ label: '思维导图', operation: 'createMinderFile', iconClass: 'file-mind'},
{ label: '流程图', operation: 'createDrawioFile', iconClass: 'file-drawio'},
{ label: 'Word', operation: 'createWordFile', iconClass: 'file-word'},
{ label: 'Excel', operation: 'createExcelFile', iconClass: 'file-excel'},
{ label: 'PPT', operation: 'createPPTFile', iconClass: 'file-ppt'},
]
{ label: '新建', operation: 'create' , homeDisable: true, child: createFiles
},
{ divider: true, operation: 'divider' },
{ label: '写文章', operation: 'createMarkdownFile'},

View File

@ -16,7 +16,7 @@
<script>
import ShowFile from "@/components/ShowFile/ShowFile";
import { fileArrangements } from '@/utils/file-operations'
import { createFiles, fileArrangements } from '@/utils/file-operations'
export default {
components: {ShowFile},
@ -39,16 +39,7 @@ export default {
},
{ label: '刷新', operation: 'refresh'},
{ divider: true, operation: 'divider' },
{ label: '新建', operation: 'create' , homeDisable: true, child: [
{ label: '文件夹', operation: 'createFolder', iconClass: 'folder'},
{ divider: true, operation: 'divider' },
{ label: '文本', operation: 'createTextFile', iconClass: 'file-txt'},
{ label: '思维导图', operation: 'createMinderFile', iconClass: 'file-mind'},
{ label: '流程图', operation: 'createDrawioFile', iconClass: 'file-drawio'},
{ label: 'Word', operation: 'createWordFile', iconClass: 'file-word'},
{ label: 'Excel', operation: 'createExcelFile', iconClass: 'file-excel'},
{ label: 'PPT', operation: 'createPPTFile', iconClass: 'file-ppt'},
]
{ label: '新建', operation: 'create' , homeDisable: true, child: createFiles
},
{ divider: true, operation: 'divider' },
{ label: '写文章', operation: 'createMarkdownFile'},

View File

@ -16,7 +16,7 @@
<script>
import ShowFile from "@/components/ShowFile/ShowFile";
import { fileArrangements } from '@/utils/file-operations'
import { createFiles, fileArrangements } from '@/utils/file-operations'
export default {
components: {ShowFile},
@ -39,16 +39,7 @@ export default {
},
{ label: '刷新', operation: 'refresh'},
{ divider: true, operation: 'divider' },
{ label: '新建', operation: 'create' , homeDisable: true, child: [
{ label: '文件夹', operation: 'createFolder', iconClass: 'folder'},
{ divider: true, operation: 'divider' },
{ label: '文本', operation: 'createTextFile', iconClass: 'file-txt'},
{ label: '思维导图', operation: 'createMinderFile', iconClass: 'file-mind'},
{ label: '流程图', operation: 'createDrawioFile', iconClass: 'file-drawio'},
{ label: 'Word', operation: 'createWordFile', iconClass: 'file-word'},
{ label: 'Excel', operation: 'createExcelFile', iconClass: 'file-excel'},
{ label: 'PPT', operation: 'createPPTFile', iconClass: 'file-ppt'},
]
{ label: '新建', operation: 'create' , homeDisable: true, child: createFiles
},
{ divider: true, operation: 'divider' },
{ label: '写文章', operation: 'createMarkdownFile'},

View File

@ -15,7 +15,7 @@
<script>
import ShowFile from "@/components/ShowFile/ShowFile";
import { fileArrangements } from '@/utils/file-operations'
import { createFiles, fileArrangements } from '@/utils/file-operations'
export default {
components: {ShowFile},
@ -38,16 +38,7 @@ export default {
},
{ label: '刷新', operation: 'refresh'},
{ divider: true, operation: 'divider' },
{ label: '新建', operation: 'create' , homeDisable: true, child: [
{ label: '文件夹', operation: 'createFolder', iconClass: 'folder'},
{ divider: true, operation: 'divider' },
{ label: '文本', operation: 'createTextFile', iconClass: 'file-txt'},
{ label: '思维导图', operation: 'createMinderFile', iconClass: 'file-mind'},
{ label: '流程图', operation: 'createDrawioFile', iconClass: 'file-drawio'},
{ label: 'Word', operation: 'createWordFile', iconClass: 'file-word'},
{ label: 'Excel', operation: 'createExcelFile', iconClass: 'file-excel'},
{ label: 'PPT', operation: 'createPPTFile', iconClass: 'file-ppt'},
]
{ label: '新建', operation: 'create' , homeDisable: true, child: createFiles
},
{ divider: true, operation: 'divider' },
{ label: '写文章', operation: 'createMarkdownFile'},

View File

@ -16,7 +16,7 @@
<script>
import ShowFile from "@/components/ShowFile/ShowFile";
import { fileArrangements } from '@/utils/file-operations'
import { createFiles, fileArrangements } from '@/utils/file-operations'
export default {
components: {ShowFile},
@ -39,16 +39,7 @@ export default {
},
{ label: '刷新', operation: 'refresh'},
{ divider: true, operation: 'divider' },
{ label: '新建', operation: 'create' , homeDisable: true, child: [
{ label: '文件夹', operation: 'createFolder', iconClass: 'folder'},
{ divider: true, operation: 'divider' },
{ label: '文本', operation: 'createTextFile', iconClass: 'file-txt'},
{ label: '思维导图', operation: 'createMinderFile', iconClass: 'file-mind'},
{ label: '流程图', operation: 'createDrawioFile', iconClass: 'file-drawio'},
{ label: 'Word', operation: 'createWordFile', iconClass: 'file-word'},
{ label: 'Excel', operation: 'createExcelFile', iconClass: 'file-excel'},
{ label: 'PPT', operation: 'createPPTFile', iconClass: 'file-ppt'},
]
{ label: '新建', operation: 'create' , homeDisable: true, child: createFiles
},
{ divider: true, operation: 'divider' },
{ label: '写文章', operation: 'createMarkdownFile'},

View File

@ -12,7 +12,7 @@
<script>
import ShowFile from "@/components/ShowFile/ShowFile";
import { fileArrangements } from '@/utils/file-operations'
import { createFiles, fileArrangements } from '@/utils/file-operations'
export default {
components: {ShowFile},
@ -32,16 +32,7 @@ export default {
},
{ label: '刷新', operation: 'refresh'},
{ divider: true, operation: 'divider' },
{ label: '新建', operation: 'create' ,child: [
{ label: '文件夹', operation: 'createFolder', iconClass: 'folder'},
{ divider: true, operation: 'divider' },
{ label: '文本', operation: 'createTextFile', iconClass: 'file-txt'},
{ label: '思维导图', operation: 'createMinderFile', iconClass: 'file-mind'},
{ label: '流程图', operation: 'createDrawioFile', iconClass: 'file-drawio'},
{ label: 'Word', operation: 'createWordFile', iconClass: 'file-word'},
{ label: 'Excel', operation: 'createExcelFile', iconClass: 'file-excel'},
{ label: 'PPT', operation: 'createPPTFile', iconClass: 'file-ppt'},
]
{ label: '新建', operation: 'create' ,child: createFiles
},
{ divider: true, operation: 'divider' },
{ label: '写文章', operation: 'createMarkdownFile'},

View File

@ -14,7 +14,7 @@
<script>
import ShowFile from "@/components/ShowFile/ShowFile";
import { fileArrangements } from '@/utils/file-operations'
import { createFiles, fileArrangements } from '@/utils/file-operations'
export default {
components: {ShowFile},
@ -37,17 +37,7 @@
},
{ label: '刷新', operation: 'refresh'},
{ divider: true, operation: 'divider' },
{ label: '新建', operation: 'create' , homeDisable: true, child: [
{ label: '文件夹', operation: 'createFolder', iconClass: 'folder'},
{ divider: true, operation: 'divider' },
{ label: '文本', operation: 'createTextFile', iconClass: 'file-txt'},
{ label: '思维导图', operation: 'createMinderFile', iconClass: 'file-mind'},
{ label: '流程图', operation: 'createDrawioFile', iconClass: 'file-drawio'},
{ label: 'Word', operation: 'createWordFile', iconClass: 'file-word'},
{ label: 'Excel', operation: 'createExcelFile', iconClass: 'file-excel'},
{ label: 'PPT', operation: 'createPPTFile', iconClass: 'file-ppt'},
]
},
{ label: '新建', operation: 'create' , homeDisable: true, child: createFiles},
{ divider: true, operation: 'divider' },
{ label: '写文章', operation: 'createMarkdownFile'},
]

View File

@ -16,7 +16,7 @@
<script>
import ShowFile from "@/components/ShowFile/ShowFile";
import { fileArrangements } from '@/utils/file-operations'
import { createFiles, fileArrangements } from '@/utils/file-operations'
export default {
components: {ShowFile},
@ -39,16 +39,7 @@ export default {
},
{ label: '刷新', operation: 'refresh'},
{ divider: true, operation: 'divider' },
{ label: '新建', operation: 'create' , homeDisable: true, child: [
{ label: '文件夹', operation: 'createFolder', iconClass: 'folder'},
{ divider: true, operation: 'divider' },
{ label: '文本', operation: 'createTextFile', iconClass: 'file-txt'},
{ label: '思维导图', operation: 'createMinderFile', iconClass: 'file-mind'},
{ label: '流程图', operation: 'createDrawioFile', iconClass: 'file-drawio'},
{ label: 'Word', operation: 'createWordFile', iconClass: 'file-word'},
{ label: 'Excel', operation: 'createExcelFile', iconClass: 'file-excel'},
{ label: 'PPT', operation: 'createPPTFile', iconClass: 'file-ppt'},
]
{ label: '新建', operation: 'create' , homeDisable: true, child: createFiles
},
{ divider: true, operation: 'divider' },
{ label: '写文章', operation: 'createMarkdownFile'},