删除功能

This commit is contained in:
jasminexz 2023-08-28 14:54:22 +08:00
parent ff755cc49d
commit a0a2e62125
8 changed files with 164 additions and 45 deletions

View File

@ -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

View File

@ -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>() // , , ,
@ -655,7 +655,7 @@ const removeListenerScroll = () => {
}
const marginTop = 75
const matchHtmlTags = 'p, h1, h2, h3, h4, h5, h6, ul, ol, li, pre, blockquote, hr, table, tr, iframe,span'
const matchHtmlTags = 'p, h1, h2, h3, h4, h5, h6, ul, ol, li, pre, blockquote, hr, table, tr, iframe, span'
const sycnScroll = (_event: Event | string, _source?: string, _lineno?: number, _colno?: number, _error?: Error): any => {
if (EditorRef.value == undefined) {
return

View File

@ -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>

View File

@ -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);

View File

@ -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'

View File

@ -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;
}

View File

@ -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
})

View File

@ -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">