mirror of
https://github.com/blossom-editor/blossom
synced 2024-11-17 14:39:21 +08:00
样式优化
This commit is contained in:
parent
d4ca45956f
commit
247e33500e
@ -1,10 +1,5 @@
|
||||
# 单引号
|
||||
singleQuote: true
|
||||
# 不以分号结尾
|
||||
semi: false
|
||||
# 每行 150
|
||||
printWidth: 150
|
||||
# 不以逗号结尾
|
||||
trailingComma: none
|
||||
# 标签末尾在同一行
|
||||
bracketSameLine: true
|
@ -156,7 +156,7 @@ html.dark {
|
||||
/* background color */
|
||||
--bl-bg-color: #333434;
|
||||
/* ================================= text styles =================================*/
|
||||
--bl-text-doctree-color: #a8a8a8;
|
||||
--bl-text-doctree-color: #d0d0d0;
|
||||
/* primary color */
|
||||
--bl-text-color: #a8a8a8;
|
||||
/* lighter than primary color */
|
||||
|
@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<!-- 文件夹操作 -->
|
||||
<div class="doc-workbench">
|
||||
<ArticleTreeWorkbench @refresh-doc-tree="getDocTree" @show-sort="handleShowSort" ref="ArticleTreeWorkbenchRef">
|
||||
</ArticleTreeWorkbench>
|
||||
<ArticleTreeWorkbench @refresh-doc-tree="getDocTree" @show-sort="handleShowSort" ref="ArticleTreeWorkbenchRef"> </ArticleTreeWorkbench>
|
||||
</div>
|
||||
|
||||
<div class="doc-trees-container" v-loading="docTreeLoading" element-loading-text="正在读取文档..."
|
||||
<div
|
||||
class="doc-trees-container"
|
||||
v-loading="docTreeLoading"
|
||||
element-loading-text="正在读取文档..."
|
||||
:style="{ fontSize: configStore.viewStyle.treeDocsFontSize }">
|
||||
|
||||
<el-menu v-if="!isEmpty(docTreeData)" class="doc-trees" :unique-opened="true" :default-active="docTreeDefaultActive">
|
||||
<!-- ================================================ L1 ================================================ -->
|
||||
<div v-for="L1 in docTreeData" :key="L1.i">
|
||||
|
||||
<!-- L1无下级 -->
|
||||
<el-menu-item v-if="isEmpty(L1.children)" :index="L1.i">
|
||||
<template #title>
|
||||
@ -53,8 +53,7 @@
|
||||
<!-- L3无下级 -->
|
||||
<el-menu-item v-if="isEmpty(L3.children)" :index="L3.i">
|
||||
<template #title>
|
||||
<div class="menu-item-wrapper" @click="clickCurDoc(L3)"
|
||||
@click.right="handleClickRightMenu(L3, $event)">
|
||||
<div class="menu-item-wrapper" @click="clickCurDoc(L3)" @click.right="handleClickRightMenu(L3, $event)">
|
||||
<ArticleTreeTitle :trees="L3" :level="3" />
|
||||
</div>
|
||||
</template>
|
||||
@ -73,8 +72,7 @@
|
||||
<!-- L4 不允许有下级, 只允许4级 -->
|
||||
<el-menu-item v-if="isEmpty(L4.children)" :index="L4.i">
|
||||
<template #title>
|
||||
<div class="menu-item-wrapper" @click="clickCurDoc(L4)" style="width: 100%;"
|
||||
@click.right="handleClickRightMenu(L4, $event)">
|
||||
<div class="menu-item-wrapper" @click="clickCurDoc(L4)" style="width: 100%" @click.right="handleClickRightMenu(L4, $event)">
|
||||
<ArticleTreeTitle :trees="L4" :level="4" />
|
||||
</div>
|
||||
</template>
|
||||
@ -87,70 +85,43 @@
|
||||
</el-sub-menu>
|
||||
</div>
|
||||
</el-menu>
|
||||
<div v-else class="doc-trees-empty-placeholder">
|
||||
暂无文档,可点击上方 ↑ 添加
|
||||
</div>
|
||||
<div v-else class="doc-trees-empty-placeholder">暂无文档,可点击上方 ↑ 添加</div>
|
||||
</div>
|
||||
|
||||
<!-- 右键菜单, 添加到 body 下 -->
|
||||
<Teleport to="body">
|
||||
<div v-show="rMenu.show" class="doc-tree-right-menu"
|
||||
:style="{ left: rMenu.clientX + 'px', top: rMenu.clientY + 'px' }" ref="ArticleDocTreeRightMenuRef">
|
||||
<div
|
||||
v-show="rMenu.show"
|
||||
class="doc-tree-right-menu"
|
||||
:style="{ left: rMenu.clientX + 'px', top: rMenu.clientY + 'px' }"
|
||||
ref="ArticleDocTreeRightMenuRef">
|
||||
<div class="doc-name">{{ curDoc.n }}</div>
|
||||
<div class="menu-content">
|
||||
<div @click="handleShowDocInfoDialog('upd')">
|
||||
<span class="iconbl bl-a-fileedit-line"></span>编辑文档
|
||||
</div>
|
||||
<div @click="syncDoc()">
|
||||
<span class="iconbl bl-a-cloudrefresh-line"></span>同步文档
|
||||
</div>
|
||||
<div @click="handleShowDocInfoDialog('add', curDoc.p)">
|
||||
<span class="iconbl bl-a-fileadd-line"></span>新增同级文档
|
||||
</div>
|
||||
<div v-if="curDoc.ty != 3" @click="handleShowDocInfoDialog('add', curDoc.i)">
|
||||
<span class="iconbl bl-a-fileadd-fill"></span>新增子级文档
|
||||
</div>
|
||||
<div @click="delDoc()">
|
||||
<span class="iconbl bl-a-fileprohibit-line"></span>删除文档
|
||||
</div>
|
||||
<div v-if="curDoc.ty === 3" @click="createUrl('link')">
|
||||
<span class="iconbl bl-correlation-line"></span>复制引用
|
||||
</div>
|
||||
<div v-if="curDoc.ty != 3" @click="handleShowArticleImportDialog()">
|
||||
<span class="iconbl bl-file-upload-line"></span>导入文章
|
||||
</div>
|
||||
<div @click="handleShowDocInfoDialog('upd')"><span class="iconbl bl-a-fileedit-line"></span>编辑文档</div>
|
||||
<div @click="syncDoc()"><span class="iconbl bl-a-cloudrefresh-line"></span>同步文档</div>
|
||||
<div @click="handleShowDocInfoDialog('add', curDoc.p)"><span class="iconbl bl-a-fileadd-line"></span>新增同级文档</div>
|
||||
<div v-if="curDoc.ty != 3" @click="handleShowDocInfoDialog('add', curDoc.i)"><span class="iconbl bl-a-fileadd-fill"></span>新增子级文档</div>
|
||||
<div @click="delDoc()"><span class="iconbl bl-a-fileprohibit-line"></span>删除文档</div>
|
||||
<div v-if="curDoc.ty === 3" @click="createUrl('link')"><span class="iconbl bl-correlation-line"></span>复制引用</div>
|
||||
<div v-if="curDoc.ty != 3" @click="handleShowArticleImportDialog()"><span class="iconbl bl-file-upload-line"></span>导入文章</div>
|
||||
|
||||
<div class="menu-item-divider" v-if="curDoc.ty === 3"></div>
|
||||
|
||||
<div v-if="curDoc.ty === 3" @click="openArticleWindow">
|
||||
<span class="iconbl bl-a-computerend-line"></span>新窗口打开
|
||||
</div>
|
||||
<div v-if="curDoc.ty === 3" @click="openArticleWindow"><span class="iconbl bl-a-computerend-line"></span>新窗口打开</div>
|
||||
|
||||
<div v-if="curDoc.ty === 3 && curDoc.o === 1" @click="createUrl('open')">
|
||||
<span class="iconbl bl-planet-line"></span>浏览器打开
|
||||
</div>
|
||||
<div v-if="curDoc.ty === 3 && curDoc.o === 1" @click="createUrl('open')"><span class="iconbl bl-planet-line"></span>浏览器打开</div>
|
||||
|
||||
<div v-if="curDoc.ty === 3" @mouseenter="handleHoverRightMenuLevel2($event, 4)">
|
||||
<span class="iconbl bl-a-rightsmallline-line"></span>
|
||||
<span class="iconbl bl-file-download-line"></span>导出文章
|
||||
<div class="menu-content-level2" :style="rMenuLevel2">
|
||||
<div @click="articleDownload">
|
||||
<span class="iconbl bl-file-markdown"></span>导出为 MD
|
||||
</div>
|
||||
<div @click="articleBackup('MARKDOWN')">
|
||||
<span class="iconbl bl-file-markdown"></span>导出为本地 MD
|
||||
</div>
|
||||
<div @click="articleDownloadHtml">
|
||||
<span class="iconbl bl-HTML"></span>导出为 HTML
|
||||
</div>
|
||||
<div @click="articleBackup('HTML')">
|
||||
<span class="iconbl bl-HTML"></span>导出为本地 HTML
|
||||
</div>
|
||||
<div @click="articleDownload"><span class="iconbl bl-file-markdown"></span>导出为 MD</div>
|
||||
<div @click="articleBackup('MARKDOWN')"><span class="iconbl bl-file-markdown"></span>导出为本地 MD</div>
|
||||
<div @click="articleDownloadHtml"><span class="iconbl bl-HTML"></span>导出为 HTML</div>
|
||||
<div @click="articleBackup('HTML')"><span class="iconbl bl-HTML"></span>导出为本地 HTML</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="curDoc.ty === 3 && curDoc.o === 1" @click="createUrl('copy')">
|
||||
<span class="iconbl bl-a-linkspread-line"></span>复制链接
|
||||
</div>
|
||||
<div v-if="curDoc.ty === 3 && curDoc.o === 1" @click="createUrl('copy')"><span class="iconbl bl-a-linkspread-line"></span>复制链接</div>
|
||||
<div v-if="curDoc.ty === 3 && curDoc.o === 1" @click="handleArticleQrCodeDialog()">
|
||||
<span class="iconbl bl-qr-code-line"></span>查看二维码
|
||||
</div>
|
||||
@ -158,22 +129,40 @@
|
||||
</div>
|
||||
</Teleport>
|
||||
|
||||
|
||||
<!-- 详情 -->
|
||||
<el-dialog v-model="isShowDocInfoDialog" width="535" top="100px" style="margin-left: 320px;" :append-to-body="true"
|
||||
:destroy-on-close="true" :close-on-click-modal="false" draggable>
|
||||
<el-dialog
|
||||
v-model="isShowDocInfoDialog"
|
||||
width="535"
|
||||
top="100px"
|
||||
style="margin-left: 320px"
|
||||
:append-to-body="true"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<ArticleInfo ref="ArticleInfoRef" @saved="savedCallback"></ArticleInfo>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 二维码 -->
|
||||
<el-dialog v-model="isShowQrCodeDialog" width="335" top="100px" :append-to-body="true" :destroy-on-close="true"
|
||||
:close-on-click-modal="false" draggable>
|
||||
<el-dialog
|
||||
v-model="isShowQrCodeDialog"
|
||||
width="335"
|
||||
top="100px"
|
||||
:append-to-body="true"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<ArticleQrCode ref="ArticleQrCodeRef"></ArticleQrCode>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 导入 -->
|
||||
<el-dialog v-model="isShowArticleImportDialog" width="335" top="80px" :append-to-body="true" :destroy-on-close="true"
|
||||
:close-on-click-modal="false" draggable>
|
||||
<el-dialog
|
||||
v-model="isShowArticleImportDialog"
|
||||
width="335"
|
||||
top="80px"
|
||||
:append-to-body="true"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<ArticleImport ref="ArticleImportRef" :doc="curDoc"></ArticleImport>
|
||||
</el-dialog>
|
||||
</template>
|
||||
@ -182,11 +171,11 @@
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useUserStore } from '@renderer/stores/user'
|
||||
import { useConfigStore } from '@renderer/stores/config'
|
||||
import { ref, onActivated, provide, onBeforeUnmount, nextTick, onMounted } from "vue"
|
||||
import { ref, onActivated, provide, onBeforeUnmount, nextTick, onMounted } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { ArrowDownBold, ArrowRightBold } from '@element-plus/icons-vue'
|
||||
import { articleDownloadHtmlApi, docTreeApi } from '@renderer/api/blossom'
|
||||
import { isNotNull } from "@renderer/assets/utils/obj"
|
||||
import { isNotNull } from '@renderer/assets/utils/obj'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { provideKeyDocTree } from '@renderer/views/doc/doc'
|
||||
import { grammar } from './scripts/markedjs'
|
||||
@ -196,7 +185,7 @@ import Notify from '@renderer/scripts/notify'
|
||||
|
||||
// components
|
||||
import ArticleTreeTitle from './ArticleTreeTitle.vue'
|
||||
import ArticleTreeWorkbench from "./ArticleTreeWorkbench.vue"
|
||||
import ArticleTreeWorkbench from './ArticleTreeWorkbench.vue'
|
||||
import ArticleQrCode from './ArticleQrCode.vue'
|
||||
import ArticleInfo from './ArticleInfo.vue'
|
||||
import ArticleImport from './ArticleImport.vue'
|
||||
@ -222,10 +211,10 @@ onBeforeUnmount(() => {
|
||||
|
||||
//#region ----------------------------------------< 菜单 >--------------------------------------
|
||||
|
||||
const docTreeLoading = ref(true) // 文档菜单的加载动画
|
||||
const showSort = ref(false) // 是否显示文档排序
|
||||
const docTreeDefaultActive = ref('') // 文档的默认选中项, 用于外部跳转后选中菜单
|
||||
const docTreeData = ref<DocTree[]>([]) // 文档菜单
|
||||
const docTreeLoading = ref(true) // 文档菜单的加载动画
|
||||
const showSort = ref(false) // 是否显示文档排序
|
||||
const docTreeDefaultActive = ref('') // 文档的默认选中项, 用于外部跳转后选中菜单
|
||||
const docTreeData = ref<DocTree[]>([]) // 文档菜单
|
||||
|
||||
// 注入的相关信息
|
||||
provide(provideKeyDocTree, docTreeData)
|
||||
@ -248,12 +237,14 @@ const getRouteQueryParams = () => {
|
||||
*/
|
||||
const getDocTree = (isOnlyOpen: boolean, isOnlySubject: boolean, isOnlyStar: boolean) => {
|
||||
docTreeLoading.value = true
|
||||
docTreeApi({ onlyPicture: false, onlyOpen: isOnlyOpen, onlySubject: isOnlySubject, onlyStar: isOnlyStar }).then(resp => {
|
||||
docTreeData.value = resp.data
|
||||
concatSort(docTreeData.value)
|
||||
}).finally(() => {
|
||||
docTreeLoading.value = false
|
||||
})
|
||||
docTreeApi({ onlyPicture: false, onlyOpen: isOnlyOpen, onlySubject: isOnlySubject, onlyStar: isOnlyStar })
|
||||
.then((resp) => {
|
||||
docTreeData.value = resp.data
|
||||
concatSort(docTreeData.value)
|
||||
})
|
||||
.finally(() => {
|
||||
docTreeLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,7 +318,7 @@ const removeListenerTreeDocsRightMenu = () => {
|
||||
const handleHoverRightMenuLevel2 = (event: MouseEvent, childMenuCount: number = 1) => {
|
||||
const domHeight = 25 * childMenuCount + 10
|
||||
if (document.body.clientHeight - event.clientY <= domHeight) {
|
||||
rMenuLevel2.value.top = (domHeight * -1 + 20) + 'px'
|
||||
rMenuLevel2.value.top = domHeight * -1 + 20 + 'px'
|
||||
} else {
|
||||
rMenuLevel2.value.top = '0px'
|
||||
}
|
||||
@ -337,16 +328,15 @@ const handleHoverRightMenuLevel2 = (event: MouseEvent, childMenuCount: number =
|
||||
* 打开新页面, 文件夹(curDoc.value.ty == 1)无法使用新页面打开
|
||||
*/
|
||||
const openArticleWindow = () => {
|
||||
if (curDoc.value.ty === 1)
|
||||
return
|
||||
openNewArticleWindow(curDoc.value.n, curDoc.value.i);
|
||||
if (curDoc.value.ty === 1) return
|
||||
openNewArticleWindow(curDoc.value.n, curDoc.value.i)
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用浏览器打开公开链接, 或复制公开链接
|
||||
*/
|
||||
const createUrl = (type: 'open' | 'copy' | 'link') => {
|
||||
let url: string = userStore.userinfo.params.WEB_ARTICLE_URL + curDoc.value.i;
|
||||
let url: string = userStore.userinfo.params.WEB_ARTICLE_URL + curDoc.value.i
|
||||
if (type == 'open') {
|
||||
openExtenal(url)
|
||||
} else if (type == 'copy') {
|
||||
@ -361,18 +351,18 @@ const createUrl = (type: 'open' | 'copy' | 'link') => {
|
||||
* 下载文章
|
||||
*/
|
||||
const articleDownload = () => {
|
||||
articleDownloadApi({ id: curDoc.value.i }).then(resp => {
|
||||
articleDownloadApi({ id: curDoc.value.i }).then((resp) => {
|
||||
let filename: string = resp.headers.get('content-disposition')
|
||||
let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
|
||||
let matches = filenameRegex.exec(filename);
|
||||
let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
|
||||
let matches = filenameRegex.exec(filename)
|
||||
if (matches != null && matches[1]) {
|
||||
filename = decodeURI(matches[1].replace(/['"]/g, ''));
|
||||
filename = decodeURI(matches[1].replace(/['"]/g, ''))
|
||||
}
|
||||
let a = document.createElement('a')
|
||||
let blob = new Blob([resp.data], { type: "text/plain" })
|
||||
let blob = new Blob([resp.data], { type: 'text/plain' })
|
||||
let objectUrl = URL.createObjectURL(blob)
|
||||
a.setAttribute("href", objectUrl)
|
||||
a.setAttribute("download", filename)
|
||||
a.setAttribute('href', objectUrl)
|
||||
a.setAttribute('download', filename)
|
||||
a.click()
|
||||
URL.revokeObjectURL(a.href)
|
||||
a.remove()
|
||||
@ -383,18 +373,18 @@ const articleDownload = () => {
|
||||
* 下载HTML文章
|
||||
*/
|
||||
const articleDownloadHtml = () => {
|
||||
articleDownloadHtmlApi({ id: curDoc.value.i }).then(resp => {
|
||||
articleDownloadHtmlApi({ id: curDoc.value.i }).then((resp) => {
|
||||
let filename: string = resp.headers.get('content-disposition')
|
||||
let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
|
||||
let matches = filenameRegex.exec(filename);
|
||||
let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
|
||||
let matches = filenameRegex.exec(filename)
|
||||
if (matches != null && matches[1]) {
|
||||
filename = decodeURI(matches[1].replace(/['"]/g, ''));
|
||||
filename = decodeURI(matches[1].replace(/['"]/g, ''))
|
||||
}
|
||||
let a = document.createElement('a')
|
||||
let blob = new Blob([resp.data], { type: "text/plain" })
|
||||
let blob = new Blob([resp.data], { type: 'text/plain' })
|
||||
let objectUrl = URL.createObjectURL(blob)
|
||||
a.setAttribute("href", objectUrl)
|
||||
a.setAttribute("download", filename)
|
||||
a.setAttribute('href', objectUrl)
|
||||
a.setAttribute('download', filename)
|
||||
a.click()
|
||||
URL.revokeObjectURL(a.href)
|
||||
a.remove()
|
||||
@ -406,17 +396,18 @@ const articleDownloadHtml = () => {
|
||||
* @param type 导出类型
|
||||
*/
|
||||
const articleBackup = (type: 'MARKDOWN' | 'HTML') => {
|
||||
articleBackupApi({ type: type, articleId: curDoc.value.i, toLocal: 'YES' }).then(resp => {
|
||||
articleBackupApi({ type: type, articleId: curDoc.value.i, toLocal: 'YES' }).then((resp) => {
|
||||
ElMessageBox.confirm(
|
||||
`由于导出为本地文章时需要导出图片等信息,所以文章将会以
|
||||
<span style="color:#C02B2B;text-decoration: underline;">备份压缩包</span>
|
||||
的形式存储在服务器上,文件名为:「${resp.data.filename}」,你可以前往备份页面查看导出进度和导出文件压缩包。`, {
|
||||
confirmButtonText: '立即查看',
|
||||
cancelButtonText: '稍后再说',
|
||||
type: 'info',
|
||||
draggable: true,
|
||||
dangerouslyUseHTMLString: true,
|
||||
}
|
||||
的形式存储在服务器上,文件名为:「${resp.data.filename}」,你可以前往备份页面查看导出进度和导出文件压缩包。`,
|
||||
{
|
||||
confirmButtonText: '立即查看',
|
||||
cancelButtonText: '稍后再说',
|
||||
type: 'info',
|
||||
draggable: true,
|
||||
dangerouslyUseHTMLString: true
|
||||
}
|
||||
).then(() => {
|
||||
ArticleTreeWorkbenchRef.value.handleShowBackupDialog()
|
||||
})
|
||||
@ -438,18 +429,20 @@ const syncDoc = () => {
|
||||
*/
|
||||
const delDoc = () => {
|
||||
let type = curDoc.value.ty === 3 ? '文章' : '文件夹'
|
||||
ElMessageBox.confirm(
|
||||
`是否确定删除${type}: <span style="color:#C02B2B;text-decoration: underline;">${curDoc.value.n}</span>?删除后将不可恢复!`, {
|
||||
confirmButtonText: '确定删除', cancelButtonText: '我再想想', type: 'info', draggable: true, dangerouslyUseHTMLString: true,
|
||||
}
|
||||
).then(() => {
|
||||
ElMessageBox.confirm(`是否确定删除${type}: <span style="color:#C02B2B;text-decoration: underline;">${curDoc.value.n}</span>?删除后将不可恢复!`, {
|
||||
confirmButtonText: '确定删除',
|
||||
cancelButtonText: '我再想想',
|
||||
type: 'info',
|
||||
draggable: true,
|
||||
dangerouslyUseHTMLString: true
|
||||
}).then(() => {
|
||||
if (curDoc.value.ty === 3) {
|
||||
articleDelApi({ id: curDoc.value.i }).then(_resp => {
|
||||
articleDelApi({ id: curDoc.value.i }).then((_resp) => {
|
||||
Notify.success(`删除文章成功`)
|
||||
getDocTree(false, false, false)
|
||||
})
|
||||
} else {
|
||||
folderDelApi({ id: curDoc.value.i }).then(_resp => {
|
||||
folderDelApi({ id: curDoc.value.i }).then((_resp) => {
|
||||
Notify.success(`删除文件夹成功`)
|
||||
getDocTree(false, false, false)
|
||||
})
|
||||
@ -461,7 +454,7 @@ const delDoc = () => {
|
||||
|
||||
//#region ----------------------------------------< 二维码 >--------------------------------------
|
||||
|
||||
const isShowQrCodeDialog = ref<boolean>(false);
|
||||
const isShowQrCodeDialog = ref<boolean>(false)
|
||||
const ArticleQrCodeRef = ref()
|
||||
|
||||
const handleArticleQrCodeDialog = () => {
|
||||
@ -494,7 +487,9 @@ const handleShowDocInfoDialog = (dialogType: DocDialogType, pid?: number) => {
|
||||
}
|
||||
isShowDocInfoDialog.value = true
|
||||
if (dialogType === 'add') {
|
||||
nextTick(() => { ArticleInfoRef.value.reload(dialogType, undefined, undefined, pid) })
|
||||
nextTick(() => {
|
||||
ArticleInfoRef.value.reload(dialogType, undefined, undefined, pid)
|
||||
})
|
||||
}
|
||||
if (dialogType === 'upd') {
|
||||
nextTick(() => {
|
||||
@ -503,11 +498,13 @@ const handleShowDocInfoDialog = (dialogType: DocDialogType, pid?: number) => {
|
||||
}
|
||||
}
|
||||
|
||||
const savedCallback = (dialogType: DocDialogType) => {
|
||||
/**
|
||||
* 保存后回调
|
||||
* @param dialogType
|
||||
*/
|
||||
const savedCallback = (_dialogType: DocDialogType) => {
|
||||
getDocTree(false, false, false)
|
||||
if (dialogType === 'upd') {
|
||||
isShowDocInfoDialog.value = false
|
||||
}
|
||||
isShowDocInfoDialog.value = false
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@ -530,7 +527,6 @@ const clickCurDoc = (tree: DocTree) => {
|
||||
const emits = defineEmits(['clickDoc'])
|
||||
|
||||
defineExpose({ getDocTreeData })
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="doc-workbench-root">
|
||||
<bl-row just="flex-end" align="flex-end">
|
||||
<div v-show="curDoc !== undefined" style="font-size: 12px; text-align: right; color: var(--bl-text-color-light)">
|
||||
<div v-show="curDoc !== undefined" style="font-size: 12px; text-align: right; color: var(--bl-text-color)">
|
||||
<span>《{{ curDoc?.name }}》</span>
|
||||
<br />
|
||||
<span style="font-size: 9px; padding-right: 5px">{{ curDoc?.id }}</span>
|
||||
@ -177,17 +177,20 @@ const openArticleReferenceWindow = () => {
|
||||
openNewArticleReferenceWindow()
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制台刷新文档列表
|
||||
*/
|
||||
const refreshDocTree = () => {
|
||||
emits('refreshDocTree', onlyOpen.value, onlySubject.value, onlyStars.value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存后的回调
|
||||
* 1. [暂无] 刷新菜单列表
|
||||
* 1. 刷新菜单列表
|
||||
* 2. 关闭 dialog 页面
|
||||
*/
|
||||
const savedCallback = () => {
|
||||
// isShowDocInfoDialog.value = false
|
||||
isShowDocInfoDialog.value = false
|
||||
emits('refreshDocTree', onlyOpen.value, onlySubject.value, onlyStars.value)
|
||||
}
|
||||
|
||||
|
@ -126,19 +126,21 @@ export const cwTheme: any = {
|
||||
}
|
||||
|
||||
const zhCNPhrases = {
|
||||
"Go to line": "前往行",
|
||||
"go": "前往",
|
||||
"Find": "查找内容",
|
||||
"Replace": "替换内容",
|
||||
"next": "下一个",
|
||||
"previous": "上一个",
|
||||
"all": "全部",
|
||||
"match case": "区分大小写",
|
||||
"by word": "全字匹配",
|
||||
"replace": "替换",
|
||||
"replace all": "替换全部",
|
||||
"close": "schließen",
|
||||
"regexp": "使用正则表达式"
|
||||
'Fold line': '折叠',
|
||||
'Unfold line': '展开',
|
||||
'Go to line': '前往行',
|
||||
go: '前往',
|
||||
Find: '查找内容',
|
||||
Replace: '替换内容',
|
||||
next: '下一个',
|
||||
previous: '上一个',
|
||||
all: '全部',
|
||||
'match case': '区分大小写',
|
||||
'by word': '全字匹配',
|
||||
replace: '替换',
|
||||
'replace all': '替换全部',
|
||||
close: 'schließen',
|
||||
regexp: '使用正则表达式'
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@
|
||||
}
|
||||
|
||||
.iconbl {
|
||||
@include themeColor(#909399, #717171);
|
||||
@include themeColor(#909399, #969696);
|
||||
text-shadow: var(--bl-iconbl-text-shadow);
|
||||
font-size: 25px;
|
||||
padding: 3px 2px;
|
||||
|
@ -1,38 +1,36 @@
|
||||
<template>
|
||||
<div class="article-info-root">
|
||||
|
||||
<!-- 标题 -->
|
||||
<div class="info-title">
|
||||
<div class="iconbl bl-a-labellist-line"></div>{{ taskSaveFormTitle }}
|
||||
<div class="iconbl bl-a-labellist-line"></div>
|
||||
{{ taskSaveFormTitle }}
|
||||
</div>
|
||||
|
||||
<div v-loading="formLoading" class="info-form">
|
||||
<el-form :inline="true" :model="taskSaveForm" :rules="taskSaveFormRule" label-width="52px" ref="TaskSaveFormRef">
|
||||
<!-- <el-form-item label="todoId">
|
||||
<el-input v-model="taskSaveForm.todoId" style="width: 90px;" disabled></el-input>
|
||||
<el-input v-model="taskSaveForm.todoName" style="width: 90px;" disabled></el-input>
|
||||
<el-input v-model="taskSaveForm.todoType" style="width: 30px;" disabled></el-input>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="标题" prop="taskName">
|
||||
<el-input v-model="taskSaveForm.taskName">
|
||||
<template #append>
|
||||
<el-tooltip content="查看 Emoji" effect="blossomt" placement="top" :hide-after="0">
|
||||
<div class="emoji-link" @click="openExtenal('https://www.emojiall.com/zh-hans')">😉</div>
|
||||
</el-tooltip>
|
||||
</template></el-input>
|
||||
</template></el-input
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item label="内容">
|
||||
<el-input type="textarea" :rows="4" v-model="taskSaveForm.taskContent"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签">
|
||||
<div class="info-tags-container">
|
||||
<el-input v-if="isShowTagInput" ref="TagInputRef" style="width: 75px;" v-model="tagInputValue"
|
||||
@keyup.enter="blurTagInput" @blur="blurTagInput" />
|
||||
<el-button v-else style="width: 75px;" @click="showInput">
|
||||
+ 标签
|
||||
</el-button>
|
||||
<el-tag v-for="tag in taskSaveForm?.taskTags" :key="tag" :disable-transitions="false"
|
||||
@close="handleTagClose(tag)" closable>
|
||||
<el-input
|
||||
v-if="isShowTagInput"
|
||||
ref="TagInputRef"
|
||||
style="width: 75px"
|
||||
v-model="tagInputValue"
|
||||
@keyup.enter="blurTagInput"
|
||||
@blur="blurTagInput" />
|
||||
<el-button v-else style="width: 75px" @click="showInput"> + 标签 </el-button>
|
||||
<el-tag v-for="tag in taskSaveForm?.taskTags" :key="tag" :disable-transitions="false" @close="handleTagClose(tag)" closable>
|
||||
{{ tag }}
|
||||
</el-tag>
|
||||
</div>
|
||||
@ -41,32 +39,45 @@
|
||||
<el-input v-model="taskSaveForm.deadLine" placeholder="如下午3点会议之间"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始于" v-if="infoType == 'upd'">
|
||||
<el-date-picker v-model="taskSaveForm.startTime" type="datetime" format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" />
|
||||
<el-date-picker
|
||||
v-model="taskSaveForm.startTime"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结束于" v-if="infoType == 'upd'">
|
||||
<el-date-picker v-model="taskSaveForm.endTime" type="datetime" format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" />
|
||||
<el-date-picker
|
||||
v-model="taskSaveForm.endTime"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="颜色" style="width: auto;">
|
||||
<el-input v-model="taskSaveForm.color" style="width:200px;margin-right: 5px;"
|
||||
placeholder="推荐半透明色,更兼容暗黑模式"></el-input>
|
||||
<el-color-picker show-alpha v-model="taskSaveForm.color" :predefine="[
|
||||
'rgba(68, 173, 56, 0.7)',
|
||||
'rgba(186, 196, 44, 0.7)',
|
||||
'rgba(235, 205, 72, 0.7)',
|
||||
'rgba(232, 144, 144, 0.7)',
|
||||
'rgba(112, 145, 188, 0.7)',
|
||||
'rgba(157, 129, 216, 0.7)',
|
||||
'rgba(0, 0, 0, 0.65)',
|
||||
]" />
|
||||
<el-form-item label="颜色" style="width: auto">
|
||||
<el-input v-model="taskSaveForm.color" style="width: 200px; margin-right: 5px" placeholder="推荐半透明色,更兼容暗黑模式"></el-input>
|
||||
<el-color-picker
|
||||
show-alpha
|
||||
v-model="taskSaveForm.color"
|
||||
:predefine="[
|
||||
'rgba(68, 173, 56, 0.7)',
|
||||
'rgba(186, 196, 44, 0.7)',
|
||||
'rgba(235, 205, 72, 0.7)',
|
||||
'rgba(232, 144, 144, 0.7)',
|
||||
'rgba(112, 145, 188, 0.7)',
|
||||
'rgba(157, 129, 216, 0.7)',
|
||||
'rgba(0, 0, 0, 0.65)'
|
||||
]" />
|
||||
|
||||
<el-tooltip content="颜色搭配参考" effect="blossomt" placement="top" :hide-after="0">
|
||||
<a href="https://colorhunt.co/" target="_blank" class="color-hunt iconbl bl-a-colorpalette-line"
|
||||
<a
|
||||
href="https://colorhunt.co/"
|
||||
target="_blank"
|
||||
class="color-hunt iconbl bl-a-colorpalette-line"
|
||||
:style="{ color: taskSaveForm.color }"></a>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<el-form-item label="进度" v-if="infoType == 'upd'" style="width: auto;">
|
||||
<el-form-item label="进度" v-if="infoType == 'upd'" style="width: auto">
|
||||
<el-input-number v-model="taskSaveForm.process" :min="0" :max="100" :step="5"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -123,7 +134,7 @@ const taskSaveFormRule = ref<FormRules<TaskInfo>>({
|
||||
|
||||
/**
|
||||
* 保存表单,内部决定是否存还是新增
|
||||
* @param formEl
|
||||
* @param formEl
|
||||
*/
|
||||
const save = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
@ -134,11 +145,11 @@ const save = async (formEl: FormInstance | undefined) => {
|
||||
if (valid) {
|
||||
if (isNotBlank(taskSaveForm.value.id)) {
|
||||
let datas = { ...taskSaveForm.value, ...{ returnTasks: true } }
|
||||
updTaskApi(datas).then(resp => {
|
||||
updTaskApi(datas).then((resp) => {
|
||||
emits('saved', resp.data)
|
||||
})
|
||||
} else {
|
||||
addTaskApi(taskSaveForm.value).then(resp => {
|
||||
addTaskApi(taskSaveForm.value).then((resp) => {
|
||||
emits('saved', resp.data)
|
||||
})
|
||||
}
|
||||
@ -151,10 +162,13 @@ const save = async (formEl: FormInstance | undefined) => {
|
||||
*/
|
||||
const delTaskBefore = () => {
|
||||
if (taskSaveForm.value.todoType === 20) {
|
||||
countTaskApi({ todoId: taskSaveForm.value.todoId }).then(resp => {
|
||||
countTaskApi({ todoId: taskSaveForm.value.todoId }).then((resp) => {
|
||||
if (resp.data == 1) {
|
||||
ElMessageBox.confirm(`当删除阶段性事项的最后一个任务时, 该事项也将一并删除, 是否确定删除?`, {
|
||||
confirmButtonText: '确定删除', cancelButtonText: '我再想想', type: 'info', draggable: true,
|
||||
confirmButtonText: '确定删除',
|
||||
cancelButtonText: '我再想想',
|
||||
type: 'info',
|
||||
draggable: true
|
||||
}).then(() => {
|
||||
delTask()
|
||||
})
|
||||
@ -162,26 +176,25 @@ const delTaskBefore = () => {
|
||||
delTask()
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
delTask()
|
||||
}
|
||||
}
|
||||
|
||||
const delTask = () => {
|
||||
delTaskApi(taskSaveForm.value).then(resp => emits('saved', resp.data))
|
||||
delTaskApi(taskSaveForm.value).then((resp) => emits('saved', resp.data))
|
||||
}
|
||||
|
||||
/**
|
||||
* 回显数据
|
||||
* @param dialogType
|
||||
* @param taskId
|
||||
* @param dialogType
|
||||
* @param taskId
|
||||
*/
|
||||
const reload = (dialogType: 'upd' | 'add', taskId?: string, todoId?: string, todoType?: TodoType) => {
|
||||
infoType.value = dialogType
|
||||
if (dialogType == 'upd') {
|
||||
taskSaveFormTitle.value = '修改任务'
|
||||
taskInfoApi({ id: taskId }).then(resp => {
|
||||
taskInfoApi({ id: taskId }).then((resp) => {
|
||||
taskSaveForm.value = resp.data
|
||||
})
|
||||
} else {
|
||||
@ -248,12 +261,11 @@ const emits = defineEmits(['saved'])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.info-tags-container {
|
||||
text-align: left;
|
||||
overflow-y: scroll;
|
||||
|
||||
&>span,
|
||||
& > span,
|
||||
button {
|
||||
margin: 3px 3px;
|
||||
}
|
||||
@ -262,4 +274,4 @@ const emits = defineEmits(['saved'])
|
||||
margin: 3px 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user