提交 383ef870 authored 作者: 张伊明's avatar 张伊明

写报新增翻译栏,新增markdown标签跳转

上级 eba3a093
差异被折叠。
......@@ -35,6 +35,7 @@
"lodash": "^4.17.21",
"markdown-it": "^14.1.0",
"pdfjs-dist": "^5.4.449",
"pinia": "^3.0.4",
"vue": "^3.4.0",
"vue-router": "^4.2.5"
},
......
......@@ -294,7 +294,15 @@ export function useMarkdownStream() {
const md = createMd()
// 预处理内容
// const processedContent = preprocessMarkdown(rawContent.value)
return md.render(rawContent.value)
let content = rawContent.value || ''
// 将 ==n== 转换为按钮样式的 HTML
// 使用正向预读和反向预读确保只匹配被 == 包裹的数字
content = content.replace(/==(\d+)==/g, (match, p1) => {
return `<button class="clause-ref-btn" data-clause="${p1}">${p1}</button>`
})
return md.render(content)
})
// 自动滚动
......
......@@ -11,6 +11,9 @@ import "./styles/elui.css";
import "./styles/main.css";
import '@/assets/fonts/font.css'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
// 引入 Pinia 实例
import pinia from './stores'
const app = createApp(App);
// 注册所有图标
......@@ -24,5 +27,6 @@ app.use(router);
app.use(ElementPlus, {
locale: zhCn,
})
app.use(pinia) // 挂载 Pinia
app.component("CardTitle", CardTitle);
app.mount("#app");
// src/stores/index.js
import { createPinia } from 'pinia'
// 创建 Pinia 实例
const pinia = createPinia()
// 导出实例,供 main.js 挂载
export default pinia
\ No newline at end of file
差异被折叠。
差异被折叠。
<template>
<div class="main-box">
<!-- 编辑模式 -->
<div v-if="store.isEditMode" class="edit-panel">
<v-md-editor
v-model="store.reportContent"
height="calc(100% - 40px)"
:disabled-menus="[]"
@upload-image="handleUploadImage"
@save="handleSave"
left-toolbar="undo redo clear | h bold italic strikethrough quote | ul ol table hr | link image code | save"
right-toolbar="preview toc sync-scroll fullscreen"
/>
</div>
<!-- 预览模式 -->
<div v-else class="content-box" ref="contentContainerRef" v-html="renderedContent"></div>
</div>
</template>
<script setup>
import { ref, watch, onMounted, onUnmounted } from "vue";
import { ElMessage } from "element-plus";
import VMdEditor from "@kangc/v-md-editor";
import "@kangc/v-md-editor/lib/style/base-editor.css";
import vuepressTheme from "@kangc/v-md-editor/lib/theme/vuepress.js";
import "@kangc/v-md-editor/lib/theme/style/vuepress.css";
import Prism from "prismjs";
import { useWrittingAsstaintStore } from "@/stores/writtingAsstaintStore";
import { useMarkdownStream } from "@/hooks/useMarkdownStream";
// 子组件直接获取Pinia Store
// 1. 绑定content渲染容器的ref
const contentContainerRef = ref(null);
const store = useWrittingAsstaintStore();
// 处理按钮点击事件
const handleGlobalClick = (e) => {
const btn = e.target.closest('.clause-ref-btn');
if (btn) {
const clauseId = btn.getAttribute('data-clause');
if (clauseId) {
store.highlightClauseId = clauseId;
// 翻译栏一直显示,所以这里只需要确保它在视图内
}
}
};
onMounted(() => {
window.addEventListener('click', handleGlobalClick);
});
onUnmounted(() => {
window.removeEventListener('click', handleGlobalClick);
});
defineExpose({
contentContainerRef
});
// Markdown流处理
const { renderedContent, updateContent } = useMarkdownStream();
// 初始化编辑器
VMdEditor.use(vuepressTheme, { Prism });
// 保存处理
const handleSave = (text, html) => {
console.log("保存内容:", { markdown: text, html: html });
store.reportContent = text;
localStorage.setItem("markdown-content", text);
ElMessage.success("保存成功!");
};
// 上传图片处理
const handleUploadImage = async (event, insertImage, files) => {
ElMessage.info("图片上传功能待实现");
// 实际项目中可调用Pinia中的上传方法
// await store.uploadImage(files[0]);
};
// 监听Store内容变化,同步更新预览
watch(
() => store.reportContent,
async (newVal) => {
await updateContent(newVal, contentContainerRef.value);
},
{ immediate: true }
);
</script>
<style lang="scss" scoped>
.main-box {
flex: 1;
height: 100%;
background: #f7f8f9;
.edit-panel {
width: calc(100% - 170px);
height: calc(100% - 40px);
margin: 20px 50px;
}
.content-box {
width: 1069px;
height: 100%;
overflow-y: auto;
padding: 20px 80px;
line-height: 1.7;
font-size: 16px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
background: rgba(255, 255, 255, 1);
margin: 17px auto 0 auto;
img {
width: 300px;
height: auto;
}
:deep(.clause-ref-btn) {
display: inline-flex;
align-items: center;
justify-content: center;
height: 1.5em;
min-width: 1.5em;
padding: 0 4px;
margin: 0 2px;
font-size: 0.9em;
line-height: 1;
color: #fff;
background-color: var(--color-main-active, #055fc2);
border: none;
border-radius: 4px;
cursor: pointer;
vertical-align: middle;
transition: background-color 0.2s;
&:hover {
background-color: #044da5;
}
&:active {
transform: translateY(1px);
}
}
}
}
</style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论