客户端:附件支持相对路径

This commit is contained in:
街角小林 2024-08-28 10:53:03 +08:00
parent cabb37c5b9
commit 0c7b548f36
6 changed files with 145 additions and 30 deletions

View File

@ -128,25 +128,34 @@ export const bindFileHandleEvent = ({ mainWindow }) => {
})
// 选择本地文件
ipcMain.handle('selectFile', (event, openDirectory = false) => {
const properties = []
if (openDirectory) {
properties.push('openDirectory')
}
const res = dialog.showOpenDialogSync({
title: '选择',
properties
})
if (res && res[0]) {
console.log(111, res[0])
return {
file: res[0],
name: path.basename(res[0])
ipcMain.handle(
'selectFile',
(event, openDirectory = false, relativePath = '') => {
const properties = ['openFile']
// 选择目录
if (openDirectory) {
properties.push('openDirectory')
}
const res = dialog.showOpenDialogSync({
title: '选择',
properties
})
if (res && res[0]) {
const name = path.basename(res[0])
let file = res[0]
if (relativePath) {
// 如果传递了路径,那么返回相对路径
file = path.relative(relativePath, res[0])
}
return {
file,
name
}
} else {
return null
}
} else {
return null
}
})
)
// 获取文件内容
ipcMain.handle('getFileContent', (event, id) => {
@ -165,6 +174,11 @@ export const bindFileHandleEvent = ({ mainWindow }) => {
})
})
// 获取文件路径
ipcMain.handle('getFilePath', (event, id) => {
return idToFilePath[id]
})
// 重命名文件
ipcMain.handle('rename', (event, id, name) => {
return new Promise(resolve => {
@ -227,7 +241,7 @@ export const bindFileHandleEvent = ({ mainWindow }) => {
const exist = fs.existsSync(file)
if (!exist) {
removeFileInRecent(file).then(() => {
notifyMainWindowRefreshRecentFileList()
notifyMainWindowRefreshRecentFileList()
})
return '文件不存在'
}
@ -235,7 +249,10 @@ export const bindFileHandleEvent = ({ mainWindow }) => {
})
// 打开指定文件
ipcMain.handle('openPath', (event, file) => {
ipcMain.handle('openPath', (event, file, relativePath = '') => {
if (!path.isAbsolute(file) && relativePath) {
file = path.resolve(relativePath, file)
}
const exist = fs.existsSync(file)
if (!exist) {
return '文件不存在'

View File

@ -11,6 +11,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
destroy: () => ipcRenderer.send('destroy'),
create: id => ipcRenderer.send('create', id),
getFileContent: id => ipcRenderer.invoke('getFileContent', id),
getFilePath: id => ipcRenderer.invoke('getFilePath', id),
save: (id, data, fileName) => ipcRenderer.invoke('save', id, data, fileName),
rename: (id, name) => ipcRenderer.invoke('rename', id, name),
openUrl: url => ipcRenderer.send('openUrl', url),
@ -25,8 +26,10 @@ contextBridge.exposeInMainWorld('electronAPI', {
openFile: file => ipcRenderer.invoke('openFile', file),
selectOpenFile: () => ipcRenderer.send('selectOpenFile'),
copyFile: file => ipcRenderer.invoke('copyFile', file),
selectFile: openDirectory => ipcRenderer.invoke('selectFile', openDirectory),
openPath: path => ipcRenderer.invoke('openPath', path),
selectFile: (openDirectory, relativePath) =>
ipcRenderer.invoke('selectFile', openDirectory, relativePath),
openPath: (path, relativePath) =>
ipcRenderer.invoke('openPath', path, relativePath),
saveClientConfig: config => ipcRenderer.invoke('saveClientConfig', config),
getClientConfig: () => ipcRenderer.invoke('getClientConfig')
})

View File

@ -295,7 +295,9 @@ export default {
newFileTip:
'Please export the currently edited file before creating a new one, Beware of content loss',
openFileTip:
'Please export the currently edited file before opening it, Beware of content loss'
'Please export the currently edited file before opening it, Beware of content loss',
isRelative: 'Relative path',
selectFolder: 'Select folder'
},
edit: {
newFeatureNoticeTitle: 'New feature reminder',

View File

@ -289,7 +289,9 @@ export default {
creatingTip: '正在创建文件',
directory: '目录',
newFileTip: '新建文件前请先导出当前编辑的文件,谨防内容丢失',
openFileTip: '打开文件前请先导出当前编辑的文件,谨防内容丢失'
openFileTip: '打开文件前请先导出当前编辑的文件,谨防内容丢失',
isRelative: '相对路径',
selectFolder: '选择文件夹'
},
edit: {
newFeatureNoticeTitle: '新特性提醒',

View File

@ -66,11 +66,18 @@ export default {
},
methods: {
//
async onSelectAttachment(activeNodes) {
async onSelectAttachment(activeNodes, config = {}) {
// activeNodes.forEach(node => {
// node.setAttachment('/test.md', '')
// })
const file = await window.electronAPI.selectFile(true)
const openDirectory = config.openDirectory || false
const isRelative = config.isRelative || false
//
let filePath = ''
if (isRelative) {
filePath = await window.electronAPI.getFilePath(this.$route.params.id)
}
const file = await window.electronAPI.selectFile(openDirectory, filePath)
if (file) {
activeNodes.forEach(node => {
node.setAttachment(file.file, file.name)
@ -83,7 +90,10 @@ export default {
// console.log(node.getData('attachmentUrl'))
const file = node.getData('attachmentUrl')
if (!file) return
const error = await window.electronAPI.openPath(file)
const filePath = await window.electronAPI.getFilePath(
this.$route.params.id
)
const error = await window.electronAPI.openPath(file, filePath)
if (error) {
this.$message.error(error)
}

View File

@ -162,10 +162,20 @@
:class="{
disabled: activeNodes.length <= 0 || hasGeneralization
}"
@click="selectAttachmentFile"
@click="selectAttachmentFile(false)"
>
<span class="icon iconfont iconfujian"></span>
<span class="text">{{ $t('toolbar.attachment') }}</span>
<div class="subToolbar">
<div class="subToolbarBtn" @click.stop>
<el-checkbox v-model="isRelative">{{
$t('toolbar.isRelative')
}}</el-checkbox>
</div>
<div class="subToolbarBtn" @click.stop="selectAttachmentFile(true)">
{{ $t('toolbar.selectFolder') }}
</div>
</div>
</div>
<div
v-if="item === 'outerFrame'"
@ -214,7 +224,8 @@ export default {
readonly: false,
isFullDataFile: false,
timer: null,
isInPainter: false
isInPainter: false,
isRelative: false
}
},
computed: {
@ -292,8 +303,11 @@ export default {
},
//
selectAttachmentFile() {
this.$bus.$emit('selectAttachment', this.activeNodes)
selectAttachmentFile(openDirectory) {
this.$bus.$emit('selectAttachment', this.activeNodes, {
openDirectory,
isRelative: this.isRelative
})
},
//
@ -328,6 +342,16 @@ export default {
&.disabled {
color: #54595f;
}
.subToolbar {
background-color: #262a2e;
.subToolbarBtn {
&:hover {
background-color: #363b3f !important;
}
}
}
}
}
@ -337,6 +361,7 @@ export default {
flex-direction: column;
cursor: pointer;
margin-right: 20px;
position: relative;
&:last-of-type {
margin-right: 0;
@ -347,6 +372,10 @@ export default {
.icon {
background: #f5f5f5;
}
.subToolbar {
visibility: visible;
}
}
}
@ -377,6 +406,42 @@ export default {
.text {
margin-top: 3px;
}
.subToolbar {
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 100%;
width: 130px;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.06);
border: 1px solid rgba(0, 0, 0, 0.06);
padding: 10px 0;
visibility: hidden;
&::before {
content: '';
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 100%;
border: 5px solid transparent;
border-bottom-color: #ccc;
}
.subToolbarBtn {
padding: 0 12px;
height: 28px;
display: flex;
align-items: center;
overflow: hidden;
&:hover {
background: #f5f5f5;
}
}
}
}
&.v {
@ -404,6 +469,22 @@ export default {
overflow: hidden;
text-overflow: ellipsis;
}
.subToolbar {
left: 100%;
top: 50%;
transform: translateY(-50%);
&::before {
left: auto;
bottom: auto;
top: 50%;
transform: translateY(-50%);
right: 100%;
border-right-color: #ccc;
border-bottom-color: transparent;
}
}
}
}
}