优化了链接
parent
2af47195c1
commit
a6e2e95cc3
|
|
@ -17,6 +17,7 @@ import {
|
|||
FileImageOutlined,
|
||||
FilePdfOutlined,
|
||||
FileTextOutlined,
|
||||
UndoOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import { Editor } from '@bytemd/react'
|
||||
import gfm from '@bytemd/plugin-gfm'
|
||||
|
|
@ -78,13 +79,19 @@ function DocumentEditor() {
|
|||
return
|
||||
}
|
||||
|
||||
// 简单的从路径获取文件名
|
||||
const fileName = linkTarget.split('/').pop()
|
||||
const linkText = `[${fileName}](${linkTarget})`
|
||||
|
||||
if (editorCtxRef.current && editorCtxRef.current.editor) {
|
||||
editorCtxRef.current.editor.replaceSelection(linkText)
|
||||
editorCtxRef.current.editor.focus()
|
||||
const editor = editorCtxRef.current.editor
|
||||
// 获取当前选中的文字
|
||||
const selection = editor.getSelection()
|
||||
|
||||
// 简单的从路径获取文件名作为备选
|
||||
const fileName = linkTarget.split('/').pop()
|
||||
// 如果没有选中文字,则使用文件名作为链接文字;否则保留原文字
|
||||
const linkTitle = selection || fileName
|
||||
const linkText = `[${linkTitle}](${linkTarget})`
|
||||
|
||||
editor.replaceSelection(linkText)
|
||||
editor.focus()
|
||||
}
|
||||
|
||||
setLinkModalVisible(false)
|
||||
|
|
@ -197,6 +204,28 @@ function DocumentEditor() {
|
|||
}
|
||||
}
|
||||
|
||||
// 重置当前编辑内容(重新从服务器加载)
|
||||
const handleReset = () => {
|
||||
if (!selectedFile) return
|
||||
|
||||
Modal.confirm({
|
||||
title: '确认重置',
|
||||
content: '确定要重置当前修改吗?所有未保存的更改都将丢失。',
|
||||
onOk: async () => {
|
||||
setLoading(true)
|
||||
try {
|
||||
const res = await getFileContent(projectId, selectedFile)
|
||||
setFileContent(res.data.content)
|
||||
Toast.success('重置成功', '已恢复至最后保存的版本')
|
||||
} catch (error) {
|
||||
Toast.error('重置失败', '无法重新加载文件内容')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const handleSaveFile = async () => {
|
||||
if (!selectedFile) {
|
||||
Toast.warning('提示', '请先选择文件')
|
||||
|
|
@ -915,12 +944,11 @@ function DocumentEditor() {
|
|||
保存
|
||||
</Button>
|
||||
<Button
|
||||
danger
|
||||
icon={<DeleteOutlined />}
|
||||
onClick={handleDelete}
|
||||
disabled={!selectedFile}
|
||||
icon={<UndoOutlined />}
|
||||
onClick={handleReset}
|
||||
disabled={!selectedFile || loading}
|
||||
>
|
||||
删除
|
||||
重置
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -249,11 +249,20 @@ function DocumentPage() {
|
|||
// 解码失败,使用原始值
|
||||
}
|
||||
|
||||
// 解析相对路径
|
||||
const targetPath = resolveRelativePath(selectedFile, decodedHref)
|
||||
// 解析路径
|
||||
let targetPath
|
||||
if (decodedHref.startsWith('.') || decodedHref.startsWith('..')) {
|
||||
// 真正的相对路径,相对于当前文件
|
||||
targetPath = resolveRelativePath(selectedFile, decodedHref)
|
||||
} else {
|
||||
// 项目内绝对路径(由编辑器生成),相对于项目根目录
|
||||
targetPath = decodedHref.startsWith('/') ? decodedHref.substring(1) : decodedHref
|
||||
}
|
||||
|
||||
// 自动展开父目录
|
||||
const parentPath = targetPath.substring(0, targetPath.lastIndexOf('/'))
|
||||
const lastSlashIndex = targetPath.lastIndexOf('/')
|
||||
if (lastSlashIndex !== -1) {
|
||||
const parentPath = targetPath.substring(0, lastSlashIndex)
|
||||
if (parentPath && !openKeys.includes(parentPath)) {
|
||||
// 收集所有父路径
|
||||
const pathParts = parentPath.split('/')
|
||||
|
|
@ -265,6 +274,7 @@ function DocumentPage() {
|
|||
}
|
||||
setOpenKeys([...new Set([...openKeys, ...allParentPaths])])
|
||||
}
|
||||
}
|
||||
|
||||
// 选中文件并加载
|
||||
setSelectedFile(targetPath)
|
||||
|
|
@ -590,15 +600,20 @@ function DocumentPage() {
|
|||
remarkPlugins={[remarkGfm]}
|
||||
rehypePlugins={[rehypeRaw, rehypeSlug, rehypeHighlight]}
|
||||
components={{
|
||||
a: ({ node, href, children, ...props }) => (
|
||||
a: ({ node, href, children, ...props }) => {
|
||||
const isExternal = href && (href.startsWith('http') || href.startsWith('//'));
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
onClick={(e) => handleMarkdownLink(e, href)}
|
||||
target={isExternal ? '_blank' : undefined}
|
||||
rel={isExternal ? 'noopener noreferrer' : undefined}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
);
|
||||
},
|
||||
}}
|
||||
>
|
||||
{markdownContent}
|
||||
|
|
|
|||
Loading…
Reference in New Issue