mirror of
https://github.com/blossom-editor/blossom
synced 2024-11-17 22:48:03 +08:00
删除功能
This commit is contained in:
parent
ff755cc49d
commit
a0a2e62125
@ -63,6 +63,10 @@ export const folderUpdApi = (data?: object): Promise<R<any>> => {
|
||||
return rq.post<R<any>>("/folder/upd", data);
|
||||
}
|
||||
|
||||
export const folderDelApi = (data?: object): Promise<R<any>> => {
|
||||
return rq.post<R<any>>("/folder/del", data);
|
||||
}
|
||||
|
||||
export const folderOpenApi = (data?: object): Promise<R<any>> => {
|
||||
return rq.post<R<any>>("/folder/open", data);
|
||||
}
|
||||
@ -138,6 +142,15 @@ export const articleUpdContentApi = (data?: object): Promise<R<any>> => {
|
||||
return rq.post<R<any>>("/article/upd/content", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文章
|
||||
* @param data {id:文章ID}
|
||||
* @returns
|
||||
*/
|
||||
export const articleDelApi = (data?: object): Promise<R<any>> => {
|
||||
return rq.post<R<any>>("/article/del", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* star 或取消 star
|
||||
* @param data
|
||||
|
@ -18,14 +18,14 @@
|
||||
<!-- L1无下级 -->
|
||||
<el-menu-item v-if="isEmpty(L1.children)" :index="L1.i">
|
||||
<template #title>
|
||||
<ArticleTreeTitle :trees="L1" @click-doc="clickCurDoc" :size="15" />
|
||||
<ArticleTreeTitle :size="15" :trees="L1" @click-doc="clickCurDoc" @refreshDocTree="getDocTree" />
|
||||
</template>
|
||||
</el-menu-item>
|
||||
|
||||
<!-- L1有下级 -->
|
||||
<el-sub-menu v-else :expand-open-icon="ArrowDownBold" :expand-close-icon="ArrowRightBold" :index="L1.i">
|
||||
<template #title>
|
||||
<ArticleTreeTitle :trees="L1" @click-doc="clickCurDoc" :size="15" />
|
||||
<ArticleTreeTitle :size="15" :trees="L1" @click-doc="clickCurDoc" @refreshDocTree="getDocTree" />
|
||||
</template>
|
||||
|
||||
<!-- ================================================ L2 ================================================ -->
|
||||
@ -33,14 +33,14 @@
|
||||
<!-- L2无下级 -->
|
||||
<el-menu-item v-if="isEmpty(L2.children)" :index="L2.i">
|
||||
<template #title>
|
||||
<ArticleTreeTitle :trees="L2" @click-doc="clickCurDoc" />
|
||||
<ArticleTreeTitle :trees="L2" @click-doc="clickCurDoc" @refreshDocTree="getDocTree" />
|
||||
</template>
|
||||
</el-menu-item>
|
||||
|
||||
<!-- L2有下级 -->
|
||||
<el-sub-menu v-else :expand-open-icon="ArrowDownBold" :expand-close-icon="ArrowRightBold" :index="L2.i">
|
||||
<template #title>
|
||||
<ArticleTreeTitle :trees="L2" @click-doc="clickCurDoc" />
|
||||
<ArticleTreeTitle :trees="L2" @click-doc="clickCurDoc" @refreshDocTree="getDocTree" />
|
||||
</template>
|
||||
|
||||
<!-- ================================================ L3 ================================================ -->
|
||||
@ -48,14 +48,14 @@
|
||||
<!-- L3无下级 -->
|
||||
<el-menu-item v-if="isEmpty(L3.children)" :index="L3.i">
|
||||
<template #title>
|
||||
<ArticleTreeTitle :trees="L3" @click-doc="clickCurDoc" />
|
||||
<ArticleTreeTitle :trees="L3" @click-doc="clickCurDoc" @refreshDocTree="getDocTree" />
|
||||
</template>
|
||||
</el-menu-item>
|
||||
|
||||
<!-- L3有下级 -->
|
||||
<el-sub-menu v-else :expand-open-icon="ArrowDownBold" :expand-close-icon="ArrowRightBold" :index="L3.i">
|
||||
<template #title>
|
||||
<ArticleTreeTitle :trees="L3" @click-doc="clickCurDoc" />
|
||||
<ArticleTreeTitle :trees="L3" @click-doc="clickCurDoc" @refreshDocTree="getDocTree" />
|
||||
</template>
|
||||
|
||||
<!-- ================================================ L4 ================================================ -->
|
||||
@ -63,7 +63,7 @@
|
||||
<!-- L4 不允许有下级, 只允许4级 -->
|
||||
<el-menu-item v-if="isEmpty(L4.children)" :index="L4.i">
|
||||
<template #title>
|
||||
<ArticleTreeTitle :trees="L4" @click-doc="clickCurDoc" />
|
||||
<ArticleTreeTitle :trees="L4" @click-doc="clickCurDoc" @refreshDocTree="getDocTree" />
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</div>
|
||||
@ -338,7 +338,7 @@ const getRouteQueryParams = () => {
|
||||
|
||||
//#region ----------------------------------------< 文档列表与当前文章 >----------------------------
|
||||
const docTreeLoading = ref(true) // 文档菜单的加载动画
|
||||
const showSort = ref(false) // 是否显示文章排序
|
||||
const showSort = ref(false) // 是否显示文档排序
|
||||
const docTreeDefaultActive = ref('') // 文档的默认选中项, 用于外部跳转后选中菜单
|
||||
const docTreeData = ref<DocTree[]>([]) // 文档菜单
|
||||
const curDoc = ref<DocInfo>() // 当前选中的文档, 包含文件夹和文章, 如果选中是文件夹, 则不会重置编辑器中的文章
|
||||
|
@ -181,16 +181,10 @@
|
||||
</div>
|
||||
|
||||
<div class="info-footer">
|
||||
<div>
|
||||
<!-- <el-button type="danger" size="default" plain>
|
||||
<span class="iconbl bl-a-fileprohibit-line" />
|
||||
删除
|
||||
</el-button> -->
|
||||
</div>
|
||||
<div></div>
|
||||
<div>
|
||||
<el-button size="default" type="primary" :disabled="saveLoading" @click="saveDoc">
|
||||
<span class="iconbl bl-a-filechoose-line" />
|
||||
保存
|
||||
<span class="iconbl bl-a-filechoose-line" /> 保存
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@ -673,4 +667,4 @@ $height-form: calc(100% - #{$height-title} - #{$height-img} - #{$height-stat} -
|
||||
}
|
||||
</style>
|
||||
|
||||
<style></style>../doc
|
||||
<style></style>
|
@ -26,7 +26,7 @@
|
||||
<div class="menu-item" @click="handleShowDocInfoDialog('upd')">
|
||||
<span class="iconbl bl-a-fileedit-line"></span>编辑文档
|
||||
</div>
|
||||
<div class="menu-item" @click="sync()">
|
||||
<div class="menu-item" @click="syncDoc()">
|
||||
<span class="iconbl bl-a-cloudrefresh-line"></span>同步文档
|
||||
</div>
|
||||
<div class="menu-item" @click="handleShowDocInfoDialog('add', props.trees.p)">
|
||||
@ -37,6 +37,9 @@
|
||||
@click="handleShowDocInfoDialog('add', props.trees.i)">
|
||||
<span class="iconbl bl-a-fileadd-fill"></span>新增<strong>子级</strong>文档
|
||||
</div>
|
||||
<div class="menu-item" @click="delDoc()">
|
||||
<span class="iconbl bl-a-fileprohibit-line"></span>删除文档
|
||||
</div>
|
||||
<!-- 只有文件夹才有子文档 -->
|
||||
<!-- <div class="menu-item" @click="handleShowDocInfoDialog('add', props.trees.i)">
|
||||
<span class="iconbl bl-a-fileprohibit-line"></span>删除文档
|
||||
@ -75,7 +78,7 @@
|
||||
<ArticleInfo ref="ArticleInfoRef"></ArticleInfo>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 详情的弹框 -->
|
||||
<!-- 二维码的弹框 -->
|
||||
<el-dialog v-model="isShowQrCodeDialog" width="335" top="100px" style="
|
||||
--el-dialog-padding-primary:0;
|
||||
--el-dialog-border-radius:10px;
|
||||
@ -91,12 +94,13 @@ import type { PropType } from 'vue'
|
||||
import { useUserStore } from '@renderer/stores/user'
|
||||
|
||||
import { grammar } from './markedjs'
|
||||
import { articleDownloadApi, articleSyncApi } from '@renderer/api/blossom'
|
||||
import { folderDelApi, articleDownloadApi, articleSyncApi, articleDelApi } from '@renderer/api/blossom'
|
||||
import { openExtenal, writeText, openNewArticleWindow } from '@renderer/assets/utils/electron'
|
||||
import { isNotBlank } from '@renderer/assets/utils/obj'
|
||||
import ArticleInfo from '@renderer/views/article/ArticleInfo.vue'
|
||||
import ArticleQrCode from './ArticleQrCode.vue'
|
||||
import Notify from '@renderer/components/Notify'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
@ -165,7 +169,7 @@ const handlClick = () => {
|
||||
|
||||
//#region ----------------------------------------< 右键菜单 >--------------------------------------
|
||||
const rMenu = ref<RightMenu>({ show: false, clientX: 0, clientY: 0 })
|
||||
const rMenuHeight = 275
|
||||
const rMenuHeight = 363
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.body.removeEventListener('click', closeMenuShow)
|
||||
@ -235,9 +239,37 @@ const articleDownload = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const sync = () => {
|
||||
/**
|
||||
* 同步文档
|
||||
*/
|
||||
const syncDoc = () => {
|
||||
articleSyncApi({ id: props.trees.i }).then((_resp) => {
|
||||
Notify.success('同步成功')
|
||||
invokeRefreshDocTree()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文档
|
||||
*/
|
||||
const delDoc = () => {
|
||||
let type = props.trees.ty === 3 ? '文章' : '文件夹'
|
||||
ElMessageBox.confirm(
|
||||
`是否确定删除${type}: <span style="color:#C02B2B;text-decoration: underline;">${props.trees.n}</span>?删除后将不可恢复!`, {
|
||||
confirmButtonText: '确定删除', cancelButtonText: '我再想想', type: 'info', draggable: true, dangerouslyUseHTMLString: true,
|
||||
}
|
||||
).then(() => {
|
||||
if (props.trees.ty === 3) {
|
||||
articleDelApi({ id: props.trees.i }).then(_resp => {
|
||||
Notify.success(`删除文章成功`)
|
||||
invokeRefreshDocTree()
|
||||
})
|
||||
} else {
|
||||
folderDelApi({ id: props.trees.i }).then(_resp => {
|
||||
Notify.success(`删除文件夹成功`)
|
||||
invokeRefreshDocTree()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -282,7 +314,11 @@ const handleShowDocInfoDialog = (dialogType: DocDialogType, pid?: number) => {
|
||||
}
|
||||
//#endregion
|
||||
|
||||
const emits = defineEmits(['clickDoc'])
|
||||
const invokeRefreshDocTree = () => {
|
||||
emits('refreshDocTree')
|
||||
}
|
||||
|
||||
const emits = defineEmits(['clickDoc', 'refreshDocTree'])
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -318,6 +354,7 @@ $icon-size: 17px;
|
||||
border-radius: 7px;
|
||||
position: relative;
|
||||
|
||||
|
||||
.doc-name {
|
||||
@include font(13px, 300);
|
||||
@include themeText(2px 2px 2px #D8D8D8, 2px 2px 2px #0A0A0A);
|
||||
|
@ -62,8 +62,8 @@ declare interface DocInfo {
|
||||
syncTime?: string,
|
||||
}
|
||||
|
||||
/** 文档类型: 1:文章文件夹|2:图片文件夹|3:文章; */
|
||||
declare type DocType = 1 | 2 | 3;
|
||||
/** 文档类型: 1:文章文件夹|2:图片文件夹|3:文章|11:分隔文档; */
|
||||
declare type DocType = 1 | 2 | 3 | 11;
|
||||
|
||||
/** 文档弹框类型: 增|删|查 */
|
||||
declare type DocDialogType = 'add' | 'upd' | 'info'
|
||||
|
@ -35,6 +35,13 @@
|
||||
// item 的 字体大小
|
||||
--el-menu-item-font-size: 13px;
|
||||
|
||||
.menu-divider {
|
||||
width: 100%;
|
||||
height: 15px;
|
||||
border-bottom: 1px solid var(--el-border-color);
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
:deep(.el-menu) {
|
||||
transition: 0.1s !important;
|
||||
}
|
||||
|
@ -5,24 +5,27 @@
|
||||
<div class="doc-container" v-loading="docTreeLoading" element-loading-text="正在读取文档...">
|
||||
<!-- 文件夹操作 -->
|
||||
<div class="doc-workbench">
|
||||
<Workbench @refresh-doc-tree="getDocTree"></Workbench>
|
||||
<Workbench @refresh-doc-tree="getDocTree" @show-sort="handleShowSort"></Workbench>
|
||||
</div>
|
||||
<!-- 文件夹 -->
|
||||
<el-menu v-if="docTreeData != undefined && docTreeData.length > 0" class="doc-trees" :collapse-transition="false">
|
||||
<!-- ================================================ L1 ================================================ -->
|
||||
<div v-for="L1 in docTreeData" :key="L1.i">
|
||||
|
||||
<div v-if="L1.ty == 11" class="menu-divider" />
|
||||
|
||||
<!-- L1无下级 -->
|
||||
<el-menu-item v-if="isEmpty(L1.children)" :index="L1.i">
|
||||
<el-menu-item v-else-if="isEmpty(L1.children)" :index="L1.i">
|
||||
<template #title>
|
||||
<PictureTitle :trees="L1" @click-doc="clickCurFolder" :size="15" />
|
||||
<PictureTitle :size="15" :trees="L1" @click-doc="clickCurFolder" @refresh-doc-tree="getDocTree" />
|
||||
</template>
|
||||
</el-menu-item>
|
||||
|
||||
|
||||
<!-- L1有下级 -->
|
||||
<el-sub-menu v-else :expand-open-icon="ArrowDownBold" :expand-close-icon="ArrowRightBold" :index="L1.i">
|
||||
<template #title>
|
||||
<PictureTitle :trees="L1" @click-doc="clickCurFolder" :size="15" />
|
||||
<PictureTitle :size="15" :trees="L1" @click-doc="clickCurFolder" @refresh-doc-tree="getDocTree" />
|
||||
</template>
|
||||
|
||||
<!-- ================================================ L2 ================================================ -->
|
||||
@ -30,14 +33,14 @@
|
||||
<!-- 级别1无下级 -->
|
||||
<el-menu-item v-if="isEmpty(L2.children)" :index="L2.i">
|
||||
<template #title>
|
||||
<PictureTitle :trees="L2" @click-doc="clickCurFolder" />
|
||||
<PictureTitle :trees="L2" @click-doc="clickCurFolder" @refresh-doc-tree="getDocTree" />
|
||||
</template>
|
||||
</el-menu-item>
|
||||
|
||||
<!-- 级别1有下级 -->
|
||||
<el-sub-menu v-else :expand-open-icon="ArrowDownBold" :expand-close-icon="ArrowRightBold" :index="L2.i">
|
||||
<template #title>
|
||||
<PictureTitle :trees="L2" @click-doc="clickCurFolder" />
|
||||
<PictureTitle :trees="L2" @click-doc="clickCurFolder" @refresh-doc-tree="getDocTree" />
|
||||
</template>
|
||||
|
||||
<!-- ================================================ L3 ================================================ -->
|
||||
@ -45,14 +48,14 @@
|
||||
<!-- 级别2无下级 -->
|
||||
<el-menu-item v-if="isEmpty(L3.children)" :index="L3.i">
|
||||
<template #title>
|
||||
<PictureTitle :trees="L3" @click-doc="clickCurFolder" />
|
||||
<PictureTitle :trees="L3" @click-doc="clickCurFolder" @refresh-doc-tree="getDocTree" />
|
||||
</template>
|
||||
</el-menu-item>
|
||||
|
||||
<!-- 级别2有下级 -->
|
||||
<el-sub-menu v-else :expand-open-icon="ArrowDownBold" :expand-close-icon="ArrowRightBold" :index="L3.i">
|
||||
<template #title>
|
||||
<PictureTitle :trees="L3" @click-doc="clickCurFolder" />
|
||||
<PictureTitle :trees="L3" @click-doc="clickCurFolder" @refresh-doc-tree="getDocTree" />
|
||||
</template>
|
||||
|
||||
<!-- ================================================ L4 ================================================ -->
|
||||
@ -60,7 +63,7 @@
|
||||
<!-- 级别3无下级 -->
|
||||
<el-menu-item v-if="isEmpty(L4.children)" :index="L4.i">
|
||||
<template #title>
|
||||
<PictureTitle :trees="L4" @click-doc="clickCurFolder" />
|
||||
<PictureTitle :trees="L4" @click-doc="clickCurFolder" @refresh-doc-tree="getDocTree" />
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</div>
|
||||
@ -214,14 +217,11 @@ const pictureCompressParam = computed(() => {
|
||||
return ''
|
||||
})
|
||||
//#region ----------------------------------------< 文件夹列表与当前文件 >----------------------------
|
||||
// 文档菜单的加载动画
|
||||
const docTreeLoading = ref(true)
|
||||
// 文档菜单
|
||||
const docTreeData = ref<DocTree[]>([])
|
||||
// 当前选中的文档, 包含文件夹和文章, 如果选中是文件夹, 则不会重置编辑器中的文章
|
||||
const curFolder = ref<DocInfo>()
|
||||
// 分页对象类型
|
||||
type PageParam = { pageNum: number, pageSize: number, pid: number, name: string, starStatus: number | undefined }
|
||||
const docTreeLoading = ref(true) // 文档菜单的加载动画
|
||||
const showSort = ref(false) // 是否显示文档排序
|
||||
const docTreeData = ref<DocTree[]>([]) // 文档菜单
|
||||
const curFolder = ref<DocInfo>() // 当前选中的文档, 包含文件夹和文章, 如果选中是文件夹, 则不会重置编辑器中的文章
|
||||
type PageParam = { pageNum: number, pageSize: number, pid: number, name: string, starStatus: number | undefined } // 分页对象类型
|
||||
// 列表参数
|
||||
const picuturePageParam = ref<PageParam>({
|
||||
pageNum: 1,
|
||||
@ -240,6 +240,31 @@ const pictureStat = ref<any>({
|
||||
provide(provideKeyDocTree, docTreeData)
|
||||
provide(provideKeyDocInfo, curFolder)
|
||||
|
||||
|
||||
/**
|
||||
* 在名称中显式排序
|
||||
* @param trees
|
||||
*/
|
||||
const concatSort = (trees: DocTree[]) => {
|
||||
for (let i = 0; i < trees.length; i++) {
|
||||
if (!isEmpty(trees[i].children)) {
|
||||
concatSort(trees[i].children as DocTree[])
|
||||
}
|
||||
if (showSort.value) {
|
||||
trees[i].n = trees[i].s + '〉' + trees[i].n
|
||||
} else {
|
||||
trees[i].n = trees[i].n.substring(trees[i].n.indexOf('〉') + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 是否显示
|
||||
*/
|
||||
const handleShowSort = () => {
|
||||
showSort.value = !showSort.value
|
||||
concatSort(docTreeData.value)
|
||||
}
|
||||
|
||||
const curIsFolder = () => {
|
||||
if (isNull(curFolder)) { return false }
|
||||
if (isNull(curFolder.value)) { return false }
|
||||
@ -268,7 +293,30 @@ const getDocTree = () => {
|
||||
docTreeData.value = []
|
||||
curFolder.value = undefined
|
||||
docTreeApi({ onlyPicture: true }).then(resp => {
|
||||
docTreeData.value = resp.data
|
||||
const docTree: DocTree[] = resp.data
|
||||
// 两种类型的交界位置
|
||||
let lastPicIndex: number = docTree.length - 1
|
||||
for (let i = 0; i < docTree.length; i++) {
|
||||
let doc = docTree[i]
|
||||
if (doc.ty === 1) {
|
||||
lastPicIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
docTree.splice(lastPicIndex, 0, {
|
||||
i: docTree[0].i - 100000,
|
||||
p: 0,
|
||||
n: '───────────────────────',
|
||||
o: 0,
|
||||
t: [],
|
||||
s: 0,
|
||||
icon: '',
|
||||
ty: 11,
|
||||
star: 0
|
||||
})
|
||||
|
||||
docTreeData.value = docTree
|
||||
}).finally(() => {
|
||||
docTreeLoading.value = false
|
||||
})
|
||||
|
@ -31,6 +31,9 @@
|
||||
@click="handleShowDocInfoDialog('add', props.trees.i)">
|
||||
<span class="iconbl bl-a-fileadd-fill"></span>新增<strong>子级</strong>文档
|
||||
</div>
|
||||
<div :class="['menu-item', props.trees.i < 0 ? 'disabled' : '']" @click="delDoc()">
|
||||
<span class="iconbl bl-a-fileprohibit-line"></span>删除文档
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
@ -62,6 +65,8 @@ import type { PropType } from 'vue'
|
||||
import { isNotBlank } from '@renderer/assets/utils/obj'
|
||||
import PictureInfo from '@renderer/views/picture/PictureInfo.vue'
|
||||
import Notify from '@renderer/components/Notify'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { folderDelApi } from '@renderer/api/blossom'
|
||||
|
||||
|
||||
//#region ----------------------------------------< 标题信息 >--------------------------------------
|
||||
@ -141,6 +146,21 @@ const handleClickRight = (event: MouseEvent) => {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文档
|
||||
*/
|
||||
const delDoc = () => {
|
||||
ElMessageBox.confirm(
|
||||
`是否确定删除文件夹: <span style="color:#C02B2B;text-decoration: underline;">${props.trees.n}</span>?删除后将不可恢复!`, {
|
||||
confirmButtonText: '确定删除', cancelButtonText: '我再想想', type: 'info', draggable: true, dangerouslyUseHTMLString: true,
|
||||
}
|
||||
).then(() => {
|
||||
folderDelApi({ id: props.trees.i }).then(_resp => {
|
||||
Notify.success(`删除文件夹成功`)
|
||||
emits('refreshDocTree')
|
||||
})
|
||||
})
|
||||
}
|
||||
//#endregion 右键菜单
|
||||
|
||||
//#region ----------------------------------------< 新增修改详情弹框 >--------------------------------------
|
||||
@ -174,7 +194,7 @@ const handleShowDocInfoDialog = (dialogType: DocDialogType, pid?: number) => {
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
const emits = defineEmits(['clickDoc'])
|
||||
const emits = defineEmits(['clickDoc', 'refreshDocTree'])
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
Loading…
Reference in New Issue
Block a user